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