diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hw/virtio-mmio.c | 58 | ||||
-rw-r--r-- | src/hw/virtio-mmio.h | 76 | ||||
-rw-r--r-- | src/hw/virtio-pci.h | 1 |
3 files changed, 135 insertions, 0 deletions
diff --git a/src/hw/virtio-mmio.c b/src/hw/virtio-mmio.c new file mode 100644 index 00000000..0d6ef6e2 --- /dev/null +++ b/src/hw/virtio-mmio.c @@ -0,0 +1,58 @@ +#include "config.h" // CONFIG_DEBUG_LEVEL +#include "malloc.h" // free +#include "output.h" // dprintf +#include "stacks.h" // run_thread +#include "string.h" // memset +#include "virtio-pci.h" +#include "virtio-ring.h" +#include "virtio-mmio.h" + +void virtio_mmio_setup_one(u64 addr) +{ + u32 magic, version, devid; + void *mmio; + + if (addr >= 0x100000000) { + dprintf(1, "virtio-mmio: %llx: above 4G\n", addr); + return; + } + + mmio = (void*)(u32)(addr); + magic = readl(mmio); + if (magic != 0x74726976) { + dprintf(1, "virtio-mmio: %llx: magic mismatch\n", addr); + return; + } + version = readl(mmio+4); + if (version != 1 /* legacy */ && + version != 2 /* 1.0 */) { + dprintf(1, "virtio-mmio: %llx: unknown version %d\n", addr, version); + return; + } + devid = readl(mmio+8); + dprintf(1, "virtio-mmio: %llx: device id %x%s\n", + addr, devid, version == 1 ? " (legacy)" : ""); + switch (devid) { + case 2: /* blk */ + /* TODO */ + break; + case 8: /* scsi */ + /* TODO */ + break; + default: + break; + } +} + +void vp_init_mmio(struct vp_device *vp, void *mmio) +{ + memset(vp, 0, sizeof(*vp)); + vp->use_mmio = 1; + vp->common.mode = VP_ACCESS_MMIO; + vp->common.memaddr = mmio; + vp->device.mode = VP_ACCESS_MMIO; + vp->device.memaddr = mmio + 0x100; + vp_reset(vp); + vp_set_status(vp, VIRTIO_CONFIG_S_ACKNOWLEDGE | + VIRTIO_CONFIG_S_DRIVER); +} diff --git a/src/hw/virtio-mmio.h b/src/hw/virtio-mmio.h new file mode 100644 index 00000000..9e0dae42 --- /dev/null +++ b/src/hw/virtio-mmio.h @@ -0,0 +1,76 @@ +#ifndef _VIRTIO_MMIO_H +#define _VIRTIO_MMIO_H + +struct vp_device; + +typedef struct virtio_mmio_cfg { + u32 magic; + u32 version; + u32 device_id; + u32 vendor_id; + + u32 device_feature; + u32 device_feature_select; + u32 res_18; + u32 res_1c; + + u32 guest_feature; + u32 guest_feature_select; + u32 legacy_guest_page_size; + u32 res_2c; + + u32 queue_select; + u32 queue_num_max; + u32 queue_num; + u32 legacy_queue_align; + + u32 legacy_queue_pfn; + u32 queue_ready; + u32 res_48; + u32 res_4c; + + u32 queue_notify; + u32 res_54; + u32 res_58; + u32 res_5c; + + u32 irq_status; + u32 irq_ack; + u32 res_68; + u32 res_6c; + + u32 device_status; + u32 res_74; + u32 res_78; + u32 res_7c; + + u32 queue_desc_lo; + u32 queue_desc_hi; + u32 res_88; + u32 res_8c; + + u32 queue_driver_lo; + u32 queue_driver_hi; + u32 res_98; + u32 res_9c; + + u32 queue_device_lo; + u32 queue_device_hi; + u32 res_a8; + u32 shm_sel; + + u32 shmem_len_lo; + u32 shmem_len_hi; + u32 shmem_base_lo; + u32 shmem_base_hi; + + u32 res_c0_f7[14]; + + u32 res_f8; + u32 config_generation; +} virtio_mmio_cfg; + +void virtio_mmio_setup_one(u64 mmio); +void vp_init_mmio(struct vp_device *vp, void *mmio); + +#endif /* _VIRTIO_MMIO_H */ diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h index 492e5c7c..26962644 100644 --- a/src/hw/virtio-pci.h +++ b/src/hw/virtio-pci.h @@ -111,6 +111,7 @@ struct vp_device { struct vp_cap common, notify, isr, device, legacy; u32 notify_off_multiplier; u8 use_modern; + u8 use_mmio; }; u64 _vp_read(struct vp_cap *cap, u32 offset, u8 size); |