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