diff --git a/blk-virtio.c b/blk-virtio.c index 7670f0c..e7eb44e 100644 --- a/blk-virtio.c +++ b/blk-virtio.c @@ -6,12 +6,80 @@ #define VIRTIO_PCI_IOPORT_SIZE 24 +struct device { + uint32_t guest_features; + uint8_t status; +}; + +static struct device device; + +static bool blk_virtio_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) +{ + unsigned long offset; + + offset = port - IOPORT_VIRTIO; + + switch (offset) { + case VIRTIO_PCI_HOST_FEATURES: + ioport__write32(data, 0x00); + break; + case VIRTIO_PCI_GUEST_FEATURES: + case VIRTIO_PCI_QUEUE_PFN: + case VIRTIO_PCI_QUEUE_NUM: + case VIRTIO_PCI_QUEUE_SEL: + case VIRTIO_PCI_QUEUE_NOTIFY: + return false; + case VIRTIO_PCI_STATUS: + ioport__write8(data, device.status); + break; + case VIRTIO_PCI_ISR: + case VIRTIO_MSI_CONFIG_VECTOR: + default: + return false; + }; + + return true; +} + +#include + +static bool blk_virtio_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) +{ + unsigned long offset; + + offset = port - IOPORT_VIRTIO; + + switch (offset) { + case VIRTIO_PCI_GUEST_FEATURES: + device.guest_features = ioport__read32(data); + break; + case VIRTIO_PCI_QUEUE_PFN: + case VIRTIO_PCI_QUEUE_SEL: + case VIRTIO_PCI_QUEUE_NOTIFY: + return false; + case VIRTIO_PCI_STATUS: + device.status = ioport__read8(data); + break; + case VIRTIO_MSI_CONFIG_VECTOR: + case VIRTIO_MSI_QUEUE_VECTOR: + default: + return false; + }; + + return true; +} + +static struct ioport_operations blk_virtio_io_ops = { + .io_in = blk_virtio_in, + .io_out = blk_virtio_out, +}; + #define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 #define PCI_DEVICE_ID_VIRTIO_BLK 0x1001 #define PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET 0x1af4 #define PCI_SUBSYSTEM_ID_VIRTIO_BLK 0x0002 -static struct pci_device_header blk_virtio_device = { +static struct pci_device_header blk_virtio_pci_device = { .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET, .device_id = PCI_DEVICE_ID_VIRTIO_BLK, .header_type = PCI_HEADER_TYPE_NORMAL, @@ -22,56 +90,9 @@ static struct pci_device_header blk_virtio_device = { .bar[0] = IOPORT_VIRTIO | PCI_BASE_ADDRESS_SPACE_IO, }; -static bool blk_virtio_in(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) -{ - unsigned long offset; - - offset = port - IOPORT_VIRTIO; - - switch (offset) { - case VIRTIO_PCI_HOST_FEATURES: - case VIRTIO_PCI_GUEST_FEATURES: - case VIRTIO_PCI_QUEUE_PFN: - case VIRTIO_PCI_QUEUE_NUM: - case VIRTIO_PCI_QUEUE_SEL: - case VIRTIO_PCI_QUEUE_NOTIFY: - case VIRTIO_PCI_STATUS: - case VIRTIO_PCI_ISR: - case VIRTIO_MSI_CONFIG_VECTOR: - return true; - }; - - return false; -} - -static bool blk_virtio_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count) -{ - unsigned long offset; - - offset = port - IOPORT_VIRTIO; - - switch (offset) { - case VIRTIO_PCI_GUEST_FEATURES: - case VIRTIO_PCI_QUEUE_PFN: - case VIRTIO_PCI_QUEUE_SEL: - case VIRTIO_PCI_QUEUE_NOTIFY: - case VIRTIO_PCI_STATUS: - case VIRTIO_MSI_CONFIG_VECTOR: - case VIRTIO_MSI_QUEUE_VECTOR: - return true; - }; - - return false; -} - -static struct ioport_operations blk_virtio_io_ops = { - .io_in = blk_virtio_in, - .io_out = blk_virtio_out, -}; - void blk_virtio__init(void) { - pci__register(&blk_virtio_device, 1); + pci__register(&blk_virtio_pci_device, 1); ioport__register(IOPORT_VIRTIO, &blk_virtio_io_ops, VIRTIO_PCI_IOPORT_SIZE); } diff --git a/include/kvm/ioport.h b/include/kvm/ioport.h index eaedc1e..b4ae9ab 100644 --- a/include/kvm/ioport.h +++ b/include/kvm/ioport.h @@ -17,4 +17,24 @@ struct ioport_operations { void ioport__register(uint16_t port, struct ioport_operations *ops, int count); +static inline uint8_t ioport__read8(uint8_t *data) +{ + return *data; +} + +static inline uint32_t ioport__read32(uint32_t *data) +{ + return *data; +} + +static inline void ioport__write8(uint8_t *data, uint8_t value) +{ + *data = value; +} + +static inline void ioport__write32(uint32_t *data, uint32_t value) +{ + *data = value; +} + #endif /* KVM__IOPORT_H */