On 23 February 2016 at 15:47, Igor R <boost.li...@gmail.com> wrote: > I implemented a simple sys_bus device that only communicates through > port io. The purpose of this device is to be accessible via /dev/port > only, with no need for any additional kernel modules. > I Defined the memory region using memory_region_init_io and registered > it using sysbus_add_io. > I registered the memory region in address 0x9000, and defined custom > read and write functions for it. > In the guest Linux I used dd if=/dev/port skip=$((0x9000)) count=1 > bs=1 to access the port io registers. > > This worked great for x86 and mips (malta) machines, however, on an > arm (versatilepb) machine, I couldn't get this method to work. > The reads and writes from 0x900X addresses did not get through to my device.
> Further inspection revealed that in arm, the kernel tries to reference > the *virtual* address 0x9000, while in mips it references the virtual > address 0x8b009000. > (In x86 a different set of opcodes are used to access the port io area). /dev/port and the IO ports implemented in QEMU with sysbus_add_io are an x86-centric idea (they correspond to what you get from doing inb and outb instructions). What an architecture without real IO ports decides to map /dev/port to do is a kernel level decision. What QEMU might or might not use sysbus_add_io for is a different decision, and there's no reason the two should line up. For ARM QEMU, sysbus_add_io is just not used, because it doesn't make sense to try to add a device with IO ports to an ARM board (with the special case exception of a PCI card, which has its own mechanism for declaring that it has PCI IO ports). I'm not sure what the kernel does with /dev/port but it looks like it sets it up to do mmio accesses to the PCI IO window. thanks -- PMM