Hello again, 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? I apologise if I should be answering my own questions by looking at the code or particular documentation resources. Paul _______________________________________________ l4-hackers mailing list l4-hackers@os.inf.tu-dresden.de http://os.inf.tu-dresden.de/mailman/listinfo/l4-hackers