[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