]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuDxe/CpuPageTable.c
ArmPkg: only attempt buildin MmCommunicationDxe for AArch64
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuPageTable.c
index c369b44f128e70a3e49e94adf5b484782fecdfb9..0a02cb3f6b7e1606536126368738d04c5ed74f7a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Page table management support.\r
 \r
-  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>\r
   Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 \r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #include <Library/SynchronizationLib.h>\r
 #include <Library/PrintLib.h>\r
 #include <Protocol/SmmBase2.h>\r
-#include <Register/Cpuid.h>\r
-#include <Register/Msr.h>\r
+#include <Register/Intel/Cpuid.h>\r
+#include <Register/Intel/Msr.h>\r
 \r
 #include "CpuDxe.h"\r
 #include "CpuPageTable.h"\r
 \r
-///\r
-/// Paging registers\r
-///\r
-#define CR0_WP                      BIT16\r
-#define CR0_PG                      BIT31\r
-#define CR4_PSE                     BIT4\r
-#define CR4_PAE                     BIT5\r
-\r
 ///\r
 /// Page Table Entry\r
 ///\r
@@ -161,6 +153,10 @@ GetCurrentPagingContext (
   UINT32                          RegEax;\r
   CPUID_EXTENDED_CPU_SIG_EDX      RegEdx;\r
   MSR_IA32_EFER_REGISTER          MsrEfer;\r
+  IA32_CR4                        Cr4;\r
+  IA32_CR0                        Cr0;\r
+  UINT32                          *Attributes;\r
+  UINTN                           *PageTableBase;\r
 \r
   //\r
   // Don't retrieve current paging context from processor if in SMM mode.\r
@@ -172,20 +168,28 @@ GetCurrentPagingContext (
     } else {\r
       mPagingContext.MachineType = IMAGE_FILE_MACHINE_I386;\r
     }\r
-    if ((AsmReadCr0 () & CR0_PG) != 0) {\r
-      mPagingContext.ContextData.X64.PageTableBase = (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);\r
+\r
+    GetPagingDetails (&mPagingContext.ContextData, &PageTableBase, &Attributes);\r
+\r
+    Cr0.UintN = AsmReadCr0 ();\r
+    Cr4.UintN = AsmReadCr4 ();\r
+\r
+    if (Cr0.Bits.PG != 0) {\r
+      *PageTableBase = (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);\r
     } else {\r
-      mPagingContext.ContextData.X64.PageTableBase = 0;\r
+      *PageTableBase = 0;\r
     }\r
-\r
-    if ((AsmReadCr4 () & CR4_PSE) != 0) {\r
-      mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE;\r
+    if (Cr0.Bits.WP  != 0) {\r
+      *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE;\r
+    }\r
+    if (Cr4.Bits.PSE != 0) {\r
+      *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE;\r
     }\r
-    if ((AsmReadCr4 () & CR4_PAE) != 0) {\r
-      mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE;\r
+    if (Cr4.Bits.PAE != 0) {\r
+      *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE;\r
     }\r
-    if ((AsmReadCr0 () & CR0_WP) != 0) {\r
-      mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE;\r
+    if (Cr4.Bits.LA57 != 0) {\r
+      *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL;\r
     }\r
 \r
     AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
@@ -197,12 +201,12 @@ GetCurrentPagingContext (
         MsrEfer.Uint64 = AsmReadMsr64(MSR_CORE_IA32_EFER);\r
         if (MsrEfer.Bits.NXE != 0) {\r
           // XD activated\r
-          mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED;\r
+          *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED;\r
         }\r
       }\r
 \r
       if (RegEdx.Bits.Page1GB != 0) {\r
-        mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT;\r
+        *Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAGE_1G_SUPPORT;\r
       }\r
     }\r
   }\r
@@ -276,14 +280,17 @@ GetPageTableEntry (
   UINTN                 Index2;\r
   UINTN                 Index3;\r
   UINTN                 Index4;\r
+  UINTN                 Index5;\r
   UINT64                *L1PageTable;\r
   UINT64                *L2PageTable;\r
   UINT64                *L3PageTable;\r
   UINT64                *L4PageTable;\r
+  UINT64                *L5PageTable;\r
   UINT64                AddressEncMask;\r
 \r
   ASSERT (PagingContext != NULL);\r
 \r
+  Index5 = ((UINTN)RShiftU64 (Address, 48)) & PAGING_PAE_INDEX_MASK;\r
   Index4 = ((UINTN)RShiftU64 (Address, 39)) & PAGING_PAE_INDEX_MASK;\r
   Index3 = ((UINTN)Address >> 30) & PAGING_PAE_INDEX_MASK;\r
   Index2 = ((UINTN)Address >> 21) & PAGING_PAE_INDEX_MASK;\r
@@ -294,7 +301,17 @@ GetPageTableEntry (
   AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;\r
 \r
   if (PagingContext->MachineType == IMAGE_FILE_MACHINE_X64) {\r
-    L4PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase;\r
+    if ((PagingContext->ContextData.X64.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL) != 0) {\r
+      L5PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase;\r
+      if (L5PageTable[Index5] == 0) {\r
+        *PageAttribute = PageNone;\r
+        return NULL;\r
+      }\r
+\r
+      L4PageTable = (UINT64 *)(UINTN)(L5PageTable[Index5] & ~AddressEncMask & PAGING_4K_ADDRESS_MASK_64);\r
+    } else {\r
+      L4PageTable = (UINT64 *)(UINTN)PagingContext->ContextData.X64.PageTableBase;\r
+    }\r
     if (L4PageTable[Index4] == 0) {\r
       *PageAttribute = PageNone;\r
       return NULL;\r
@@ -382,6 +399,7 @@ ConvertPageEntryAttribute (
 {\r
   UINT64  CurrentPageEntry;\r
   UINT64  NewPageEntry;\r
+  UINT32  *PageAttributes;\r
 \r
   CurrentPageEntry = *PageEntry;\r
   NewPageEntry = CurrentPageEntry;\r
@@ -425,7 +443,10 @@ ConvertPageEntryAttribute (
       break;\r
     }\r
   }\r
-  if ((PagingContext->ContextData.Ia32.Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED) != 0) {\r
+\r
+  GetPagingDetails (&PagingContext->ContextData, NULL, &PageAttributes);\r
+\r
+  if ((*PageAttributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_XD_ACTIVATED) != 0) {\r
     if ((Attributes & EFI_MEMORY_XP) != 0) {\r
       switch (PageAction) {\r
       case PageActionAssign:\r
@@ -581,12 +602,14 @@ IsReadOnlyPageWriteProtected (
   VOID\r
   )\r
 {\r
+  IA32_CR0  Cr0;\r
   //\r
   // To avoid unforseen consequences, don't touch paging settings in SMM mode\r
   // in this driver.\r
   //\r
   if (!IsInSmm ()) {\r
-    return ((AsmReadCr0 () & CR0_WP) != 0);\r
+    Cr0.UintN = AsmReadCr0 ();\r
+    return (BOOLEAN) (Cr0.Bits.WP != 0);\r
   }\r
   return FALSE;\r
 }\r
@@ -599,12 +622,15 @@ DisableReadOnlyPageWriteProtect (
   VOID\r
   )\r
 {\r
+  IA32_CR0  Cr0;\r
   //\r
   // To avoid unforseen consequences, don't touch paging settings in SMM mode\r
   // in this driver.\r
   //\r
   if (!IsInSmm ()) {\r
-    AsmWriteCr0 (AsmReadCr0 () & ~CR0_WP);\r
+    Cr0.UintN = AsmReadCr0 ();\r
+    Cr0.Bits.WP = 0;\r
+    AsmWriteCr0 (Cr0.UintN);\r
   }\r
 }\r
 \r
@@ -616,12 +642,15 @@ EnableReadOnlyPageWriteProtect (
   VOID\r
   )\r
 {\r
+  IA32_CR0  Cr0;\r
   //\r
   // To avoid unforseen consequences, don't touch paging settings in SMM mode\r
   // in this driver.\r
   //\r
   if (!IsInSmm ()) {\r
-    AsmWriteCr0 (AsmReadCr0 () | CR0_WP);\r
+    Cr0.UintN = AsmReadCr0 ();\r
+    Cr0.Bits.WP = 1;\r
+    AsmWriteCr0 (Cr0.UintN);\r
   }\r
 }\r
 \r
@@ -747,7 +776,7 @@ ConvertMemoryPageAttributes (
   }\r
 \r
   //\r
-  // Below logic is to check 2M/4K page to make sure we donot waist memory.\r
+  // Below logic is to check 2M/4K page to make sure we do not waste memory.\r
   //\r
   Status = EFI_SUCCESS;\r
   while (Length != 0) {\r
@@ -809,7 +838,7 @@ Done:
 \r
   Caller should make sure BaseAddress and Length is at page boundary.\r
 \r
-  Caller need guarentee the TPL <= TPL_NOTIFY, if there is split page request.\r
+  Caller need guarantee the TPL <= TPL_NOTIFY, if there is split page request.\r
 \r
   @param[in]  PagingContext     The paging context. NULL means get page table from current CPU context.\r
   @param[in]  BaseAddress       The physical address that is the start address of a memory region.\r
@@ -940,7 +969,7 @@ RefreshGcdMemoryAttributesFromPaging (
                     );\r
     if (EFI_ERROR (Status)) {\r
       //\r
-      // If we cannot udpate the capabilities, we cannot update its\r
+      // If we cannot update the capabilities, we cannot update its\r
       // attributes either. So just simply skip current block of memory.\r
       //\r
       DEBUG ((\r
@@ -1317,15 +1346,18 @@ InitializePageTableLib (
   )\r
 {\r
   PAGE_TABLE_LIB_PAGING_CONTEXT     CurrentPagingContext;\r
+  UINT32                            *Attributes;\r
+  UINTN                             *PageTableBase;\r
 \r
   GetCurrentPagingContext (&CurrentPagingContext);\r
 \r
+  GetPagingDetails (&CurrentPagingContext.ContextData, &PageTableBase, &Attributes);\r
+\r
   //\r
   // Reserve memory of page tables for future uses, if paging is enabled.\r
   //\r
-  if (CurrentPagingContext.ContextData.X64.PageTableBase != 0 &&\r
-      (CurrentPagingContext.ContextData.Ia32.Attributes &\r
-       PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) != 0) {\r
+  if ((*PageTableBase != 0) &&\r
+      (*Attributes & PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PAE) != 0) {\r
     DisableReadOnlyPageWriteProtect ();\r
     InitializePageTablePool (1);\r
     EnableReadOnlyPageWriteProtect ();\r
@@ -1340,10 +1372,10 @@ InitializePageTableLib (
     ASSERT (mLastPFEntryPointer != NULL);\r
   }\r
 \r
-  DEBUG ((DEBUG_INFO, "CurrentPagingContext:\n", CurrentPagingContext.MachineType));\r
+  DEBUG ((DEBUG_INFO, "CurrentPagingContext:\n"));\r
   DEBUG ((DEBUG_INFO, "  MachineType   - 0x%x\n", CurrentPagingContext.MachineType));\r
-  DEBUG ((DEBUG_INFO, "  PageTableBase - 0x%x\n", CurrentPagingContext.ContextData.X64.PageTableBase));\r
-  DEBUG ((DEBUG_INFO, "  Attributes    - 0x%x\n", CurrentPagingContext.ContextData.X64.Attributes));\r
+  DEBUG ((DEBUG_INFO, "  PageTableBase - 0x%Lx\n", (UINT64)*PageTableBase));\r
+  DEBUG ((DEBUG_INFO, "  Attributes    - 0x%x\n", *Attributes));\r
 \r
   return ;\r
 }\r