[SeaBIOS] [PATCH 2/2] edd: Reduce parameters to fill_generic_edd()

Kevin O'Connor kevin at koconnor.net
Thu Aug 13 15:49:10 CET 2015


Have callers of fill_generic_edd() calculate the edd iface_path
field.  Have callers determine if the bus type is PCI vs ISA.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/block.c | 77 ++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 45 insertions(+), 32 deletions(-)

diff --git a/src/block.c b/src/block.c
index cd732c1..97e05fa 100644
--- a/src/block.c
+++ b/src/block.c
@@ -287,10 +287,18 @@ map_floppy_drive(struct drive_s *drive)
  * Extended Disk Drive (EDD) get drive parameters
  ****************************************************************/
 
+// flags for bus_iface field in fill_generic_edd()
+#define EDD_ISA        0x01
+#define EDD_PCI        0x02
+#define EDD_BUS_MASK   0x0f
+#define EDD_ATA        0x10
+#define EDD_SCSI       0x20
+#define EDD_IFACE_MASK 0xf0
+
+// Fill in EDD info
 static int
 fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf
-                 , u32 dpte_so, char *iface_type
-                 , int bdf, u8 channel, u16 iobase, u64 device_path)
+                 , u32 dpte_so, u8 bus_iface, u32 iface_path, u32 device_path)
 {
     u16 seg = edd.seg;
     struct int13dpt_s *param_far = (void*)(edd.offset+0);
@@ -342,7 +350,7 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf
     SET_FARVAR(seg, param_far->size, 30);
     SET_FARVAR(seg, param_far->dpte.segoff, dpte_so);
 
-    if (size < 66 || !iface_type)
+    if (size < 66 || !bus_iface)
         return DISK_RET_SUCCESS;
 
     // EDD 3.x
@@ -351,32 +359,22 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf
     SET_FARVAR(seg, param_far->reserved1, 0);
     SET_FARVAR(seg, param_far->reserved2, 0);
 
-    int i;
-    for (i=0; i<sizeof(param_far->iface_type); i++)
-        SET_FARVAR(seg, param_far->iface_type[i], GET_GLOBAL(iface_type[i]));
-
-    if (bdf != -1) {
-        SET_FARVAR(seg, param_far->host_bus[0], 'P');
-        SET_FARVAR(seg, param_far->host_bus[1], 'C');
-        SET_FARVAR(seg, param_far->host_bus[2], 'I');
-        SET_FARVAR(seg, param_far->host_bus[3], ' ');
-
-        u32 path = (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8)
-                    | (pci_bdf_to_fn(bdf) << 16));
-        if (t13)
-            path |= channel << 24;
-
-        SET_FARVAR(seg, param_far->iface_path, path);
-    } else {
-        // ISA
-        SET_FARVAR(seg, param_far->host_bus[0], 'I');
-        SET_FARVAR(seg, param_far->host_bus[1], 'S');
-        SET_FARVAR(seg, param_far->host_bus[2], 'A');
-        SET_FARVAR(seg, param_far->host_bus[3], ' ');
-
-        SET_FARVAR(seg, param_far->iface_path, iobase);
+    const char *host_bus = "ISA ";
+    if ((bus_iface & EDD_BUS_MASK) == EDD_PCI) {
+        host_bus = "PCI ";
+        if (!t13)
+            // Phoenix v3 spec (pre t13) did not define the PCI channel field
+            iface_path &= 0x00ffffff;
     }
-
+    memcpy_far(seg, param_far->host_bus, SEG_BIOS, host_bus
+               , sizeof(param_far->host_bus));
+    SET_FARVAR(seg, param_far->iface_path, iface_path);
+
+    const char *iface_type = "ATA     ";
+    if ((bus_iface & EDD_IFACE_MASK) == EDD_SCSI)
+        iface_type = "SCSI    ";
+    memcpy_far(seg, param_far->iface_type, SEG_BIOS, iface_type
+               , sizeof(param_far->iface_type));
     if (t13) {
         SET_FARVAR(seg, param_far->t13.device_path[0], device_path);
         SET_FARVAR(seg, param_far->t13.device_path[1], 0);
@@ -393,8 +391,17 @@ fill_generic_edd(struct segoff_s edd, struct drive_s *drive_gf
     return DISK_RET_SUCCESS;
 }
 
+// Build an EDD "iface_path" field for a PCI device
+static u32
+edd_pci_path(u16 bdf, u8 channel)
+{
+    return (pci_bdf_to_bus(bdf) | (pci_bdf_to_dev(bdf) << 8)
+            | (pci_bdf_to_fn(bdf) << 16) | ((u32)channel << 24));
+}
+
 struct dpte_s DefaultDPTE VARLOW;
 
+// EDD info for ATA and ATAPI drives
 static int
 fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf)
 {
@@ -447,11 +454,17 @@ fill_ata_edd(struct segoff_s edd, struct drive_s *drive_gf)
     u8 sum = checksum_far(SEG_LOW, &DefaultDPTE, 15);
     SET_LOW(DefaultDPTE.checksum, -sum);
 
+    u32 bustype = EDD_ISA, ifpath = iobase1;
+    if (bdf >= 0) {
+        bustype = EDD_PCI;
+        ifpath = edd_pci_path(bdf, channel);
+    }
     return fill_generic_edd(
         edd, drive_gf, SEGOFF(SEG_LOW, (u32)&DefaultDPTE).segoff
-        , "ATA     ", bdf, channel, iobase1, slave);
+        , bustype | EDD_ATA, ifpath, slave);
 }
 
+// Fill Extended Disk Drive (EDD) "Get drive parameters" info for a drive
 int noinline
 fill_edd(struct segoff_s edd, struct drive_s *drive_gf)
 {
@@ -462,10 +475,10 @@ fill_edd(struct segoff_s edd, struct drive_s *drive_gf)
     case DTYPE_VIRTIO_BLK:
     case DTYPE_VIRTIO_SCSI:
         return fill_generic_edd(
-            edd, drive_gf, 0xffffffff
-            , "SCSI    ", GET_GLOBALFLAT(drive_gf->cntl_id), 0, 0, 0);
+            edd, drive_gf, 0xffffffff, EDD_PCI | EDD_SCSI
+            , edd_pci_path(GET_GLOBALFLAT(drive_gf->cntl_id), 0), 0);
     default:
-        return fill_generic_edd(edd, drive_gf, 0, NULL, 0, 0, 0, 0);
+        return fill_generic_edd(edd, drive_gf, 0, 0, 0, 0);
     }
 }
 
-- 
1.9.3




More information about the SeaBIOS mailing list