]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/PlatformPei/MemDetect.c
OvmfPkg/Csm/LegacyBiosDxe: Fix Legacy16GetTableAddress call for E820 data
[mirror_edk2.git] / OvmfPkg / PlatformPei / MemDetect.c
index 2f9e835513649457e2746015a7042cb161d34728..d451989f31c9b20b2154f8d65be89f6b02e296ce 100644 (file)
@@ -2,13 +2,7 @@
   Memory Detection for Virtual Machines.\r
 \r
   Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 Module Name:\r
 \r
@@ -20,6 +14,7 @@ Module Name:
 // The package level header files this module uses\r
 //\r
 #include <IndustryStandard/E820.h>\r
+#include <IndustryStandard/I440FxPiix4.h>\r
 #include <IndustryStandard/Q35MchIch9.h>\r
 #include <PiPei.h>\r
 \r
@@ -48,6 +43,8 @@ STATIC UINT32 mS3AcpiReservedMemorySize;
 \r
 STATIC UINT16 mQ35TsegMbytes;\r
 \r
+UINT32 mQemuUc32Base;\r
+\r
 VOID\r
 Q35TsegMbytesInitialization (\r
   VOID\r
@@ -104,6 +101,54 @@ Q35TsegMbytesInitialization (
 }\r
 \r
 \r
+VOID\r
+QemuUc32BaseInitialization (\r
+  VOID\r
+  )\r
+{\r
+  UINT32 LowerMemorySize;\r
+  UINT32 Uc32Size;\r
+\r
+  if (mXen) {\r
+    return;\r
+  }\r
+\r
+  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
+    //\r
+    // On q35, the 32-bit area that we'll mark as UC, through variable MTRRs,\r
+    // starts at PcdPciExpressBaseAddress. The platform DSC is responsible for\r
+    // setting PcdPciExpressBaseAddress such that describing the\r
+    // [PcdPciExpressBaseAddress, 4GB) range require a very small number of\r
+    // variable MTRRs (preferably 1 or 2).\r
+    //\r
+    ASSERT (FixedPcdGet64 (PcdPciExpressBaseAddress) <= MAX_UINT32);\r
+    mQemuUc32Base = (UINT32)FixedPcdGet64 (PcdPciExpressBaseAddress);\r
+    return;\r
+  }\r
+\r
+  ASSERT (mHostBridgeDevId == INTEL_82441_DEVICE_ID);\r
+  //\r
+  // On i440fx, start with the [LowerMemorySize, 4GB) range. Make sure one\r
+  // variable MTRR suffices by truncating the size to a whole power of two,\r
+  // while keeping the end affixed to 4GB. This will round the base up.\r
+  //\r
+  LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
+  Uc32Size = GetPowerOfTwo32 ((UINT32)(SIZE_4GB - LowerMemorySize));\r
+  mQemuUc32Base = (UINT32)(SIZE_4GB - Uc32Size);\r
+  //\r
+  // Assuming that LowerMemorySize is at least 1 byte, Uc32Size is at most 2GB.\r
+  // Therefore mQemuUc32Base is at least 2GB.\r
+  //\r
+  ASSERT (mQemuUc32Base >= BASE_2GB);\r
+\r
+  if (mQemuUc32Base != LowerMemorySize) {\r
+    DEBUG ((DEBUG_VERBOSE, "%a: rounded UC32 base from 0x%x up to 0x%x, for "\r
+      "an UC32 size of 0x%x\n", __FUNCTION__, LowerMemorySize, mQemuUc32Base,\r
+      Uc32Size));\r
+  }\r
+}\r
+\r
+\r
 /**\r
   Iterate over the RAM entries in QEMU's fw_cfg E820 RAM map that start outside\r
   of the 32-bit address range.\r
@@ -694,11 +739,11 @@ QemuInitializeRam (
     ASSERT_EFI_ERROR (Status);\r
 \r
     //\r
-    // Set memory range from the "top of lower RAM" (RAM below 4GB) to 4GB as\r
-    // uncacheable\r
+    // Set the memory range from the start of the 32-bit MMIO area (32-bit PCI\r
+    // MMIO aperture on i440fx, PCIEXBAR on q35) to 4GB as uncacheable.\r
     //\r
-    Status = MtrrSetMemoryAttribute (LowerMemorySize,\r
-               SIZE_4GB - LowerMemorySize, CacheUncacheable);\r
+    Status = MtrrSetMemoryAttribute (mQemuUc32Base, SIZE_4GB - mQemuUc32Base,\r
+               CacheUncacheable);\r
     ASSERT_EFI_ERROR (Status);\r
   }\r
 }\r