X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FQemuVideoDxe%2FVbeShim.c;h=e45a08e8873f15cdf366b0b4a537e6b579460392;hp=ae25b644cfc0490c48414f5bf8ef3c7b27ea0b1d;hb=947f3737abf65fda63f3ffd97fddfa6986986868;hpb=90803342b1b6060f1ddbb1aaea54fdf86a7ff9ad diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.c b/OvmfPkg/QemuVideoDxe/VbeShim.c index ae25b644cf..e45a08e887 100644 --- a/OvmfPkg/QemuVideoDxe/VbeShim.c +++ b/OvmfPkg/QemuVideoDxe/VbeShim.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "Qemu.h" #include "VbeShim.h" @@ -63,7 +64,8 @@ InstallVbeShim ( EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF; UINTN Segment0Pages; IVT_ENTRY *Int0x10; - EFI_STATUS Status; + EFI_STATUS Segment0AllocationStatus; + UINT16 HostBridgeDevId; UINTN Pam1Address; UINT8 Pam1; UINTN SegmentCPages; @@ -87,10 +89,14 @@ InstallVbeShim ( // Segment0Pages = 1; Int0x10 = (IVT_ENTRY *)(UINTN)Segment0 + 0x10; - Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, - Segment0Pages, &Segment0); - - if (EFI_ERROR (Status)) { + Segment0AllocationStatus = gBS->AllocatePages ( + AllocateAddress, + EfiBootServicesCode, + Segment0Pages, + &Segment0 + ); + + if (EFI_ERROR (Segment0AllocationStatus)) { EFI_PHYSICAL_ADDRESS Handler; // @@ -100,7 +106,7 @@ InstallVbeShim ( // Handler = (Int0x10->Segment << 4) + Int0x10->Offset; if (Handler >= SegmentC && Handler < SegmentF) { - DEBUG ((EFI_D_VERBOSE, "%a: Video BIOS handler found at %04x:%04x\n", + DEBUG ((EFI_D_INFO, "%a: Video BIOS handler found at %04x:%04x\n", __FUNCTION__, Int0x10->Segment, Int0x10->Offset)); return; } @@ -109,8 +115,12 @@ InstallVbeShim ( // Otherwise we'll overwrite the Int10h vector, even though we may not own // the page at zero. // - DEBUG ((EFI_D_VERBOSE, "%a: failed to allocate page at zero: %r\n", - __FUNCTION__, Status)); + DEBUG (( + DEBUG_INFO, + "%a: failed to allocate page at zero: %r\n", + __FUNCTION__, + Segment0AllocationStatus + )); } else { // // We managed to allocate the page at zero. SVN r14218 guarantees that it @@ -123,7 +133,30 @@ InstallVbeShim ( // // Put the shim in place first. // - Pam1Address = PCI_LIB_ADDRESS (0, 0, 0, 0x5A); + // Start by determining the address of the PAM1 register. + // + HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId); + switch (HostBridgeDevId) { + case INTEL_82441_DEVICE_ID: + Pam1Address = PMC_REGISTER_PIIX4 (PIIX4_PAM1); + break; + case INTEL_Q35_MCH_DEVICE_ID: + Pam1Address = DRAMC_REGISTER_Q35 (MCH_PAM1); + break; + default: + DEBUG (( + DEBUG_ERROR, + "%a: unknown host bridge device ID: 0x%04x\n", + __FUNCTION__, + HostBridgeDevId + )); + ASSERT (FALSE); + + if (!EFI_ERROR (Segment0AllocationStatus)) { + gBS->FreePages (Segment0, Segment0Pages); + } + return; + } // // low nibble covers 0xC0000 to 0xC3FFF // high nibble covers 0xC4000 to 0xC7FFF @@ -134,7 +167,7 @@ InstallVbeShim ( PciWrite8 (Pam1Address, Pam1 | (BIT1 | BIT0)); // - // We never added memory space durig PEI or DXE for the C segment, so we + // 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. // @@ -153,13 +186,13 @@ InstallVbeShim ( CopyMem (VbeInfo->Signature, "VESA", 4); VbeInfo->VesaVersion = 0x0300; - VbeInfo->OemNameAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr); + VbeInfo->OemNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; CopyMem (Ptr, "QEMU", 5); Ptr += 5; VbeInfo->Capabilities = BIT0; // DAC can be switched into 8-bit mode - VbeInfo->ModeListAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr); + VbeInfo->ModeListAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; *(UINT16*)Ptr = 0x00f1; // mode number Ptr += 2; *(UINT16*)Ptr = 0xFFFF; // mode list terminator @@ -168,17 +201,17 @@ InstallVbeShim ( VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536); VbeInfo->OemSoftwareVersion = 0x0000; - VbeInfo->VendorNameAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr); + VbeInfo->VendorNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; CopyMem (Ptr, "OVMF", 5); Ptr += 5; - VbeInfo->ProductNameAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr); + VbeInfo->ProductNameAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; Printed = AsciiSPrint ((CHAR8 *)Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%s", CardName); Ptr += Printed + 1; - VbeInfo->ProductRevAddress = (UINT32)(SegmentC << 12 | (UINT16)(UINTN)Ptr); + VbeInfo->ProductRevAddress = (UINT32)SegmentC << 12 | (UINT16)(UINTN)Ptr; CopyMem (Ptr, mProductRevision, sizeof mProductRevision); Ptr += sizeof mProductRevision; @@ -268,8 +301,8 @@ InstallVbeShim ( // // Second, point the Int10h vector at the shim. // - Int0x10->Segment = SegmentC >> 4; - Int0x10->Offset = (EFI_PHYSICAL_ADDRESS)(UINTN)(VbeModeInfo + 1) - SegmentC; + Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4); + Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC); DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__)); }