Date: Fri, 16 Jan 2015 20:48:35 -0700 From: Ian Lepore <ian@freebsd.org> To: Johny Mattsson <johny.mattsson+fbsd@gmail.com> Cc: freebsd-arm@freebsd.org Subject: Re: mmap-issue Message-ID: <1421466515.14601.323.camel@freebsd.org> In-Reply-To: <CAGW5k5YqK-xP_erf6H2XXUKmX8Dkbex81SYC5am5saAAqRfp8A@mail.gmail.com> References: <54B945FB.10609@freenet.de> <1421432019.14601.302.camel@freebsd.org> <CAGW5k5YqK-xP_erf6H2XXUKmX8Dkbex81SYC5am5saAAqRfp8A@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--=-unJQW8/bIhpk1ulCm/5l Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On Sat, 2015-01-17 at 10:34 +1100, Johny Mattsson wrote: > On 17 January 2015 at 05:13, Ian Lepore <ian@freebsd.org> wrote: > > > My gut-level reply is "Don't try to access hardware registers like that, > > you're only going to run into problems" (as you already have). But I've > > just been informed that linux allows such things. > > > Indeed it does, and what a life^Wproject-saver it can be! Only last year I > had to deal with an existing large-scale deployment (100,000s of devices) > where a peripheral on the SPI bus had a hardware bug where it could > intermittently "lose" a clock pulse and get itself completely out of sync > on the bus. Being able to quietly pull the SPI control from the driver and > do a little dance on the clock and data lines in GPIO mode before returning > control to the driver saved the day on that one. > > A few years before that, we had some extremely performance sensitive > network I/O to deal with, where we effectively had a driver stub which > allocated the resources and then allowed them to be mmap()ed into userspace > for direct hardware control. Given the complexity of the system, it wasn't > considered viable to have this processing done in the kernel. > That's a very different thing... a driver that exists primarily to give userland access to hardware can be written to map the memory correctly and presumably won't be accessing the hardware concurrently with userland and so on. It's a bit safer than just using /dev/mem to start bashing on hardware without any cooperation from the bits of the OS doing the same. Anyway, after glancing at the code implementing /dev/mem on freebsd arm I think it's woefully incomplete. It's basically a copy of the i386 code, which means it assumes that caches take care of themselves at some hardware level. What we need is something more like the PowerPC implementation that supports the ioctls documented in mem(4) for setting up uncached mappings. All in all, I think it could take a while to fix this properly. For the near term, the attached patch may be a reasonable(ish) hack to get device access to work. (Its drawback is that it can only detect device memory if it's part of the statically-mapped resources for the platform. On the plus side, for beaglebone all device memory is statically mapped in ti_machdep.c.) This is completely untested other than "it compiles." -- Ian --=-unJQW8/bIhpk1ulCm/5l Content-Disposition: inline; filename="devmem_uncacheable_hack.diff" Content-Type: text/x-patch; name="devmem_uncacheable_hack.diff"; charset="us-ascii" Content-Transfer-Encoding: 7bit Index: sys/arm/arm/mem.c =================================================================== --- sys/arm/arm/mem.c (revision 277262) +++ sys/arm/arm/mem.c (working copy) @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include <vm/pmap.h> #include <vm/vm_extern.h> +#include <machine/devmap.h> #include <machine/memdev.h> #include <machine/vmparam.h> @@ -152,7 +153,7 @@ memrw(struct cdev *dev, struct uio *uio, int flags int memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, - int prot __unused, vm_memattr_t *memattr __unused) + int prot __unused, vm_memattr_t *memattr) { if (dev2unit(dev) == CDEV_MINOR_MEM) *paddr = offset; @@ -159,5 +160,7 @@ memmmap(struct cdev *dev, vm_ooffset_t offset, vm_ else if (dev2unit(dev) == CDEV_MINOR_KMEM) *paddr = vtophys(offset); /* else panic! */ + if (arm_devmap_ptov(*paddr, 4) != NULL) + *memattr = VM_MEMATTR_UNCACHEABLE; return (0); } --=-unJQW8/bIhpk1ulCm/5l--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1421466515.14601.323.camel>