Date: Fri, 16 Jan 2015 11:13:39 -0700 From: Ian Lepore <ian@freebsd.org> To: Manuel =?ISO-8859-1?Q?St=FChn?= <freebsdnewbie@freenet.de> Cc: freebsd-arm@freebsd.org Subject: Re: mmap-issue Message-ID: <1421432019.14601.302.camel@freebsd.org> In-Reply-To: <54B945FB.10609@freenet.de> References: <54B945FB.10609@freenet.de>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 2015-01-16 at 18:10 +0100, Manuel St=FChn wrote: > Hi, >=20 > I'm seeing unexpected behavior using mmap( /dev/mem ) on my beaglebone=20 > black. It seems to me, that writing to/reading from this mapped pointer= =20 > does not immediatly take effect. The code looks like this: >=20 > #define GPIO1 0x4804C000 > #define CLR_REG 0x190 > #define SET_REG 0x194 > #define LED0 21 > #define LED1 22 > #define LED2 23 > #define LED3 24 >=20 > int fd =3D open( "/dev/mem", O_RDWR ); >=20 > int pagesize =3D getpagesize(); >=20 > volatile uint32_t* ptr =3D > mmap( 0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_ADDR )= ; >=20 > ptr[SET_REG] =3D LED0 << 1; >=20 >=20 > I mapped for testing purposes the AM335x-GPIO-registers from /dev/mem. > Writing into these mmap'ed registers for toggling some LEDs does not=20 > immediatly take effect. I have to call it several times to get one=20 > LED-toggle. Is there any data caching I'm missing? >=20 > Thanks for hints. 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. It seems crazy to me to allow userland access to the same hardware that freebsd drivers are trying to work with. So I think the right answer is that you should investigate using gpioctl and libgpio and the /dev/gpiocN devices. The direct answer to the problem you're seeing is probably that you need to flush the L2 cache write buffers to ensure that the writes make it all the way to the hardware, and there is no userland API for doing that. You may also be running into a problem related to an ARM restriction that a given physical address must not be mapped twice using different memory attributes, and those address ranges are already mapped by the kernel as Device memory, so remapping them as Normal memory via /dev/mem may result in the dreaded "undefined behavior." -- Ian
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1421432019.14601.302.camel>