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