/** @file\r
- x64 Long Mode Virtual Memory Management Definitions \r
+ x64 Long Mode Virtual Memory Management Definitions\r
\r
References:\r
1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel\r
3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel\r
4) AMD64 Architecture Programmer's Manual Volume 2: System Programming\r
\r
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, 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
+SPDX-License-Identifier: BSD-2-Clause-Patent\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
+**/\r
\r
-**/ \r
#ifndef _VIRTUAL_MEMORY_H_\r
#define _VIRTUAL_MEMORY_H_\r
\r
-\r
-#define SYS_CODE64_SEL 0x38\r
-\r
+#define SYS_CODE64_SEL 0x38\r
\r
#pragma pack(1)\r
\r
typedef union {\r
struct {\r
- UINT32 LimitLow : 16;\r
- UINT32 BaseLow : 16;\r
- UINT32 BaseMid : 8;\r
- UINT32 Type : 4;\r
- UINT32 System : 1;\r
- UINT32 Dpl : 2;\r
- UINT32 Present : 1;\r
- UINT32 LimitHigh : 4;\r
- UINT32 Software : 1;\r
- UINT32 Reserved : 1;\r
- UINT32 DefaultSize : 1;\r
- UINT32 Granularity : 1;\r
- UINT32 BaseHigh : 8;\r
+ UINT32 LimitLow : 16;\r
+ UINT32 BaseLow : 16;\r
+ UINT32 BaseMid : 8;\r
+ UINT32 Type : 4;\r
+ UINT32 System : 1;\r
+ UINT32 Dpl : 2;\r
+ UINT32 Present : 1;\r
+ UINT32 LimitHigh : 4;\r
+ UINT32 Software : 1;\r
+ UINT32 Reserved : 1;\r
+ UINT32 DefaultSize : 1;\r
+ UINT32 Granularity : 1;\r
+ UINT32 BaseHigh : 8;\r
} Bits;\r
- UINT64 Uint64;\r
+ UINT64 Uint64;\r
} IA32_GDT;\r
\r
typedef struct {\r
- IA32_IDT_GATE_DESCRIPTOR Ia32IdtEntry;\r
- UINT32 Offset32To63;\r
- UINT32 Reserved;\r
+ IA32_IDT_GATE_DESCRIPTOR Ia32IdtEntry;\r
+ UINT32 Offset32To63;\r
+ UINT32 Reserved;\r
} X64_IDT_GATE_DESCRIPTOR;\r
\r
//\r
\r
typedef union {\r
struct {\r
- UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
- UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
- UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
- UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
- UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
- UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
- UINT64 Reserved:1; // Reserved\r
- UINT64 MustBeZero:2; // Must Be Zero\r
- UINT64 Available:3; // Available for use by system software\r
- UINT64 PageTableBaseAddress:40; // Page Table Base Address\r
- UINT64 AvabilableHigh:11; // Available for use by system software\r
- UINT64 Nx:1; // No Execute bit\r
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Reserved : 1; // Reserved\r
+ UINT64 MustBeZero : 2; // Must Be Zero\r
+ UINT64 Available : 3; // Available for use by system software\r
+ UINT64 PageTableBaseAddress : 40; // Page Table Base Address\r
+ UINT64 AvabilableHigh : 11; // Available for use by system software\r
+ UINT64 Nx : 1; // No Execute bit\r
} Bits;\r
UINT64 Uint64;\r
} PAGE_MAP_AND_DIRECTORY_POINTER;\r
//\r
typedef union {\r
struct {\r
- UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
- UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
- UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
- UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
- UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
- UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
- UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
- UINT64 PAT:1; //\r
- UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
- UINT64 Available:3; // Available for use by system software\r
- UINT64 PageTableBaseAddress:40; // Page Table Base Address\r
- UINT64 AvabilableHigh:11; // Available for use by system software\r
- UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution\r
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page\r
+ UINT64 PAT : 1; //\r
+ UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
+ UINT64 Available : 3; // Available for use by system software\r
+ UINT64 PageTableBaseAddress : 40; // Page Table Base Address\r
+ UINT64 AvabilableHigh : 11; // Available for use by system software\r
+ UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution\r
} Bits;\r
UINT64 Uint64;\r
} PAGE_TABLE_4K_ENTRY;\r
//\r
typedef union {\r
struct {\r
- UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
- UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
- UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
- UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
- UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
- UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
- UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
- UINT64 MustBe1:1; // Must be 1 \r
- UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
- UINT64 Available:3; // Available for use by system software\r
- UINT64 PAT:1; //\r
- UINT64 MustBeZero:8; // Must be zero;\r
- UINT64 PageTableBaseAddress:31; // Page Table Base Address\r
- UINT64 AvabilableHigh:11; // Available for use by system software\r
- UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution\r
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page\r
+ UINT64 MustBe1 : 1; // Must be 1\r
+ UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
+ UINT64 Available : 3; // Available for use by system software\r
+ UINT64 PAT : 1; //\r
+ UINT64 MustBeZero : 8; // Must be zero;\r
+ UINT64 PageTableBaseAddress : 31; // Page Table Base Address\r
+ UINT64 AvabilableHigh : 11; // Available for use by system software\r
+ UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution\r
} Bits;\r
UINT64 Uint64;\r
} PAGE_TABLE_ENTRY;\r
//\r
typedef union {\r
struct {\r
- UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory\r
- UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r
- UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r
- UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching\r
- UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r
- UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
- UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page\r
- UINT64 MustBe1:1; // Must be 1 \r
- UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
- UINT64 Available:3; // Available for use by system software\r
- UINT64 PAT:1; //\r
- UINT64 MustBeZero:17; // Must be zero;\r
- UINT64 PageTableBaseAddress:22; // Page Table Base Address\r
- UINT64 AvabilableHigh:11; // Available for use by system software\r
- UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution\r
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory\r
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write\r
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User\r
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching\r
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached\r
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)\r
+ UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page\r
+ UINT64 MustBe1 : 1; // Must be 1\r
+ UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write\r
+ UINT64 Available : 3; // Available for use by system software\r
+ UINT64 PAT : 1; //\r
+ UINT64 MustBeZero : 17; // Must be zero;\r
+ UINT64 PageTableBaseAddress : 22; // Page Table Base Address\r
+ UINT64 AvabilableHigh : 11; // Available for use by system software\r
+ UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution\r
} Bits;\r
UINT64 Uint64;\r
} PAGE_TABLE_1G_ENTRY;\r
\r
#pragma pack()\r
\r
-#define IA32_PG_P BIT0\r
-#define IA32_PG_RW BIT1\r
+#define CR0_WP BIT16\r
+\r
+#define IA32_PG_P BIT0\r
+#define IA32_PG_RW BIT1\r
+#define IA32_PG_PS BIT7\r
+\r
+#define PAGING_PAE_INDEX_MASK 0x1FF\r
+\r
+#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull\r
+#define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull\r
+#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r
+\r
+#define PAGING_L1_ADDRESS_SHIFT 12\r
+#define PAGING_L2_ADDRESS_SHIFT 21\r
+#define PAGING_L3_ADDRESS_SHIFT 30\r
+#define PAGING_L4_ADDRESS_SHIFT 39\r
+\r
+#define PAGING_PML4E_NUMBER 4\r
+\r
+#define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB\r
+#define PAGE_TABLE_POOL_UNIT_SIZE SIZE_2MB\r
+#define PAGE_TABLE_POOL_UNIT_PAGES EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE)\r
+#define PAGE_TABLE_POOL_ALIGN_MASK \\r
+ (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1))\r
+\r
+typedef struct {\r
+ VOID *NextPool;\r
+ UINTN Offset;\r
+ UINTN FreePages;\r
+} PAGE_TABLE_POOL;\r
+\r
+/**\r
+ Check if Execute Disable Bit (IA32_EFER.NXE) should be enabled or not.\r
+\r
+ @retval TRUE IA32_EFER.NXE should be enabled.\r
+ @retval FALSE IA32_EFER.NXE should not be enabled.\r
\r
-#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r
+**/\r
+BOOLEAN\r
+IsEnableNonExecNeeded (\r
+ VOID\r
+ );\r
\r
/**\r
Enable Execute Disable Bit.\r
@param[in, out] PageEntry2M Pointer to 2M page entry.\r
@param[in] StackBase Stack base address.\r
@param[in] StackSize Stack size.\r
+ @param[in] GhcbBase GHCB page area base address.\r
+ @param[in] GhcbSize GHCB page area size.\r
\r
**/\r
VOID\r
Split2MPageTo4K (\r
- IN EFI_PHYSICAL_ADDRESS PhysicalAddress,\r
- IN OUT UINT64 *PageEntry2M,\r
- IN EFI_PHYSICAL_ADDRESS StackBase,\r
- IN UINTN StackSize\r
+ IN EFI_PHYSICAL_ADDRESS PhysicalAddress,\r
+ IN OUT UINT64 *PageEntry2M,\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize,\r
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,\r
+ IN UINTN GhcbSize\r
);\r
\r
/**\r
\r
@param[in] StackBase Stack base address.\r
@param[in] StackSize Stack size.\r
+ @param[in] GhcbBase GHCB page area base address.\r
+ @param[in] GhcbSize GHCB page area size.\r
\r
@return The address of 4 level page map.\r
\r
**/\r
UINTN\r
CreateIdentityMappingPageTables (\r
- IN EFI_PHYSICAL_ADDRESS StackBase,\r
- IN UINTN StackSize\r
+ IN EFI_PHYSICAL_ADDRESS StackBase,\r
+ IN UINTN StackSize,\r
+ IN EFI_PHYSICAL_ADDRESS GhcbBase,\r
+ IN UINTN GhcbkSize\r
);\r
\r
-\r
/**\r
- \r
+\r
Fix up the vector number in the vector code.\r
- \r
+\r
@param VectorBase Base address of the vector handler.\r
@param VectorNum Index of vector.\r
\r
VOID\r
EFIAPI\r
AsmVectorFixup (\r
- VOID *VectorBase,\r
- UINT8 VectorNum\r
+ VOID *VectorBase,\r
+ UINT8 VectorNum\r
);\r
\r
-\r
/**\r
- \r
+\r
Get the information of vector template.\r
- \r
+\r
@param TemplateBase Base address of the template code.\r
- \r
+\r
@return Size of the Template code.\r
\r
**/\r
OUT VOID **TemplateBase\r
);\r
\r
+/**\r
+ Clear legacy memory located at the first 4K-page.\r
+\r
+ This function traverses the whole HOB list to check if memory from 0 to 4095\r
+ exists and has not been allocated, and then clear it if so.\r
+\r
+ @param HobStart The start of HobList passed to DxeCore.\r
+\r
+**/\r
+VOID\r
+ClearFirst4KPage (\r
+ IN VOID *HobStart\r
+ );\r
+\r
+/**\r
+ Return configure status of NULL pointer detection feature.\r
+\r
+ @return TRUE NULL pointer detection feature is enabled\r
+ @return FALSE NULL pointer detection feature is disabled\r
+**/\r
+BOOLEAN\r
+IsNullDetectionEnabled (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Prevent the memory pages used for page table from been overwritten.\r
+\r
+ @param[in] PageTableBase Base address of page table (CR3).\r
+ @param[in] Level4Paging Level 4 paging flag.\r
+\r
+**/\r
+VOID\r
+EnablePageTableProtection (\r
+ IN UINTN PageTableBase,\r
+ IN BOOLEAN Level4Paging\r
+ );\r
+\r
+/**\r
+ This API provides a way to allocate memory for page table.\r
+\r
+ This API can be called more than once to allocate memory for page tables.\r
+\r
+ Allocates the number of 4KB pages and returns a pointer to the allocated\r
+ buffer. The buffer returned is aligned on a 4KB boundary.\r
+\r
+ If Pages is 0, then NULL is returned.\r
+ If there is not enough memory remaining to satisfy the request, then NULL is\r
+ returned.\r
+\r
+ @param Pages The number of 4 KB pages to allocate.\r
+\r
+ @return A pointer to the allocated buffer or NULL if allocation fails.\r
+\r
+**/\r
+VOID *\r
+AllocatePageTableMemory (\r
+ IN UINTN Pages\r
+ );\r
\r
-#endif \r
+#endif\r