[SeaBIOS] [PATCH 1/9] Provide full EDD 3.0 info for virtio disk

Gleb Natapov gleb at redhat.com
Thu Dec 23 10:29:35 CET 2010


Fill out entire EDD 3.0 structure for virtio disk. Currently only EDD 1.0
part is filled which is missing such important info as device path. Use
SCSI device type since virtio is not defined by EDD spec and virtio disk pci
device uses SCSI class.

Signed-off-by: Gleb Natapov <gleb at redhat.com>
---
 src/disk.c |  126 ++++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 73 insertions(+), 53 deletions(-)

diff --git a/src/disk.c b/src/disk.c
index 242c742..56c369a 100644
--- a/src/disk.c
+++ b/src/disk.c
@@ -544,64 +544,78 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
     }
     SET_INT13DPT(regs, blksize, blksize);
 
-    if (size < 30 || (type != DTYPE_ATA && type != DTYPE_ATAPI)) {
+    if (size < 30 ||
+        (type != DTYPE_ATA && type != DTYPE_ATAPI && type != DTYPE_VIRTIO)) {
         disk_ret(regs, DISK_RET_SUCCESS);
         return;
     }
 
     // EDD 2.x
 
-    u16 ebda_seg = get_ebda_seg();
+    int bdf;
+    u16 iobase1;
+    u64 device_path;
     SET_INT13DPT(regs, size, 30);
+    if (type == DTYPE_ATA || type == DTYPE_ATAPI) {
+        u16 ebda_seg = get_ebda_seg();
 
-    SET_INT13DPT(regs, dpte_segment, ebda_seg);
-    SET_INT13DPT(regs, dpte_offset
-                 , offsetof(struct extended_bios_data_area_s, dpte));
-
-    // Fill in dpte
-    struct atadrive_s *adrive_g = container_of(
-        drive_g, struct atadrive_s, drive);
-    struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
-    u8 slave = GET_GLOBAL(adrive_g->slave);
-    u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
-    u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
-    u8 irq = GET_GLOBALFLAT(chan_gf->irq);
-
-    u16 options = 0;
-    if (type == DTYPE_ATA) {
-        u8 translation = GET_GLOBAL(drive_g->translation);
-        if (translation != TRANSLATION_NONE) {
-            options |= 1<<3; // CHS translation
-            if (translation == TRANSLATION_LBA)
-                options |= 1<<9;
-            if (translation == TRANSLATION_RECHS)
-                options |= 3<<9;
+        SET_INT13DPT(regs, dpte_segment, ebda_seg);
+        SET_INT13DPT(regs, dpte_offset
+                     , offsetof(struct extended_bios_data_area_s, dpte));
+
+        // Fill in dpte
+        struct atadrive_s *adrive_g = container_of(
+            drive_g, struct atadrive_s, drive);
+        struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
+        u8 slave = GET_GLOBAL(adrive_g->slave);
+        u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
+        u8 irq = GET_GLOBALFLAT(chan_gf->irq);
+        iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
+        bdf = GET_GLOBALFLAT(chan_gf->pci_bdf);
+        device_path = slave;
+
+        u16 options = 0;
+        if (type == DTYPE_ATA) {
+            u8 translation = GET_GLOBAL(drive_g->translation);
+            if (translation != TRANSLATION_NONE) {
+                options |= 1<<3; // CHS translation
+                if (translation == TRANSLATION_LBA)
+                    options |= 1<<9;
+                if (translation == TRANSLATION_RECHS)
+                    options |= 3<<9;
+            }
+        } else {
+            // ATAPI
+            options |= 1<<5; // removable device
+            options |= 1<<6; // atapi device
         }
+        options |= 1<<4; // lba translation
+        if (CONFIG_ATA_PIO32)
+            options |= 1<<7;
+
+        SET_EBDA2(ebda_seg, dpte.iobase1, iobase1);
+        SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC);
+        SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)
+                                          | ATA_CB_DH_LBA));
+        SET_EBDA2(ebda_seg, dpte.unused, 0xcb);
+        SET_EBDA2(ebda_seg, dpte.irq, irq);
+        SET_EBDA2(ebda_seg, dpte.blkcount, 1);
+        SET_EBDA2(ebda_seg, dpte.dma, 0);
+        SET_EBDA2(ebda_seg, dpte.pio, 0);
+        SET_EBDA2(ebda_seg, dpte.options, options);
+        SET_EBDA2(ebda_seg, dpte.reserved, 0);
+        SET_EBDA2(ebda_seg, dpte.revision, 0x11);
+
+        u8 sum = checksum_far(
+            ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15);
+        SET_EBDA2(ebda_seg, dpte.checksum, -sum);
     } else {
-        // ATAPI
-        options |= 1<<5; // removable device
-        options |= 1<<6; // atapi device
+        SET_INT13DPT(regs, dpte_segment, 0);
+        SET_INT13DPT(regs, dpte_offset, 0);
+        bdf = GET_GLOBAL(drive_g->cntl_id);
+        device_path = 0;
+        iobase1 = 0;
     }
