Matt DeVillier has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/86275?usp=email )
Change subject: drivers/intel/gma: Fix alignment of extended VBT in opregion ......................................................................
drivers/intel/gma: Fix alignment of extended VBT in opregion
Intel's reference implementation in Slimbootloader pads the area allocated for the extended VBT to the nearest 512-byte boundary, which strongly suggests that the Windows driver expects the same.
TEST=build/boot Linux 6.9, Win11 on starlabs/starlite_adl, verify VBT read properly by OS.
Change-Id: Ib3784eea6eb929ffec9672fc123b833c11c057e8 Signed-off-by: Matt DeVillier matt.devillier@gmail.com --- M src/drivers/intel/gma/opregion.c 1 file changed, 7 insertions(+), 4 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/75/86275/1
diff --git a/src/drivers/intel/gma/opregion.c b/src/drivers/intel/gma/opregion.c index f97d373..37a8413 100644 --- a/src/drivers/intel/gma/opregion.c +++ b/src/drivers/intel/gma/opregion.c @@ -287,7 +287,7 @@ * values correctly for the opregion. */ static void opregion_add_ext_vbt(igd_opregion_t *opregion, uint8_t *ext_vbt, - optionrom_vbt_t *vbt) + optionrom_vbt_t *vbt, size_t ext_vbt_size) { opregion_header_t *header = &opregion->header; /* Copy VBT into extended VBT region (at offset 8 KiB) */ @@ -301,7 +301,7 @@ else opregion->mailbox3.rvda = (uintptr_t)ext_vbt;
- opregion->mailbox3.rvds = vbt->hdr_vbt_size; + opregion->mailbox3.rvds = ext_vbt_size; }
/* Initialize IGD OpRegion, called from ACPI code and OS drivers */ @@ -311,6 +311,7 @@ struct region_device rdev; optionrom_vbt_t *vbt = NULL; size_t opregion_size = sizeof(igd_opregion_t); + size_t ext_vbt_size;
if (acpi_is_wakeup_s3()) return intel_gma_restore_opregion(); @@ -331,7 +332,9 @@ }
/* Add the space for the extended VBT header even if it's not used */ - opregion_size += vbt->hdr_vbt_size; + /* Align the VBT to nearest 512 byte boundary */ + ext_vbt_size = (vbt->hdr_vbt_size & (uint32_t)~(0x1ff)) + 0x200; + opregion_size += ext_vbt_size;
opregion = cbmem_add(CBMEM_ID_IGD_OPREGION, opregion_size); if (!opregion) { @@ -353,7 +356,7 @@ if (is_ext_vbt_required(opregion, vbt)) { /* Place extended VBT just after opregion */ uint8_t *ext_vbt = (uint8_t *)opregion + sizeof(*opregion); - opregion_add_ext_vbt(opregion, ext_vbt, vbt); + opregion_add_ext_vbt(opregion, ext_vbt, vbt, ext_vbt_size); } else { /* Raw VBT size which can fit in gvd1 */ memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size);