and PC_ROM_MIN_VGA is #defined as 0xc0000 in "include/hw/loader.h".
OVMF places the VBE Shim into the C segment, and points the 0x10 interrupt vector at it. See "OvmfPkg/QemuVideoDxe/VbeShim.c", function InstallVbeShim():
> SegmentC = 0xC0000;
>
> [...]
>
> //
> // Put the shim in place first.
> //
> Pam1Address = PCI_LIB_ADDRESS (0, 0, 0, 0x5A);
> //
> // low nibble covers 0xC0000 to 0xC3FFF
> // high nibble covers 0xC4000 to 0xC7FFF
> // bit1 in each nibble is Write Enable
> // bit0 in each nibble is Read Enable
> //
> Pam1 = PciRead8 (Pam1Address);
> PciWrite8 (Pam1Address, Pam1 | (BIT1 | BIT0));
>
> //
> // We never added memory space during PEI or DXE for the C segment, so we
> // don't need to (and can't) allocate from there. Also, guest operating
> // systems will see a hole in the UEFI memory map there.
> //
> SegmentCPages = 4;
>
> ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages));
> CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim);
>
> [...]
>
> //
> // Clear Write Enable (bit1), keep Read Enable (bit0) set
> //
> PciWrite8 (Pam1Address, (Pam1 & ~BIT1) | BIT0);
>
> //
> // Second, point the Int10h vector at the shim.
> //
> Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4);
> Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC);
Thanks, Gerd, for the CC -- I agree, this commit (208fa0e43645) almost certainly breaks the VBE Shim. Displaying the patch with a bit larger context,
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c .59435390ba62 100644 init(PCMachineS tate *pcms, sizeof( *option_ rom_mr) ); region_ init_ram( option_ rom_mr, NULL, "pc.rom", PC_ROM_SIZE, region_ set_readonly( option_ rom_mr, true); region_ add_subregion_ overlap( rom_memory,
> index 22e16031b03b.
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1442,8 +1442,11 @@ void pc_memory_
>
> option_rom_mr = g_malloc(
> memory_
> &error_fatal);
> + if (pcmc->pci_enabled) {
> + memory_
> + }
> memory_
> PC_ROM_MIN_VGA,
> option_rom_mr,
> 1);
and PC_ROM_MIN_VGA is #defined as 0xc0000 in "include/ hw/loader. h".
OVMF places the VBE Shim into the C segment, and points the 0x10 interrupt vector at it. See "OvmfPkg/ QemuVideoDxe/ VbeShim. c", function InstallVbeShim():
> SegmentC = 0xC0000;
>
> [...]
>
> //
> // Put the shim in place first.
> //
> Pam1Address = PCI_LIB_ADDRESS (0, 0, 0, 0x5A);
> //
> // low nibble covers 0xC0000 to 0xC3FFF
> // high nibble covers 0xC4000 to 0xC7FFF
> // bit1 in each nibble is Write Enable
> // bit0 in each nibble is Read Enable
> //
> Pam1 = PciRead8 (Pam1Address);
> PciWrite8 (Pam1Address, Pam1 | (BIT1 | BIT0));
>
> //
> // We never added memory space during PEI or DXE for the C segment, so we
> // don't need to (and can't) allocate from there. Also, guest operating
> // systems will see a hole in the UEFI memory map there.
> //
> SegmentCPages = 4;
>
> ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages));
> CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim);
>
> [...]
>
> //
> // Clear Write Enable (bit1), keep Read Enable (bit0) set
> //
> PciWrite8 (Pam1Address, (Pam1 & ~BIT1) | BIT0);
>
> //
> // Second, point the Int10h vector at the shim.
> //
> Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4);
> Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC);