Add stubs to permit devices to specify their boot priority.
authorKevin O'Connor <kevin@koconnor.net>
Tue, 28 Dec 2010 00:26:57 +0000 (19:26 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 28 Dec 2010 00:26:57 +0000 (19:26 -0500)
Add support for passing in priorities to bootlist system.

Based on patch by: Gleb Natapov <gleb@redhat.com>

src/ahci.c
src/ata.c
src/boot.c
src/boot.h
src/coreboot.c
src/floppy.c
src/ioport.h
src/optionroms.c
src/usb-msc.c
src/virtio-blk.c

index 03e39ad14782300355d01461cbf534ef417a394a..a7f458f4be32896853747d0be308975c1ee39722 100644 (file)
@@ -382,7 +382,7 @@ ahci_port_init(struct ahci_ctrl_s *ctrl, u32 pnr)
         // Setup disk geometry translation.
         setup_translation(&port->drive);
         // Register with bcv system.
-        boot_add_hd(&port->drive);
+        boot_add_hd(&port->drive, -1);
     } else {
         // found cdrom (atapi)
         port->drive.blksize = CDROM_SECTOR_SIZE;
@@ -397,7 +397,7 @@ ahci_port_init(struct ahci_ctrl_s *ctrl, u32 pnr)
 
         // fill cdidmap
         if (iscd)
-            boot_add_cd(&port->drive);
+            boot_add_cd(&port->drive, -1);
     }
     dprintf(1, "%s\n", port->drive.desc);
 
index e01f842539b0e1b34131bf6f3f2b8dbb6e9ad606..872c5e3f92a652473610a66515245da1293a49cd 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -783,8 +783,12 @@ init_drive_atapi(struct atadrive_s *dummy, u16 *buffer)
     dprintf(1, "%s\n", adrive_g->drive.desc);
 
     // fill cdidmap
-    if (iscd)
-        boot_add_cd(&adrive_g->drive);
+    if (iscd) {
+        int prio = bootprio_find_ata_device(adrive_g->chan_gf->pci_bdf,
+                                            adrive_g->chan_gf->chanid,
+                                            adrive_g->slave);
+        boot_add_cd(&adrive_g->drive, prio);
+    }
 
     return adrive_g;
 }
@@ -833,8 +837,11 @@ init_drive_ata(struct atadrive_s *dummy, u16 *buffer)
     // Setup disk geometry translation.
     setup_translation(&adrive_g->drive);
 
+    int prio = bootprio_find_ata_device(adrive_g->chan_gf->pci_bdf,
+                                        adrive_g->chan_gf->chanid,
+                                        adrive_g->slave);
     // Register with bcv system.
-    boot_add_hd(&adrive_g->drive);
+    boot_add_hd(&adrive_g->drive, prio);
 
     return adrive_g;
 }
index 62d6487709eae27551aa5a8ec0ef8b6a41ff52ff..d37e10fa872c242aca03ae5fad471715cac1731e 100644 (file)
 
 struct ipl_s IPL;
 
-struct bootentry_s {
-    int type;
-    union {
-        u32 data;
-        struct segoff_s vector;
-        struct drive_s *drive;
-    };
-    int priority;
-    const char *description;
-    struct bootentry_s *next;
-};
-
-static struct bootentry_s *BootList;
-
 
 /****************************************************************
- * Boot setup
+ * Boot priority ordering
  ****************************************************************/
 
 static void
@@ -70,6 +56,36 @@ loadBootOrder(void)
     } while(f);
 }
 
+int bootprio_find_pci_device(int bdf)
+{
+    return -1;
+}
+
+int bootprio_find_ata_device(int bdf, int chanid, int slave)
+{
+    return -1;
+}
+
+int bootprio_find_fdc_device(int bfd, int port, int fdid)
+{
+    return -1;
+}
+
+int bootprio_find_pci_rom(int bdf, int instance)
+{
+    return -1;
+}
+
+int bootprio_find_named_rom(const char *name, int instance)
+{
+    return -1;
+}
+
+
+/****************************************************************
+ * Boot setup
+ ****************************************************************/
+
 #define DEFAULT_PRIO           9999
 
 static int DefaultFloppyPrio = 101;
@@ -112,9 +128,23 @@ boot_setup(void)
 
 
 /****************************************************************
- * IPL and BCV handlers
+ * BootList handling
  ****************************************************************/
 
+struct bootentry_s {
+    int type;
+    union {
+        u32 data;
+        struct segoff_s vector;
+        struct drive_s *drive;
+    };
+    int priority;
+    const char *description;
+    struct bootentry_s *next;
+};
+
+static struct bootentry_s *BootList;
+
 static void
 bootentry_add(int type, int prio, u32 data, const char *desc)
 {
@@ -152,49 +182,56 @@ bootentry_add(int type, int prio, u32 data, const char *desc)
     *pprev = be;
 }
 
