Add OPROM mapping support to coreboot
authorStefan Reinauer <reinauer@chromium.org>
Mon, 23 Jan 2012 22:17:52 +0000 (14:17 -0800)
committerMarc Jones <marcj303@gmail.com>
Mon, 6 Feb 2012 23:09:58 +0000 (00:09 +0100)
This allows to add a PCI ID mapping function for option roms so that the same
option rom can be used for a series of devices / PCI IDs. Intel and AMD often
use the same option rom for a number of PCI devices with differend IDs.

A function to implement such a mapping could look like this (or anything else
appropriate):

/* some vga option roms are used for several chipsets but they only have one
 * PCI ID in their header. If we encounter such an option rom, we need to do
 * the mapping ourselfes
 */

u32 map_oprom_vendev(u32 vendev)
{
    u32 new_vendev=vendev;

    switch(vendev) {
    case 0xa0118086:
        new_vendev=0xa0018086;
        break;
    }

    return new_vendev;
}

Change-Id: I1be7fe113b895075d43ea48fe706b039cef136d2
Reviewed-on: http://review.coreboot.org/573
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-by: Marc Jones <marcj303@gmail.com>
src/devices/pci_rom.c
src/include/device/pci_rom.h

index 56712df5c5c3c1fc5697fcc55e3d97621c7995bd..471c7e2a7a51fe2eaf08bacf5d79196294845478 100644 (file)
@@ -37,6 +37,19 @@ struct rom_header *pci_rom_probe(struct device *dev)
        /* If it's in FLASH, then don't check device for ROM. */
        rom_header = cbfs_load_optionrom(dev->vendor, dev->device, NULL);
 
+       u32 vendev = dev->vendor | (dev->device << 16);
+       u32 mapped_vendev = vendev;
+
+       if (map_oprom_vendev)
+               mapped_vendev = map_oprom_vendev(vendev);
+
+       if (!rom_header) {
+               if (vendev != mapped_vendev) {
+                       rom_header = cbfs_load_optionrom(mapped_vendev &
+                                       0xffff, mapped_vendev >> 16, NULL);
+               }
+       }
+
        if (rom_header) {
                printk(BIOS_DEBUG, "In CBFS, ROM address for %s = %p\n",
                       dev_path(dev), rom_header);
@@ -78,8 +91,10 @@ 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 the device id is mapped, a mismatch is expected */
+       if ((dev->vendor != rom_data->vendor
+           || dev->device != rom_data->device)
+           && (vendev == mapped_vendev)) {
                printk(BIOS_ERR, "ID mismatch: vendor ID %04x, "
                       "device ID %04x\n", rom_data->vendor, rom_data->device);
                return NULL;
index f2683410fde4a810f1306e3253dd41938d64aba1..fe772764911de195f84aca21a438e98f746d2660 100644 (file)
@@ -35,5 +35,6 @@ struct  pci_data {
 
 struct rom_header *pci_rom_probe(struct device *dev);
 struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header);
+u32 __attribute__((weak)) map_oprom_vendev(u32 vendev);
 
 #endif