[SeaBIOS] [PATCH] Search PCIv3 device list in optionroms if present

Daniel Verkamp daniel at drv.nu
Fri Aug 17 06:07:39 CEST 2012


PCI Firmware Specification v3.0 defined a new optional device list,
allowing a single optionrom to handle several device IDs.  Add support
for this list when looking for an optionrom for a PCI device.

Signed-off-by: Daniel Verkamp <daniel at drv.nu>
---
 src/optionroms.c |   33 ++++++++++++++++++++++++++++-----
 src/optionroms.h |    2 +-
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/optionroms.c b/src/optionroms.c
index 00697b2..0023d90 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -292,19 +292,42 @@ map_pcirom(struct pci_device *pci)
             goto fail;
         }
 
-        if (pd->vendor == pci->vendor && pd->device == pci->device
-            && pd->type == PCIROM_CODETYPE_X86)
-            // A match
-            break;
+        void *nextrom = (void*)((u32)rom + pd->ilen * 512);
+
+        if (pd->vendor == pci->vendor && pd->type == PCIROM_CODETYPE_X86)
+        {
+            if (pd->device == pci->device)
+            {
+                dprintf(6, "Matched device in PCI header\n");
+                goto found;
+            }
+
+            // PCI header device ID did not match, but vendor ID did
+            // search device list if available
+            if (pd->drevision >= 3 && pd->devicelist) {
+                u16 *devicelist = (u16*)((u32)pd + pd->devicelist);
+                dprintf(6, "Searching PCIv3 device ID list at %p\n", devicelist);
+                while (devicelist < (u16*)nextrom && *devicelist) {
+                    dprintf(6, "Dev list entry: %04x\n", *devicelist);
+                    if (*devicelist == pci->device) {
+                        dprintf(6, "Matched device in PCIv3 device list\n");
+                        goto found;
+                    }
+                    devicelist++;
+                }
+                dprintf(6, "Didn't match device ID list\n");
+            }
+        }
         dprintf(6, "Didn't match dev/ven (got %04x:%04x) or type (got %d)\n"
                 , pd->vendor, pd->device, pd->type);
         if (pd->indicator & 0x80) {
             dprintf(6, "No more images left\n");
             goto fail;
         }
-        rom = (void*)((u32)rom + pd->ilen * 512);
+        rom = nextrom;
     }
 
+found:
     rom = copy_rom(rom);
     pci_config_writel(bdf, PCI_ROM_ADDRESS, orig);
     return rom;
diff --git a/src/optionroms.h b/src/optionroms.h
index 94ca4ae..487ea45 100644
--- a/src/optionroms.h
+++ b/src/optionroms.h
@@ -20,7 +20,7 @@ struct pci_data {
     u32 signature;
     u16 vendor;
     u16 device;
-    u16 vitaldata;
+    u16 devicelist;
     u16 dlen;
     u8 drevision;
     u8 class_lo;
-- 
1.7.8.6




More information about the SeaBIOS mailing list