Configuring a virtio device over PCI
Posted: Sun Mar 17, 2019 2:07 pm
Hey all, I've been working on adding a PCI + virtio layer to xv6 (a teaching OS). I've been using the osdev pages on PCI and virtio + the virtio 1.0 specification to build this. I've also been looking at existing implementations in minix, linux and a hobby operating system linked to in the osdev virtio page.
I've been having issues with configuring the virtio device itself. The specification talks about finding the VIRTIO_PCI_CAP_COMMON_CFG in the PCI capabilities list, figure out which BAR it is mapped to, and that's where you'll find the configuration structure. When I read from the address obtained from the BAR (BAR4), I don't get any valid values. I am running the OS in a debug build of qemu, and setting up breakpoints in the appropriate memory region handlers(virtio_pci_common_read/write), I don't see any of them being hit.
I tried the legacy interface of using the io space address in BAR0 (always the address 0xC000), but using the in/out instructions and reading/writing from the registers specified in the specification (and minix implementations), I do not get any valid values (it's all 1s). Setting up breakpoints in the functions handling the reads and writes to this region also was a dead end.
The only way I am able to configure the device is by using the VIRTIO_PCI_CAP_PCI_CFG and setting up the window to read and write values. The specification mentions that this is not the preferred way to configure the device. This also does not let me read device specific configuration for the network device which contains the mac address.
I apologize if I missed anything obvious. I've been banging my head against this problem for a while now and I would appreciate some help pointing me in the right direction .
I've been having issues with configuring the virtio device itself. The specification talks about finding the VIRTIO_PCI_CAP_COMMON_CFG in the PCI capabilities list, figure out which BAR it is mapped to, and that's where you'll find the configuration structure. When I read from the address obtained from the BAR (BAR4), I don't get any valid values. I am running the OS in a debug build of qemu, and setting up breakpoints in the appropriate memory region handlers(virtio_pci_common_read/write), I don't see any of them being hit.
I tried the legacy interface of using the io space address in BAR0 (always the address 0xC000), but using the in/out instructions and reading/writing from the registers specified in the specification (and minix implementations), I do not get any valid values (it's all 1s). Setting up breakpoints in the functions handling the reads and writes to this region also was a dead end.
The only way I am able to configure the device is by using the VIRTIO_PCI_CAP_PCI_CFG and setting up the window to read and write values. The specification mentions that this is not the preferred way to configure the device. This also does not let me read device specific configuration for the network device which contains the mac address.
I apologize if I missed anything obvious. I've been banging my head against this problem for a while now and I would appreciate some help pointing me in the right direction .