]>
Commit | Line | Data |
---|---|---|
a1f22614 BS |
1 | /** @file\r |
2 | \r | |
3 | Virtual Memory Management Services to set or clear the memory encryption bit\r | |
4 | \r | |
4bd6bf31 LE |
5 | Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r |
6 | Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r | |
a1f22614 | 7 | \r |
b26f0cf9 | 8 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
a1f22614 | 9 | \r |
4bd6bf31 | 10 | Code is derived from MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h\r |
a1f22614 BS |
11 | \r |
12 | **/\r | |
13 | \r | |
14 | #ifndef __VIRTUAL_MEMORY__\r | |
15 | #define __VIRTUAL_MEMORY__\r | |
16 | \r | |
a1f22614 BS |
17 | #include <Library/BaseLib.h>\r |
18 | #include <Library/BaseMemoryLib.h>\r | |
bd13ecf3 | 19 | #include <Library/CacheMaintenanceLib.h>\r |
a1f22614 BS |
20 | #include <Library/DebugLib.h>\r |
21 | #include <Library/MemoryAllocationLib.h>\r | |
bd13ecf3 | 22 | #include <Uefi.h>\r |
a1f22614 | 23 | \r |
a1f22614 BS |
24 | #define SYS_CODE64_SEL 0x38\r |
25 | \r | |
26 | #pragma pack(1)\r | |
27 | \r | |
28 | //\r | |
29 | // Page-Map Level-4 Offset (PML4) and\r | |
30 | // Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB\r | |
31 | //\r | |
32 | \r | |
33 | typedef union {\r | |
34 | struct {\r | |
4bd6bf31 LE |
35 | UINT64 Present:1; // 0 = Not present in memory,\r |
36 | // 1 = Present in memory\r | |
a1f22614 BS |
37 | UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r |
38 | UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r | |
4bd6bf31 LE |
39 | UINT64 WriteThrough:1; // 0 = Write-Back caching,\r |
40 | // 1 = Write-Through caching\r | |
a1f22614 | 41 | UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r |
4bd6bf31 LE |
42 | UINT64 Accessed:1; // 0 = Not accessed,\r |
43 | // 1 = Accessed (set by CPU)\r | |
a1f22614 BS |
44 | UINT64 Reserved:1; // Reserved\r |
45 | UINT64 MustBeZero:2; // Must Be Zero\r | |
46 | UINT64 Available:3; // Available for use by system software\r | |
47 | UINT64 PageTableBaseAddress:40; // Page Table Base Address\r | |
48 | UINT64 AvabilableHigh:11; // Available for use by system software\r | |
49 | UINT64 Nx:1; // No Execute bit\r | |
50 | } Bits;\r | |
51 | UINT64 Uint64;\r | |
52 | } PAGE_MAP_AND_DIRECTORY_POINTER;\r | |
53 | \r | |
54 | //\r | |
55 | // Page Table Entry 4KB\r | |
56 | //\r | |
57 | typedef union {\r | |
58 | struct {\r | |
4bd6bf31 LE |
59 | UINT64 Present:1; // 0 = Not present in memory,\r |
60 | // 1 = Present in memory\r | |
a1f22614 BS |
61 | UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r |
62 | UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r | |
4bd6bf31 LE |
63 | UINT64 WriteThrough:1; // 0 = Write-Back caching,\r |
64 | // 1 = Write-Through caching\r | |
a1f22614 | 65 | UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r |
4bd6bf31 LE |
66 | UINT64 Accessed:1; // 0 = Not accessed,\r |
67 | // 1 = Accessed (set by CPU)\r | |
68 | UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by\r | |
69 | // processor on access to page\r | |
a1f22614 | 70 | UINT64 PAT:1; //\r |
4bd6bf31 LE |
71 | UINT64 Global:1; // 0 = Not global page, 1 = global page\r |
72 | // TLB not cleared on CR3 write\r | |
a1f22614 BS |
73 | UINT64 Available:3; // Available for use by system software\r |
74 | UINT64 PageTableBaseAddress:40; // Page Table Base Address\r | |
75 | UINT64 AvabilableHigh:11; // Available for use by system software\r | |
4bd6bf31 LE |
76 | UINT64 Nx:1; // 0 = Execute Code,\r |
77 | // 1 = No Code Execution\r | |
a1f22614 BS |
78 | } Bits;\r |
79 | UINT64 Uint64;\r | |
80 | } PAGE_TABLE_4K_ENTRY;\r | |
81 | \r | |
82 | //\r | |
83 | // Page Table Entry 2MB\r | |
84 | //\r | |
85 | typedef union {\r | |
86 | struct {\r | |
4bd6bf31 LE |
87 | UINT64 Present:1; // 0 = Not present in memory,\r |
88 | // 1 = Present in memory\r | |
a1f22614 BS |
89 | UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r |
90 | UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r | |
4bd6bf31 LE |
91 | UINT64 WriteThrough:1; // 0 = Write-Back caching,\r |
92 | // 1=Write-Through caching\r | |
a1f22614 | 93 | UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r |
4bd6bf31 LE |
94 | UINT64 Accessed:1; // 0 = Not accessed,\r |
95 | // 1 = Accessed (set by CPU)\r | |
96 | UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by\r | |
97 | // processor on access to page\r | |
a1f22614 | 98 | UINT64 MustBe1:1; // Must be 1\r |
4bd6bf31 LE |
99 | UINT64 Global:1; // 0 = Not global page, 1 = global page\r |
100 | // TLB not cleared on CR3 write\r | |
a1f22614 BS |
101 | UINT64 Available:3; // Available for use by system software\r |
102 | UINT64 PAT:1; //\r | |
103 | UINT64 MustBeZero:8; // Must be zero;\r | |
104 | UINT64 PageTableBaseAddress:31; // Page Table Base Address\r | |
105 | UINT64 AvabilableHigh:11; // Available for use by system software\r | |
4bd6bf31 LE |
106 | UINT64 Nx:1; // 0 = Execute Code,\r |
107 | // 1 = No Code Execution\r | |
a1f22614 BS |
108 | } Bits;\r |
109 | UINT64 Uint64;\r | |
110 | } PAGE_TABLE_ENTRY;\r | |
111 | \r | |
112 | //\r | |
113 | // Page Table Entry 1GB\r | |
114 | //\r | |
115 | typedef union {\r | |
116 | struct {\r | |
4bd6bf31 LE |
117 | UINT64 Present:1; // 0 = Not present in memory,\r |
118 | // 1 = Present in memory\r | |
a1f22614 BS |
119 | UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write\r |
120 | UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User\r | |
4bd6bf31 LE |
121 | UINT64 WriteThrough:1; // 0 = Write-Back caching,\r |
122 | // 1 = Write-Through caching\r | |
a1f22614 | 123 | UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached\r |
4bd6bf31 LE |
124 | UINT64 Accessed:1; // 0 = Not accessed,\r |
125 | // 1 = Accessed (set by CPU)\r | |
126 | UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by\r | |
127 | // processor on access to page\r | |
a1f22614 | 128 | UINT64 MustBe1:1; // Must be 1\r |
4bd6bf31 LE |
129 | UINT64 Global:1; // 0 = Not global page, 1 = global page\r |
130 | // TLB not cleared on CR3 write\r | |
a1f22614 BS |
131 | UINT64 Available:3; // Available for use by system software\r |
132 | UINT64 PAT:1; //\r | |
133 | UINT64 MustBeZero:17; // Must be zero;\r | |
134 | UINT64 PageTableBaseAddress:22; // Page Table Base Address\r | |
135 | UINT64 AvabilableHigh:11; // Available for use by system software\r | |
4bd6bf31 LE |
136 | UINT64 Nx:1; // 0 = Execute Code,\r |
137 | // 1 = No Code Execution\r | |
a1f22614 BS |
138 | } Bits;\r |
139 | UINT64 Uint64;\r | |
140 | } PAGE_TABLE_1G_ENTRY;\r | |
141 | \r | |
142 | #pragma pack()\r | |
143 | \r | |
144 | #define IA32_PG_P BIT0\r | |
145 | #define IA32_PG_RW BIT1\r | |
b721aa74 BS |
146 | #define IA32_PG_PS BIT7\r |
147 | \r | |
148 | #define PAGING_PAE_INDEX_MASK 0x1FF\r | |
149 | \r | |
150 | #define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull\r | |
151 | #define PAGING_2M_ADDRESS_MASK_64 0x000FFFFFFFE00000ull\r | |
152 | #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r | |
153 | \r | |
154 | #define PAGING_L1_ADDRESS_SHIFT 12\r | |
155 | #define PAGING_L2_ADDRESS_SHIFT 21\r | |
156 | #define PAGING_L3_ADDRESS_SHIFT 30\r | |
157 | #define PAGING_L4_ADDRESS_SHIFT 39\r | |
158 | \r | |
159 | #define PAGING_PML4E_NUMBER 4\r | |
a1f22614 BS |
160 | \r |
161 | #define PAGETABLE_ENTRY_MASK ((1UL << 9) - 1)\r | |
162 | #define PML4_OFFSET(x) ( (x >> 39) & PAGETABLE_ENTRY_MASK)\r | |
163 | #define PDP_OFFSET(x) ( (x >> 30) & PAGETABLE_ENTRY_MASK)\r | |
164 | #define PDE_OFFSET(x) ( (x >> 21) & PAGETABLE_ENTRY_MASK)\r | |
165 | #define PTE_OFFSET(x) ( (x >> 12) & PAGETABLE_ENTRY_MASK)\r | |
166 | #define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull\r | |
167 | \r | |
b721aa74 BS |
168 | #define PAGE_TABLE_POOL_ALIGNMENT BASE_2MB\r |
169 | #define PAGE_TABLE_POOL_UNIT_SIZE SIZE_2MB\r | |
4bd6bf31 LE |
170 | #define PAGE_TABLE_POOL_UNIT_PAGES \\r |
171 | EFI_SIZE_TO_PAGES (PAGE_TABLE_POOL_UNIT_SIZE)\r | |
b721aa74 BS |
172 | #define PAGE_TABLE_POOL_ALIGN_MASK \\r |
173 | (~(EFI_PHYSICAL_ADDRESS)(PAGE_TABLE_POOL_ALIGNMENT - 1))\r | |
174 | \r | |
175 | typedef struct {\r | |
176 | VOID *NextPool;\r | |
177 | UINTN Offset;\r | |
178 | UINTN FreePages;\r | |
179 | } PAGE_TABLE_POOL;\r | |
180 | \r | |
181 | \r | |
182 | \r | |
a1f22614 | 183 | /**\r |
4bd6bf31 | 184 | This function clears memory encryption bit for the memory region specified by\r |
1532e5d5 | 185 | PhysicalAddress and Length from the current page table context.\r |
a1f22614 | 186 | \r |
1532e5d5 LE |
187 | @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use\r |
188 | current CR3)\r | |
4bd6bf31 LE |
189 | @param[in] PhysicalAddress The physical address that is the start\r |
190 | address of a memory region.\r | |
a1f22614 | 191 | @param[in] Length The length of memory region\r |
4bd6bf31 LE |
192 | @param[in] Flush Flush the caches before applying the\r |
193 | encryption mask\r | |
a1f22614 | 194 | \r |
4bd6bf31 LE |
195 | @retval RETURN_SUCCESS The attributes were cleared for the\r |
196 | memory region.\r | |
a1f22614 | 197 | @retval RETURN_INVALID_PARAMETER Number of pages is zero.\r |
1532e5d5 | 198 | @retval RETURN_UNSUPPORTED Clearing the memory encyrption attribute\r |
4bd6bf31 | 199 | is not supported\r |
a1f22614 BS |
200 | **/\r |
201 | RETURN_STATUS\r | |
202 | EFIAPI\r | |
203 | InternalMemEncryptSevSetMemoryDecrypted (\r | |
1532e5d5 LE |
204 | IN PHYSICAL_ADDRESS Cr3BaseAddress,\r |
205 | IN PHYSICAL_ADDRESS PhysicalAddress,\r | |
206 | IN UINTN Length,\r | |
207 | IN BOOLEAN Flush\r | |
a1f22614 BS |
208 | );\r |
209 | \r | |
210 | /**\r | |
211 | This function sets memory encryption bit for the memory region specified by\r | |
68e60a38 | 212 | PhysicalAddress and Length from the current page table context.\r |
a1f22614 | 213 | \r |
68e60a38 LE |
214 | @param[in] Cr3BaseAddress Cr3 Base Address (if zero then use\r |
215 | current CR3)\r | |
4bd6bf31 LE |
216 | @param[in] PhysicalAddress The physical address that is the start\r |
217 | address of a memory region.\r | |
a1f22614 BS |
218 | @param[in] Length The length of memory region\r |
219 | @param[in] Flush Flush the caches before applying the\r | |
220 | encryption mask\r | |
221 | \r | |
68e60a38 LE |
222 | @retval RETURN_SUCCESS The attributes were set for the memory\r |
223 | region.\r | |
a1f22614 | 224 | @retval RETURN_INVALID_PARAMETER Number of pages is zero.\r |
4bd6bf31 LE |
225 | @retval RETURN_UNSUPPORTED Setting the memory encyrption attribute\r |
226 | is not supported\r | |
a1f22614 BS |
227 | **/\r |
228 | RETURN_STATUS\r | |
229 | EFIAPI\r | |
230 | InternalMemEncryptSevSetMemoryEncrypted (\r | |
68e60a38 LE |
231 | IN PHYSICAL_ADDRESS Cr3BaseAddress,\r |
232 | IN PHYSICAL_ADDRESS PhysicalAddress,\r | |
233 | IN UINTN Length,\r | |
234 | IN BOOLEAN Flush\r | |
a1f22614 BS |
235 | );\r |
236 | \r | |
237 | #endif\r |