[PATCH v4 22/45] pci: Allow the video BIOS to work in SPL with QEMU
Bin Meng
bmeng.cn at gmail.com
Thu Jul 13 06:00:41 CEST 2023
Hi Simon,
On Mon, Jun 19, 2023 at 8:01 PM Simon Glass <sjg at chromium.org> wrote:
>
> QEMU emulates two common machines (Q35 and i440fx) which use mapping to
> determine whether RAM is present below 1MB. In order to copy the video
> BIOS to c0000 we need to flip this mapping over to RAM. This does not
> happen automatically until SPL has finished running.
>
> Switch in RAM at these address so that the video BIOS can be loaded and
> run. This fix was found in the seabios code base.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> (no changes since v1)
>
> drivers/pci/pci_rom.c | 46 +++++++++++++++++++++++++++++++++++++++++++
> include/pci_ids.h | 1 +
> 2 files changed, 47 insertions(+)
>
> diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
> index f0dfe6314907..0f44238bbbc8 100644
> --- a/drivers/pci/pci_rom.c
> +++ b/drivers/pci/pci_rom.c
> @@ -141,6 +141,49 @@ static int pci_rom_probe(struct udevice *dev, struct pci_rom_header **hdrp)
> return 0;
> }
>
> +#define Q35_HOST_BRIDGE_PAM0 0x90
> +#define I440FX_PAM0 0x59
> +
> +/**
> + * intel_set_writable_ram() - Set RAM to be writable
> + *
> + * This is needed for QEMU when using Q35 or I440FX emulation, since otherwise
> + * there is no RAM available at c0000
> + *
> + * See Intel 82945G/82945G/82945GC GMCH and 82945P/82945PL MCH Datasheet for
> + * information about the PAM0-PAM6 registers
> + */
> +static void intel_set_writable_ram(void)
> +{
> + struct udevice *dev;
> + int pam0 = -1;
> + int i;
> +
> + for (pci_find_first_device(&dev); dev; pci_find_next_device(&dev)) {
> + const struct pci_child_plat *pdata = dev_get_parent_plat(dev);
> +
> + if (pdata->vendor == PCI_VENDOR_ID_INTEL) {
> + if (pdata->device == PCI_DEVICE_ID_INTEL_Q35_MCH) {
> + pam0 = Q35_HOST_BRIDGE_PAM0;
> + break;
> + } else if (pdata->device == PCI_DEVICE_ID_INTEL_82441) {
> + pam0 = I440FX_PAM0;
> + break;
> + }
> + }
> + }
> +
> + if (!dev)
> + return;
> +
> + // Adjust RAM to be writable from c0000 to f0000
> + for (i = 1; i <= 6; i++)
> + dm_pci_write_config8(dev, pam0 + i, 0x33);
> +
> + // Also f0000-100000
> + dm_pci_write_config8(dev, pam0, 0x30);
> +}
> +
> /**
> * pci_rom_load() - Load a ROM image and return a pointer to it
> *
> @@ -185,6 +228,9 @@ static int pci_rom_load(struct pci_rom_header *rom_header,
> return -ENOMEM;
> *allocedp = true;
> #endif
> + /* QEMU hacks */
> + intel_set_writable_ram();
I don't like inserting chip-specific logic in the generic codes.
The logic is already in qemu_chipset_init(). We should allow
qemu_chipset_init() to be called in the SPL.
> +
> if (target != rom_header) {
> ulong start = get_timer(0);
>
> diff --git a/include/pci_ids.h b/include/pci_ids.h
> index 88b0a6404585..856d53264114 100644
> --- a/include/pci_ids.h
> +++ b/include/pci_ids.h
> @@ -2870,6 +2870,7 @@
> #define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
> #define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
> #define PCI_DEVICE_ID_INTEL_ICH9_AHCI 0x2922
> +#define PCI_DEVICE_ID_INTEL_Q35_MCH 0x29c0
> #define PCI_DEVICE_ID_INTEL_I7_MCR 0x2c18
> #define PCI_DEVICE_ID_INTEL_I7_MC_TAD 0x2c19
> #define PCI_DEVICE_ID_INTEL_I7_MC_RAS 0x2c1a
> --
Regards,
Bin
More information about the U-Boot
mailing list