]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / MemoryAttributesTable.c
... / ...
CommitLineData
1/** @file\r
2 UEFI MemoryAttributesTable support\r
3\r
4Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include <PiDxe.h>\r
10#include <Library/BaseLib.h>\r
11#include <Library/BaseMemoryLib.h>\r
12#include <Library/MemoryAllocationLib.h>\r
13#include <Library/UefiBootServicesTableLib.h>\r
14#include <Library/DxeServicesTableLib.h>\r
15#include <Library/DebugLib.h>\r
16#include <Library/UefiLib.h>\r
17\r
18#include <Guid/EventGroup.h>\r
19\r
20#include <Guid/MemoryAttributesTable.h>\r
21#include <Guid/PropertiesTable.h>\r
22\r
23#include "DxeMain.h"\r
24\r
25/**\r
26 This function for GetMemoryMap() with properties table capability.\r
27\r
28 It calls original GetMemoryMap() to get the original memory map information. Then\r
29 plus the additional memory map entries for PE Code/Data seperation.\r
30\r
31 @param MemoryMapSize A pointer to the size, in bytes, of the\r
32 MemoryMap buffer. On input, this is the size of\r
33 the buffer allocated by the caller. On output,\r
34 it is the size of the buffer returned by the\r
35 firmware if the buffer was large enough, or the\r
36 size of the buffer needed to contain the map if\r
37 the buffer was too small.\r
38 @param MemoryMap A pointer to the buffer in which firmware places\r
39 the current memory map.\r
40 @param MapKey A pointer to the location in which firmware\r
41 returns the key for the current memory map.\r
42 @param DescriptorSize A pointer to the location in which firmware\r
43 returns the size, in bytes, of an individual\r
44 EFI_MEMORY_DESCRIPTOR.\r
45 @param DescriptorVersion A pointer to the location in which firmware\r
46 returns the version number associated with the\r
47 EFI_MEMORY_DESCRIPTOR.\r
48\r
49 @retval EFI_SUCCESS The memory map was returned in the MemoryMap\r
50 buffer.\r
51 @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current\r
52 buffer size needed to hold the memory map is\r
53 returned in MemoryMapSize.\r
54 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
55\r
56**/\r
57EFI_STATUS\r
58EFIAPI\r
59CoreGetMemoryMapWithSeparatedImageSection (\r
60 IN OUT UINTN *MemoryMapSize,\r
61 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
62 OUT UINTN *MapKey,\r
63 OUT UINTN *DescriptorSize,\r
64 OUT UINT32 *DescriptorVersion\r
65 );\r
66\r
67extern EFI_PROPERTIES_TABLE mPropertiesTable;\r
68EFI_MEMORY_ATTRIBUTES_TABLE *mMemoryAttributesTable = NULL;\r
69BOOLEAN mMemoryAttributesTableReadyToBoot = FALSE;\r
70\r
71/**\r
72 Install MemoryAttributesTable.\r
73\r
74**/\r
75VOID\r
76InstallMemoryAttributesTable (\r
77 VOID\r
78 )\r
79{\r
80 UINTN MemoryMapSize;\r
81 EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
82 EFI_MEMORY_DESCRIPTOR *MemoryMapStart;\r
83 UINTN MapKey;\r
84 UINTN DescriptorSize;\r
85 UINT32 DescriptorVersion;\r
86 UINTN Index;\r
87 EFI_STATUS Status;\r
88 UINT32 RuntimeEntryCount;\r
89 EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;\r
90 EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;\r
91\r
92 if (gMemoryMapTerminated) {\r
93 //\r
94 // Directly return after MemoryMap terminated.\r
95 //\r
96 return;\r
97 }\r
98\r
99 if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {\r
100 DEBUG ((EFI_D_VERBOSE, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, "));\r
101 DEBUG ((EFI_D_VERBOSE, "because Runtime Driver Section Alignment is not %dK.\n", RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10));\r
102 return ;\r
103 }\r
104\r
105 if (mMemoryAttributesTable == NULL) {\r
106 //\r
107 // InstallConfigurationTable here to occupy one entry for MemoryAttributesTable\r
108 // before GetMemoryMap below, as InstallConfigurationTable may allocate runtime\r
109 // memory for the new entry.\r
110 //\r
111 Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID *) (UINTN) MAX_ADDRESS);\r
112 ASSERT_EFI_ERROR (Status);\r
113 }\r
114\r
115 MemoryMapSize = 0;\r
116 MemoryMap = NULL;\r
117 Status = CoreGetMemoryMapWithSeparatedImageSection (\r
118 &MemoryMapSize,\r
119 MemoryMap,\r
120 &MapKey,\r
121 &DescriptorSize,\r
122 &DescriptorVersion\r
123 );\r
124 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
125\r
126 do {\r
127 MemoryMap = AllocatePool (MemoryMapSize);\r
128 ASSERT (MemoryMap != NULL);\r
129\r
130 Status = CoreGetMemoryMapWithSeparatedImageSection (\r
131 &MemoryMapSize,\r
132 MemoryMap,\r
133 &MapKey,\r
134 &DescriptorSize,\r
135 &DescriptorVersion\r
136 );\r
137 if (EFI_ERROR (Status)) {\r
138 FreePool (MemoryMap);\r
139 }\r
140 } while (Status == EFI_BUFFER_TOO_SMALL);\r
141\r
142 MemoryMapStart = MemoryMap;\r
143 RuntimeEntryCount = 0;\r
144 for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {\r
145 switch (MemoryMap->Type) {\r
146 case EfiRuntimeServicesCode:\r
147 case EfiRuntimeServicesData:\r
148 RuntimeEntryCount ++;\r
149 break;\r
150 }\r
151 MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
152 }\r
153\r
154 //\r
155 // Allocate MemoryAttributesTable\r
156 //\r
157 MemoryAttributesTable = AllocatePool (sizeof(EFI_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount);\r
158 ASSERT (MemoryAttributesTable != NULL);\r
159 MemoryAttributesTable->Version = EFI_MEMORY_ATTRIBUTES_TABLE_VERSION;\r
160 MemoryAttributesTable->NumberOfEntries = RuntimeEntryCount;\r
161 MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize;\r
162 MemoryAttributesTable->Reserved = 0;\r
163 DEBUG ((EFI_D_VERBOSE, "MemoryAttributesTable:\n"));\r
164 DEBUG ((EFI_D_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version));\r
165 DEBUG ((EFI_D_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries));\r
166 DEBUG ((EFI_D_VERBOSE, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize));\r
167 MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1);\r
168 MemoryMap = MemoryMapStart;\r
169 for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {\r
170 switch (MemoryMap->Type) {\r
171 case EfiRuntimeServicesCode:\r
172 case EfiRuntimeServicesData:\r
173 CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize);\r
174 MemoryAttributesEntry->Attribute &= (EFI_MEMORY_RO|EFI_MEMORY_XP|EFI_MEMORY_RUNTIME);\r
175 DEBUG ((EFI_D_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry));\r
176 DEBUG ((EFI_D_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type));\r
177 DEBUG ((EFI_D_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart));\r
178 DEBUG ((EFI_D_VERBOSE, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart));\r
179 DEBUG ((EFI_D_VERBOSE, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages));\r
180 DEBUG ((EFI_D_VERBOSE, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute));\r
181 MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR(MemoryAttributesEntry, DescriptorSize);\r
182 break;\r
183 }\r
184 MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
185 }\r
186 MemoryMap = MemoryMapStart;\r
187 FreePool (MemoryMap);\r
188\r
189 //\r
190 // Update configuratoin table for MemoryAttributesTable.\r
191 //\r
192 Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, MemoryAttributesTable);\r
193 ASSERT_EFI_ERROR (Status);\r
194\r
195 if (mMemoryAttributesTable != NULL) {\r
196 FreePool (mMemoryAttributesTable);\r
197 }\r
198 mMemoryAttributesTable = MemoryAttributesTable;\r
199}\r
200\r
201/**\r
202 Install MemoryAttributesTable on memory allocation.\r
203\r
204 @param[in] MemoryType EFI memory type.\r
205**/\r
206VOID\r
207InstallMemoryAttributesTableOnMemoryAllocation (\r
208 IN EFI_MEMORY_TYPE MemoryType\r
209 )\r
210{\r
211 //\r
212 // Install MemoryAttributesTable after ReadyToBoot on runtime memory allocation.\r
213 //\r
214 if (mMemoryAttributesTableReadyToBoot &&\r
215 ((MemoryType == EfiRuntimeServicesCode) || (MemoryType == EfiRuntimeServicesData))) {\r
216 InstallMemoryAttributesTable ();\r
217 }\r
218}\r
219\r
220/**\r
221 Install MemoryAttributesTable on ReadyToBoot.\r
222\r
223 @param[in] Event The Event this notify function registered to.\r
224 @param[in] Context Pointer to the context data registered to the Event.\r
225**/\r
226VOID\r
227EFIAPI\r
228InstallMemoryAttributesTableOnReadyToBoot (\r
229 IN EFI_EVENT Event,\r
230 IN VOID *Context\r
231 )\r
232{\r
233 InstallMemoryAttributesTable ();\r
234 mMemoryAttributesTableReadyToBoot = TRUE;\r
235}\r
236\r
237/**\r
238 Install initial MemoryAttributesTable on EndOfDxe.\r
239 Then SMM can consume this information.\r
240\r
241 @param[in] Event The Event this notify function registered to.\r
242 @param[in] Context Pointer to the context data registered to the Event.\r
243**/\r
244VOID\r
245EFIAPI\r
246InstallMemoryAttributesTableOnEndOfDxe (\r
247 IN EFI_EVENT Event,\r
248 IN VOID *Context\r
249 )\r
250{\r
251 InstallMemoryAttributesTable ();\r
252}\r
253\r
254/**\r
255 Initialize MemoryAttrubutesTable support.\r
256**/\r
257VOID\r
258EFIAPI\r
259CoreInitializeMemoryAttributesTable (\r
260 VOID\r
261 )\r
262{\r
263 EFI_STATUS Status;\r
264 EFI_EVENT ReadyToBootEvent;\r
265 EFI_EVENT EndOfDxeEvent;\r
266\r
267 //\r
268 // Construct the table at ReadyToBoot.\r
269 //\r
270 Status = CoreCreateEventInternal (\r
271 EVT_NOTIFY_SIGNAL,\r
272 TPL_CALLBACK,\r
273 InstallMemoryAttributesTableOnReadyToBoot,\r
274 NULL,\r
275 &gEfiEventReadyToBootGuid,\r
276 &ReadyToBootEvent\r
277 );\r
278 ASSERT_EFI_ERROR (Status);\r
279\r
280 //\r
281 // Construct the initial table at EndOfDxe,\r
282 // then SMM can consume this information.\r
283 // Use TPL_NOTIFY here, as such SMM code (TPL_CALLBACK)\r
284 // can run after it.\r
285 //\r
286 Status = CoreCreateEventInternal (\r
287 EVT_NOTIFY_SIGNAL,\r
288 TPL_NOTIFY,\r
289 InstallMemoryAttributesTableOnEndOfDxe,\r
290 NULL,\r
291 &gEfiEndOfDxeEventGroupGuid,\r
292 &EndOfDxeEvent\r
293 );\r
294 ASSERT_EFI_ERROR (Status);\r
295 return ;\r
296}\r