+// Return the given priority if it's set - defaultprio otherwise.
+static inline int defPrio(int priority, int defaultprio) {
+    return (priority < 0) ? defaultprio : priority;
+}
+
 // Add a BEV vector for a given pnp compatible option rom.
 void
-boot_add_bev(u16 seg, u16 bev, u16 desc)
+boot_add_bev(u16 seg, u16 bev, u16 desc, int prio)
 {
-    bootentry_add(IPL_TYPE_BEV, DefaultBEVPrio, SEGOFF(seg, bev).segoff
+    bootentry_add(IPL_TYPE_BEV, defPrio(prio, DefaultBEVPrio)
+                  , SEGOFF(seg, bev).segoff
                   , desc ? MAKE_FLATPTR(seg, desc) : "Unknown");
     DefaultBEVPrio = DEFAULT_PRIO;
 }
 
 // Add a bcv entry for an expansion card harddrive or legacy option rom
 void
-boot_add_bcv(u16 seg, u16 ip, u16 desc)
+boot_add_bcv(u16 seg, u16 ip, u16 desc, int prio)
 {
-    bootentry_add(IPL_TYPE_BCV, DEFAULT_PRIO, SEGOFF(seg, ip).segoff
+    bootentry_add(IPL_TYPE_BCV, defPrio(prio, DEFAULT_PRIO)
+                  , SEGOFF(seg, ip).segoff
                   , desc ? MAKE_FLATPTR(seg, desc) : "Legacy option rom");
 }
 
 void
-boot_add_floppy(struct drive_s *drive_g)
+boot_add_floppy(struct drive_s *drive_g, int prio)
 {
-    bootentry_add(IPL_TYPE_FLOPPY, DefaultFloppyPrio, (u32)drive_g
-                  , drive_g->desc);
+    bootentry_add(IPL_TYPE_FLOPPY, defPrio(prio, DefaultFloppyPrio)
+                  , (u32)drive_g, drive_g->desc);
 }
 
 void
-boot_add_hd(struct drive_s *drive_g)
+boot_add_hd(struct drive_s *drive_g, int prio)
 {
-    bootentry_add(IPL_TYPE_HARDDISK, DefaultHDPrio, (u32)drive_g
-                  , drive_g->desc);
+    bootentry_add(IPL_TYPE_HARDDISK, defPrio(prio, DefaultHDPrio)
+                  , (u32)drive_g, drive_g->desc);
 }
 
 void
-boot_add_cd(struct drive_s *drive_g)
+boot_add_cd(struct drive_s *drive_g, int prio)
 {
-    bootentry_add(IPL_TYPE_CDROM, DefaultCDPrio, (u32)drive_g
-                  , drive_g->desc);
+    bootentry_add(IPL_TYPE_CDROM, defPrio(prio, DefaultCDPrio)
+                  , (u32)drive_g, drive_g->desc);
 }
 
 // Add a CBFS payload entry
 void
-boot_add_cbfs(void *data, const char *desc)
+boot_add_cbfs(void *data, const char *desc, int prio)
 {
-    bootentry_add(IPL_TYPE_CBFS, DEFAULT_PRIO, (u32)data, desc);
+    bootentry_add(IPL_TYPE_CBFS, defPrio(prio, DEFAULT_PRIO), (u32)data, desc);
 }
 
 
index f1a428e0fa9658b317dc056891d045abcd666f48..fa455d5efd795a277a967dde32a3201e031365f3 100644 (file)
@@ -35,14 +35,18 @@ struct ipl_s {
 // boot.c
 extern struct ipl_s IPL;
 void boot_setup(void);
-void boot_add_bev(u16 seg, u16 bev, u16 desc);
-void boot_add_bcv(u16 seg, u16 ip, u16 desc);
+void boot_add_bev(u16 seg, u16 bev, u16 desc, int prio);
+void boot_add_bcv(u16 seg, u16 ip, u16 desc, int prio);
 struct drive_s;
-void boot_add_floppy(struct drive_s *drive_g);
-void boot_add_hd(struct drive_s *drive_g);
-void boot_add_cd(struct drive_s *drive_g);
-void boot_add_cbfs(void *data, const char *desc);
-
+void boot_add_floppy(struct drive_s *drive_g, int prio);
+void boot_add_hd(struct drive_s *drive_g, int prio);
+void boot_add_cd(struct drive_s *drive_g, int prio);
+void boot_add_cbfs(void *data, const char *desc, int prio);
 void boot_prep(void);
+int bootprio_find_pci_device(int bdf);
+int bootprio_find_ata_device(int bdf, int chanid, int slave);
+int bootprio_find_fdc_device(int bfd, int port, int fdid);
+int bootprio_find_pci_rom(int bdf, int instance);
+int bootprio_find_named_rom(const char *name, int instance);
 
 #endif // __BOOT_H
index dab0a54e6f59ebab8cec681c39ee5bd1cbc99baa..503a6d2721b9d8409a923aed71437613b88b92b3 100644 (file)
@@ -608,7 +608,7 @@ register_cbfs_payload(void)
         if (!desc)
             break;
         snprintf(desc, MAXDESCSIZE, "Payload [%s]", &filename[4]);
-        boot_add_cbfs(file, desc);
+        boot_add_cbfs(file, desc, -1);
     }
 }
 
index 8986e39bdb5ac96f36066039b21bc84d7fff9856..bfca63fdeb935b3b41c8cf38a33ff774cf87aadb 100644 (file)
@@ -14,6 +14,8 @@
 #include "pic.h" // eoi_pic1
 #include "bregs.h" // struct bregs
 #include "boot.h" // boot_add_floppy
+#include "pci.h" // pci_to_bdf
+#include "pci_ids.h" // PCI_CLASS_BRIDGE_ISA
 
 #define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors
 #define FLOPPY_DATALEN 0xff   // Not used - because size code is 0x02
@@ -117,7 +119,10 @@ addFloppy(int floppyid, int ftype, int driver)
     memcpy(&drive_g->lchs, &FloppyInfo[ftype].chs
            , sizeof(FloppyInfo[ftype].chs));
 
-    boot_add_floppy(drive_g);
+    int bdf = pci_find_class(PCI_CLASS_BRIDGE_ISA); /* isa-to-pci bridge */
+    int prio = bootprio_find_fdc_device(bdf, PORT_FD_BASE, floppyid);
+
+    boot_add_floppy(drive_g, prio);
     return drive_g;
 }
 
