device/pci_rom: Set VBIOS checksum when filling VFCT table

AMD's Windows display drivers validate the checksum of the VBIOS data
in the VFCT table (which gets modified by the FSP GOP driver), so
ensure it is set correctly after copying the VBIOS into the table if the
FSP GOP driver was run. Without the correct checksum, the Windows GPU
drivers will fail to load with a code 43 error in Device Manager.

Thanks to coolstar for root causing the issue.

TEST=build/boot Win11 on google/skyrim (frostflow), ensure GPU driver
loaded and functional.

Change-Id: I809f87865fd2a25fb106444574b619746aec068d
Signed-off-by: Matt DeVillier <matt.devillier@amd.corp-partner.google.com>
Signed-off-by: CoolStar <coolstarorganization@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/77628
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com>
This commit is contained in:
Matt DeVillier 2023-09-03 12:51:58 -05:00 committed by Felix Held
parent bfd85218a7
commit 7c04d0e6fd
2 changed files with 13 additions and 2 deletions

View File

@ -245,10 +245,19 @@ pci_rom_acpi_fill_vfct(const struct device *device, acpi_vfct_t *vfct_struct,
header->PCIFunction = PCI_FUNC(device->path.pci.devfn); header->PCIFunction = PCI_FUNC(device->path.pci.devfn);
header->PCIDevice = PCI_SLOT(device->path.pci.devfn); header->PCIDevice = PCI_SLOT(device->path.pci.devfn);
header->ImageLength = rom->size * 512; header->ImageLength = rom->size * 512;
memcpy((void *)&header->VbiosContent, rom, header->ImageLength); memcpy((void *)header->VbiosContent, rom, header->ImageLength);
vfct_struct->VBIOSImageOffset = (size_t)header - (size_t)vfct_struct; vfct_struct->VBIOSImageOffset = (size_t)header - (size_t)vfct_struct;
/* Calculate and set checksum for VBIOS data if FSP GOP driver used,
Since GOP driver modifies ATOMBIOS tables at end of VBIOS */
if (CONFIG(RUN_FSP_GOP)) {
/* Clear existing checksum before recalculating */
header->VbiosContent[VFCT_VBIOS_CHECKSUM_OFFSET] = 0;
header->VbiosContent[VFCT_VBIOS_CHECKSUM_OFFSET] =
acpi_checksum(header->VbiosContent, header->ImageLength);
}
current += header->ImageLength; current += header->ImageLength;
return current; return current;
} }

View File

@ -466,6 +466,8 @@ typedef struct acpi_lpi_desc_ncst {
uint64_t counter_frequency; /* Frequency in cycles per second - 0 means TSC freq */ uint64_t counter_frequency; /* Frequency in cycles per second - 0 means TSC freq */
} __packed acpi_lpi_desc_ncst_t; } __packed acpi_lpi_desc_ncst_t;
#define VFCT_VBIOS_CHECKSUM_OFFSET 0x21
/* VFCT image header */ /* VFCT image header */
typedef struct acpi_vfct_image_hdr { typedef struct acpi_vfct_image_hdr {
u32 PCIBus; u32 PCIBus;
@ -477,7 +479,7 @@ typedef struct acpi_vfct_image_hdr {
u16 SSID; u16 SSID;
u32 Revision; u32 Revision;
u32 ImageLength; u32 ImageLength;
u8 VbiosContent; // dummy - copy VBIOS here u8 VbiosContent[]; // dummy - copy VBIOS here
} __packed acpi_vfct_image_hdr_t; } __packed acpi_vfct_image_hdr_t;
/* VFCT (VBIOS Fetch Table) */ /* VFCT (VBIOS Fetch Table) */