]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c
MdeModulePkg/Application: Fix various typos
[mirror_edk2.git] / MdeModulePkg / Application / MemoryProfileInfo / MemoryProfileInfo.c
... / ...
CommitLineData
1/** @file\r
2\r
3 Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>\r
4 SPDX-License-Identifier: BSD-2-Clause-Patent\r
5\r
6**/\r
7\r
8#include <Uefi.h>\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/UefiLib.h>\r
14#include <Library/UefiApplicationEntryPoint.h>\r
15#include <Library/UefiBootServicesTableLib.h>\r
16#include <Library/UefiRuntimeServicesTableLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/DxeServicesLib.h>\r
19#include <Library/PrintLib.h>\r
20\r
21#include <Protocol/SmmCommunication.h>\r
22#include <Protocol/SmmAccess2.h>\r
23\r
24#include <Guid/MemoryProfile.h>\r
25#include <Guid/PiSmmCommunicationRegionTable.h>\r
26\r
27CHAR8 *mActionString[] = {\r
28 "Unknown",\r
29 "gBS->AllocatePages",\r
30 "gBS->FreePages",\r
31 "gBS->AllocatePool",\r
32 "gBS->FreePool",\r
33};\r
34\r
35CHAR8 *mSmmActionString[] = {\r
36 "SmmUnknown",\r
37 "gSmst->SmmAllocatePages",\r
38 "gSmst->SmmFreePages",\r
39 "gSmst->SmmAllocatePool",\r
40 "gSmst->SmmFreePool",\r
41};\r
42\r
43typedef struct {\r
44 MEMORY_PROFILE_ACTION Action;\r
45 CHAR8 *String;\r
46} ACTION_STRING;\r
47\r
48ACTION_STRING mExtActionString[] = {\r
49 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, "Lib:AllocatePages"},\r
50 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, "Lib:AllocateRuntimePages"},\r
51 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, "Lib:AllocateReservedPages"},\r
52 {MEMORY_PROFILE_ACTION_LIB_FREE_PAGES, "Lib:FreePages"},\r
53 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, "Lib:AllocateAlignedPages"},\r
54 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, "Lib:AllocateAlignedRuntimePages"},\r
55 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, "Lib:AllocateAlignedReservedPages"},\r
56 {MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES, "Lib:FreeAlignedPages"},\r
57 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, "Lib:AllocatePool"},\r
58 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, "Lib:AllocateRuntimePool"},\r
59 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, "Lib:AllocateReservedPool"},\r
60 {MEMORY_PROFILE_ACTION_LIB_FREE_POOL, "Lib:FreePool"},\r
61 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, "Lib:AllocateZeroPool"},\r
62 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, "Lib:AllocateRuntimeZeroPool"},\r
63 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, "Lib:AllocateReservedZeroPool"},\r
64 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, "Lib:AllocateCopyPool"},\r
65 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, "Lib:AllocateRuntimeCopyPool"},\r
66 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, "Lib:AllocateReservedCopyPool"},\r
67 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, "Lib:ReallocatePool"},\r
68 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, "Lib:ReallocateRuntimePool"},\r
69 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, "Lib:ReallocateReservedPool"},\r
70};\r
71\r
72CHAR8 mUserDefinedActionString[] = {"UserDefined-0x80000000"};\r
73\r
74CHAR8 *mMemoryTypeString[] = {\r
75 "EfiReservedMemoryType",\r
76 "EfiLoaderCode",\r
77 "EfiLoaderData",\r
78 "EfiBootServicesCode",\r
79 "EfiBootServicesData",\r
80 "EfiRuntimeServicesCode",\r
81 "EfiRuntimeServicesData",\r
82 "EfiConventionalMemory",\r
83 "EfiUnusableMemory",\r
84 "EfiACPIReclaimMemory",\r
85 "EfiACPIMemoryNVS",\r
86 "EfiMemoryMappedIO",\r
87 "EfiMemoryMappedIOPortSpace",\r
88 "EfiPalCode",\r
89 "EfiPersistentMemory",\r
90 "EfiOSReserved",\r
91 "EfiOemReserved",\r
92};\r
93\r
94CHAR8 *mSubsystemString[] = {\r
95 "Unknown",\r
96 "NATIVE",\r
97 "WINDOWS_GUI",\r
98 "WINDOWS_CUI",\r
99 "Unknown",\r
100 "Unknown",\r
101 "Unknown",\r
102 "POSIX_CUI",\r
103 "Unknown",\r
104 "WINDOWS_CE_GUI",\r
105 "EFI_APPLICATION",\r
106 "EFI_BOOT_SERVICE_DRIVER",\r
107 "EFI_RUNTIME_DRIVER",\r
108 "EFI_ROM",\r
109 "XBOX",\r
110 "Unknown",\r
111};\r
112\r
113CHAR8 *mFileTypeString[] = {\r
114 "Unknown",\r
115 "RAW",\r
116 "FREEFORM",\r
117 "SECURITY_CORE",\r
118 "PEI_CORE",\r
119 "DXE_CORE",\r
120 "PEIM",\r
121 "DRIVER",\r
122 "COMBINED_PEIM_DRIVER",\r
123 "APPLICATION",\r
124 "SMM",\r
125 "FIRMWARE_VOLUME_IMAGE",\r
126 "COMBINED_SMM_DXE",\r
127 "SMM_CORE",\r
128};\r
129\r
130#define PROFILE_NAME_STRING_LENGTH 64\r
131CHAR8 mNameString[PROFILE_NAME_STRING_LENGTH + 1];\r
132\r
133//\r
134// Profile summary information\r
135//\r
136#define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE SIGNATURE_32 ('M','P','A','S')\r
137#define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION 0x0001\r
138\r
139typedef struct {\r
140 MEMORY_PROFILE_COMMON_HEADER Header;\r
141 PHYSICAL_ADDRESS CallerAddress;\r
142 MEMORY_PROFILE_ACTION Action;\r
143 CHAR8 *ActionString;\r
144 UINT32 AllocateCount;\r
145 UINT64 TotalSize;\r
146} MEMORY_PROFILE_ALLOC_SUMMARY_INFO;\r
147\r
148typedef struct {\r
149 UINT32 Signature;\r
150 MEMORY_PROFILE_ALLOC_SUMMARY_INFO AllocSummaryInfo;\r
151 LIST_ENTRY Link;\r
152} MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA;\r
153\r
154typedef struct {\r
155 UINT32 Signature;\r
156 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
157 LIST_ENTRY *AllocSummaryInfoList;\r
158 LIST_ENTRY Link;\r
159} MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA;\r
160\r
161typedef struct {\r
162 UINT32 Signature;\r
163 MEMORY_PROFILE_CONTEXT *Context;\r
164 LIST_ENTRY *DriverSummaryInfoList;\r
165} MEMORY_PROFILE_CONTEXT_SUMMARY_DATA;\r
166\r
167LIST_ENTRY mImageSummaryQueue = INITIALIZE_LIST_HEAD_VARIABLE (mImageSummaryQueue);\r
168MEMORY_PROFILE_CONTEXT_SUMMARY_DATA mMemoryProfileContextSummary;\r
169\r
170/**\r
171 Get the file name portion of the Pdb File Name.\r
172\r
173 The portion of the Pdb File Name between the last backslash and\r
174 either a following period or the end of the string is copied into\r
175 AsciiBuffer. The name is truncated, if necessary, to ensure that\r
176 AsciiBuffer is not overrun.\r
177\r
178 @param[in] PdbFileName Pdb file name.\r
179 @param[out] AsciiBuffer The resultant Ascii File Name.\r
180\r
181**/\r
182VOID\r
183GetShortPdbFileName (\r
184 IN CHAR8 *PdbFileName,\r
185 OUT CHAR8 *AsciiBuffer\r
186 )\r
187{\r
188 UINTN IndexPdb; // Current work location within a Pdb string.\r
189 UINTN IndexBuffer; // Current work location within a Buffer string.\r
190 UINTN StartIndex;\r
191 UINTN EndIndex;\r
192\r
193 ZeroMem (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1);\r
194\r
195 if (PdbFileName == NULL) {\r
196 AsciiStrnCpyS (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1, " ", 1);\r
197 } else {\r
198 StartIndex = 0;\r
199 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++);\r
200 for (IndexPdb = 0; PdbFileName[IndexPdb] != 0; IndexPdb++) {\r
201 if ((PdbFileName[IndexPdb] == '\\') || (PdbFileName[IndexPdb] == '/')) {\r
202 StartIndex = IndexPdb + 1;\r
203 }\r
204\r
205 if (PdbFileName[IndexPdb] == '.') {\r
206 EndIndex = IndexPdb;\r
207 }\r
208 }\r
209\r
210 IndexBuffer = 0;\r
211 for (IndexPdb = StartIndex; IndexPdb < EndIndex; IndexPdb++) {\r
212 AsciiBuffer[IndexBuffer] = PdbFileName[IndexPdb];\r
213 IndexBuffer++;\r
214 if (IndexBuffer >= PROFILE_NAME_STRING_LENGTH) {\r
215 AsciiBuffer[PROFILE_NAME_STRING_LENGTH] = 0;\r
216 break;\r
217 }\r
218 }\r
219 }\r
220}\r
221\r
222/**\r
223 Get a human readable name for an image.\r
224 The following methods will be tried orderly:\r
225 1. Image PDB\r
226 2. FFS UI section\r
227 3. Image GUID\r
228\r
229 @param[in] DriverInfo Pointer to memory profile driver info.\r
230\r
231 @return The resulting Ascii name string is stored in the mNameString global array.\r
232\r
233**/\r
234CHAR8 *\r
235GetDriverNameString (\r
236 IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo\r
237 )\r
238{\r
239 EFI_STATUS Status;\r
240 CHAR16 *NameString;\r
241 UINTN StringSize;\r
242\r
243 //\r
244 // Method 1: Get the name string from image PDB\r
245 //\r
246 if (DriverInfo->PdbStringOffset != 0) {\r
247 GetShortPdbFileName ((CHAR8 *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset), mNameString);\r
248 return mNameString;\r
249 }\r
250\r
251 if (!IsZeroGuid (&DriverInfo->FileName)) {\r
252 //\r
253 // Try to get the image's FFS UI section by image GUID\r
254 //\r
255 NameString = NULL;\r
256 StringSize = 0;\r
257 Status = GetSectionFromAnyFv (\r
258 &DriverInfo->FileName,\r
259 EFI_SECTION_USER_INTERFACE,\r
260 0,\r
261 (VOID **) &NameString,\r
262 &StringSize\r
263 );\r
264 if (!EFI_ERROR (Status)) {\r
265 //\r
266 // Method 2: Get the name string from FFS UI section\r
267 //\r
268 if (StrLen (NameString) > PROFILE_NAME_STRING_LENGTH) {\r
269 NameString[PROFILE_NAME_STRING_LENGTH] = 0;\r
270 }\r
271 UnicodeStrToAsciiStrS (NameString, mNameString, sizeof (mNameString));\r
272 FreePool (NameString);\r
273 return mNameString;\r
274 }\r
275 }\r
276\r
277 //\r
278 // Method 3: Get the name string from image GUID\r
279 //\r
280 AsciiSPrint (mNameString, sizeof (mNameString), "%g", &DriverInfo->FileName);\r
281 return mNameString;\r
282}\r
283\r
284/**\r
285 Memory type to string.\r
286\r
287 @param[in] MemoryType Memory type.\r
288\r
289 @return Pointer to string.\r
290\r
291**/\r
292CHAR8 *\r
293ProfileMemoryTypeToStr (\r
294 IN EFI_MEMORY_TYPE MemoryType\r
295 )\r
296{\r
297 UINTN Index;\r
298\r
299 if ((UINT32) MemoryType >= 0x80000000) {\r
300 //\r
301 // OS reserved memory type.\r
302 //\r
303 Index = EfiMaxMemoryType;\r
304 } else if ((UINT32) MemoryType >= 0x70000000) {\r
305 //\r
306 // OEM reserved memory type.\r
307 //\r
308 Index = EfiMaxMemoryType + 1;\r
309 } else {\r
310 Index = MemoryType;\r
311 }\r
312\r
313 return mMemoryTypeString[Index];\r
314}\r
315\r
316/**\r
317 Action to string.\r
318\r
319 @param[in] Action Profile action.\r
320 @param[in] UserDefinedActionString Pointer to user defined action string.\r
321 @param[in] IsForSmm TRUE - SMRAM profile.\r
322 FALSE - UEFI memory profile.\r
323\r
324 @return Pointer to string.\r
325\r
326**/\r
327CHAR8 *\r
328ProfileActionToStr (\r
329 IN MEMORY_PROFILE_ACTION Action,\r
330 IN CHAR8 *UserDefinedActionString,\r
331 IN BOOLEAN IsForSmm\r
332 )\r
333{\r
334 UINTN Index;\r
335 UINTN ActionStringCount;\r
336 CHAR8 **ActionString;\r
337\r
338 if (IsForSmm) {\r
339 ActionString = mSmmActionString;\r
340 ActionStringCount = ARRAY_SIZE (mSmmActionString);\r
341 } else {\r
342 ActionString = mActionString;\r
343 ActionStringCount = ARRAY_SIZE (mActionString);\r
344 }\r
345\r
346 if ((UINTN) (UINT32) Action < ActionStringCount) {\r
347 return ActionString[Action];\r
348 }\r
349 for (Index = 0; Index < ARRAY_SIZE (mExtActionString); Index++) {\r
350 if (mExtActionString[Index].Action == Action) {\r
351 return mExtActionString[Index].String;\r
352 }\r
353 }\r
354 if ((Action & MEMORY_PROFILE_ACTION_USER_DEFINED_MASK) != 0) {\r
355 if (UserDefinedActionString != NULL) {\r
356 return UserDefinedActionString;\r
357 }\r
358 AsciiSPrint (mUserDefinedActionString, sizeof (mUserDefinedActionString), "UserDefined-0x%08x", Action);\r
359 return mUserDefinedActionString;\r
360 }\r
361\r
362 return ActionString[0];\r
363}\r
364\r
365/**\r
366 Dump memory profile allocate information.\r
367\r
368 @param[in] DriverInfo Pointer to memory profile driver info.\r
369 @param[in] AllocIndex Memory profile alloc info index.\r
370 @param[in] AllocInfo Pointer to memory profile alloc info.\r
371 @param[in] IsForSmm TRUE - SMRAM profile.\r
372 FALSE - UEFI memory profile.\r
373\r
374 @return Pointer to next memory profile alloc info.\r
375\r
376**/\r
377MEMORY_PROFILE_ALLOC_INFO *\r
378DumpMemoryProfileAllocInfo (\r
379 IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo,\r
380 IN UINTN AllocIndex,\r
381 IN MEMORY_PROFILE_ALLOC_INFO *AllocInfo,\r
382 IN BOOLEAN IsForSmm\r
383 )\r
384{\r
385 CHAR8 *ActionString;\r
386\r
387 if (AllocInfo->Header.Signature != MEMORY_PROFILE_ALLOC_INFO_SIGNATURE) {\r
388 return NULL;\r
389 }\r
390\r
391 if (AllocInfo->ActionStringOffset != 0) {\r
392 ActionString = (CHAR8 *) ((UINTN) AllocInfo + AllocInfo->ActionStringOffset);\r
393 } else {\r
394 ActionString = NULL;\r
395 }\r
396\r
397 Print (L" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex);\r
398 Print (L" Signature - 0x%08x\n", AllocInfo->Header.Signature);\r
399 Print (L" Length - 0x%04x\n", AllocInfo->Header.Length);\r
400 Print (L" Revision - 0x%04x\n", AllocInfo->Header.Revision);\r
401 Print (L" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo->CallerAddress, (UINTN) (AllocInfo->CallerAddress - DriverInfo->ImageBase));\r
402 Print (L" SequenceId - 0x%08x\n", AllocInfo->SequenceId);\r
403 Print (L" Action - 0x%08x (%a)\n", AllocInfo->Action, ProfileActionToStr (AllocInfo->Action, ActionString, IsForSmm));\r
404 Print (L" MemoryType - 0x%08x (%a)\n", AllocInfo->MemoryType, ProfileMemoryTypeToStr (AllocInfo->MemoryType));\r
405 Print (L" Buffer - 0x%016lx\n", AllocInfo->Buffer);\r
406 Print (L" Size - 0x%016lx\n", AllocInfo->Size);\r
407\r
408 return (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) AllocInfo + AllocInfo->Header.Length);\r
409}\r
410\r
411/**\r
412 Dump memory profile driver information.\r
413\r
414 @param[in] DriverIndex Memory profile driver info index.\r
415 @param[in] DriverInfo Pointer to memory profile driver info.\r
416 @param[in] IsForSmm TRUE - SMRAM profile.\r
417 FALSE - UEFI memory profile.\r
418\r
419 @return Pointer to next memory profile driver info.\r
420\r
421**/\r
422MEMORY_PROFILE_DRIVER_INFO *\r
423DumpMemoryProfileDriverInfo (\r
424 IN UINTN DriverIndex,\r
425 IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo,\r
426 IN BOOLEAN IsForSmm\r
427 )\r
428{\r
429 UINTN TypeIndex;\r
430 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
431 UINTN AllocIndex;\r
432 CHAR8 *NameString;\r
433\r
434 if (DriverInfo->Header.Signature != MEMORY_PROFILE_DRIVER_INFO_SIGNATURE) {\r
435 return NULL;\r
436 }\r
437 Print (L" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex);\r
438 Print (L" Signature - 0x%08x\n", DriverInfo->Header.Signature);\r
439 Print (L" Length - 0x%04x\n", DriverInfo->Header.Length);\r
440 Print (L" Revision - 0x%04x\n", DriverInfo->Header.Revision);\r
441 NameString = GetDriverNameString (DriverInfo);\r
442 Print (L" FileName - %a\n", NameString);\r
443 if (DriverInfo->PdbStringOffset != 0) {\r
444 Print (L" Pdb - %a\n", (CHAR8 *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset));\r
445 }\r
446 Print (L" ImageBase - 0x%016lx\n", DriverInfo->ImageBase);\r
447 Print (L" ImageSize - 0x%016lx\n", DriverInfo->ImageSize);\r
448 Print (L" EntryPoint - 0x%016lx\n", DriverInfo->EntryPoint);\r
449 Print (L" ImageSubsystem - 0x%04x (%a)\n", DriverInfo->ImageSubsystem, mSubsystemString[(DriverInfo->ImageSubsystem < sizeof(mSubsystemString)/sizeof(mSubsystemString[0])) ? DriverInfo->ImageSubsystem : 0]);\r
450 Print (L" FileType - 0x%02x (%a)\n", DriverInfo->FileType, mFileTypeString[(DriverInfo->FileType < sizeof(mFileTypeString)/sizeof(mFileTypeString[0])) ? DriverInfo->FileType : 0]);\r
451 Print (L" CurrentUsage - 0x%016lx\n", DriverInfo->CurrentUsage);\r
452 Print (L" PeakUsage - 0x%016lx\n", DriverInfo->PeakUsage);\r
453 for (TypeIndex = 0; TypeIndex < sizeof (DriverInfo->CurrentUsageByType) / sizeof (DriverInfo->CurrentUsageByType[0]); TypeIndex++) {\r
454 if ((DriverInfo->CurrentUsageByType[TypeIndex] != 0) ||\r
455 (DriverInfo->PeakUsageByType[TypeIndex] != 0)) {\r
456 Print (L" CurrentUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, DriverInfo->CurrentUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
457 Print (L" PeakUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, DriverInfo->PeakUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
458 }\r
459 }\r
460 Print (L" AllocRecordCount - 0x%08x\n", DriverInfo->AllocRecordCount);\r
461\r
462 AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) DriverInfo + DriverInfo->Header.Length);\r
463 for (AllocIndex = 0; AllocIndex < DriverInfo->AllocRecordCount; AllocIndex++) {\r
464 AllocInfo = DumpMemoryProfileAllocInfo (DriverInfo, AllocIndex, AllocInfo, IsForSmm);\r
465 if (AllocInfo == NULL) {\r
466 return NULL;\r
467 }\r
468 }\r
469 return (MEMORY_PROFILE_DRIVER_INFO *) AllocInfo;\r
470}\r
471\r
472/**\r
473 Dump memory profile context information.\r
474\r
475 @param[in] Context Pointer to memory profile context.\r
476 @param[in] IsForSmm TRUE - SMRAM profile.\r
477 FALSE - UEFI memory profile.\r
478\r
479 @return Pointer to the end of memory profile context buffer.\r
480\r
481**/\r
482VOID *\r
483DumpMemoryProfileContext (\r
484 IN MEMORY_PROFILE_CONTEXT *Context,\r
485 IN BOOLEAN IsForSmm\r
486 )\r
487{\r
488 UINTN TypeIndex;\r
489 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
490 UINTN DriverIndex;\r
491\r
492 if (Context->Header.Signature != MEMORY_PROFILE_CONTEXT_SIGNATURE) {\r
493 return NULL;\r
494 }\r
495 Print (L"MEMORY_PROFILE_CONTEXT\n");\r
496 Print (L" Signature - 0x%08x\n", Context->Header.Signature);\r
497 Print (L" Length - 0x%04x\n", Context->Header.Length);\r
498 Print (L" Revision - 0x%04x\n", Context->Header.Revision);\r
499 Print (L" CurrentTotalUsage - 0x%016lx\n", Context->CurrentTotalUsage);\r
500 Print (L" PeakTotalUsage - 0x%016lx\n", Context->PeakTotalUsage);\r
501 for (TypeIndex = 0; TypeIndex < sizeof (Context->CurrentTotalUsageByType) / sizeof (Context->CurrentTotalUsageByType[0]); TypeIndex++) {\r
502 if ((Context->CurrentTotalUsageByType[TypeIndex] != 0) ||\r
503 (Context->PeakTotalUsageByType[TypeIndex] != 0)) {\r
504 Print (L" CurrentTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, Context->CurrentTotalUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
505 Print (L" PeakTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, Context->PeakTotalUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);\r
506 }\r
507 }\r
508 Print (L" TotalImageSize - 0x%016lx\n", Context->TotalImageSize);\r
509 Print (L" ImageCount - 0x%08x\n", Context->ImageCount);\r
510 Print (L" SequenceCount - 0x%08x\n", Context->SequenceCount);\r
511\r
512 DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) ((UINTN) Context + Context->Header.Length);\r
513 for (DriverIndex = 0; DriverIndex < Context->ImageCount; DriverIndex++) {\r
514 DriverInfo = DumpMemoryProfileDriverInfo (DriverIndex, DriverInfo, IsForSmm);\r
515 if (DriverInfo == NULL) {\r
516 return NULL;\r
517 }\r
518 }\r
519 return (VOID *) DriverInfo;\r
520}\r
521\r
522/**\r
523 Dump memory profile descriptor information.\r
524\r
525 @param[in] DescriptorIndex Memory profile descriptor index.\r
526 @param[in] Descriptor Pointer to memory profile descriptor.\r
527\r
528 @return Pointer to next memory profile descriptor.\r
529\r
530**/\r
531MEMORY_PROFILE_DESCRIPTOR *\r
532DumpMemoryProfileDescriptor (\r
533 IN UINTN DescriptorIndex,\r
534 IN MEMORY_PROFILE_DESCRIPTOR *Descriptor\r
535 )\r
536{\r
537 if (Descriptor->Header.Signature != MEMORY_PROFILE_DESCRIPTOR_SIGNATURE) {\r
538 return NULL;\r
539 }\r
540 Print (L" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex);\r
541 Print (L" Signature - 0x%08x\n", Descriptor->Header.Signature);\r
542 Print (L" Length - 0x%04x\n", Descriptor->Header.Length);\r
543 Print (L" Revision - 0x%04x\n", Descriptor->Header.Revision);\r
544 Print (L" Address - 0x%016lx\n", Descriptor->Address);\r
545 Print (L" Size - 0x%016lx\n", Descriptor->Size);\r
546\r
547 return (MEMORY_PROFILE_DESCRIPTOR *) ((UINTN) Descriptor + Descriptor->Header.Length);\r
548}\r
549\r
550/**\r
551 Dump memory profile free memory information.\r
552\r
553 @param[in] FreeMemory Pointer to memory profile free memory.\r
554\r
555 @return Pointer to the end of memory profile free memory buffer.\r
556\r
557**/\r
558VOID *\r
559DumpMemoryProfileFreeMemory (\r
560 IN MEMORY_PROFILE_FREE_MEMORY *FreeMemory\r
561 )\r
562{\r
563 MEMORY_PROFILE_DESCRIPTOR *Descriptor;\r
564 UINTN DescriptorIndex;\r
565\r
566 if (FreeMemory->Header.Signature != MEMORY_PROFILE_FREE_MEMORY_SIGNATURE) {\r
567 return NULL;\r
568 }\r
569 Print (L"MEMORY_PROFILE_FREE_MEMORY\n");\r
570 Print (L" Signature - 0x%08x\n", FreeMemory->Header.Signature);\r
571 Print (L" Length - 0x%04x\n", FreeMemory->Header.Length);\r
572 Print (L" Revision - 0x%04x\n", FreeMemory->Header.Revision);\r
573 Print (L" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory->TotalFreeMemoryPages);\r
574 Print (L" FreeMemoryEntryCount - 0x%08x\n", FreeMemory->FreeMemoryEntryCount);\r
575\r
576 Descriptor = (MEMORY_PROFILE_DESCRIPTOR *) ((UINTN) FreeMemory + FreeMemory->Header.Length);\r
577 for (DescriptorIndex = 0; DescriptorIndex < FreeMemory->FreeMemoryEntryCount; DescriptorIndex++) {\r
578 Descriptor = DumpMemoryProfileDescriptor (DescriptorIndex, Descriptor);\r
579 if (Descriptor == NULL) {\r
580 return NULL;\r
581 }\r
582 }\r
583\r
584 return (VOID *) Descriptor;\r
585}\r
586\r
587/**\r
588 Dump memory profile memory range information.\r
589\r
590 @param[in] MemoryRange Pointer to memory profile memory range.\r
591\r
592 @return Pointer to the end of memory profile memory range buffer.\r
593\r
594**/\r
595VOID *\r
596DumpMemoryProfileMemoryRange (\r
597 IN MEMORY_PROFILE_MEMORY_RANGE *MemoryRange\r
598 )\r
599{\r
600 MEMORY_PROFILE_DESCRIPTOR *Descriptor;\r
601 UINTN DescriptorIndex;\r
602\r
603 if (MemoryRange->Header.Signature != MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE) {\r
604 return NULL;\r
605 }\r
606 Print (L"MEMORY_PROFILE_MEMORY_RANGE\n");\r
607 Print (L" Signature - 0x%08x\n", MemoryRange->Header.Signature);\r
608 Print (L" Length - 0x%04x\n", MemoryRange->Header.Length);\r
609 Print (L" Revision - 0x%04x\n", MemoryRange->Header.Revision);\r
610 Print (L" MemoryRangeCount - 0x%08x\n", MemoryRange->MemoryRangeCount);\r
611\r
612 Descriptor = (MEMORY_PROFILE_DESCRIPTOR *) ((UINTN) MemoryRange + MemoryRange->Header.Length);\r
613 for (DescriptorIndex = 0; DescriptorIndex < MemoryRange->MemoryRangeCount; DescriptorIndex++) {\r
614 Descriptor = DumpMemoryProfileDescriptor (DescriptorIndex, Descriptor);\r
615 if (Descriptor == NULL) {\r
616 return NULL;\r
617 }\r
618 }\r
619\r
620 return (VOID *) Descriptor;\r
621}\r
622\r
623/**\r
624 Scan memory profile by Signature.\r
625\r
626 @param[in] ProfileBuffer Memory profile base address.\r
627 @param[in] ProfileSize Memory profile size.\r
628 @param[in] Signature Signature.\r
629\r
630 @return Pointer to the structure with the signature.\r
631\r
632**/\r
633VOID *\r
634ScanMemoryProfileBySignature (\r
635 IN PHYSICAL_ADDRESS ProfileBuffer,\r
636 IN UINT64 ProfileSize,\r
637 IN UINT32 Signature\r
638 )\r
639{\r
640 MEMORY_PROFILE_COMMON_HEADER *CommonHeader;\r
641 UINTN ProfileEnd;\r
642\r
643 ProfileEnd = (UINTN) (ProfileBuffer + ProfileSize);\r
644 CommonHeader = (MEMORY_PROFILE_COMMON_HEADER *) (UINTN) ProfileBuffer;\r
645 while ((UINTN) CommonHeader < ProfileEnd) {\r
646 if (CommonHeader->Signature == Signature) {\r
647 //\r
648 // Found it.\r
649 //\r
650 return (VOID *) CommonHeader;\r
651 }\r
652 if (CommonHeader->Length == 0) {\r
653 ASSERT (FALSE);\r
654 return NULL;\r
655 }\r
656 CommonHeader = (MEMORY_PROFILE_COMMON_HEADER *) ((UINTN) CommonHeader + CommonHeader->Length);\r
657 }\r
658\r
659 return NULL;\r
660}\r
661\r
662/**\r
663 Dump memory profile information.\r
664\r
665 @param[in] ProfileBuffer Memory profile base address.\r
666 @param[in] ProfileSize Memory profile size.\r
667 @param[in] IsForSmm TRUE - SMRAM profile.\r
668 FALSE - UEFI memory profile.\r
669\r
670**/\r
671VOID\r
672DumpMemoryProfile (\r
673 IN PHYSICAL_ADDRESS ProfileBuffer,\r
674 IN UINT64 ProfileSize,\r
675 IN BOOLEAN IsForSmm\r
676 )\r
677{\r
678 MEMORY_PROFILE_CONTEXT *Context;\r
679 MEMORY_PROFILE_FREE_MEMORY *FreeMemory;\r
680 MEMORY_PROFILE_MEMORY_RANGE *MemoryRange;\r
681\r
682 Context = (MEMORY_PROFILE_CONTEXT *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_CONTEXT_SIGNATURE);\r
683 if (Context != NULL) {\r
684 DumpMemoryProfileContext (Context, IsForSmm);\r
685 }\r
686\r
687 FreeMemory = (MEMORY_PROFILE_FREE_MEMORY *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE);\r
688 if (FreeMemory != NULL) {\r
689 DumpMemoryProfileFreeMemory (FreeMemory);\r
690 }\r
691\r
692 MemoryRange = (MEMORY_PROFILE_MEMORY_RANGE *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE);\r
693 if (MemoryRange != NULL) {\r
694 DumpMemoryProfileMemoryRange (MemoryRange);\r
695 }\r
696}\r
697\r
698/**\r
699 Get Allocate summary information structure by caller address.\r
700\r
701 @param[in] CallerAddress Caller address.\r
702 @param[in] DriverSummaryInfoData Driver summary information data structure.\r
703\r
704 @return Allocate summary information structure by caller address.\r
705\r
706**/\r
707MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *\r
708GetAllocSummaryInfoByCallerAddress (\r
709 IN PHYSICAL_ADDRESS CallerAddress,\r
710 IN MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData\r
711 )\r
712{\r
713 LIST_ENTRY *AllocSummaryInfoList;\r
714 LIST_ENTRY *AllocSummaryLink;\r
715 MEMORY_PROFILE_ALLOC_SUMMARY_INFO *AllocSummaryInfo;\r
716 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
717\r
718 AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;\r
719\r
720 for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;\r
721 AllocSummaryLink != AllocSummaryInfoList;\r
722 AllocSummaryLink = AllocSummaryLink->ForwardLink) {\r
723 AllocSummaryInfoData = CR (\r
724 AllocSummaryLink,\r
725 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,\r
726 Link,\r
727 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE\r
728 );\r
729 AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
730 if (AllocSummaryInfo->CallerAddress == CallerAddress) {\r
731 return AllocSummaryInfoData;\r
732 }\r
733 }\r
734 return NULL;\r
735}\r
736\r
737/**\r
738 Create Allocate summary information structure and\r
739 link to Driver summary information data structure.\r
740\r
741 @param[in, out] DriverSummaryInfoData Driver summary information data structure.\r
742 @param[in] AllocInfo Pointer to memory profile alloc info.\r
743\r
744 @return Pointer to next memory profile alloc info.\r
745\r
746**/\r
747MEMORY_PROFILE_ALLOC_INFO *\r
748CreateAllocSummaryInfo (\r
749 IN OUT MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData,\r
750 IN MEMORY_PROFILE_ALLOC_INFO *AllocInfo\r
751 )\r
752{\r
753 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
754 MEMORY_PROFILE_ALLOC_SUMMARY_INFO *AllocSummaryInfo;\r
755\r
756 if (AllocInfo->Header.Signature != MEMORY_PROFILE_ALLOC_INFO_SIGNATURE) {\r
757 return NULL;\r
758 }\r
759\r
760 AllocSummaryInfoData = GetAllocSummaryInfoByCallerAddress (AllocInfo->CallerAddress, DriverSummaryInfoData);\r
761 if (AllocSummaryInfoData == NULL) {\r
762 AllocSummaryInfoData = AllocatePool (sizeof (*AllocSummaryInfoData));\r
763 if (AllocSummaryInfoData == NULL) {\r
764 return NULL;\r
765 }\r
766\r
767 AllocSummaryInfoData->Signature = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE;\r
768 AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
769 AllocSummaryInfo->Header.Signature = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE;\r
770 AllocSummaryInfo->Header.Length = sizeof (*AllocSummaryInfo);\r
771 AllocSummaryInfo->Header.Revision = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION;\r
772 AllocSummaryInfo->CallerAddress = AllocInfo->CallerAddress;\r
773 AllocSummaryInfo->Action = AllocInfo->Action;\r
774 if (AllocInfo->ActionStringOffset != 0) {\r
775 AllocSummaryInfo->ActionString = (CHAR8 *) ((UINTN) AllocInfo + AllocInfo->ActionStringOffset);\r
776 } else {\r
777 AllocSummaryInfo->ActionString = NULL;\r
778 }\r
779 AllocSummaryInfo->AllocateCount = 0;\r
780 AllocSummaryInfo->TotalSize = 0;\r
781 InsertTailList (DriverSummaryInfoData->AllocSummaryInfoList, &AllocSummaryInfoData->Link);\r
782 }\r
783 AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
784 AllocSummaryInfo->AllocateCount ++;\r
785 AllocSummaryInfo->TotalSize += AllocInfo->Size;\r
786\r
787 return (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) AllocInfo + AllocInfo->Header.Length);\r
788}\r
789\r
790/**\r
791 Create Driver summary information structure and\r
792 link to Context summary information data structure.\r
793\r
794 @param[in, out] ContextSummaryData Context summary information data structure.\r
795 @param[in] DriverInfo Pointer to memory profile driver info.\r
796\r
797 @return Pointer to next memory profile driver info.\r
798\r
799**/\r
800MEMORY_PROFILE_DRIVER_INFO *\r
801CreateDriverSummaryInfo (\r
802 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *ContextSummaryData,\r
803 IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo\r
804 )\r
805{\r
806 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData;\r
807 MEMORY_PROFILE_ALLOC_INFO *AllocInfo;\r
808 UINTN AllocIndex;\r
809\r
810 if (DriverInfo->Header.Signature != MEMORY_PROFILE_DRIVER_INFO_SIGNATURE) {\r
811 return NULL;\r
812 }\r
813\r
814 DriverSummaryInfoData = AllocatePool (sizeof (*DriverSummaryInfoData) + sizeof (LIST_ENTRY));\r
815 if (DriverSummaryInfoData == NULL) {\r
816 return NULL;\r
817 }\r
818 DriverSummaryInfoData->Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;\r
819 DriverSummaryInfoData->DriverInfo = DriverInfo;\r
820 DriverSummaryInfoData->AllocSummaryInfoList = (LIST_ENTRY *) (DriverSummaryInfoData + 1);\r
821 InitializeListHead (DriverSummaryInfoData->AllocSummaryInfoList);\r
822 InsertTailList (ContextSummaryData->DriverSummaryInfoList, &DriverSummaryInfoData->Link);\r
823\r
824 AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) DriverInfo + DriverInfo->Header.Length);\r
825 for (AllocIndex = 0; AllocIndex < DriverInfo->AllocRecordCount; AllocIndex++) {\r
826 AllocInfo = CreateAllocSummaryInfo (DriverSummaryInfoData, AllocInfo);\r
827 if (AllocInfo == NULL) {\r
828 return NULL;\r
829 }\r
830 }\r
831 return (MEMORY_PROFILE_DRIVER_INFO *) AllocInfo;\r
832}\r
833\r
834/**\r
835 Create Context summary information structure.\r
836\r
837 @param[in] ProfileBuffer Memory profile base address.\r
838 @param[in] ProfileSize Memory profile size.\r
839\r
840 @return Context summary information structure.\r
841\r
842**/\r
843MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *\r
844CreateContextSummaryData (\r
845 IN PHYSICAL_ADDRESS ProfileBuffer,\r
846 IN UINT64 ProfileSize\r
847 )\r
848{\r
849 MEMORY_PROFILE_CONTEXT *Context;\r
850 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
851 UINTN DriverIndex;\r
852\r
853 Context = (MEMORY_PROFILE_CONTEXT *) ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_CONTEXT_SIGNATURE);\r
854 if (Context == NULL) {\r
855 return NULL;\r
856 }\r
857\r
858 mMemoryProfileContextSummary.Signature = MEMORY_PROFILE_CONTEXT_SIGNATURE;\r
859 mMemoryProfileContextSummary.Context = Context;\r
860 mMemoryProfileContextSummary.DriverSummaryInfoList = &mImageSummaryQueue;\r
861\r
862 DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) ((UINTN) Context + Context->Header.Length);\r
863 for (DriverIndex = 0; DriverIndex < Context->ImageCount; DriverIndex++) {\r
864 DriverInfo = CreateDriverSummaryInfo (&mMemoryProfileContextSummary, DriverInfo);\r
865 if (DriverInfo == NULL) {\r
866 return NULL;\r
867 }\r
868 }\r
869\r
870 return &mMemoryProfileContextSummary;\r
871}\r
872\r
873/**\r
874 Dump Context summary information.\r
875\r
876 @param[in] ContextSummaryData Context summary information data.\r
877 @param[in] IsForSmm TRUE - SMRAM profile.\r
878 FALSE - UEFI memory profile.\r
879\r
880**/\r
881VOID\r
882DumpContextSummaryData (\r
883 IN MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *ContextSummaryData,\r
884 IN BOOLEAN IsForSmm\r
885 )\r
886{\r
887 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData;\r
888 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
889 LIST_ENTRY *DriverSummaryInfoList;\r
890 LIST_ENTRY *DriverSummaryLink;\r
891 LIST_ENTRY *AllocSummaryInfoList;\r
892 LIST_ENTRY *AllocSummaryLink;\r
893 MEMORY_PROFILE_DRIVER_INFO *DriverInfo;\r
894 MEMORY_PROFILE_ALLOC_SUMMARY_INFO *AllocSummaryInfo;\r
895 CHAR8 *NameString;\r
896\r
897 if (ContextSummaryData == NULL) {\r
898 return ;\r
899 }\r
900\r
901 Print (L"\nSummary Data:\n");\r
902\r
903 DriverSummaryInfoList = ContextSummaryData->DriverSummaryInfoList;\r
904 for (DriverSummaryLink = DriverSummaryInfoList->ForwardLink;\r
905 DriverSummaryLink != DriverSummaryInfoList;\r
906 DriverSummaryLink = DriverSummaryLink->ForwardLink) {\r
907 DriverSummaryInfoData = CR (\r
908 DriverSummaryLink,\r
909 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA,\r
910 Link,\r
911 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
912 );\r
913 DriverInfo = DriverSummaryInfoData->DriverInfo;\r
914\r
915 NameString = GetDriverNameString (DriverInfo);\r
916 Print (L"\nDriver - %a (Usage - 0x%08x)", NameString, DriverInfo->CurrentUsage);\r
917 if (DriverInfo->CurrentUsage == 0) {\r
918 Print (L"\n");\r
919 continue;\r
920 }\r
921\r
922 if (DriverInfo->PdbStringOffset != 0) {\r
923 Print (L" (Pdb - %a)\n", (CHAR8 *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset));\r
924 } else {\r
925 Print (L"\n");\r
926 }\r
927 Print (L"Caller List:\n");\r
928 Print(L" Count Size RVA Action\n");\r
929 Print(L"========== ================== ================== (================================)\n");\r
930 AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;\r
931 for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;\r
932 AllocSummaryLink != AllocSummaryInfoList;\r
933 AllocSummaryLink = AllocSummaryLink->ForwardLink) {\r
934 AllocSummaryInfoData = CR (\r
935 AllocSummaryLink,\r
936 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,\r
937 Link,\r
938 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE\r
939 );\r
940 AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;\r
941\r
942 Print(L"0x%08x 0x%016lx <== 0x%016lx",\r
943 AllocSummaryInfo->AllocateCount,\r
944 AllocSummaryInfo->TotalSize,\r
945 AllocSummaryInfo->CallerAddress - DriverInfo->ImageBase\r
946 );\r
947 Print (L" (%a)\n", ProfileActionToStr (AllocSummaryInfo->Action, AllocSummaryInfo->ActionString, IsForSmm));\r
948 }\r
949 }\r
950 return ;\r
951}\r
952\r
953/**\r
954 Destroy Context summary information.\r
955\r
956 @param[in, out] ContextSummaryData Context summary information data.\r
957\r
958**/\r
959VOID\r
960DestroyContextSummaryData (\r
961 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *ContextSummaryData\r
962 )\r
963{\r
964 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA *DriverSummaryInfoData;\r
965 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *AllocSummaryInfoData;\r
966 LIST_ENTRY *DriverSummaryInfoList;\r
967 LIST_ENTRY *DriverSummaryLink;\r
968 LIST_ENTRY *AllocSummaryInfoList;\r
969 LIST_ENTRY *AllocSummaryLink;\r
970\r
971 if (ContextSummaryData == NULL) {\r
972 return ;\r
973 }\r
974\r
975 DriverSummaryInfoList = ContextSummaryData->DriverSummaryInfoList;\r
976 for (DriverSummaryLink = DriverSummaryInfoList->ForwardLink;\r
977 DriverSummaryLink != DriverSummaryInfoList;\r
978 ) {\r
979 DriverSummaryInfoData = CR (\r
980 DriverSummaryLink,\r
981 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA,\r
982 Link,\r
983 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE\r
984 );\r
985 DriverSummaryLink = DriverSummaryLink->ForwardLink;\r
986\r
987 AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;\r
988 for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;\r
989 AllocSummaryLink != AllocSummaryInfoList;\r
990 ) {\r
991 AllocSummaryInfoData = CR (\r
992 AllocSummaryLink,\r
993 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,\r
994 Link,\r
995 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE\r
996 );\r
997 AllocSummaryLink = AllocSummaryLink->ForwardLink;\r
998\r
999 RemoveEntryList (&AllocSummaryInfoData->Link);\r
1000 FreePool (AllocSummaryInfoData);\r
1001 }\r
1002\r
1003 RemoveEntryList (&DriverSummaryInfoData->Link);\r
1004 FreePool (DriverSummaryInfoData);\r
1005 }\r
1006 return ;\r
1007}\r
1008\r
1009/**\r
1010 Get and dump UEFI memory profile data.\r
1011\r
1012 @return EFI_SUCCESS Get the memory profile data successfully.\r
1013 @return other Fail to get the memory profile data.\r
1014\r
1015**/\r
1016EFI_STATUS\r
1017GetUefiMemoryProfileData (\r
1018 VOID\r
1019 )\r
1020{\r
1021 EFI_STATUS Status;\r
1022 EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;\r
1023 VOID *Data;\r
1024 UINT64 Size;\r
1025 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *MemoryProfileContextSummaryData;\r
1026 BOOLEAN RecordingState;\r
1027\r
1028 Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol);\r
1029 if (EFI_ERROR (Status)) {\r
1030 DEBUG ((EFI_D_ERROR, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status));\r
1031 return Status;\r
1032 }\r
1033\r
1034 //\r
1035 // Set recording state if needed.\r
1036 //\r
1037 RecordingState = MEMORY_PROFILE_RECORDING_DISABLE;\r
1038 Status = ProfileProtocol->GetRecordingState (ProfileProtocol, &RecordingState);\r
1039 if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {\r
1040 ProfileProtocol->SetRecordingState (ProfileProtocol, MEMORY_PROFILE_RECORDING_DISABLE);\r
1041 }\r
1042\r
1043 Size = 0;\r
1044 Data = NULL;\r
1045 Status = ProfileProtocol->GetData (\r
1046 ProfileProtocol,\r
1047 &Size,\r
1048 Data\r
1049 );\r
1050 if (Status != EFI_BUFFER_TOO_SMALL) {\r
1051 Print (L"UefiMemoryProfile: GetData - %r\n", Status);\r
1052 goto Done;\r
1053 }\r
1054\r
1055 Data = AllocateZeroPool ((UINTN) Size);\r
1056 if (Data == NULL) {\r
1057 Status = EFI_OUT_OF_RESOURCES;\r
1058 Print (L"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size, Status);\r
1059 return Status;\r
1060 }\r
1061\r
1062 Status = ProfileProtocol->GetData (\r
1063 ProfileProtocol,\r
1064 &Size,\r
1065 Data\r
1066 );\r
1067 if (EFI_ERROR (Status)) {\r
1068 Print (L"UefiMemoryProfile: GetData - %r\n", Status);\r
1069 goto Done;\r
1070 }\r
1071\r
1072\r
1073 Print (L"UefiMemoryProfileSize - 0x%x\n", Size);\r
1074 Print (L"======= UefiMemoryProfile begin =======\n");\r
1075 DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) Data, Size, FALSE);\r
1076\r
1077 //\r
1078 // Dump summary information\r
1079 //\r
1080 MemoryProfileContextSummaryData = CreateContextSummaryData ((PHYSICAL_ADDRESS) (UINTN) Data, Size);\r
1081 if (MemoryProfileContextSummaryData != NULL) {\r
1082 DumpContextSummaryData (MemoryProfileContextSummaryData, FALSE);\r
1083 DestroyContextSummaryData (MemoryProfileContextSummaryData);\r
1084 }\r
1085\r
1086 Print (L"======= UefiMemoryProfile end =======\n\n\n");\r
1087\r
1088Done:\r
1089 if (Data != NULL) {\r
1090 FreePool (Data);\r
1091 }\r
1092\r
1093 //\r
1094 // Restore recording state if needed.\r
1095 //\r
1096 if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {\r
1097 ProfileProtocol->SetRecordingState (ProfileProtocol, MEMORY_PROFILE_RECORDING_ENABLE);\r
1098 }\r
1099\r
1100 return Status;\r
1101}\r
1102\r
1103/**\r
1104 Get and dump SMRAM profile data.\r
1105\r
1106 @return EFI_SUCCESS Get the SMRAM profile data successfully.\r
1107 @return other Fail to get the SMRAM profile data.\r
1108\r
1109**/\r
1110EFI_STATUS\r
1111GetSmramProfileData (\r
1112 VOID\r
1113 )\r
1114{\r
1115 EFI_STATUS Status;\r
1116 UINTN CommSize;\r
1117 UINT8 *CommBuffer;\r
1118 EFI_SMM_COMMUNICATE_HEADER *CommHeader;\r
1119 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *CommGetProfileInfo;\r
1120 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *CommGetProfileData;\r
1121 SMRAM_PROFILE_PARAMETER_RECORDING_STATE *CommRecordingState;\r
1122 UINTN ProfileSize;\r
1123 VOID *ProfileBuffer;\r
1124 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;\r
1125 UINTN MinimalSizeNeeded;\r
1126 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
1127 UINT32 Index;\r
1128 EFI_MEMORY_DESCRIPTOR *Entry;\r
1129 VOID *Buffer;\r
1130 UINTN Size;\r
1131 UINTN Offset;\r
1132 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *MemoryProfileContextSummaryData;\r
1133 BOOLEAN RecordingState;\r
1134\r
1135 ProfileBuffer = NULL;\r
1136\r
1137 Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication);\r
1138 if (EFI_ERROR (Status)) {\r
1139 DEBUG ((EFI_D_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status));\r
1140 return Status;\r
1141 }\r
1142\r
1143 MinimalSizeNeeded = sizeof (EFI_GUID) +\r
1144 sizeof (UINTN) +\r
1145 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO),\r
1146 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET),\r
1147 sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE)));\r
1148 MinimalSizeNeeded += MAX (sizeof (MEMORY_PROFILE_CONTEXT),\r
1149 MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO),\r
1150 MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO),\r
1151 MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR),\r
1152 MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY),\r
1153 sizeof (MEMORY_PROFILE_MEMORY_RANGE))))));\r
1154\r
1155 Status = EfiGetSystemConfigurationTable (\r
1156 &gEdkiiPiSmmCommunicationRegionTableGuid,\r
1157 (VOID **) &PiSmmCommunicationRegionTable\r
1158 );\r
1159 if (EFI_ERROR (Status)) {\r
1160 DEBUG ((EFI_D_ERROR, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status));\r
1161 return Status;\r
1162 }\r
1163 ASSERT (PiSmmCommunicationRegionTable != NULL);\r
1164 Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1);\r
1165 Size = 0;\r
1166 for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
1167 if (Entry->Type == EfiConventionalMemory) {\r
1168 Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages);\r
1169 if (Size >= MinimalSizeNeeded) {\r
1170 break;\r
1171 }\r
1172 }\r
1173 Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
1174 }\r
1175 ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
1176 CommBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;\r
1177\r
1178 //\r
1179 // Set recording state if needed.\r
1180 //\r
1181 RecordingState = MEMORY_PROFILE_RECORDING_DISABLE;\r
1182\r
1183 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
1184 CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));\r
1185 CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE);\r
1186\r
1187 CommRecordingState = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
1188 CommRecordingState->Header.Command = SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE;\r
1189 CommRecordingState->Header.DataLength = sizeof (*CommRecordingState);\r
1190 CommRecordingState->Header.ReturnStatus = (UINT64)-1;\r
1191 CommRecordingState->RecordingState = MEMORY_PROFILE_RECORDING_DISABLE;\r
1192\r
1193 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
1194 Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
1195 if (EFI_ERROR (Status)) {\r
1196 DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status));\r
1197 return Status;\r
1198 }\r
1199\r
1200 if (CommRecordingState->Header.ReturnStatus != 0) {\r
1201 Print (L"SmramProfile: GetRecordingState - 0x%0x\n", CommRecordingState->Header.ReturnStatus);\r
1202 return EFI_SUCCESS;\r
1203 }\r
1204 RecordingState = CommRecordingState->RecordingState;\r
1205 if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {\r
1206 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
1207 CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));\r
1208 CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE);\r
1209\r
1210 CommRecordingState = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
1211 CommRecordingState->Header.Command = SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE;\r
1212 CommRecordingState->Header.DataLength = sizeof (*CommRecordingState);\r
1213 CommRecordingState->Header.ReturnStatus = (UINT64)-1;\r
1214 CommRecordingState->RecordingState = MEMORY_PROFILE_RECORDING_DISABLE;\r
1215\r
1216 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
1217 SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
1218 }\r
1219\r
1220 //\r
1221 // Get Size\r
1222 //\r
1223 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
1224 CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));\r
1225 CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO);\r
1226\r
1227 CommGetProfileInfo = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
1228 CommGetProfileInfo->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO;\r
1229 CommGetProfileInfo->Header.DataLength = sizeof (*CommGetProfileInfo);\r
1230 CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1;\r
1231 CommGetProfileInfo->ProfileSize = 0;\r
1232\r
1233 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
1234 Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
1235 ASSERT_EFI_ERROR (Status);\r
1236\r
1237 if (CommGetProfileInfo->Header.ReturnStatus != 0) {\r
1238 Status = EFI_SUCCESS;\r
1239 Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus);\r
1240 goto Done;\r
1241 }\r
1242\r
1243 ProfileSize = (UINTN) CommGetProfileInfo->ProfileSize;\r
1244\r
1245 //\r
1246 // Get Data\r
1247 //\r
1248 ProfileBuffer = AllocateZeroPool (ProfileSize);\r
1249 if (ProfileBuffer == NULL) {\r
1250 Status = EFI_OUT_OF_RESOURCES;\r
1251 Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize, Status);\r
1252 goto Done;\r
1253 }\r
1254\r
1255 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
1256 CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid));\r
1257 CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET);\r
1258\r
1259 CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
1260 CommGetProfileData->Header.Command = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET;\r
1261 CommGetProfileData->Header.DataLength = sizeof (*CommGetProfileData);\r
1262 CommGetProfileData->Header.ReturnStatus = (UINT64)-1;\r
1263\r
1264 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
1265 Buffer = (UINT8 *) CommHeader + CommSize;\r
1266 Size -= CommSize;\r
1267\r
1268 CommGetProfileData->ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) Buffer;\r
1269 CommGetProfileData->ProfileOffset = 0;\r
1270 while (CommGetProfileData->ProfileOffset < ProfileSize) {\r
1271 Offset = (UINTN) CommGetProfileData->ProfileOffset;\r
1272 if (Size <= (ProfileSize - CommGetProfileData->ProfileOffset)) {\r
1273 CommGetProfileData->ProfileSize = (UINT64) Size;\r
1274 } else {\r
1275 CommGetProfileData->ProfileSize = (UINT64) (ProfileSize - CommGetProfileData->ProfileOffset);\r
1276 }\r
1277 Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
1278 ASSERT_EFI_ERROR (Status);\r
1279\r
1280 if (CommGetProfileData->Header.ReturnStatus != 0) {\r
1281 Status = EFI_SUCCESS;\r
1282 Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);\r
1283 goto Done;\r
1284 }\r
1285 CopyMem ((UINT8 *) ProfileBuffer + Offset, (VOID *) (UINTN) CommGetProfileData->ProfileBuffer, (UINTN) CommGetProfileData->ProfileSize);\r
1286 }\r
1287\r
1288\r
1289 Print (L"SmramProfileSize - 0x%x\n", ProfileSize);\r
1290 Print (L"======= SmramProfile begin =======\n");\r
1291 DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize, TRUE);\r
1292\r
1293 //\r
1294 // Dump summary information\r
1295 //\r
1296 MemoryProfileContextSummaryData = CreateContextSummaryData ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize);\r
1297 if (MemoryProfileContextSummaryData != NULL) {\r
1298 DumpContextSummaryData (MemoryProfileContextSummaryData, TRUE);\r
1299 DestroyContextSummaryData (MemoryProfileContextSummaryData);\r
1300 }\r
1301\r
1302 Print (L"======= SmramProfile end =======\n\n\n");\r
1303\r
1304Done:\r
1305 if (ProfileBuffer != NULL) {\r
1306 FreePool (ProfileBuffer);\r
1307 }\r
1308\r
1309 //\r
1310 // Restore recording state if needed.\r
1311 //\r
1312 if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {\r
1313 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
1314 CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));\r
1315 CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE);\r
1316\r
1317 CommRecordingState = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
1318 CommRecordingState->Header.Command = SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE;\r
1319 CommRecordingState->Header.DataLength = sizeof (*CommRecordingState);\r
1320 CommRecordingState->Header.ReturnStatus = (UINT64)-1;\r
1321 CommRecordingState->RecordingState = MEMORY_PROFILE_RECORDING_ENABLE;\r
1322\r
1323 CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
1324 SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
1325 }\r
1326\r
1327 return Status;\r
1328}\r
1329\r
1330/**\r
1331 The user Entry Point for Application. The user code starts with this function\r
1332 as the real entry point for the image goes into a library that calls this function.\r
1333\r
1334 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
1335 @param[in] SystemTable A pointer to the EFI System Table.\r
1336\r
1337 @retval EFI_SUCCESS The entry point is executed successfully.\r
1338 @retval other Some error occurs when executing this entry point.\r
1339\r
1340**/\r
1341EFI_STATUS\r
1342EFIAPI\r
1343UefiMain (\r
1344 IN EFI_HANDLE ImageHandle,\r
1345 IN EFI_SYSTEM_TABLE *SystemTable\r
1346 )\r
1347{\r
1348 EFI_STATUS Status;\r
1349\r
1350 Status = GetUefiMemoryProfileData ();\r
1351 if (EFI_ERROR (Status)) {\r
1352 DEBUG ((EFI_D_ERROR, "GetUefiMemoryProfileData - %r\n", Status));\r
1353 }\r
1354\r
1355 Status = GetSmramProfileData ();\r
1356 if (EFI_ERROR (Status)) {\r
1357 DEBUG ((EFI_D_ERROR, "GetSmramProfileData - %r\n", Status));\r
1358 }\r
1359\r
1360 return EFI_SUCCESS;\r
1361}\r