[SeaBIOS] [PATCH 7/9] Create mapping between rom address and boot priority.

Kevin O'Connor kevin at koconnor.net
Fri Dec 24 19:33:20 CET 2010


On Fri, Dec 24, 2010 at 12:13:14PM -0500, Kevin O'Connor wrote:
> On Thu, Dec 23, 2010 at 11:29:41AM +0200, Gleb Natapov wrote:
> > At the time of bev/bcv initialization the device rom was loaded from is
> > no longer know. Only memory address where rom resides is know at this
> > point. This patch create mapping between boot priority and rom address
> > at rom initialization time for use during bev/bcv init.
> > 
> > Signed-off-by: Gleb Natapov <gleb at redhat.com>
> 
> I find this patch confusing.  How about the patch below instead?

Hrmm - instead of tracking the priority of each rom, lets track the
source of each rom, and then calculate the priority when adding the
bev/bcv.  How about the attached instead?  (It is admittedly more
complex, but it gives me the ability to set priorities for each BCV.)

-Kevin
-------------- next part --------------
commit 16ef4c87505b415d033b39722e5e829d13708f77
Author: Kevin O'Connor <kevin at koconnor.net>
Date:   Fri Dec 24 13:28:12 2010 -0500

    Support qemu based romfile wrappers to be called out of order.
    
    If the file requested isn't the last file read, then reread the index
    to find the given file.

diff --git a/src/paravirt.c b/src/paravirt.c
index 74d3743..dcb2798 100644
--- a/src/paravirt.c
+++ b/src/paravirt.c
@@ -338,26 +338,43 @@ u32 qemu_cfg_find_file(const char *name)
     return __cfg_next_prefix_file(name, strlen(name) + 1, 0);
 }
 
+static int
+__qemu_cfg_set_file(u32 select)
+{
+    if (!qemu_cfg_present)
+        return -1;
+    if (select == ntohs(LastFile.select))
+        return 0;
+
+    u32 count;
+    qemu_cfg_read_entry(&count, QEMU_CFG_FILE_DIR, sizeof(count));
+    count = ntohl(count);
+    u32 e;
+    for (e = 0; e < count; e++) {
+        qemu_cfg_read((void*)&LastFile, sizeof(LastFile));
+        if (select == ntohs(LastFile.select))
+            return 0;
+    }
+    return -1;
+}
+
 int qemu_cfg_size_file(u32 select)
 {
-    if (select != ntohs(LastFile.select))
+    if (__qemu_cfg_set_file(select))
         return -1;
     return ntohl(LastFile.size);
 }
 
