X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=OvmfPkg%2FQemuVideoDxe%2FVbeShim.c;h=c23dc984d4538f0b955ecddff465d0b7829ce9eb;hb=07135c12205805fa0ffcc0d0f347c3d4de37188b;hp=81c11664f4938a514375ff6a94657dadf69629f3;hpb=ea5396f31a8db7344177b4dd5335ebd617861d58;p=mirror_edk2.git diff --git a/OvmfPkg/QemuVideoDxe/VbeShim.c b/OvmfPkg/QemuVideoDxe/VbeShim.c index 81c11664f4..c23dc984d4 100644 --- a/OvmfPkg/QemuVideoDxe/VbeShim.c +++ b/OvmfPkg/QemuVideoDxe/VbeShim.c @@ -12,19 +12,14 @@ Copyright (C) 2014, Red Hat, Inc. Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
- This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License which accompanies this - distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT - WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include +#include #include "Qemu.h" #include "VbeShim.h" @@ -63,7 +58,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; @@ -73,6 +69,20 @@ InstallVbeShim ( UINTN Printed; VBE_MODE_INFO *VbeModeInfo; + if ((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT0|BIT7)) == BIT0) { + DEBUG (( + DEBUG_WARN, + "%a: page 0 protected, not installing VBE shim\n", + __FUNCTION__ + )); + DEBUG (( + DEBUG_WARN, + "%a: page 0 protection prevents Windows 7 from booting anyway\n", + __FUNCTION__ + )); + return; + } + Segment0 = 0x00000; SegmentC = 0xC0000; SegmentF = 0xF0000; @@ -86,11 +96,15 @@ InstallVbeShim ( // The allocation request may fail, eg. if LegacyBiosDxe has already run. // Segment0Pages = 1; - Int0x10 = (IVT_ENTRY *)(UINTN)Segment0 + 0x10; - Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode, - Segment0Pages, &Segment0); - - if (EFI_ERROR (Status)) { + Int0x10 = (IVT_ENTRY *)(UINTN)(Segment0 + 0x10 * sizeof (IVT_ENTRY)); + Segment0AllocationStatus = gBS->AllocatePages ( + AllocateAddress, + EfiBootServicesCode, + Segment0Pages, + &Segment0 + ); + + if (EFI_ERROR (Segment0AllocationStatus)) { EFI_PHYSICAL_ADDRESS Handler; // @@ -100,7 +114,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 +123,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 +141,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 +175,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 +194,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 +209,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,7 +309,7 @@ InstallVbeShim ( // // Second, point the Int10h vector at the shim. // - Int0x10->Segment = (UINT16) (SegmentC >> 4); + Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4); Int0x10->Offset = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC); DEBUG ((EFI_D_INFO, "%a: VBE shim installed\n", __FUNCTION__));