From dbcfa67c2888666bca5a06b37bdafc585fd5fbf6 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 5 Mar 2025 11:24:56 +0100 Subject: [PATCH] device/pci_device: Move PCI Option ROM code into pci_rom.c Move PCI Option ROM handling code into device/pci_rom.c as it's already using a majority of functions within this file. Change-Id: I50fc3bf45a1ab6572ab031b9e24ca2f882a13aad Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/86733 Tested-by: build bot (Jenkins) Reviewed-by: Ana Carolina Cabral Reviewed-by: Felix Held --- src/device/pci_device.c | 90 +------------------------------- src/device/pci_rom.c | 99 ++++++++++++++++++++++++++++++++++-- src/include/device/pci_rom.h | 1 + 3 files changed, 99 insertions(+), 91 deletions(-) diff --git a/src/device/pci_device.c b/src/device/pci_device.c index d03d88df39..29fde7ca6c 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -839,97 +839,11 @@ void pci_dev_set_subsystem(struct device *dev, unsigned int vendor, } } -static int should_run_oprom(struct device *dev, struct rom_header *rom) -{ - static int should_run = -1; - - if (dev->upstream->segment_group) { - printk(BIOS_ERR, "Only option ROMs of devices in first PCI segment group can " - "be run.\n"); - return 0; - } - - if (CONFIG(VENDORCODE_ELTAN_VBOOT)) - if (rom != NULL) - if (!verified_boot_should_run_oprom(rom)) - return 0; - - if (should_run >= 0) - return should_run; - - if (CONFIG(ALWAYS_RUN_OPROM)) { - should_run = 1; - return should_run; - } - - /* Don't run VGA option ROMs, unless we have to print - * something on the screen before the kernel is loaded. - */ - should_run = display_init_required(); - - if (!should_run) - printk(BIOS_DEBUG, "Not running VGA Option ROM\n"); - return should_run; -} - -static int should_load_oprom(struct device *dev) -{ - /* If S3_VGA_ROM_RUN is disabled, skip running VGA option - * ROMs when coming out of an S3 resume. - */ - if (!CONFIG(S3_VGA_ROM_RUN) && acpi_is_wakeup_s3() && - ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)) - return 0; - if (CONFIG(ALWAYS_LOAD_OPROM)) - return 1; - if (should_run_oprom(dev, NULL)) - return 1; - - return 0; -} - -static void oprom_pre_graphics_stall(void) -{ - if (CONFIG_PRE_GRAPHICS_DELAY_MS) - mdelay(CONFIG_PRE_GRAPHICS_DELAY_MS); -} - /** Default handler: only runs the relevant PCI BIOS. */ void pci_dev_init(struct device *dev) { - struct rom_header *rom, *ram; - - if (!CONFIG(VGA_ROM_RUN)) - return; - - /* Only execute VGA ROMs. */ - if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)) - return; - - if (!should_load_oprom(dev)) - return; - timestamp_add_now(TS_OPROM_INITIALIZE); - - rom = pci_rom_probe(dev); - if (rom == NULL) - return; - - ram = pci_rom_load(dev, rom); - if (ram == NULL) - return; - timestamp_add_now(TS_OPROM_COPY_END); - - if (!should_run_oprom(dev, rom)) - return; - - /* Wait for any configured pre-graphics delay */ - oprom_pre_graphics_stall(); - - run_bios(dev, (unsigned long)ram); - - gfx_set_init_done(1); - printk(BIOS_DEBUG, "VGA Option ROM was run\n"); - timestamp_add_now(TS_OPROM_END); + if (CONFIG(VGA_ROM_RUN)) + pci_rom_run(dev); } /** Default device operation for PCI devices */ diff --git a/src/device/pci_rom.c b/src/device/pci_rom.c index 037f96eb66..dc41ef14ce 100644 --- a/src/device/pci_rom.c +++ b/src/device/pci_rom.c @@ -1,16 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include +#include #include #include +#include #include #include #include #include #include #include -#include -#include -#include +#include /* Rmodules don't like weak symbols. */ u32 __weak map_oprom_vendev(u32 vendev) { return vendev; } @@ -183,6 +186,96 @@ struct rom_header *pci_rom_load(struct device *dev, return (struct rom_header *)(pci_ram_image_start-rom_size); } +static int should_run_oprom(struct device *dev, struct rom_header *rom) +{ + static int should_run = -1; + + if (dev->upstream->segment_group) { + printk(BIOS_ERR, "Only option ROMs of devices in first PCI segment group can " + "be run.\n"); + return 0; + } + + if (CONFIG(VENDORCODE_ELTAN_VBOOT)) + if (rom != NULL) + if (!verified_boot_should_run_oprom(rom)) + return 0; + + if (should_run >= 0) + return should_run; + + if (CONFIG(ALWAYS_RUN_OPROM)) { + should_run = 1; + return should_run; + } + + /* Don't run VGA option ROMs, unless we have to print + * something on the screen before the kernel is loaded. + */ + should_run = display_init_required(); + + if (!should_run) + printk(BIOS_DEBUG, "Not running VGA Option ROM\n"); + return should_run; +} + +static int should_load_oprom(struct device *dev) +{ + /* If S3_VGA_ROM_RUN is disabled, skip running VGA option + * ROMs when coming out of an S3 resume. + */ + if (!CONFIG(S3_VGA_ROM_RUN) && acpi_is_wakeup_s3() && + ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)) + return 0; + if (CONFIG(ALWAYS_LOAD_OPROM)) + return 1; + if (should_run_oprom(dev, NULL)) + return 1; + + return 0; +} + +static void oprom_pre_graphics_stall(void) +{ + if (CONFIG_PRE_GRAPHICS_DELAY_MS) + mdelay(CONFIG_PRE_GRAPHICS_DELAY_MS); +} + +/** Load an Option ROM into the C-segment and run it if necessary */ +void pci_rom_run(struct device *dev) +{ + struct rom_header *rom, *ram; + + /* Only execute VGA ROMs. */ + if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)) + return; + + if (!should_load_oprom(dev)) + return; + timestamp_add_now(TS_OPROM_INITIALIZE); + + rom = pci_rom_probe(dev); + if (rom == NULL) + return; + + ram = pci_rom_load(dev, rom); + if (ram == NULL) + return; + timestamp_add_now(TS_OPROM_COPY_END); + + if (!should_run_oprom(dev, rom)) + return; + + /* Wait for any configured pre-graphics delay */ + oprom_pre_graphics_stall(); + + run_bios(dev, (unsigned long)ram); + + gfx_set_init_done(1); + printk(BIOS_DEBUG, "VGA Option ROM was run\n"); + timestamp_add_now(TS_OPROM_END); +} + /* ACPI */ #if CONFIG(HAVE_ACPI_TABLES) diff --git a/src/include/device/pci_rom.h b/src/include/device/pci_rom.h index 531ec18ffa..5e4b85e0ad 100644 --- a/src/include/device/pci_rom.h +++ b/src/include/device/pci_rom.h @@ -53,6 +53,7 @@ pci_rom_write_acpi_tables(const struct device *device, unsigned long current, struct acpi_rsdp *rsdp); +void pci_rom_run(struct device *dev); void pci_rom_ssdt(const struct device *device); u32 map_oprom_vendev(u32 vendev);