Marc Jones (marcj303@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/534
-gerrit
commit 6deec7b7e51981b15094427b9570eda4350d7177 Author: Martin Roth Martin@se-eng.com Date: Thu Jan 12 14:23:48 2012 -0700
Fix to allow one vbios ROM to match multiple PCI device IDs
This change allows a single option ROM to be decompressed from CBFS and loaded for PCI devices with different PCI device IDs. This is needed to support "generic" video BIOS ROMs designed to work with multiple different device IDs.
The method of doing this is with an AND mask which is applied to the PCI device ID for VGA devices both when selecting the ROM to decompress from CBFS and before comparison with the ROM device ID to initialize.
The main problem with this method is that if there were two PCI devices with very similar Device IDs and both had ROMs stored in CBFS, a VGA device and another device, the wrong ROM could be accidentally applied. Because of this, it's important to keep the mask as narrow as possible. 0xff00 shouldn't be used if 0xfff0 will work.
Change-Id: Ic68af575fe73d6700b5575b55148feef529637ef Signed-off-by: Martin L Roth martin@se-eng.com Signed-off-by: Marc Jones marcj303@gmail.com --- src/Kconfig | 32 ++++++++++++++++++++++++++++++++ src/devices/pci_rom.c | 21 ++++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig index 525d452..abdad83 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -2,6 +2,7 @@ ## This file is part of the coreboot project. ## ## Copyright (C) 2009-2010 coresystems GmbH +## Copyright (C) 2012 Sage Electronic Engineering, LLC ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -465,6 +466,13 @@ config COMPRESSED_PAYLOAD_NRV2B
endmenu
+# This options is here to avoid "undefined" warnings. +# The actual selection and help texts are in the following menu. + +config VGA_BIOS_DEVICEID_MASK + hex + default 0xffff + menu "VGA BIOS"
config VGA_BIOS @@ -497,6 +505,30 @@ config VGA_BIOS_ID the "0x" prefix) and 3230 specifies the PCI device ID of the video card (also in hex, without "0x" prefix).
+config VGA_BIOS_DEVICEID_MASK + hex "VGA device PCI device ID mask" + depends on VGA_BIOS + default 0xffff + help + This is an AND mask that is applied to the PCI device ID that + would associate your VGA BIOS to your video card when deciding + to apply the rom to the PCI device. + + Example: 0xFFF8 + + In the above example, the lowest 3 bits of the device ID would not + be included when comparing the ROM's programmed device ID with + the device ID of the actual PCI device. This allows a rom with + a device ID of 3230 to match against any PCI devices with ids + in the range of 3230 to 3237 + + WARNING: This mask should be kept as narrow as possible to avoid + loading an incorrect rom for a device out of CBFS. If you're + using a mask of 0x0000, you're *probably* doing something wrong. + + Note: The device ID portion of the VGA_BIOS_ID should have any + masked bits set to zero in the above entry. + config INTEL_MBI bool "Add an MBI image" depends on NORTHBRIDGE_INTEL_I82830 diff --git a/src/devices/pci_rom.c b/src/devices/pci_rom.c index 56712df..b5dce97 100644 --- a/src/devices/pci_rom.c +++ b/src/devices/pci_rom.c @@ -6,6 +6,7 @@ * (Written by Yinghai Lu yhlu@tyan.com for Tyan) * Copyright (C) 2005 Ronald G. Minnich rminnich@gmail.com * Copyright (C) 2005-2007 Stefan Reinauer stepan@openbios.org + * Copyright (C) 2012 Sage Electronic Engineering, LLC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,7 +36,11 @@ struct rom_header *pci_rom_probe(struct device *dev) struct pci_data *rom_data;
/* If it's in FLASH, then don't check device for ROM. */ - rom_header = cbfs_load_optionrom(dev->vendor, dev->device, NULL); + if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) + rom_header = cbfs_load_optionrom(dev->vendor, + (dev->device & CONFIG_VGA_BIOS_DEVICEID_MASK), NULL); + else + rom_header = cbfs_load_optionrom(dev->vendor, dev->device, NULL);
if (rom_header) { printk(BIOS_DEBUG, "In CBFS, ROM address for %s = %p\n", @@ -78,8 +83,18 @@ struct rom_header *pci_rom_probe(struct device *dev)
printk(BIOS_SPEW, "PCI ROM image, vendor ID %04x, device ID %04x,\n", rom_data->vendor, rom_data->device); - if (dev->vendor != rom_data->vendor - || dev->device != rom_data->device) { + + if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) { + if (dev->vendor != rom_data->vendor + || ((dev->device & CONFIG_VGA_BIOS_DEVICEID_MASK) != + (rom_data->device & CONFIG_VGA_BIOS_DEVICEID_MASK))) { + printk(BIOS_ERR, "ID mismatch: vendor ID %04x, " + "device ID %04x\n", rom_data->vendor, + rom_data->device); + return NULL; + } + } else if (dev->vendor != rom_data->vendor + || dev->device != rom_data->device) { printk(BIOS_ERR, "ID mismatch: vendor ID %04x, " "device ID %04x\n", rom_data->vendor, rom_data->device); return NULL;