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). Thanks, Adam _______________________________________________ l4-hackers mailing list l4-hackers@os.inf.tu-dresden.de http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers