]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / MemoryAttributesTable.c
CommitLineData
285a682c
JY
1/** @file\r
2 PI SMM MemoryAttributes support\r
3\r
4Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
285a682c
JY
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/SmmServicesTableLib.h>\r
15#include <Library/DebugLib.h>\r
16#include <Library/PcdLib.h>\r
17\r
18#include <Library/PeCoffLib.h>\r
19#include <Library/PeCoffGetEntryPointLib.h>\r
20\r
21#include <Guid/PiSmmMemoryAttributesTable.h>\r
22\r
23#include "PiSmmCore.h"\r
24\r
25#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
26 ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))\r
27\r
1436aea4 28#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C')\r
285a682c
JY
29\r
30typedef struct {\r
1436aea4
MK
31 UINT32 Signature;\r
32 LIST_ENTRY Link;\r
33 EFI_PHYSICAL_ADDRESS CodeSegmentBase;\r
34 UINT64 CodeSegmentSize;\r
285a682c
JY
35} IMAGE_PROPERTIES_RECORD_CODE_SECTION;\r
36\r
1436aea4 37#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D')\r
285a682c
JY
38\r
39typedef struct {\r
1436aea4
MK
40 UINT32 Signature;\r
41 LIST_ENTRY Link;\r
42 EFI_PHYSICAL_ADDRESS ImageBase;\r
43 UINT64 ImageSize;\r
44 UINTN CodeSegmentCount;\r
45 LIST_ENTRY CodeSegmentList;\r
285a682c
JY
46} IMAGE_PROPERTIES_RECORD;\r
47\r
1436aea4 48#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')\r
285a682c
JY
49\r
50typedef struct {\r
1436aea4
MK
51 UINT32 Signature;\r
52 UINTN ImageRecordCount;\r
53 UINTN CodeSegmentCountMax;\r
54 LIST_ENTRY ImageRecordList;\r
285a682c
JY
55} IMAGE_PROPERTIES_PRIVATE_DATA;\r
56\r
57IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData = {\r
58 IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE,\r
59 0,\r
60 0,\r
61 INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData.ImageRecordList)\r
62};\r
63\r
64#define EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA BIT0\r
65\r
1436aea4 66UINT64 mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA;\r
285a682c
JY
67\r
68//\r
69// Below functions are for MemoryMap\r
70//\r
71\r
72/**\r
73 Converts a number of EFI_PAGEs to a size in bytes.\r
74\r
75 NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.\r
76\r
77 @param[in] Pages The number of EFI_PAGES.\r
78\r
79 @return The number of bytes associated with the number of EFI_PAGEs specified\r
80 by Pages.\r
81**/\r
82STATIC\r
83UINT64\r
84EfiPagesToSize (\r
1436aea4 85 IN UINT64 Pages\r
285a682c
JY
86 )\r
87{\r
88 return LShiftU64 (Pages, EFI_PAGE_SHIFT);\r
89}\r
90\r
91/**\r
92 Converts a size, in bytes, to a number of EFI_PAGESs.\r
93\r
94 NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.\r
95\r
96 @param[in] Size A size in bytes.\r
97\r
98 @return The number of EFI_PAGESs associated with the number of bytes specified\r
99 by Size.\r
100\r
101**/\r
102STATIC\r
103UINT64\r
104EfiSizeToPages (\r
1436aea4 105 IN UINT64 Size\r
285a682c
JY
106 )\r
107{\r
108 return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0);\r
109}\r
110\r
285a682c
JY
111/**\r
112 Sort memory map entries based upon PhysicalStart, from low to high.\r
113\r
11ee1bc9
DB
114 @param[in,out] MemoryMap A pointer to the buffer in which firmware places\r
115 the current memory map.\r
116 @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer.\r
117 @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
285a682c
JY
118**/\r
119STATIC\r
120VOID\r
121SortMemoryMap (\r
122 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
123 IN UINTN MemoryMapSize,\r
124 IN UINTN DescriptorSize\r
125 )\r
126{\r
1436aea4
MK
127 EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;\r
128 EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;\r
129 EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;\r
130 EFI_MEMORY_DESCRIPTOR TempMemoryMap;\r
285a682c 131\r
1436aea4 132 MemoryMapEntry = MemoryMap;\r
285a682c 133 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
1436aea4 134 MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);\r
285a682c
JY
135 while (MemoryMapEntry < MemoryMapEnd) {\r
136 while (NextMemoryMapEntry < MemoryMapEnd) {\r
137 if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) {\r
1436aea4
MK
138 CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));\r
139 CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));\r
140 CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof (EFI_MEMORY_DESCRIPTOR));\r
285a682c
JY
141 }\r
142\r
143 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
144 }\r
145\r
1436aea4
MK
146 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
147 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
285a682c
JY
148 }\r
149\r
1436aea4 150 return;\r
285a682c
JY
151}\r
152\r
153/**\r
4be497df 154 Merge continuous memory map entries whose have same attributes.\r
285a682c
JY
155\r
156 @param[in, out] MemoryMap A pointer to the buffer in which firmware places\r
157 the current memory map.\r
158 @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the\r
159 MemoryMap buffer. On input, this is the size of\r
160 the current memory map. On output,\r
161 it is the size of new memory map after merge.\r
162 @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
163**/\r
164STATIC\r
165VOID\r
166MergeMemoryMap (\r
167 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
168 IN OUT UINTN *MemoryMapSize,\r
169 IN UINTN DescriptorSize\r
170 )\r
171{\r
1436aea4
MK
172 EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;\r
173 EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;\r
174 UINT64 MemoryBlockLength;\r
175 EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry;\r
176 EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry;\r
285a682c 177\r
1436aea4 178 MemoryMapEntry = MemoryMap;\r
285a682c 179 NewMemoryMapEntry = MemoryMap;\r
1436aea4 180 MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize);\r
285a682c 181 while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {\r
1436aea4 182 CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR));\r
285a682c
JY
183 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
184\r
185 do {\r
1436aea4 186 MemoryBlockLength = (UINT64)(EfiPagesToSize (MemoryMapEntry->NumberOfPages));\r
285a682c
JY
187 if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&\r
188 (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&\r
189 (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&\r
1436aea4
MK
190 ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart))\r
191 {\r
285a682c
JY
192 MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
193 if (NewMemoryMapEntry != MemoryMapEntry) {\r
194 NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
195 }\r
196\r
197 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
198 continue;\r
199 } else {\r
200 MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
201 break;\r
202 }\r
203 } while (TRUE);\r
204\r
1436aea4 205 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
285a682c
JY
206 NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);\r
207 }\r
208\r
209 *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap;\r
210\r
1436aea4 211 return;\r
285a682c
JY
212}\r
213\r
214/**\r
215 Enforce memory map attributes.\r
216 This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP.\r
217\r
218 @param[in, out] MemoryMap A pointer to the buffer in which firmware places\r
219 the current memory map.\r
220 @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer.\r
221 @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
222**/\r
223STATIC\r
224VOID\r
225EnforceMemoryMapAttribute (\r
226 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
227 IN UINTN MemoryMapSize,\r
228 IN UINTN DescriptorSize\r
229 )\r
230{\r
1436aea4
MK
231 EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;\r
232 EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;\r
285a682c
JY
233\r
234 MemoryMapEntry = MemoryMap;\r
1436aea4 235 MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize);\r
285a682c 236 while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) {\r
026e2ca2
JY
237 if (MemoryMapEntry->Attribute != 0) {\r
238 // It is PE image, the attribute is already set.\r
239 } else {\r
240 switch (MemoryMapEntry->Type) {\r
1436aea4
MK
241 case EfiRuntimeServicesCode:\r
242 MemoryMapEntry->Attribute = EFI_MEMORY_RO;\r
243 break;\r
244 case EfiRuntimeServicesData:\r
245 default:\r
246 MemoryMapEntry->Attribute |= EFI_MEMORY_XP;\r
247 break;\r
026e2ca2 248 }\r
285a682c 249 }\r
1436aea4 250\r
285a682c
JY
251 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
252 }\r
253\r
1436aea4 254 return;\r
285a682c
JY
255}\r
256\r
257/**\r
258 Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].\r
259\r
260 @param[in] Buffer Start Address\r
261 @param[in] Length Address length\r
262\r
263 @return first image record covered by [buffer, length]\r
264**/\r
265STATIC\r
266IMAGE_PROPERTIES_RECORD *\r
267GetImageRecordByAddress (\r
268 IN EFI_PHYSICAL_ADDRESS Buffer,\r
269 IN UINT64 Length\r
270 )\r
271{\r
1436aea4
MK
272 IMAGE_PROPERTIES_RECORD *ImageRecord;\r
273 LIST_ENTRY *ImageRecordLink;\r
274 LIST_ENTRY *ImageRecordList;\r
285a682c
JY
275\r
276 ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;\r
277\r
278 for (ImageRecordLink = ImageRecordList->ForwardLink;\r
279 ImageRecordLink != ImageRecordList;\r
1436aea4
MK
280 ImageRecordLink = ImageRecordLink->ForwardLink)\r
281 {\r
285a682c
JY
282 ImageRecord = CR (\r
283 ImageRecordLink,\r
284 IMAGE_PROPERTIES_RECORD,\r
285 Link,\r
286 IMAGE_PROPERTIES_RECORD_SIGNATURE\r
287 );\r
288\r
289 if ((Buffer <= ImageRecord->ImageBase) &&\r
1436aea4
MK
290 (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize))\r
291 {\r
285a682c
JY
292 return ImageRecord;\r
293 }\r
294 }\r
295\r
296 return NULL;\r
297}\r
298\r
299/**\r
300 Set the memory map to new entries, according to one old entry,\r
301 based upon PE code section and data section in image record\r
302\r
303 @param[in] ImageRecord An image record whose [ImageBase, ImageSize] covered\r
304 by old memory map entry.\r
305 @param[in, out] NewRecord A pointer to several new memory map entries.\r
4be497df 306 The caller guarantee the buffer size be 1 +\r
285a682c
JY
307 (SplitRecordCount * DescriptorSize) calculated\r
308 below.\r
309 @param[in] OldRecord A pointer to one old memory map entry.\r
310 @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
311**/\r
312STATIC\r
313UINTN\r
314SetNewRecord (\r
1436aea4
MK
315 IN IMAGE_PROPERTIES_RECORD *ImageRecord,\r
316 IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord,\r
317 IN EFI_MEMORY_DESCRIPTOR *OldRecord,\r
318 IN UINTN DescriptorSize\r
285a682c
JY
319 )\r
320{\r
1436aea4
MK
321 EFI_MEMORY_DESCRIPTOR TempRecord;\r
322 IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
323 LIST_ENTRY *ImageRecordCodeSectionLink;\r
324 LIST_ENTRY *ImageRecordCodeSectionEndLink;\r
325 LIST_ENTRY *ImageRecordCodeSectionList;\r
326 UINTN NewRecordCount;\r
327 UINT64 PhysicalEnd;\r
328 UINT64 ImageEnd;\r
329\r
330 CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));\r
331 PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);\r
285a682c
JY
332 NewRecordCount = 0;\r
333\r
026e2ca2
JY
334 //\r
335 // Always create a new entry for non-PE image record\r
336 //\r
337 if (ImageRecord->ImageBase > TempRecord.PhysicalStart) {\r
1436aea4 338 NewRecord->Type = TempRecord.Type;\r
026e2ca2
JY
339 NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
340 NewRecord->VirtualStart = 0;\r
1436aea4 341 NewRecord->NumberOfPages = EfiSizeToPages (ImageRecord->ImageBase - TempRecord.PhysicalStart);\r
026e2ca2 342 NewRecord->Attribute = TempRecord.Attribute;\r
1436aea4
MK
343 NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
344 NewRecordCount++;\r
026e2ca2 345 TempRecord.PhysicalStart = ImageRecord->ImageBase;\r
1436aea4 346 TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);\r
026e2ca2
JY
347 }\r
348\r
285a682c
JY
349 ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;\r
350\r
1436aea4 351 ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;\r
285a682c
JY
352 ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;\r
353 while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
354 ImageRecordCodeSection = CR (\r
355 ImageRecordCodeSectionLink,\r
356 IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
357 Link,\r
358 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
359 );\r
360 ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
361\r
362 if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) {\r
363 //\r
364 // DATA\r
365 //\r
1436aea4 366 NewRecord->Type = EfiRuntimeServicesData;\r
285a682c
JY
367 NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
368 NewRecord->VirtualStart = 0;\r
1436aea4 369 NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart);\r
285a682c
JY
370 NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;\r
371 if (NewRecord->NumberOfPages != 0) {\r
372 NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
1436aea4 373 NewRecordCount++;\r
285a682c
JY
374 }\r
375\r
376 //\r
377 // CODE\r
378 //\r
1436aea4 379 NewRecord->Type = EfiRuntimeServicesCode;\r
285a682c
JY
380 NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase;\r
381 NewRecord->VirtualStart = 0;\r
1436aea4 382 NewRecord->NumberOfPages = EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize);\r
285a682c
JY
383 NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO;\r
384 if (NewRecord->NumberOfPages != 0) {\r
385 NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize);\r
1436aea4 386 NewRecordCount++;\r
285a682c
JY
387 }\r
388\r
1436aea4
MK
389 TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages (ImageRecordCodeSection->CodeSegmentSize));\r
390 TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - TempRecord.PhysicalStart);\r
285a682c
JY
391 if (TempRecord.NumberOfPages == 0) {\r
392 break;\r
393 }\r
394 }\r
395 }\r
396\r
397 ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize;\r
398\r
399 //\r
400 // Final DATA\r
401 //\r
402 if (TempRecord.PhysicalStart < ImageEnd) {\r
1436aea4 403 NewRecord->Type = EfiRuntimeServicesData;\r
285a682c
JY
404 NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
405 NewRecord->VirtualStart = 0;\r
406 NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart);\r
407 NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP;\r
1436aea4 408 NewRecordCount++;\r
285a682c
JY
409 }\r
410\r
411 return NewRecordCount;\r
412}\r
413\r
414/**\r
415 Return the max number of new splitted entries, according to one old entry,\r
416 based upon PE code section and data section.\r
417\r
418 @param[in] OldRecord A pointer to one old memory map entry.\r
419\r
420 @retval 0 no entry need to be splitted.\r
421 @return the max number of new splitted entries\r
422**/\r
423STATIC\r
424UINTN\r
425GetMaxSplitRecordCount (\r
1436aea4 426 IN EFI_MEMORY_DESCRIPTOR *OldRecord\r
285a682c
JY
427 )\r
428{\r
1436aea4
MK
429 IMAGE_PROPERTIES_RECORD *ImageRecord;\r
430 UINTN SplitRecordCount;\r
431 UINT64 PhysicalStart;\r
432 UINT64 PhysicalEnd;\r
285a682c
JY
433\r
434 SplitRecordCount = 0;\r
1436aea4
MK
435 PhysicalStart = OldRecord->PhysicalStart;\r
436 PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize (OldRecord->NumberOfPages);\r
285a682c
JY
437\r
438 do {\r
439 ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);\r
440 if (ImageRecord == NULL) {\r
441 break;\r
442 }\r
1436aea4 443\r
026e2ca2 444 SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 2);\r
1436aea4 445 PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;\r
285a682c
JY
446 } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));\r
447\r
285a682c
JY
448 return SplitRecordCount;\r
449}\r
450\r
451/**\r
452 Split the memory map to new entries, according to one old entry,\r
453 based upon PE code section and data section.\r
454\r
455 @param[in] OldRecord A pointer to one old memory map entry.\r
456 @param[in, out] NewRecord A pointer to several new memory map entries.\r
4be497df 457 The caller guarantee the buffer size be 1 +\r
285a682c
JY
458 (SplitRecordCount * DescriptorSize) calculated\r
459 below.\r
460 @param[in] MaxSplitRecordCount The max number of splitted entries\r
461 @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
462\r
463 @retval 0 no entry is splitted.\r
464 @return the real number of splitted record.\r
465**/\r
466STATIC\r
467UINTN\r
468SplitRecord (\r
1436aea4
MK
469 IN EFI_MEMORY_DESCRIPTOR *OldRecord,\r
470 IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord,\r
471 IN UINTN MaxSplitRecordCount,\r
472 IN UINTN DescriptorSize\r
285a682c
JY
473 )\r
474{\r
1436aea4
MK
475 EFI_MEMORY_DESCRIPTOR TempRecord;\r
476 IMAGE_PROPERTIES_RECORD *ImageRecord;\r
477 IMAGE_PROPERTIES_RECORD *NewImageRecord;\r
478 UINT64 PhysicalStart;\r
479 UINT64 PhysicalEnd;\r
480 UINTN NewRecordCount;\r
481 UINTN TotalNewRecordCount;\r
285a682c
JY
482\r
483 if (MaxSplitRecordCount == 0) {\r
484 CopyMem (NewRecord, OldRecord, DescriptorSize);\r
485 return 0;\r
486 }\r
487\r
488 TotalNewRecordCount = 0;\r
489\r
490 //\r
491 // Override previous record\r
492 //\r
1436aea4 493 CopyMem (&TempRecord, OldRecord, sizeof (EFI_MEMORY_DESCRIPTOR));\r
285a682c 494 PhysicalStart = TempRecord.PhysicalStart;\r
1436aea4 495 PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize (TempRecord.NumberOfPages);\r
285a682c
JY
496\r
497 ImageRecord = NULL;\r
498 do {\r
499 NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart);\r
500 if (NewImageRecord == NULL) {\r
501 //\r
502 // No more image covered by this range, stop\r
503 //\r
026e2ca2 504 if (PhysicalEnd > PhysicalStart) {\r
285a682c 505 //\r
026e2ca2 506 // Always create a new entry for non-PE image record\r
285a682c 507 //\r
1436aea4 508 NewRecord->Type = TempRecord.Type;\r
026e2ca2
JY
509 NewRecord->PhysicalStart = TempRecord.PhysicalStart;\r
510 NewRecord->VirtualStart = 0;\r
511 NewRecord->NumberOfPages = TempRecord.NumberOfPages;\r
512 NewRecord->Attribute = TempRecord.Attribute;\r
1436aea4 513 TotalNewRecordCount++;\r
285a682c 514 }\r
1436aea4 515\r
285a682c
JY
516 break;\r
517 }\r
1436aea4 518\r
285a682c
JY
519 ImageRecord = NewImageRecord;\r
520\r
521 //\r
522 // Set new record\r
523 //\r
1436aea4 524 NewRecordCount = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize);\r
285a682c 525 TotalNewRecordCount += NewRecordCount;\r
1436aea4 526 NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize);\r
285a682c
JY
527\r
528 //\r
529 // Update PhysicalStart, in order to exclude the image buffer already splitted.\r
530 //\r
1436aea4 531 PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize;\r
285a682c
JY
532 TempRecord.PhysicalStart = PhysicalStart;\r
533 TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart);\r
534 } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd));\r
535\r
536 return TotalNewRecordCount - 1;\r
537}\r
538\r
539/**\r
540 Split the original memory map, and add more entries to describe PE code section and data section.\r
541 This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.\r
542 This function will merge entries with same attributes finally.\r
543\r
544 NOTE: It assumes PE code/data section are page aligned.\r
545 NOTE: It assumes enough entry is prepared for new memory map.\r
546\r
547 Split table:\r
548 +---------------+\r
549 | Record X |\r
550 +---------------+\r
551 | Record RtCode |\r
552 +---------------+\r
553 | Record Y |\r
554 +---------------+\r
555 ==>\r
556 +---------------+\r
557 | Record X |\r
026e2ca2
JY
558 +---------------+\r
559 | Record RtCode |\r
285a682c
JY
560 +---------------+ ----\r
561 | Record RtData | |\r
562 +---------------+ |\r
563 | Record RtCode | |-> PE/COFF1\r
564 +---------------+ |\r
565 | Record RtData | |\r
566 +---------------+ ----\r
026e2ca2
JY
567 | Record RtCode |\r
568 +---------------+ ----\r
285a682c
JY
569 | Record RtData | |\r
570 +---------------+ |\r
571 | Record RtCode | |-> PE/COFF2\r
572 +---------------+ |\r
573 | Record RtData | |\r
574 +---------------+ ----\r
026e2ca2
JY
575 | Record RtCode |\r
576 +---------------+\r
285a682c
JY
577 | Record Y |\r
578 +---------------+\r
579\r
580 @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the\r
581 MemoryMap buffer. On input, this is the size of\r
582 old MemoryMap before split. The actual buffer\r
583 size of MemoryMap is MemoryMapSize +\r
584 (AdditionalRecordCount * DescriptorSize) calculated\r
585 below. On output, it is the size of new MemoryMap\r
586 after split.\r
587 @param[in, out] MemoryMap A pointer to the buffer in which firmware places\r
588 the current memory map.\r
589 @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.\r
590**/\r
591STATIC\r
592VOID\r
593SplitTable (\r
594 IN OUT UINTN *MemoryMapSize,\r
595 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
596 IN UINTN DescriptorSize\r
597 )\r
598{\r
1436aea4
MK
599 INTN IndexOld;\r
600 INTN IndexNew;\r
601 UINTN MaxSplitRecordCount;\r
602 UINTN RealSplitRecordCount;\r
603 UINTN TotalSplitRecordCount;\r
604 UINTN AdditionalRecordCount;\r
285a682c 605\r
026e2ca2 606 AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;\r
285a682c
JY
607\r
608 TotalSplitRecordCount = 0;\r
609 //\r
610 // Let old record point to end of valid MemoryMap buffer.\r
611 //\r
612 IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1;\r
613 //\r
614 // Let new record point to end of full MemoryMap buffer.\r
615 //\r
616 IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount;\r
1436aea4 617 for ( ; IndexOld >= 0; IndexOld--) {\r
285a682c
JY
618 MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize));\r
619 //\r
620 // Split this MemoryMap record\r
621 //\r
1436aea4 622 IndexNew -= MaxSplitRecordCount;\r
285a682c
JY
623 RealSplitRecordCount = SplitRecord (\r
624 (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize),\r
625 (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize),\r
626 MaxSplitRecordCount,\r
627 DescriptorSize\r
628 );\r
629 //\r
630 // Adjust IndexNew according to real split.\r
631 //\r
026e2ca2
JY
632 if (MaxSplitRecordCount != RealSplitRecordCount) {\r
633 CopyMem (\r
634 ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize),\r
635 ((UINT8 *)MemoryMap + IndexNew * DescriptorSize),\r
636 (RealSplitRecordCount + 1) * DescriptorSize\r
637 );\r
638 }\r
1436aea4
MK
639\r
640 IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount;\r
285a682c 641 TotalSplitRecordCount += RealSplitRecordCount;\r
1436aea4 642 IndexNew--;\r
285a682c 643 }\r
1436aea4 644\r
285a682c
JY
645 //\r
646 // Move all records to the beginning.\r
647 //\r
648 CopyMem (\r
649 MemoryMap,\r
650 (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize,\r
651 (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize\r
652 );\r
653\r
654 *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount;\r
655\r
656 //\r
657 // Sort from low to high (Just in case)\r
658 //\r
659 SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize);\r
660\r
661 //\r
662 // Set RuntimeData to XP\r
663 //\r
664 EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, DescriptorSize);\r
665\r
666 //\r
667 // Merge same type to save entry size\r
668 //\r
669 MergeMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize);\r
670\r
1436aea4 671 return;\r
285a682c
JY
672}\r
673\r
674/**\r
675 This function for GetMemoryMap() with memory attributes table.\r
676\r
677 It calls original GetMemoryMap() to get the original memory map information. Then\r
4be497df 678 plus the additional memory map entries for PE Code/Data separation.\r
285a682c
JY
679\r
680 @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the\r
681 MemoryMap buffer. On input, this is the size of\r
682 the buffer allocated by the caller. On output,\r
683 it is the size of the buffer returned by the\r
684 firmware if the buffer was large enough, or the\r
685 size of the buffer needed to contain the map if\r
686 the buffer was too small.\r
687 @param[in, out] MemoryMap A pointer to the buffer in which firmware places\r
688 the current memory map.\r
689 @param[out] MapKey A pointer to the location in which firmware\r
690 returns the key for the current memory map.\r
691 @param[out] DescriptorSize A pointer to the location in which firmware\r
692 returns the size, in bytes, of an individual\r
693 EFI_MEMORY_DESCRIPTOR.\r
694 @param[out] DescriptorVersion A pointer to the location in which firmware\r
695 returns the version number associated with the\r
696 EFI_MEMORY_DESCRIPTOR.\r
697\r
698 @retval EFI_SUCCESS The memory map was returned in the MemoryMap\r
699 buffer.\r
700 @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current\r
701 buffer size needed to hold the memory map is\r
702 returned in MemoryMapSize.\r
703 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
704\r
705**/\r
706STATIC\r
707EFI_STATUS\r
708EFIAPI\r
709SmmCoreGetMemoryMapMemoryAttributesTable (\r
710 IN OUT UINTN *MemoryMapSize,\r
711 IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,\r
712 OUT UINTN *MapKey,\r
713 OUT UINTN *DescriptorSize,\r
714 OUT UINT32 *DescriptorVersion\r
715 )\r
716{\r
717 EFI_STATUS Status;\r
718 UINTN OldMemoryMapSize;\r
719 UINTN AdditionalRecordCount;\r
720\r
721 //\r
722 // If PE code/data is not aligned, just return.\r
723 //\r
724 if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {\r
725 return SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);\r
726 }\r
727\r
728 if (MemoryMapSize == NULL) {\r
729 return EFI_INVALID_PARAMETER;\r
730 }\r
731\r
026e2ca2 732 AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount;\r
285a682c
JY
733\r
734 OldMemoryMapSize = *MemoryMapSize;\r
1436aea4 735 Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion);\r
285a682c
JY
736 if (Status == EFI_BUFFER_TOO_SMALL) {\r
737 *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;\r
738 } else if (Status == EFI_SUCCESS) {\r
739 if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) {\r
740 *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount;\r
741 //\r
742 // Need update status to buffer too small\r
743 //\r
744 Status = EFI_BUFFER_TOO_SMALL;\r
745 } else {\r
746 //\r
747 // Split PE code/data\r
748 //\r
1436aea4 749 ASSERT (MemoryMap != NULL);\r
285a682c
JY
750 SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);\r
751 }\r
752 }\r
753\r
754 return Status;\r
755}\r
756\r
757//\r
758// Below functions are for ImageRecord\r
759//\r
760\r
761/**\r
24648548 762 Set MemoryProtectionAttribute according to PE/COFF image section alignment.\r
285a682c
JY
763\r
764 @param[in] SectionAlignment PE/COFF section alignment\r
765**/\r
766STATIC\r
767VOID\r
768SetMemoryAttributesTableSectionAlignment (\r
769 IN UINT32 SectionAlignment\r
770 )\r
771{\r
115d9753 772 if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) &&\r
1436aea4
MK
773 ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0))\r
774 {\r
285a682c
JY
775 DEBUG ((DEBUG_VERBOSE, "SMM SetMemoryAttributesTableSectionAlignment - Clear\n"));\r
776 mMemoryProtectionAttribute &= ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA);\r
777 }\r
778}\r
779\r
780/**\r
781 Swap two code sections in image record.\r
782\r
783 @param[in] FirstImageRecordCodeSection first code section in image record\r
784 @param[in] SecondImageRecordCodeSection second code section in image record\r
785**/\r
786STATIC\r
787VOID\r
788SwapImageRecordCodeSection (\r
1436aea4
MK
789 IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection,\r
790 IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection\r
285a682c
JY
791 )\r
792{\r
1436aea4 793 IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection;\r
285a682c
JY
794\r
795 TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase;\r
796 TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize;\r
797\r
798 FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase;\r
799 FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize;\r
800\r
801 SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase;\r
802 SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize;\r
803}\r
804\r
805/**\r
806 Sort code section in image record, based upon CodeSegmentBase from low to high.\r
807\r
808 @param[in] ImageRecord image record to be sorted\r
809**/\r
810STATIC\r
811VOID\r
812SortImageRecordCodeSection (\r
1436aea4 813 IN IMAGE_PROPERTIES_RECORD *ImageRecord\r
285a682c
JY
814 )\r
815{\r
1436aea4
MK
816 IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
817 IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection;\r
818 LIST_ENTRY *ImageRecordCodeSectionLink;\r
819 LIST_ENTRY *NextImageRecordCodeSectionLink;\r
820 LIST_ENTRY *ImageRecordCodeSectionEndLink;\r
821 LIST_ENTRY *ImageRecordCodeSectionList;\r
285a682c
JY
822\r
823 ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;\r
824\r
1436aea4 825 ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;\r
285a682c 826 NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
1436aea4 827 ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;\r
285a682c
JY
828 while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
829 ImageRecordCodeSection = CR (\r
830 ImageRecordCodeSectionLink,\r
831 IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
832 Link,\r
833 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
834 );\r
835 while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
836 NextImageRecordCodeSection = CR (\r
837 NextImageRecordCodeSectionLink,\r
838 IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
839 Link,\r
840 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
841 );\r
842 if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) {\r
843 SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection);\r
844 }\r
1436aea4 845\r
285a682c
JY
846 NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink;\r
847 }\r
848\r
1436aea4 849 ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
285a682c
JY
850 NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
851 }\r
852}\r
853\r
854/**\r
855 Check if code section in image record is valid.\r
856\r
857 @param[in] ImageRecord image record to be checked\r
858\r
859 @retval TRUE image record is valid\r
860 @retval FALSE image record is invalid\r
861**/\r
862STATIC\r
863BOOLEAN\r
864IsImageRecordCodeSectionValid (\r
1436aea4 865 IN IMAGE_PROPERTIES_RECORD *ImageRecord\r
285a682c
JY
866 )\r
867{\r
1436aea4
MK
868 IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
869 IMAGE_PROPERTIES_RECORD_CODE_SECTION *LastImageRecordCodeSection;\r
870 LIST_ENTRY *ImageRecordCodeSectionLink;\r
871 LIST_ENTRY *ImageRecordCodeSectionEndLink;\r
872 LIST_ENTRY *ImageRecordCodeSectionList;\r
285a682c
JY
873\r
874 DEBUG ((DEBUG_VERBOSE, "SMM ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount));\r
875\r
876 ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList;\r
877\r
1436aea4 878 ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink;\r
285a682c 879 ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList;\r
1436aea4 880 LastImageRecordCodeSection = NULL;\r
285a682c
JY
881 while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) {\r
882 ImageRecordCodeSection = CR (\r
883 ImageRecordCodeSectionLink,\r
884 IMAGE_PROPERTIES_RECORD_CODE_SECTION,\r
885 Link,\r
886 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE\r
887 );\r
888 if (ImageRecordCodeSection->CodeSegmentSize == 0) {\r
889 return FALSE;\r
890 }\r
1436aea4 891\r
285a682c
JY
892 if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) {\r
893 return FALSE;\r
894 }\r
1436aea4 895\r
285a682c
JY
896 if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) {\r
897 return FALSE;\r
898 }\r
1436aea4 899\r
285a682c
JY
900 if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) {\r
901 return FALSE;\r
902 }\r
1436aea4 903\r
285a682c
JY
904 if (LastImageRecordCodeSection != NULL) {\r
905 if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) {\r
906 return FALSE;\r
907 }\r
908 }\r
909\r
910 LastImageRecordCodeSection = ImageRecordCodeSection;\r
911 ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink;\r
912 }\r
913\r
914 return TRUE;\r
915}\r
916\r
917/**\r
918 Swap two image records.\r
919\r
920 @param[in] FirstImageRecord first image record.\r
921 @param[in] SecondImageRecord second image record.\r
922**/\r
923STATIC\r
924VOID\r
925SwapImageRecord (\r
1436aea4
MK
926 IN IMAGE_PROPERTIES_RECORD *FirstImageRecord,\r
927 IN IMAGE_PROPERTIES_RECORD *SecondImageRecord\r
285a682c
JY
928 )\r
929{\r
1436aea4 930 IMAGE_PROPERTIES_RECORD TempImageRecord;\r
285a682c 931\r
1436aea4
MK
932 TempImageRecord.ImageBase = FirstImageRecord->ImageBase;\r
933 TempImageRecord.ImageSize = FirstImageRecord->ImageSize;\r
285a682c
JY
934 TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount;\r
935\r
1436aea4
MK
936 FirstImageRecord->ImageBase = SecondImageRecord->ImageBase;\r
937 FirstImageRecord->ImageSize = SecondImageRecord->ImageSize;\r
285a682c
JY
938 FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount;\r
939\r
1436aea4
MK
940 SecondImageRecord->ImageBase = TempImageRecord.ImageBase;\r
941 SecondImageRecord->ImageSize = TempImageRecord.ImageSize;\r
285a682c
JY
942 SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount;\r
943\r
944 SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList);\r
945}\r
946\r
947/**\r
948 Sort image record based upon the ImageBase from low to high.\r
949**/\r
950STATIC\r
951VOID\r
952SortImageRecord (\r
953 VOID\r
954 )\r
955{\r
1436aea4
MK
956 IMAGE_PROPERTIES_RECORD *ImageRecord;\r
957 IMAGE_PROPERTIES_RECORD *NextImageRecord;\r
958 LIST_ENTRY *ImageRecordLink;\r
959 LIST_ENTRY *NextImageRecordLink;\r
960 LIST_ENTRY *ImageRecordEndLink;\r
961 LIST_ENTRY *ImageRecordList;\r
285a682c
JY
962\r
963 ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;\r
964\r
1436aea4 965 ImageRecordLink = ImageRecordList->ForwardLink;\r
285a682c 966 NextImageRecordLink = ImageRecordLink->ForwardLink;\r
1436aea4 967 ImageRecordEndLink = ImageRecordList;\r
285a682c
JY
968 while (ImageRecordLink != ImageRecordEndLink) {\r
969 ImageRecord = CR (\r
970 ImageRecordLink,\r
971 IMAGE_PROPERTIES_RECORD,\r
972 Link,\r
973 IMAGE_PROPERTIES_RECORD_SIGNATURE\r
974 );\r
975 while (NextImageRecordLink != ImageRecordEndLink) {\r
976 NextImageRecord = CR (\r
977 NextImageRecordLink,\r
978 IMAGE_PROPERTIES_RECORD,\r
979 Link,\r
980 IMAGE_PROPERTIES_RECORD_SIGNATURE\r
981 );\r
982 if (ImageRecord->ImageBase > NextImageRecord->ImageBase) {\r
983 SwapImageRecord (ImageRecord, NextImageRecord);\r
984 }\r
1436aea4 985\r
285a682c
JY
986 NextImageRecordLink = NextImageRecordLink->ForwardLink;\r
987 }\r
988\r
1436aea4 989 ImageRecordLink = ImageRecordLink->ForwardLink;\r
285a682c
JY
990 NextImageRecordLink = ImageRecordLink->ForwardLink;\r
991 }\r
992}\r
993\r
994/**\r
995 Dump image record.\r
996**/\r
997STATIC\r
998VOID\r
999DumpImageRecord (\r
1000 VOID\r
1001 )\r
1002{\r
1436aea4
MK
1003 IMAGE_PROPERTIES_RECORD *ImageRecord;\r
1004 LIST_ENTRY *ImageRecordLink;\r
1005 LIST_ENTRY *ImageRecordList;\r
1006 UINTN Index;\r
285a682c
JY
1007\r
1008 ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList;\r
1009\r
1436aea4 1010 for (ImageRecordLink = ImageRecordList->ForwardLink, Index = 0;\r
285a682c 1011 ImageRecordLink != ImageRecordList;\r
1436aea4
MK
1012 ImageRecordLink = ImageRecordLink->ForwardLink, Index++)\r
1013 {\r
285a682c
JY
1014 ImageRecord = CR (\r
1015 ImageRecordLink,\r
1016 IMAGE_PROPERTIES_RECORD,\r
1017 Link,\r
1018 IMAGE_PROPERTIES_RECORD_SIGNATURE\r
1019 );\r
1020 DEBUG ((DEBUG_VERBOSE, "SMM Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize));\r
1021 }\r
1022}\r
1023\r
1024/**\r
1025 Insert image record.\r
1026\r
1027 @param[in] DriverEntry Driver information\r
1028**/\r
1029VOID\r
1030SmmInsertImageRecord (\r
1031 IN EFI_SMM_DRIVER_ENTRY *DriverEntry\r
1032 )\r
1033{\r
1436aea4
MK
1034 VOID *ImageAddress;\r
1035 EFI_IMAGE_DOS_HEADER *DosHdr;\r
1036 UINT32 PeCoffHeaderOffset;\r
1037 UINT32 SectionAlignment;\r
1038 EFI_IMAGE_SECTION_HEADER *Section;\r
1039 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
1040 UINT8 *Name;\r
1041 UINTN Index;\r
1042 IMAGE_PROPERTIES_RECORD *ImageRecord;\r
1043 CHAR8 *PdbPointer;\r
1044 IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection;\r
285a682c
JY
1045\r
1046 DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%x\n", DriverEntry));\r
1047 DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%016lx - 0x%08x\n", DriverEntry->ImageBuffer, DriverEntry->NumberOfPage));\r
1048\r
1436aea4 1049 ImageRecord = AllocatePool (sizeof (*ImageRecord));\r
285a682c 1050 if (ImageRecord == NULL) {\r
1436aea4 1051 return;\r
285a682c 1052 }\r
1436aea4 1053\r
285a682c
JY
1054 ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE;\r
1055\r
1056 DEBUG ((DEBUG_VERBOSE, "SMM ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));\r
1057\r
1058 //\r
1059 // Step 1: record whole region\r
1060 //\r
1061 ImageRecord->ImageBase = DriverEntry->ImageBuffer;\r
1436aea4 1062 ImageRecord->ImageSize = EfiPagesToSize (DriverEntry->NumberOfPage);\r
285a682c
JY
1063\r
1064 ImageAddress = (VOID *)(UINTN)DriverEntry->ImageBuffer;\r
1065\r
1436aea4 1066 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);\r
285a682c
JY
1067 if (PdbPointer != NULL) {\r
1068 DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer));\r
1069 }\r
1070\r
1071 //\r
1072 // Check PE/COFF image\r
1073 //\r
1436aea4 1074 DosHdr = (EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress;\r
285a682c
JY
1075 PeCoffHeaderOffset = 0;\r
1076 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
1077 PeCoffHeaderOffset = DosHdr->e_lfanew;\r
1078 }\r
1079\r
1436aea4 1080 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset);\r
285a682c
JY
1081 if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
1082 DEBUG ((DEBUG_VERBOSE, "SMM Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature));\r
1083 goto Finish;\r
1084 }\r
1085\r
1086 //\r
1087 // Get SectionAlignment\r
1088 //\r
05cfd73f 1089 if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
1436aea4 1090 SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;\r
285a682c 1091 } else {\r
1436aea4 1092 SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment;\r
285a682c
JY
1093 }\r
1094\r
1095 SetMemoryAttributesTableSectionAlignment (SectionAlignment);\r
115d9753 1096 if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) {\r
1436aea4
MK
1097 DEBUG ((\r
1098 DEBUG_WARN,\r
1099 "SMM !!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",\r
1100 SectionAlignment,\r
1101 RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10\r
1102 ));\r
1103 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);\r
285a682c 1104 if (PdbPointer != NULL) {\r
92b126ae 1105 DEBUG ((DEBUG_WARN, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));\r
285a682c 1106 }\r
1436aea4 1107\r
285a682c
JY
1108 goto Finish;\r
1109 }\r
1110\r
1436aea4
MK
1111 Section = (EFI_IMAGE_SECTION_HEADER *)(\r
1112 (UINT8 *)(UINTN)ImageAddress +\r
1113 PeCoffHeaderOffset +\r
1114 sizeof (UINT32) +\r
1115 sizeof (EFI_IMAGE_FILE_HEADER) +\r
1116 Hdr.Pe32->FileHeader.SizeOfOptionalHeader\r
1117 );\r
285a682c
JY
1118 ImageRecord->CodeSegmentCount = 0;\r
1119 InitializeListHead (&ImageRecord->CodeSegmentList);\r
1120 for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {\r
1121 Name = Section[Index].Name;\r
1122 DEBUG ((\r
1123 DEBUG_VERBOSE,\r
1124 "SMM Section - '%c%c%c%c%c%c%c%c'\n",\r
1125 Name[0],\r
1126 Name[1],\r
1127 Name[2],\r
1128 Name[3],\r
1129 Name[4],\r
1130 Name[5],\r
1131 Name[6],\r
1132 Name[7]\r
1133 ));\r
1134\r
1135 if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) {\r
1136 DEBUG ((DEBUG_VERBOSE, "SMM VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize));\r
1137 DEBUG ((DEBUG_VERBOSE, "SMM VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress));\r
1138 DEBUG ((DEBUG_VERBOSE, "SMM SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData));\r
1139 DEBUG ((DEBUG_VERBOSE, "SMM PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData));\r
1140 DEBUG ((DEBUG_VERBOSE, "SMM PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations));\r
1141 DEBUG ((DEBUG_VERBOSE, "SMM PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers));\r
1142 DEBUG ((DEBUG_VERBOSE, "SMM NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations));\r
1143 DEBUG ((DEBUG_VERBOSE, "SMM NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers));\r
1144 DEBUG ((DEBUG_VERBOSE, "SMM Characteristics - 0x%08x\n", Section[Index].Characteristics));\r
1145\r
1146 //\r
1147 // Step 2: record code section\r
1148 //\r
1436aea4 1149 ImageRecordCodeSection = AllocatePool (sizeof (*ImageRecordCodeSection));\r
285a682c 1150 if (ImageRecordCodeSection == NULL) {\r
1436aea4 1151 return;\r
285a682c 1152 }\r
1436aea4 1153\r
285a682c
JY
1154 ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE;\r
1155\r
1156 ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress;\r
1157 ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData;\r
1158\r
1159 DEBUG ((DEBUG_VERBOSE, "SMM ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize));\r
1160\r
1161 InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link);\r
1162 ImageRecord->CodeSegmentCount++;\r
1163 }\r
1164 }\r
1165\r
1166 if (ImageRecord->CodeSegmentCount == 0) {\r
1167 SetMemoryAttributesTableSectionAlignment (1);\r
1168 DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));\r
1436aea4 1169 PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageAddress);\r
285a682c
JY
1170 if (PdbPointer != NULL) {\r
1171 DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer));\r
1172 }\r
1436aea4 1173\r
285a682c
JY
1174 goto Finish;\r
1175 }\r
1176\r
1177 //\r
1178 // Final\r
1179 //\r
1180 SortImageRecordCodeSection (ImageRecord);\r
1181 //\r
1182 // Check overlap all section in ImageBase/Size\r
1183 //\r
1184 if (!IsImageRecordCodeSectionValid (ImageRecord)) {\r
1185 DEBUG ((DEBUG_ERROR, "SMM IsImageRecordCodeSectionValid - FAIL\n"));\r
1186 goto Finish;\r
1187 }\r
1188\r
1189 InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link);\r
1190 mImagePropertiesPrivateData.ImageRecordCount++;\r
1191\r
285a682c
JY
1192 if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) {\r
1193 mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount;\r
1194 }\r
1195\r
3d817fd1
JW
1196 SortImageRecord ();\r
1197\r
285a682c 1198Finish:\r
1436aea4 1199 return;\r
285a682c
JY
1200}\r
1201\r
285a682c
JY
1202/**\r
1203 Publish MemoryAttributesTable to SMM configuration table.\r
1204**/\r
1205VOID\r
1206PublishMemoryAttributesTable (\r
1207 VOID\r
1208 )\r
1209{\r
1436aea4
MK
1210 UINTN MemoryMapSize;\r
1211 EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
1212 UINTN MapKey;\r
1213 UINTN DescriptorSize;\r
1214 UINT32 DescriptorVersion;\r
1215 UINTN Index;\r
1216 EFI_STATUS Status;\r
1217 UINTN RuntimeEntryCount;\r
1218 EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable;\r
1219 EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry;\r
1220 UINTN MemoryAttributesTableSize;\r
285a682c
JY
1221\r
1222 MemoryMapSize = 0;\r
1436aea4
MK
1223 MemoryMap = NULL;\r
1224 Status = SmmCoreGetMemoryMapMemoryAttributesTable (\r
1225 &MemoryMapSize,\r
1226 MemoryMap,\r
1227 &MapKey,\r
1228 &DescriptorSize,\r
1229 &DescriptorVersion\r
1230 );\r
285a682c
JY
1231 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
1232\r
1233 do {\r
391cffcb 1234 DEBUG ((DEBUG_VERBOSE, "MemoryMapSize - 0x%x\n", MemoryMapSize));\r
285a682c
JY
1235 MemoryMap = AllocatePool (MemoryMapSize);\r
1236 ASSERT (MemoryMap != NULL);\r
391cffcb 1237 DEBUG ((DEBUG_VERBOSE, "MemoryMap - 0x%x\n", MemoryMap));\r
285a682c
JY
1238\r
1239 Status = SmmCoreGetMemoryMapMemoryAttributesTable (\r
1240 &MemoryMapSize,\r
1241 MemoryMap,\r
1242 &MapKey,\r
1243 &DescriptorSize,\r
1244 &DescriptorVersion\r
1245 );\r
1246 if (EFI_ERROR (Status)) {\r
1247 FreePool (MemoryMap);\r
1248 }\r
1249 } while (Status == EFI_BUFFER_TOO_SMALL);\r
1250\r
1251 //\r
1252 // Allocate MemoryAttributesTable\r
1253 //\r
1436aea4
MK
1254 RuntimeEntryCount = MemoryMapSize/DescriptorSize;\r
1255 MemoryAttributesTableSize = sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount;\r
1256 MemoryAttributesTable = AllocatePool (sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount);\r
285a682c
JY
1257 ASSERT (MemoryAttributesTable != NULL);\r
1258 MemoryAttributesTable->Version = EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE_VERSION;\r
1259 MemoryAttributesTable->NumberOfEntries = (UINT32)RuntimeEntryCount;\r
1260 MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize;\r
1261 MemoryAttributesTable->Reserved = 0;\r
391cffcb
YG
1262 DEBUG ((DEBUG_VERBOSE, "MemoryAttributesTable:\n"));\r
1263 DEBUG ((DEBUG_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version));\r
1264 DEBUG ((DEBUG_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries));\r
1265 DEBUG ((DEBUG_VERBOSE, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize));\r
285a682c
JY
1266 MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1);\r
1267 for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) {\r
1268 CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize);\r
391cffcb
YG
1269 DEBUG ((DEBUG_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry));\r
1270 DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type));\r
1271 DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart));\r
1272 DEBUG ((DEBUG_VERBOSE, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart));\r
1273 DEBUG ((DEBUG_VERBOSE, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages));\r
1274 DEBUG ((DEBUG_VERBOSE, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute));\r
1436aea4 1275 MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, DescriptorSize);\r
285a682c 1276\r
1436aea4 1277 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize);\r
285a682c
JY
1278 }\r
1279\r
1280 Status = gSmst->SmmInstallConfigurationTable (gSmst, &gEdkiiPiSmmMemoryAttributesTableGuid, MemoryAttributesTable, MemoryAttributesTableSize);\r
1281 ASSERT_EFI_ERROR (Status);\r
1282}\r
1283\r
285a682c
JY
1284/**\r
1285 This function installs all SMM image record information.\r
1286**/\r
1287VOID\r
1288SmmInstallImageRecord (\r
1289 VOID\r
1290 )\r
1291{\r
1436aea4
MK
1292 EFI_STATUS Status;\r
1293 UINTN NoHandles;\r
1294 EFI_HANDLE *HandleBuffer;\r
1295 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
1296 UINTN Index;\r
1297 EFI_SMM_DRIVER_ENTRY DriverEntry;\r
285a682c
JY
1298\r
1299 Status = SmmLocateHandleBuffer (\r
1300 ByProtocol,\r
1301 &gEfiLoadedImageProtocolGuid,\r
1302 NULL,\r
1303 &NoHandles,\r
1304 &HandleBuffer\r
1305 );\r
1306 if (EFI_ERROR (Status)) {\r
1436aea4 1307 return;\r
285a682c
JY
1308 }\r
1309\r
1310 for (Index = 0; Index < NoHandles; Index++) {\r
1311 Status = gSmst->SmmHandleProtocol (\r
1312 HandleBuffer[Index],\r
1313 &gEfiLoadedImageProtocolGuid,\r
1314 (VOID **)&LoadedImage\r
1315 );\r
1316 if (EFI_ERROR (Status)) {\r
1317 continue;\r
1318 }\r
1436aea4 1319\r
285a682c
JY
1320 DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize));\r
1321 {\r
1436aea4 1322 VOID *PdbPointer;\r
285a682c
JY
1323 PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);\r
1324 if (PdbPointer != NULL) {\r
1325 DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer));\r
1326 }\r
1327 }\r
1328 DEBUG ((DEBUG_VERBOSE, "\n"));\r
1436aea4 1329 ZeroMem (&DriverEntry, sizeof (DriverEntry));\r
285a682c 1330 DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase;\r
1436aea4 1331 DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)LoadedImage->ImageSize);\r
285a682c
JY
1332 SmmInsertImageRecord (&DriverEntry);\r
1333 }\r
1334\r
1335 FreePool (HandleBuffer);\r
1336}\r
1337\r
1338/**\r
1339 Install MemoryAttributesTable.\r
1340\r
1341 @param[in] Protocol Points to the protocol's unique identifier.\r
1342 @param[in] Interface Points to the interface instance.\r
1343 @param[in] Handle The handle on which the interface was installed.\r
1344\r
1345 @retval EFI_SUCCESS Notification runs successfully.\r
1346**/\r
1347EFI_STATUS\r
1348EFIAPI\r
1349SmmInstallMemoryAttributesTable (\r
1350 IN CONST EFI_GUID *Protocol,\r
1351 IN VOID *Interface,\r
1352 IN EFI_HANDLE Handle\r
1353 )\r
1354{\r
1355 SmmInstallImageRecord ();\r
1356\r
391cffcb 1357 DEBUG ((DEBUG_VERBOSE, "SMM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute));\r
285a682c
JY
1358 if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) {\r
1359 return EFI_SUCCESS;\r
1360 }\r
1361\r
1362 DEBUG ((DEBUG_VERBOSE, "SMM Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount));\r
1363 DEBUG ((DEBUG_VERBOSE, "SMM Dump ImageRecord:\n"));\r
1364 DumpImageRecord ();\r
1365\r
1366 PublishMemoryAttributesTable ();\r
1367\r
1368 return EFI_SUCCESS;\r
1369}\r
1370\r
1371/**\r
1372 Initialize MemoryAttributesTable support.\r
1373**/\r
1374VOID\r
1375EFIAPI\r
1376SmmCoreInitializeMemoryAttributesTable (\r
1377 VOID\r
1378 )\r
1379{\r
1436aea4
MK
1380 EFI_STATUS Status;\r
1381 VOID *Registration;\r
285a682c
JY
1382\r
1383 Status = gSmst->SmmRegisterProtocolNotify (\r
1384 &gEfiSmmEndOfDxeProtocolGuid,\r
1385 SmmInstallMemoryAttributesTable,\r
1386 &Registration\r
1387 );\r
1388 ASSERT_EFI_ERROR (Status);\r
1389\r
1436aea4 1390 return;\r
285a682c 1391}\r