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> Reviewed-on: https://review.coreboot.org/c/coreboot/+/86385 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Felix Held <felix-coreboot@felixheld.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
257375eb24
commit
85e503e641
2 changed files with 56 additions and 57 deletions
|
|
@ -169,12 +169,15 @@ struct rom_header *pci_rom_load(struct device *dev,
|
|||
memcpy((void *)PCI_VGA_RAM_IMAGE_START, rom_header,
|
||||
rom_size);
|
||||
}
|
||||
|
||||
dev->pci_vga_option_rom = (struct rom_header *)(PCI_VGA_RAM_IMAGE_START);
|
||||
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);
|
||||
|
||||
dev->pci_vga_option_rom = (struct rom_header *)pci_ram_image_start;
|
||||
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 +186,6 @@ struct rom_header *pci_rom_load(struct device *dev,
|
|||
/* 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 +193,8 @@ ati_rom_acpi_fill_vfct(const struct device *device, acpi_vfct_t *vfct_struct,
|
|||
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) {
|
||||
|
|
@ -273,6 +253,7 @@ pci_rom_write_acpi_tables(const struct device *device, unsigned long current,
|
|||
|
||||
void pci_rom_ssdt(const struct device *device)
|
||||
{
|
||||
const struct rom_header *rom;
|
||||
static size_t ngfx;
|
||||
|
||||
/* Only handle display devices */
|
||||
|
|
@ -283,12 +264,43 @@ void pci_rom_ssdt(const struct device *device)
|
|||
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;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const char *scope = acpi_device_path(device);
|
||||
|
|
@ -297,34 +309,9 @@ void pci_rom_ssdt(const struct device *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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* 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
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ struct chip_operations {
|
|||
struct bus;
|
||||
|
||||
struct acpi_rsdp;
|
||||
struct rom_header;
|
||||
|
||||
struct device_operations {
|
||||
void (*read_resources)(struct device *dev);
|
||||
|
|
@ -127,6 +128,17 @@ struct device {
|
|||
struct device_operations *ops;
|
||||
struct chip_operations *chip_ops;
|
||||
const char *name;
|
||||
/*
|
||||
* 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 guaranteed 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;
|
||||
#if CONFIG(GENERATE_SMBIOS_TABLES)
|
||||
u8 smbios_slot_type;
|
||||
u8 smbios_slot_data_width;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue