summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Include
diff options
context:
space:
mode:
authorRay Ni <ray.ni@intel.com>2022-07-14 14:33:18 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2022-08-09 07:08:05 +0000
commit75e3c2435c7f10675d075ae7e5d4e9dea7331bcf (patch)
treec4a7f12186d10f552bf2a814f97079da0ea73cce /UefiCpuPkg/Include
parentf1688ec9dab680ad8a56ec0a3d0b1346933d7e07 (diff)
downloadedk2-75e3c2435c7f10675d075ae7e5d4e9dea7331bcf.tar.gz
edk2-75e3c2435c7f10675d075ae7e5d4e9dea7331bcf.tar.bz2
edk2-75e3c2435c7f10675d075ae7e5d4e9dea7331bcf.zip
UefiCpuPkg: Create CpuPageTableLib for manipulating X86 paging structs
The lib includes two APIs: * PageTableMap It creates/updates mapping from LA to PA. The implementation only supports paging structures used in 64bit mode now. PAE paging structure support will be added in future. * PageTableParse It parses the page table and returns the mapping relations in an array of IA32_MAP_ENTRY. It passed some stress tests. These test code will be upstreamed in other patches following edk2 Unit Test framework. Signed-off-by: Ray Ni <ray.ni@intel.com> Reviewed-by: Eric Dong <eric.dong@intel.com>
Diffstat (limited to 'UefiCpuPkg/Include')
-rw-r--r--UefiCpuPkg/Include/Library/CpuPageTableLib.h129
1 files changed, 129 insertions, 0 deletions
diff --git a/UefiCpuPkg/Include/Library/CpuPageTableLib.h b/UefiCpuPkg/Include/Library/CpuPageTableLib.h
new file mode 100644
index 0000000000..2dc9b7d18e
--- /dev/null
+++ b/UefiCpuPkg/Include/Library/CpuPageTableLib.h
@@ -0,0 +1,129 @@
+/** @file
+ Public include file for PageTableLib library.
+
+ Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PAGE_TABLE_LIB_H_
+#define PAGE_TABLE_LIB_H_
+
+typedef union {
+ struct {
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Dirty : 1; // 0 = Not dirty, 1 = Dirty (set by CPU)
+ UINT64 Pat : 1; // PAT
+
+ UINT64 Global : 1; // 0 = Not global, 1 = Global (if CR4.PGE = 1)
+ UINT64 Reserved1 : 3; // Ignored
+
+ UINT64 PageTableBaseAddress : 40; // Page Table Base Address
+ UINT64 Reserved2 : 7; // Ignored
+ UINT64 ProtectionKey : 4; // Protection key
+ UINT64 Nx : 1; // No Execute bit
+ } Bits;
+ UINT64 Uint64;
+} IA32_MAP_ATTRIBUTE;
+
+#define IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK 0xFFFFFFFFFF000ull
+#define IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS(pa) ((pa)->Uint64 & IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK)
+#define IA32_MAP_ATTRIBUTE_ATTRIBUTES(pa) ((pa)->Uint64 & ~IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK)
+
+//
+// Below enum follows "4.1.1 Four Paging Modes" in Chapter 4 Paging of SDM Volume 3.
+// Page1GB is only supported in 4-level and 5-level.
+//
+typedef enum {
+ Paging32bit,
+
+ //
+ // High byte in paging mode indicates the max levels of the page table.
+ // Low byte in paging mode indicates the max level that can be a leaf entry.
+ //
+ PagingPae = 0x0302,
+
+ Paging4Level = 0x0402,
+ Paging4Level1GB = 0x0403,
+
+ Paging5Level = 0x0502,
+ Paging5Level1GB = 0x0503,
+
+ PagingModeMax
+} PAGING_MODE;
+
+/**
+ Create or update page table to map [LinearAddress, LinearAddress + Length) with specified attribute.
+
+ @param[in, out] PageTable The pointer to the page table to update, or pointer to NULL if a new page table is to be created.
+ @param[in] PagingMode The paging mode.
+ @param[in] Buffer The free buffer to be used for page table creation/updating.
+ @param[in, out] BufferSize The buffer size.
+ On return, the remaining buffer size.
+ The free buffer is used from the end so caller can supply the same Buffer pointer with an updated
+ BufferSize in the second call to this API.
+ @param[in] LinearAddress The start of the linear address range.
+ @param[in] Length The length of the linear address range.
+ @param[in] Attribute The attribute of the linear address range.
+ All non-reserved fields in IA32_MAP_ATTRIBUTE are supported to set in the page table.
+ Page table entries that map the linear address range are reset to 0 before set to the new attribute
+ when a new physical base address is set.
+ @param[in] Mask The mask used for attribute. The corresponding field in Attribute is ignored if that in Mask is 0.
+
+ @retval RETURN_UNSUPPORTED PagingMode is not supported.
+ @retval RETURN_INVALID_PARAMETER PageTable, BufferSize, Attribute or Mask is NULL.
+ @retval RETURN_INVALID_PARAMETER *BufferSize is not multiple of 4KB.
+ @retval RETURN_BUFFER_TOO_SMALL The buffer is too small for page table creation/updating.
+ BufferSize is updated to indicate the expected buffer size.
+ Caller may still get RETURN_BUFFER_TOO_SMALL with the new BufferSize.
+ @retval RETURN_SUCCESS PageTable is created/updated successfully.
+**/
+RETURN_STATUS
+EFIAPI
+PageTableMap (
+ IN OUT UINTN *PageTable OPTIONAL,
+ IN PAGING_MODE PagingMode,
+ IN VOID *Buffer,
+ IN OUT UINTN *BufferSize,
+ IN UINT64 LinearAddress,
+ IN UINT64 Length,
+ IN IA32_MAP_ATTRIBUTE *Attribute,
+ IN IA32_MAP_ATTRIBUTE *Mask
+ );
+
+typedef struct {
+ UINT64 LinearAddress;
+ UINT64 Length;
+ IA32_MAP_ATTRIBUTE Attribute;
+} IA32_MAP_ENTRY;
+
+/**
+ Parse page table.
+
+ @param[in] PageTable Pointer to the page table.
+ @param[in] PagingMode The paging mode.
+ @param[out] Map Return an array that describes multiple linear address ranges.
+ @param[in, out] MapCount On input, the maximum number of entries that Map can hold.
+ On output, the number of entries in Map.
+
+ @retval RETURN_UNSUPPORTED PageLevel is not 5 or 4.
+ @retval RETURN_INVALID_PARAMETER MapCount is NULL.
+ @retval RETURN_INVALID_PARAMETER *MapCount is not 0 but Map is NULL.
+ @retval RETURN_BUFFER_TOO_SMALL *MapCount is too small.
+ @retval RETURN_SUCCESS Page table is parsed successfully.
+**/
+RETURN_STATUS
+EFIAPI
+PageTableParse (
+ IN UINTN PageTable,
+ IN PAGING_MODE PagingMode,
+ IN IA32_MAP_ENTRY *Map,
+ IN OUT UINTN *MapCount
+ );
+
+#endif