index 5bd7f28f370a7209da5d44b4e6bd077b003dba39..3282fb49546af3acdc1daace77ad37785af8c904 100644 (file)
@@ -43,6 +43,7 @@
 #define PORT_LPT1              0x0378
 #define PORT_SERIAL3           0x03e8
 #define PORT_ATA1_CTRL_BASE    0x03f4
+#define PORT_FD_BASE           0x03f0
 #define PORT_FD_DOR            0x03f2
 #define PORT_FD_STATUS         0x03f4
 #define PORT_FD_DATA           0x03f5
index 2ac432571d9ee73b3ffe946c33360038dc5e5071..a94b46c35d2617adda54f717563e500bb189e3c4 100644 (file)
@@ -220,6 +220,16 @@ setRomSource(u64 *sources, struct rom_header *rom, u64 source)
         sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN] = source;
 }
 
+static int
+getRomPriority(u64 *sources, struct rom_header *rom, int instance)
+{
+    u64 source = sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN];
+    if (!source)
+        return -1;
+    if (source & RS_PCIROM)
+        return bootprio_find_pci_rom(source, instance);
+    return bootprio_find_named_rom(romfile_name(source), instance);
+}
 
 /****************************************************************
  * Roms in CBFS
@@ -412,19 +422,24 @@ optionrom_setup(void)
         struct pnp_data *pnp = get_pnp_rom(rom);
         if (! pnp) {
             // Legacy rom.
-            boot_add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0);
+            boot_add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0
+                         , getRomPriority(sources, rom, 0));
             continue;
         }
         // PnP rom.
-        if (pnp->bev)
+        if (pnp->bev) {
             // Can boot system - add to IPL list.
-            boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname);
-        else
+            boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname
+                         , getRomPriority(sources, rom, 0));
+        } else {
             // Check for BCV (there may be multiple).
+            int instance = 0;
             while (pnp && pnp->bcv) {
-                boot_add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname);
+                boot_add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname
+                             , getRomPriority(sources, rom, instance++));
                 pnp = get_pnp_next(rom, pnp);
             }
+        }
     }
 }
 
index 378143ec914c4602d79b8e2dfa8ca7974f55490f..2a6c31a0e706f4a75f91b673c3a12dc2c5e4be3b 100644 (file)
@@ -143,7 +143,7 @@ setup_drive_cdrom(struct disk_op_s *op)
 {
     op->drive_g->blksize = CDROM_SECTOR_SIZE;
     op->drive_g->sectors = (u64)-1;
-    boot_add_cd(op->drive_g);
+    boot_add_cd(op->drive_g, -1);
     return 0;
 }
 
@@ -171,7 +171,7 @@ setup_drive_hd(struct disk_op_s *op)
     setup_translation(op->drive_g);
 
     // Register with bcv system.
-    boot_add_hd(op->drive_g);
+    boot_add_hd(op->drive_g, -1);
 
     return 0;
 }
index def8313d0fe9b4bd1acbae016768fc5cdea85b44..834523a6c4a321c0e9cf2a5357f0ab77b3291af3 100644 (file)
@@ -156,7 +156,7 @@ init_virtio_blk(u16 bdf)
     vdrive_g->drive.desc = desc;
 
     setup_translation(&vdrive_g->drive);
-    boot_add_hd(&vdrive_g->drive);
+    boot_add_hd(&vdrive_g->drive, bootprio_find_pci_device(bdf));
 
     vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE |
                   VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);