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

Reply via email to