-    options |= 1<<4; // lba translation
-    if (CONFIG_ATA_PIO32)
-        options |= 1<<7;
-
-    SET_EBDA2(ebda_seg, dpte.iobase1, iobase1);
-    SET_EBDA2(ebda_seg, dpte.iobase2, iobase2 + ATA_CB_DC);
-    SET_EBDA2(ebda_seg, dpte.prefix, ((slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0)
-                                      | ATA_CB_DH_LBA));
-    SET_EBDA2(ebda_seg, dpte.unused, 0xcb);
-    SET_EBDA2(ebda_seg, dpte.irq, irq);
-    SET_EBDA2(ebda_seg, dpte.blkcount, 1);
-    SET_EBDA2(ebda_seg, dpte.dma, 0);
-    SET_EBDA2(ebda_seg, dpte.pio, 0);
-    SET_EBDA2(ebda_seg, dpte.options, options);
-    SET_EBDA2(ebda_seg, dpte.reserved, 0);
-    SET_EBDA2(ebda_seg, dpte.revision, 0x11);
-
-    u8 sum = checksum_far(
-        ebda_seg, (void*)offsetof(struct extended_bios_data_area_s, dpte), 15);
-    SET_EBDA2(ebda_seg, dpte.checksum, -sum);
 
     if (size < 66) {
         disk_ret(regs, DISK_RET_SUCCESS);
@@ -614,7 +628,6 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
     SET_INT13DPT(regs, reserved1, 0);
     SET_INT13DPT(regs, reserved2, 0);
 
-    int bdf = GET_GLOBALFLAT(chan_gf->pci_bdf);
     if (bdf != -1) {
         SET_INT13DPT(regs, host_bus[0], 'P');
         SET_INT13DPT(regs, host_bus[1], 'C');
@@ -634,16 +647,23 @@ disk_1348(struct bregs *regs, struct drive_s *drive_g)
         SET_INT13DPT(regs, iface_path, iobase1);
     }
 
-    SET_INT13DPT(regs, iface_type[0], 'A');
-    SET_INT13DPT(regs, iface_type[1], 'T');
-    SET_INT13DPT(regs, iface_type[2], 'A');
-    SET_INT13DPT(regs, iface_type[3], 0);
+    if (type != DTYPE_VIRTIO) {
+        SET_INT13DPT(regs, iface_type[0], 'A');
+        SET_INT13DPT(regs, iface_type[1], 'T');
+        SET_INT13DPT(regs, iface_type[2], 'A');
+        SET_INT13DPT(regs, iface_type[3], 0);
+    } else {
+        SET_INT13DPT(regs, iface_type[0], 'S');
+        SET_INT13DPT(regs, iface_type[1], 'C');
+        SET_INT13DPT(regs, iface_type[2], 'S');
+        SET_INT13DPT(regs, iface_type[3], 'I');
+    }
     SET_INT13DPT(regs, iface_type[4], 0);
     SET_INT13DPT(regs, iface_type[5], 0);
     SET_INT13DPT(regs, iface_type[6], 0);
     SET_INT13DPT(regs, iface_type[7], 0);
 
-    SET_INT13DPT(regs, device_path, slave);
+    SET_INT13DPT(regs, device_path, device_path);
 
     SET_INT13DPT(regs, checksum
                  , -checksum_far(regs->ds, (void*)(regs->si+30), 35));
-- 
1.7.2.3




More information about the SeaBIOS mailing list