[SeaBIOS] [PATCH 2/2] Add PCI option ROM blacklist in CBFS

Timothy Pearson tpearson at raptorengineeringinc.com
Thu Feb 12 00:32:36 CET 2015


File:
pci_optrom_blacklist.txt

Syntax:
<bus>,<device>,<function>
Numbers or a single wildcard ('*') are allowed
Each blacklisted device is placed on separate line

Examples:
Blacklist device 01:04.0:
1,4,0
Blacklist all devices on bus 5:
5,*,*

TEST: Booted ASUS KFSN4-DRE with iPXE ROMs built in to CBFS;
with the two add-on network devices blacklisted the add-on
network ROMs were ignored while the on-board iPXE ROMs executed
normally.

Signed-off-by: Timothy Pearson <tpearson at raptorengineeringinc.com>
---
  src/optionroms.c |  112 
+++++++++++++++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/src/optionroms.c b/src/optionroms.c
index fbcb6ca..44967e7 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -1,5 +1,6 @@
  // Option rom scanning code.
  //
+// Copyright (C) 2015  Timothy Pearson <tpearson at raptorengineeringinc.com>
  // Copyright (C) 2008  Kevin O'Connor <kevin at koconnor.net>
  // Copyright (C) 2002  MandrakeSoft S.A.
  //
@@ -346,12 +347,119 @@ init_pcirom(struct pci_device *pci, int isvga, 
u64 *sources)
   * Non-VGA option rom init
   ****************************************************************/

+u8 char_is_digit(const char c) {
+    if ((c >= '0') && (c <= '9'))
+        return 1;
+    else
+        return 0;
+}
+
+int atoi(const char* c)
+{
+    int value = 0;
+
+    while (char_is_digit(*c)) {
+        value *= 10;
+        value += (int) (*c - '0');
+        c++;
+    }
+
+    return value;
+}
+
+/* 256: Match none
+ * 257: Match any
+ */
+struct pci_optrom_blacklist_entry {
+	u16 bus;
+	u16 device;
+	u16 function;
+};
+
+u8 pci_device_option_rom_is_blacklisted(struct pci_device *pci, struct 
pci_optrom_blacklist_entry *pci_optrom_blacklist, int 
pci_optrom_blacklist_count)
+{
+    if (!pci)
+        return 0;
+
+    int i;
+    for (i=0; i<pci_optrom_blacklist_count; i++) {
+        if ((pci_optrom_blacklist[i].bus == pci_bdf_to_bus(pci->bdf)) 
|| (pci_optrom_blacklist[i].bus == 257)) {
+            if ((pci_optrom_blacklist[i].device == 
pci_bdf_to_dev(pci->bdf)) || (pci_optrom_blacklist[i].device == 257)) {
+                if ((pci_optrom_blacklist[i].function == 
pci_bdf_to_fn(pci->bdf)) || (pci_optrom_blacklist[i].function == 257)) {
+                    return 1;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
  void
  optionrom_setup(void)
  {
      if (! CONFIG_OPTIONROMS)
          return;

+    struct pci_optrom_blacklist_entry *pci_optrom_blacklist = NULL;
+    int pci_optrom_blacklist_count = 0;
+
+    dprintf(3, "Checking for PCI option ROM blacklist\n");
+    int filesize;
+    u8 *filedata = romfile_loadfile("pci_optrom_blacklist.txt", &filesize);
+    if (filedata) {
+        int i = 0;
+        while (filedata[i]) {
+            if (filedata[i] == '\n')
+                pci_optrom_blacklist_count++;
+            i++;
+        }
+        pci_optrom_blacklist = malloc_tmphigh(sizeof(struct 
pci_optrom_blacklist_entry)
+                                   * pci_optrom_blacklist_count);
+        int bdf_parse = 0;
+        int j = 0;
+        i=0;
+        u16 value = 0;
+        pci_optrom_blacklist_count = 0;
+        char bdf_tmp[4];
+        while (filedata[i]) {
+            if ((j > 3) || (bdf_parse > 2)) {
+                dprintf(1, "WARNING: Incorrect value in PCI option ROM 
blacklist\n");
+                pci_optrom_blacklist[pci_optrom_blacklist_count].bus = 256;
+                pci_optrom_blacklist[pci_optrom_blacklist_count].device 
= 256;
+ 
pci_optrom_blacklist[pci_optrom_blacklist_count].function = 256;
+            } else {
+                bdf_tmp[j] = filedata[i];
+                j++;
+                if ((filedata[i] == ',') || (filedata[i] == '\n')) {
+                    bdf_tmp[j] = 0;
+                    if (bdf_tmp[0] == '*')
+                        value = 257;
+                    else
+                        value = atoi(bdf_tmp);
+                    if (bdf_parse == 0)
+ 
pci_optrom_blacklist[pci_optrom_blacklist_count].bus = value;
+                    if (bdf_parse == 1)
+ 
pci_optrom_blacklist[pci_optrom_blacklist_count].device = value;
+                    if (bdf_parse == 2)
+ 
pci_optrom_blacklist[pci_optrom_blacklist_count].function = value;
+                    bdf_parse++;
+                    j=0;
+                }
+            }
+            if (filedata[i] == '\n') {
+                dprintf(3, "PCI device %02x:%02x.%x added to PCI option 
ROM blacklist\n",
+                    pci_optrom_blacklist[pci_optrom_blacklist_count].bus,
+ 
pci_optrom_blacklist[pci_optrom_blacklist_count].device,
+ 
pci_optrom_blacklist[pci_optrom_blacklist_count].function);
+                pci_optrom_blacklist_count++;
+                bdf_parse=0;
+            }
+            i++;
+        }
+        free(filedata);
+    }
+
      dprintf(1, "Scan for option roms\n");
      u64 sources[(BUILD_BIOS_ADDR - BUILD_ROM_START) / OPTION_ROM_ALIGN];
      memset(sources, 0, sizeof(sources));
@@ -373,13 +481,15 @@ optionrom_setup(void)
          foreachpci(pci) {
              if (pci->class == PCI_CLASS_DISPLAY_VGA || pci->have_driver)
                  continue;
-            init_pcirom(pci, 0, sources);
+            if (!pci_device_option_rom_is_blacklisted(pci, 
pci_optrom_blacklist, pci_optrom_blacklist_count))
+                init_pcirom(pci, 0, sources);
          }

          // Find and deploy CBFS roms not associated with a device.
          run_file_roms("genroms/", 0, sources);
      }
      rom_reserve(0);
+    free(pci_optrom_blacklist);

      // All option roms found and deployed - now build BEV/BCV vectors.

-- 
1.7.9.5

-- 
Timothy Pearson
Raptor Engineering
+1 (415) 727-8645
http://www.raptorengineeringinc.com



More information about the SeaBIOS mailing list