I/O memory access and hardware page mappings

Adam Lackorzynski adam at os.inf.tu-dresden.de
Tue Jul 25 23:47:26 CEST 2017

Hi Paul,

On Mon Jul 24, 2017 at 16:55:37 +0200, Paul Boddie wrote:
> Having looked at the l4vbus_gpio functions and struggled with providing 
> suitable devices, I decided to take the simpler approach and just ask for the 
> I/O memory of the devices and access that directly. However, this didn't prove 
> as straightforward as anticipated, either.
> The aim was to take the previously-mentioned device resources of the following 
> form and to perform l4io_request_iomem (or l4io_request_resource_iomem) to get 
> addresses of virtual regions corresponding to the different physical memory 
> regions.
>     PORTA = Hw.Device(function()
>       Property.hid = "jz4780-gpio-PORTA";
>       Resource.regs = Res.mmio(0x10010000, 0x100100ff);
>       ...
>     end);
>     PORTB = Hw.Device(function()
>       Property.hid = "jz4780-gpio-PORTB";
>       Resource.regs = Res.mmio(0x10010100, 0x100101ff);
>       ...
>     end);
>     ...
>     PORTF = Hw.Device(function()
>       Property.hid = "jz4780-gpio-PORTF";
>       Resource.regs = Res.mmio(0x10010500, 0x100105ff);
>       ...
>     end);
> It was indeed possible to obtain the resources involved with individual ports 
> and also to obtain an address for each port region. However, accesses relative 
> to these base addresses did not produce the expected results (LED output 
> changes, switch input changes).
> (Looking at the virtual and physical regions in jdb suggested that the 
> accesses were not being propagated, although I was also not successful in 
> putting values into physical memory addresses and obtaining any of the 
> expected results, either.)
> Now, I did wonder how such a small, 256-byte region mapping would actually 
> work with my hardware. The JZ4780 does not support pages smaller than 4K when 
> mapping memory, but I did notice that I do get an exception if trying to 
> access beyond the end of the virtual region.
> (I found this out when considering that perhaps the virtual address might 
> actually point to the base of the hardware page containing the region. So, I 
> added a region offset to the base and tried to perform a memory access. 
> Obviously, returning the hardware page address would be an unfortunate choice 
> because it would oblige the API user to know about such things. Clearly, the 
> API should return the address of the actual region, and maybe it does.)
> So, if this smaller-than-hardware page size is enforced, there must be a 
> mechanism above the plain TLB mechanism that performs such enforcement. One 
> interesting thing I noticed was that when requesting two different regions, 
> the virtual addresses for the base of the regions were 4K apart, not 256 bytes 
> apart. In any case, I was left wondering if any such mechanism might be 
> preventing accesses from being correctly propagated.
> To simplify things a bit more, I then decided to just define the entire GPIO 
> region in the device tree:
>   GPIO = Hw.Device(function()
>     Property.hid = "JZ4780 GPIO";
>     Resource.regs = Res.mmio(0x10010000, 0x100105ff);
>   end);
> Requesting the memory for this device succeeds as before, but then performing 
> accesses relative to the returned virtual address (with port F at vaddr + 
> 0x500, for instance) also succeeds and produces the desired result, unlike 
> before.
> So, what is this mechanism that handles accesses to regions that do not 
> correspond to hardware pages (either in size or alignment)? Is there some kind 
> of address-based trapping that redirects accesses to some kind of privately-
> allocated page that is then mapped to the hardware page concerned? Is it 
> possible that this mechanism does not work on MIPS or on my specific device?

There's no mechanism here that handles MMIO region sizes smaller than
page size. Rather, l4io_request_iomem and friends to not handle
addresses with offsets very well. Obviously I'll fix this.
For now, please just use page-aligned physical addresses (and size).


More information about the l4-hackers mailing list