]> xenbits.xensource.com Git - osstest/seabios.git/commitdiff
virtio-mmio: add support for block devices.
authorGerd Hoffmann <kraxel@redhat.com>
Mon, 9 Mar 2020 07:05:21 +0000 (08:05 +0100)
committerGerd Hoffmann <kraxel@redhat.com>
Fri, 15 May 2020 11:37:07 +0000 (13:37 +0200)
Add and use bootprio_find_mmio_device() to figure
the boot priority of virtio-mmio block devices.

Add init_virtio_blk_mmio to initialize one
virtio-mmio block device.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
src/boot.c
src/hw/virtio-blk.c
src/hw/virtio-blk.h
src/hw/virtio-mmio.c
src/util.h

index f2f084bea8433f81570d5e8edc6e7fb04aae34e4..cc87b1d98476537f849ab142bddc90168183fc6a 100644 (file)
@@ -316,6 +316,15 @@ int bootprio_find_pci_device(struct pci_device *pci)
     return find_prio(desc);
 }
 
+int bootprio_find_mmio_device(void *mmio)
+{
+    if (!CONFIG_BOOTORDER)
+        return -1;
+    char desc[256];
+    snprintf(desc, sizeof(desc), "/virtio-mmio@%016x/*", (u32)mmio);
+    return find_prio(desc);
+}
+
 int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun)
 {
     if (!CONFIG_BOOTORDER)
index a5e28fc858b1e4b036a58e6959ef5952653d2084..3b198965c8ba4ff3f4d7e27ddd525f4904c981b2 100644 (file)
@@ -20,6 +20,7 @@
 #include "string.h" // memset
 #include "util.h" // usleep, bootprio_find_pci_device, is_bootprio_strict
 #include "virtio-pci.h"
+#include "virtio-mmio.h"
 #include "virtio-ring.h"
 #include "virtio-blk.h"
 
@@ -193,6 +194,76 @@ fail:
     free(vdrive);
 }
 
+void
+init_virtio_blk_mmio(void *mmio)
+{
+    u8 status = VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER;
+    dprintf(1, "found virtio-blk-mmio at %p\n", mmio);
+    struct virtiodrive_s *vdrive = malloc_low(sizeof(*vdrive));
+    if (!vdrive) {
+        warn_noalloc();
+        return;
+    }
+    memset(vdrive, 0, sizeof(*vdrive));
+    vdrive->drive.type = DTYPE_VIRTIO_BLK;
+    vdrive->drive.cntl_id = (u32)mmio;
+
+    vp_init_mmio(&vdrive->vp, mmio);
+    if (vp_find_vq(&vdrive->vp, 0, &vdrive->vq) < 0 ) {
+        dprintf(1, "fail to find vq for virtio-blk-mmio %p\n", mmio);
+        goto fail;
+    }
+
+    struct vp_device *vp = &vdrive->vp;
+    u64 features = vp_get_features(vp);
+    u64 version1 = 1ull << VIRTIO_F_VERSION_1;
+    u64 blk_size = 1ull << VIRTIO_BLK_F_BLK_SIZE;
+
+    features = features & (version1 | blk_size);
+    vp_set_features(vp, features);
+    status |= VIRTIO_CONFIG_S_FEATURES_OK;
+    vp_set_status(vp, status);
+    if (!(vp_get_status(vp) & VIRTIO_CONFIG_S_FEATURES_OK)) {
+        dprintf(1, "device didn't accept features: %p\n", mmio);
+        goto fail;
+    }
+
+    vdrive->drive.sectors =
+        vp_read(&vp->device, struct virtio_blk_config, capacity);
+    if (features & blk_size) {
+        vdrive->drive.blksize =
+            vp_read(&vp->device, struct virtio_blk_config, blk_size);
+    } else {
+        vdrive->drive.blksize = DISK_SECTOR_SIZE;
+    }
+    if (vdrive->drive.blksize != DISK_SECTOR_SIZE) {
+        dprintf(1, "virtio-blk-mmio %p block size %d is unsupported\n",
+                mmio, vdrive->drive.blksize);
+        goto fail;
+    }
+    dprintf(1, "virtio-blk-mmio %p blksize=%d sectors=%u\n",
+            mmio, vdrive->drive.blksize, (u32)vdrive->drive.sectors);
+
+    vdrive->drive.pchs.cylinder =
+        vp_read(&vp->device, struct virtio_blk_config, cylinders);
+    vdrive->drive.pchs.head =
+        vp_read(&vp->device, struct virtio_blk_config, heads);
+    vdrive->drive.pchs.sector =
+        vp_read(&vp->device, struct virtio_blk_config, sectors);
+
+    char *desc = znprintf(MAXDESCSIZE, "Virtio disk mmio:%p", mmio);
+    boot_add_hd(&vdrive->drive, desc, bootprio_find_mmio_device(mmio));
+
+    status |= VIRTIO_CONFIG_S_DRIVER_OK;
+    vp_set_status(&vdrive->vp, status);
+    return;
+
+fail:
+    vp_reset(&vdrive->vp);
+    free(vdrive->vq);
+    free(vdrive);
+}
+
 void
 virtio_blk_setup(void)
 {
index 157bed62744aa2c71363a0397235ea18f01f0bc3..d20461a2a3b2f0abdf8f45714a5621fe7465e323 100644 (file)
@@ -39,5 +39,6 @@ struct virtio_blk_outhdr {
 struct disk_op_s;
 int virtio_blk_process_op(struct disk_op_s *op);
 void virtio_blk_setup(void);
+void init_virtio_blk_mmio(void *mmio);
 
 #endif /* _VIRTIO_BLK_H */
index daca8a098a0bca513b5bc9f39ecfab40e5a70461..adb28f730592cd1b3512049344ad78fec0cfd2e7 100644 (file)
@@ -4,6 +4,7 @@
 #include "stacks.h" // run_thread
 #include "string.h" // memset
 #include "virtio-pci.h"
+#include "virtio-blk.h"
 #include "virtio-scsi.h"
 #include "virtio-ring.h"
 #include "virtio-mmio.h"
@@ -35,7 +36,7 @@ void virtio_mmio_setup_one(u64 addr)
             addr, devid, version == 1 ? " (legacy)" : "");
     switch (devid) {
     case 2: /* blk */
-        /* TODO */
+        run_thread(init_virtio_blk_mmio, mmio);
         break;
     case 8: /* scsi */
         run_thread(init_virtio_scsi_mmio, mmio);
index 1c82e09ed87bb921835ca628b6baa5ba1b65fc0d..4f27fc307439ab73b7724d8695ad19d48ed98615 100644 (file)
@@ -30,6 +30,7 @@ void bcv_prepboot(void);
 u8 is_bootprio_strict(void);
 struct pci_device;
 int bootprio_find_pci_device(struct pci_device *pci);
+int bootprio_find_mmio_device(void *mmio);
 int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun);
 int bootprio_find_scsi_mmio_device(void *mmio, int target, int lun);
 int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave);