Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/86385?usp=email )
Change subject: device/pci_rom: Keep track of VBIOS ......................................................................
device/pci_rom: Keep track of VBIOS
Currently the VBIOS is placed somewhere in DRAM when necessary. While generating ACPI tables the code attempts to find the VBIOS by looking at "known" places.
Simplify the code and keep track of the VBIOS using a pointer in struct device by filling it in pci_rom_load(). The following patches will reuse this pointer to generalize the code even more.
Change-Id: Ib27d30e3b07740d6098d4f7a5c4f5d8bce976f00 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/device/pci_rom.c M src/include/device/device.h 2 files changed, 59 insertions(+), 55 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/85/86385/1
diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c index 0fe94db..70e18ab 100644 --- a/src/device/pci_rom.c +++ b/src/device/pci_rom.c @@ -169,12 +169,18 @@ memcpy((void *)PCI_VGA_RAM_IMAGE_START, rom_header, rom_size); } +#if CONFIG(HAVE_ACPI_TABLES) + dev->pci_vga_option_rom = (struct rom_header *)(PCI_VGA_RAM_IMAGE_START); +#endif return (struct rom_header *)(PCI_VGA_RAM_IMAGE_START); }
printk(BIOS_DEBUG, "Copying non-VGA ROM image from %p to %p, 0x%x bytes\n", rom_header, pci_ram_image_start, rom_size);
+#if CONFIG(HAVE_ACPI_TABLES) + dev->pci_vga_option_rom = (struct rom_header *)pci_ram_image_start; +#endif memcpy(pci_ram_image_start, rom_header, rom_size); pci_ram_image_start += rom_size; return (struct rom_header *)(pci_ram_image_start-rom_size); @@ -183,30 +189,6 @@ /* ACPI */ #if CONFIG(HAVE_ACPI_TABLES)
-/* VBIOS may be modified after oprom init so use the copy if present. */ -static struct rom_header *check_initialized(const struct device *dev) -{ - struct rom_header *run_rom; - struct pci_data *rom_data; - - if (!CONFIG(VGA_ROM_RUN) && !CONFIG(RUN_FSP_GOP)) - return NULL; - - run_rom = (struct rom_header *)(uintptr_t)PCI_VGA_RAM_IMAGE_START; - if (read_le16(&run_rom->signature) != PCI_ROM_HDR) - return NULL; - - rom_data = (struct pci_data *)((u8 *)run_rom - + read_le16(&run_rom->data)); - - if (read_le32(&rom_data->signature) == PCI_DATA_HDR - && read_le16(&rom_data->device) == dev->device - && read_le16(&rom_data->vendor) == dev->vendor) - return run_rom; - else - return NULL; -} - static unsigned long ati_rom_acpi_fill_vfct(const struct device *device, acpi_vfct_t *vfct_struct, unsigned long current) @@ -214,7 +196,8 @@ acpi_vfct_image_hdr_t *header = &vfct_struct->image_hdr; struct rom_header *rom;
- rom = check_initialized(device); + /* Already loaded into DRAM? */ + rom = device->pci_vga_option_rom; if (!rom) rom = pci_rom_probe(device); if (!rom) { @@ -277,6 +260,7 @@
void pci_rom_ssdt(const struct device *device) { + const struct rom_header *rom; static size_t ngfx;
/* Only handle display devices */ @@ -287,48 +271,54 @@ if (!device->enabled) return;
- /* Probe for option rom */ - const struct rom_header *rom = pci_rom_probe(device); - if (!rom || !rom->size) { - printk(BIOS_WARNING, "%s: Missing PCI Option ROM\n", - dev_path(device)); - return; - } - const char *scope = acpi_device_path(device); if (!scope) { printk(BIOS_ERR, "%s: Missing ACPI scope\n", dev_path(device)); return; }
- /* Supports up to four devices. */ - if ((CBMEM_ID_ROM0 + ngfx) > CBMEM_ID_ROM3) { - printk(BIOS_ERR, "%s: Out of CBMEM IDs.\n", dev_path(device)); - return; - } + /* Already loaded into DRAM? */ + rom = device->pci_vga_option_rom; + if (!rom) { + /* Probe for option rom */ + rom = pci_rom_probe(device); + if (!rom || !rom->size) { + printk(BIOS_WARNING, "%s: Missing PCI Option ROM\n", + dev_path(device)); + return; + }
- /* Prepare memory */ - const size_t cbrom_length = rom->size * 512; - if (!cbrom_length) { - printk(BIOS_ERR, "%s: ROM has zero length!\n", - dev_path(device)); - return; - } + /* Supports up to four devices. */ + if ((CBMEM_ID_ROM0 + ngfx) > CBMEM_ID_ROM3) { + printk(BIOS_ERR, "%s: Out of CBMEM IDs.\n", dev_path(device)); + return; + }
- void *cbrom = cbmem_add(CBMEM_ID_ROM0 + ngfx, cbrom_length); - if (!cbrom) { - printk(BIOS_ERR, "%s: Failed to allocate CBMEM.\n", - dev_path(device)); - return; - } - /* Increment CBMEM id for next device */ - ngfx++; + /* Prepare memory */ + const size_t cbrom_length = rom->size * 512; + if (!cbrom_length) { + printk(BIOS_ERR, "%s: ROM has zero length!\n", + dev_path(device)); + return; + }
- memcpy(cbrom, rom, cbrom_length); + void *cbrom = cbmem_add(CBMEM_ID_ROM0 + ngfx, cbrom_length); + if (!cbrom) { + printk(BIOS_ERR, "%s: Failed to allocate CBMEM.\n", + dev_path(device)); + return; + } + /* Increment CBMEM id for next device */ + ngfx++; + + memcpy(cbrom, rom, cbrom_length); + + rom = cbrom; + }
/* write _ROM method */ acpigen_write_scope(scope); - acpigen_write_rom(cbrom, cbrom_length); + acpigen_write_rom((void *)rom, rom->size * 512); acpigen_pop_len(); /* pop scope */ } #endif diff --git a/src/include/device/device.h b/src/include/device/device.h index 901f717..2cee563 100644 --- a/src/include/device/device.h +++ b/src/include/device/device.h @@ -36,6 +36,7 @@ struct bus;
struct acpi_rsdp; +struct rom_header;
struct device_operations { void (*read_resources)(struct device *dev); @@ -127,6 +128,19 @@ struct device_operations *ops; struct chip_operations *chip_ops; const char *name; +#if CONFIG(HAVE_ACPI_TABLES) + /* + * A pointer to the corresponding PCI Option ROM. + * + * When set the Option ROM has been placed in usable DRAM in + * an area that is marked as reserved. This can be for example + * the legacy C-segment or a CBMEM area. The Option ROM is + * read writeable and guaranted to be used by the device. + * The PCIR data header might still have a different vendor and + * device ID. + */ + struct rom_header *pci_vga_option_rom; +#endif #if CONFIG(GENERATE_SMBIOS_TABLES) u8 smbios_slot_type; u8 smbios_slot_data_width;