OvmfPkg/MemEncryptSevLib: find pages of initial SMRAM save state map
[mirror_edk2.git] / OvmfPkg / Library / BaseMemEncryptSevLib / MemEncryptSevLibInternal.c
index 7078ab0d3f4607a4b4160e7a760b6d1e24d8ca34..b92ba50c616c4d1caa310d373c0d34578f5d1633 100644 (file)
 #include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/MemEncryptSevLib.h>\r
+#include <Library/PcdLib.h>\r
 #include <Register/Amd/Cpuid.h>\r
 #include <Register/Amd/Msr.h>\r
 #include <Register/Cpuid.h>\r
+#include <Register/QemuSmramSaveStateMap.h>\r
+#include <Register/SmramSaveStateMap.h>\r
+#include <Uefi/UefiBaseType.h>\r
 \r
 STATIC BOOLEAN mSevStatus = FALSE;\r
 STATIC BOOLEAN mSevStatusChecked = FALSE;\r
@@ -87,3 +91,50 @@ MemEncryptSevIsEnabled (
 \r
   return mSevStatus;\r
 }\r
+\r
+\r
+/**\r
+  Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM\r
+  Save State Map.\r
+\r
+  @param[out] BaseAddress     The base address of the lowest-address page that\r
+                              covers the initial SMRAM Save State Map.\r
+\r
+  @param[out] NumberOfPages   The number of pages in the page range that covers\r
+                              the initial SMRAM Save State Map.\r
+\r
+  @retval RETURN_SUCCESS      BaseAddress and NumberOfPages have been set on\r
+                              output.\r
+\r
+  @retval RETURN_UNSUPPORTED  SMM is unavailable.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+MemEncryptSevLocateInitialSmramSaveStateMapPages (\r
+  OUT UINTN *BaseAddress,\r
+  OUT UINTN *NumberOfPages\r
+  )\r
+{\r
+  UINTN MapStart;\r
+  UINTN MapEnd;\r
+  UINTN MapPagesStart; // MapStart rounded down to page boundary\r
+  UINTN MapPagesEnd;   // MapEnd rounded up to page boundary\r
+  UINTN MapPagesSize;  // difference between MapPagesStart and MapPagesEnd\r
+\r
+  if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  MapStart      = SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET;\r
+  MapEnd        = MapStart + sizeof (QEMU_SMRAM_SAVE_STATE_MAP);\r
+  MapPagesStart = MapStart & ~(UINTN)EFI_PAGE_MASK;\r
+  MapPagesEnd   = ALIGN_VALUE (MapEnd, EFI_PAGE_SIZE);\r
+  MapPagesSize  = MapPagesEnd - MapPagesStart;\r
+\r
+  ASSERT ((MapPagesSize & EFI_PAGE_MASK) == 0);\r
+\r
+  *BaseAddress   = MapPagesStart;\r
+  *NumberOfPages = MapPagesSize >> EFI_PAGE_SHIFT;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r