-
 const char* qemu_cfg_name_file(u32 select)
 {
-    if (select != ntohs(LastFile.select))
+    if (__qemu_cfg_set_file(select))
         return NULL;
     return LastFile.name;
 }
 
 int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen)
 {
-    if (!qemu_cfg_present)
-        return -1;
-    if (!select || select != ntohs(LastFile.select))
+    if (!select || __qemu_cfg_set_file(select))
         return -1;
     int len = qemu_cfg_size_file(select);
     if (len < 0 || len > maxlen)
-------------- next part --------------
diff --git a/src/boot.c b/src/boot.c
index 5137345..9777bd6 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -21,6 +21,18 @@ struct ipl_s IPL;
  * Boot setup
  ****************************************************************/
 
+int
+bootprio_find_pci_device(int bdf, int instance)
+{
+    return -1;
+}
+
+int
+bootprio_find_named_rom(const char *name, int instance)
+{
+    return -1;
+}
+
 static void
 loadBootOrder(void)
 {
@@ -113,7 +125,7 @@ boot_setup(void)
 
 // Add a BEV vector for a given pnp compatible option rom.
 void
-add_bev(u16 seg, u16 bev, u16 desc)
+add_bev(u16 seg, u16 bev, u16 desc, int prio)
 {
     if (! CONFIG_BOOT)
         return;
@@ -150,7 +162,7 @@ add_baid_cdrom(struct drive_s *drive_g)
 
 // Add a bcv entry for an expansion card harddrive or legacy option rom
 void
-add_bcv(u16 seg, u16 ip, u16 desc)
+add_bcv(u16 seg, u16 ip, u16 desc, int prio)
 {
     if (! CONFIG_BOOT)
         return;
diff --git a/src/boot.h b/src/boot.h
index 778aebd..272c574 100644
--- a/src/boot.h
+++ b/src/boot.h
@@ -41,12 +41,14 @@ struct ipl_s {
 // boot.c
 extern struct ipl_s IPL;
 void boot_setup(void);
-void add_bev(u16 seg, u16 bev, u16 desc);
-void add_bcv(u16 seg, u16 ip, u16 desc);
+void add_bev(u16 seg, u16 bev, u16 desc, int prio);
+void add_bcv(u16 seg, u16 ip, u16 desc, int prio);
 struct drive_s;
 void add_bcv_internal(struct drive_s *drive_g);
 void add_baid_cdrom(struct drive_s *drive_g);
 
 void boot_prep(void);
+int bootprio_find_pci_device(int bdf, int instance);
+int bootprio_find_named_rom(const char *name, int instance);
 
 #endif // __BOOT_H
diff --git a/src/optionroms.c b/src/optionroms.c
index 854c33f..697b4ef 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -211,6 +211,26 @@ init_optionrom(struct rom_header *rom, u16 bdf, int isvga)
     return 0;
 }
 
+#define RS_PCIROM (1LL<<33)
+
+static void
+setRomSource(u64 *sources, struct rom_header *rom, u64 source)
+{
+    if (sources)
+        sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN] = source;
+}
+
+static u8
+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_device(source, instance);
+    return bootprio_find_named_rom(romfile_name(source), instance);
+}
+
 
 /****************************************************************
  * Roms in CBFS
@@ -240,16 +260,19 @@ lookup_hardcode(u32 vendev)
 
 // Run all roms in a given CBFS directory.
 static void
-run_file_roms(const char *prefix, int isvga)
+run_file_roms(const char *prefix, int isvga, u64 *sources)
 {
     u32 file = 0;
     for (;;) {
         file = romfile_findprefix(prefix, file);
         if (!file)
             break;
-        int ret = romfile_copy(file, (void*)RomEnd, max_rom() - RomEnd);
-        if (ret > 0)
-            init_optionrom((void*)RomEnd, 0, isvga);
+        struct rom_header *rom = (void*)RomEnd;
+        int ret = romfile_copy(file, rom, max_rom() - RomEnd);
+        if (ret > 0) {
+            setRomSource(sources, rom, file);
+            init_optionrom(rom, 0, isvga);
+        }
     }
 }
 
@@ -330,7 +353,7 @@ fail:
 
 // Attempt to map and initialize the option rom on a given PCI device.
 static int
-init_pcirom(u16 bdf, int isvga)
+init_pcirom(u16 bdf, int isvga, u64 *sources)
 {
     u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
     dprintf(4, "Attempting to init PCI bdf %02x:%02x.%x (vd %04x:%04x)\n"
@@ -342,6 +365,7 @@ init_pcirom(u16 bdf, int isvga)
     if (! rom)
         // No ROM present.
         return -1;
+    setRomSource(sources, rom, RS_PCIROM | bdf);
     return init_optionrom(rom, bdf, isvga);
 }
 
@@ -357,7 +381,8 @@ optionrom_setup(void)
         return;
 
     dprintf(1, "Scan for option roms\n");
-
+    u64 sources[(BUILD_BIOS_ADDR - BUILD_ROM_START) / OPTION_ROM_ALIGN];
+    memset(sources, 0, sizeof(sources));
     u32 post_vga = RomEnd;
 
     if (CONFIG_OPTIONROMS_DEPLOYED) {
@@ -378,11 +403,11 @@ optionrom_setup(void)
             if (v == 0x0000 || v == 0xffff || v == PCI_CLASS_DISPLAY_VGA
                 || (CONFIG_ATA && v == PCI_CLASS_STORAGE_IDE))
                 continue;
-            init_pcirom(bdf, 0);
+            init_pcirom(bdf, 0, sources);
         }
 
         // Find and deploy CBFS roms not associated with a device.
-        run_file_roms("genroms/", 0);
+        run_file_roms("genroms/", 0, sources);
     }
 
     // All option roms found and deployed - now build BEV/BCV vectors.
@@ -394,21 +419,25 @@ optionrom_setup(void)
             pos += OPTION_ROM_ALIGN;
             continue;
         }
+        int instance = 0;
         pos += ALIGN(rom->size * 512, OPTION_ROM_ALIGN);
         struct pnp_data *pnp = get_pnp_rom(rom);
         if (! pnp) {
             // Legacy rom.
-            add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0);
+            add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0
+                    , getRomPriority(sources, rom, instance));
             continue;
         }
         // PnP rom.
         if (pnp->bev)
             // Can boot system - add to IPL list.
-            add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname);
+            add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname
+                    , getRomPriority(sources, rom, instance));
         else
             // Check for BCV (there may be multiple).
             while (pnp && pnp->bcv) {
-                add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname);
+                add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname
+                        , getRomPriority(sources, rom, instance++));
                 pnp = get_pnp_next(rom, pnp);
             }
     }
@@ -438,10 +467,10 @@ vga_setup(void)
         // Find and deploy PCI VGA rom.
         int bdf = VGAbdf = pci_find_vga();
         if (bdf >= 0)
-            init_pcirom(bdf, 1);
+            init_pcirom(bdf, 1, NULL);
 
         // Find and deploy CBFS vga-style roms not associated with a device.
-        run_file_roms("vgaroms/", 1);
+        run_file_roms("vgaroms/", 1, NULL);
     }
 
     if (RomEnd == BUILD_ROM_START) {


More information about the SeaBIOS mailing list