/** @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
- 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
**/\r
\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
UINT32 RegEax;\r
CPUID_EXTENDED_CPU_SIG_EDX RegEdx;\r
MSR_IA32_EFER_REGISTER MsrEfer;\r
+ IA32_CR4 Cr4;\r
+ IA32_CR0 Cr0;\r
\r
//\r
// Don't retrieve current paging context from processor if in SMM mode.\r
} else {\r
mPagingContext.MachineType = IMAGE_FILE_MACHINE_I386;\r
}\r
- if ((AsmReadCr0 () & CR0_PG) != 0) {\r
+\r
+ Cr0.UintN = AsmReadCr0 ();\r
+ Cr4.UintN = AsmReadCr4 ();\r
+\r
+ if (Cr0.Bits.PG != 0) {\r
mPagingContext.ContextData.X64.PageTableBase = (AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64);\r
} else {\r
mPagingContext.ContextData.X64.PageTableBase = 0;\r
}\r
-\r
- if ((AsmReadCr4 () & CR4_PSE) != 0) {\r
+ if (Cr0.Bits.WP != 0) {\r
+ mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_WP_ENABLE;\r
+ }\r
+ if (Cr4.Bits.PSE != 0) {\r
mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_PSE;\r
}\r
- if ((AsmReadCr4 () & CR4_PAE) != 0) {\r
+ if (Cr4.Bits.PAE != 0) {\r
mPagingContext.ContextData.Ia32.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
+ mPagingContext.ContextData.Ia32.Attributes |= PAGE_TABLE_LIB_PAGING_CONTEXT_IA32_X64_ATTRIBUTES_5_LEVEL;\r
}\r
\r
AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
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
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
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
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
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
// Display ExceptionType, CPU information and Image information\r
//\r
DumpCpuContext (ExceptionType, SystemContext);\r
- if (!NonStopMode) {\r
+ if (NonStopMode) {\r
+ //\r
+ // Set TF in EFLAGS\r
+ //\r
+ if (mPagingContext.MachineType == IMAGE_FILE_MACHINE_I386) {\r
+ SystemContext.SystemContextIa32->Eflags |= (UINT32)BIT8;\r
+ } else {\r
+ SystemContext.SystemContextX64->Rflags |= (UINT64)BIT8;\r
+ }\r
+ } else {\r
CpuDeadLoop ();\r
}\r
}\r