]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/PlatformPei/MemDetect.c
OvmfPkg/MemEncryptSevLib: Make the MemEncryptSevLib available for SEC
[mirror_edk2.git] / OvmfPkg / PlatformPei / MemDetect.c
index 8fdc9c2ed7c9676163e5a3afa1518a0a15ddeaba..ffbbef891a1178cc000d77a232f0fa9ddda36f7f 100644 (file)
@@ -27,12 +27,14 @@ Module Name:
 #include <Library/DebugLib.h>\r
 #include <Library/HobLib.h>\r
 #include <Library/IoLib.h>\r
+#include <Library/MemEncryptSevLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/PciLib.h>\r
 #include <Library/PeimEntryPoint.h>\r
 #include <Library/ResourcePublicationLib.h>\r
 #include <Library/MtrrLib.h>\r
 #include <Library/QemuFwCfgLib.h>\r
+#include <Library/QemuFwCfgSimpleParserLib.h>\r
 \r
 #include "Platform.h"\r
 #include "Cmos.h"\r
@@ -103,6 +105,22 @@ Q35SmramAtDefaultSmbaseInitialization (
   ASSERT (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID);\r
 \r
   mQ35SmramAtDefaultSmbase = FALSE;\r
+  if (FeaturePcdGet (PcdCsmEnable)) {\r
+    DEBUG ((DEBUG_INFO, "%a: SMRAM at default SMBASE not checked due to CSM\n",\r
+      __FUNCTION__));\r
+  } else {\r
+    UINTN CtlReg;\r
+    UINT8 CtlRegVal;\r
+\r
+    CtlReg = DRAMC_REGISTER_Q35 (MCH_DEFAULT_SMBASE_CTL);\r
+    PciWrite8 (CtlReg, MCH_DEFAULT_SMBASE_QUERY);\r
+    CtlRegVal = PciRead8 (CtlReg);\r
+    mQ35SmramAtDefaultSmbase = (BOOLEAN)(CtlRegVal ==\r
+                                         MCH_DEFAULT_SMBASE_IN_RAM);\r
+    DEBUG ((DEBUG_INFO, "%a: SMRAM at default SMBASE %a\n", __FUNCTION__,\r
+      mQ35SmramAtDefaultSmbase ? "found" : "not found"));\r
+  }\r
+\r
   PcdStatus = PcdSetBoolS (PcdQ35SmramAtDefaultSmbase,\r
                 mQ35SmramAtDefaultSmbase);\r
   ASSERT_RETURN_ERROR (PcdStatus);\r
@@ -320,7 +338,7 @@ GetFirstNonAddress (
 {\r
   UINT64               FirstNonAddress;\r
   UINT64               Pci64Base, Pci64Size;\r
-  CHAR8                MbString[7 + 1];\r
+  UINT32               FwCfgPciMmio64Mb;\r
   EFI_STATUS           Status;\r
   FIRMWARE_CONFIG_ITEM FwCfgItem;\r
   UINTN                FwCfgSize;\r
@@ -363,30 +381,35 @@ GetFirstNonAddress (
 \r
   //\r
   // See if the user specified the number of megabytes for the 64-bit PCI host\r
-  // aperture. The number of non-NUL characters in MbString allows for\r
-  // 9,999,999 MB, which is approximately 10 TB.\r
+  // aperture. Accept an aperture size up to 16TB.\r
   //\r
   // As signaled by the "X-" prefix, this knob is experimental, and might go\r
   // away at any time.\r
   //\r
-  Status = QemuFwCfgFindFile ("opt/ovmf/X-PciMmio64Mb", &FwCfgItem,\r
-             &FwCfgSize);\r
-  if (!EFI_ERROR (Status)) {\r
-    if (FwCfgSize >= sizeof MbString) {\r
-      DEBUG ((EFI_D_WARN,\r
-        "%a: ignoring malformed 64-bit PCI host aperture size from fw_cfg\n",\r
-        __FUNCTION__));\r
-    } else {\r
-      QemuFwCfgSelectItem (FwCfgItem);\r
-      QemuFwCfgReadBytes (FwCfgSize, MbString);\r
-      MbString[FwCfgSize] = '\0';\r
-      Pci64Size = LShiftU64 (AsciiStrDecimalToUint64 (MbString), 20);\r
+  Status = QemuFwCfgParseUint32 ("opt/ovmf/X-PciMmio64Mb", FALSE,\r
+             &FwCfgPciMmio64Mb);\r
+  switch (Status) {\r
+  case EFI_UNSUPPORTED:\r
+  case EFI_NOT_FOUND:\r
+    break;\r
+  case EFI_SUCCESS:\r
+    if (FwCfgPciMmio64Mb <= 0x1000000) {\r
+      Pci64Size = LShiftU64 (FwCfgPciMmio64Mb, 20);\r
+      break;\r
     }\r
+    //\r
+    // fall through\r
+    //\r
+  default:\r
+    DEBUG ((DEBUG_WARN,\r
+      "%a: ignoring malformed 64-bit PCI host aperture size from fw_cfg\n",\r
+      __FUNCTION__));\r
+    break;\r
   }\r
 \r
   if (Pci64Size == 0) {\r
     if (mBootMode != BOOT_ON_S3_RESUME) {\r
-      DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",\r
+      DEBUG ((DEBUG_INFO, "%a: disabling 64-bit PCI host aperture\n",\r
         __FUNCTION__));\r
       PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);\r
       ASSERT_RETURN_ERROR (PcdStatus);\r
@@ -444,7 +467,7 @@ GetFirstNonAddress (
     PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);\r
     ASSERT_RETURN_ERROR (PcdStatus);\r
 \r
-    DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",\r
+    DEBUG ((DEBUG_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",\r
       __FUNCTION__, Pci64Base, Pci64Size));\r
   }\r
 \r
@@ -604,7 +627,7 @@ PublishPeiMemory (
     MemorySize = mS3AcpiReservedMemorySize;\r
   } else {\r
     PeiMemoryCap = GetPeiMemoryCap ();\r
-    DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",\r
+    DEBUG ((DEBUG_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",\r
       __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));\r
 \r
     //\r
@@ -683,7 +706,7 @@ QemuInitializeRam (
   MTRR_SETTINGS               MtrrSettings;\r
   EFI_STATUS                  Status;\r
 \r
-  DEBUG ((EFI_D_INFO, "%a called\n", __FUNCTION__));\r
+  DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__));\r
 \r
   //\r
   // Determine total memory size available\r
@@ -844,6 +867,28 @@ InitializeRamRegions (
       (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),\r
       EfiACPIMemoryNVS\r
       );\r
+\r
+    if (MemEncryptSevEsIsEnabled ()) {\r
+      //\r
+      // If SEV-ES is enabled, reserve the GHCB-related memory area. This\r
+      // includes the extra page table used to break down the 2MB page\r
+      // mapping into 4KB page entries where the GHCB resides and the\r
+      // GHCB area itself.\r
+      //\r
+      // Since this memory range will be used by the Reset Vector on S3\r
+      // resume, it must be reserved as ACPI NVS.\r
+      //\r
+      BuildMemoryAllocationHob (\r
+        (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecGhcbPageTableBase),\r
+        (UINT64)(UINTN) PcdGet32 (PcdOvmfSecGhcbPageTableSize),\r
+        EfiACPIMemoryNVS\r
+        );\r
+      BuildMemoryAllocationHob (\r
+        (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecGhcbBase),\r
+        (UINT64)(UINTN) PcdGet32 (PcdOvmfSecGhcbSize),\r
+        EfiACPIMemoryNVS\r
+        );\r
+    }\r
 #endif\r
   }\r
 \r
@@ -895,5 +940,25 @@ InitializeRamRegions (
           );\r
       }\r
     }\r
+\r
+#ifdef MDE_CPU_X64\r
+    if (MemEncryptSevEsIsEnabled ()) {\r
+      //\r
+      // If SEV-ES is enabled, reserve the SEV-ES work area.\r
+      //\r
+      // Since this memory range will be used by the Reset Vector on S3\r
+      // resume, it must be reserved as ACPI NVS.\r
+      //\r
+      // If S3 is unsupported, then various drivers might still write to the\r
+      // work area. We ought to prevent DXE from serving allocation requests\r
+      // such that they would overlap the work area.\r
+      //\r
+      BuildMemoryAllocationHob (\r
+        (EFI_PHYSICAL_ADDRESS)(UINTN) FixedPcdGet32 (PcdSevEsWorkAreaBase),\r
+        (UINT64)(UINTN) FixedPcdGet32 (PcdSevEsWorkAreaSize),\r
+        mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData\r
+        );\r
+    }\r
+#endif\r
   }\r
 }\r