3 Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/BaseLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/MemoryAllocationLib.h>
13 #include <Library/UefiLib.h>
14 #include <Library/UefiApplicationEntryPoint.h>
15 #include <Library/UefiBootServicesTableLib.h>
16 #include <Library/UefiRuntimeServicesTableLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/DxeServicesLib.h>
19 #include <Library/PrintLib.h>
21 #include <Protocol/SmmCommunication.h>
22 #include <Protocol/SmmAccess2.h>
24 #include <Guid/MemoryProfile.h>
25 #include <Guid/PiSmmCommunicationRegionTable.h>
27 CHAR8
*mActionString
[] = {
35 CHAR8
*mSmmActionString
[] = {
37 "gSmst->SmmAllocatePages",
38 "gSmst->SmmFreePages",
39 "gSmst->SmmAllocatePool",
44 MEMORY_PROFILE_ACTION Action
;
48 ACTION_STRING mExtActionString
[] = {
49 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES
, "Lib:AllocatePages"},
50 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES
, "Lib:AllocateRuntimePages"},
51 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES
, "Lib:AllocateReservedPages"},
52 {MEMORY_PROFILE_ACTION_LIB_FREE_PAGES
, "Lib:FreePages"},
53 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES
, "Lib:AllocateAlignedPages"},
54 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES
, "Lib:AllocateAlignedRuntimePages"},
55 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES
, "Lib:AllocateAlignedReservedPages"},
56 {MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES
, "Lib:FreeAlignedPages"},
57 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL
, "Lib:AllocatePool"},
58 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL
, "Lib:AllocateRuntimePool"},
59 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL
, "Lib:AllocateReservedPool"},
60 {MEMORY_PROFILE_ACTION_LIB_FREE_POOL
, "Lib:FreePool"},
61 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL
, "Lib:AllocateZeroPool"},
62 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL
, "Lib:AllocateRuntimeZeroPool"},
63 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL
, "Lib:AllocateReservedZeroPool"},
64 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL
, "Lib:AllocateCopyPool"},
65 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL
, "Lib:AllocateRuntimeCopyPool"},
66 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL
, "Lib:AllocateReservedCopyPool"},
67 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL
, "Lib:ReallocatePool"},
68 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL
, "Lib:ReallocateRuntimePool"},
69 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL
, "Lib:ReallocateReservedPool"},
72 CHAR8 mUserDefinedActionString
[] = {"UserDefined-0x80000000"};
74 CHAR8
*mMemoryTypeString
[] = {
75 "EfiReservedMemoryType",
78 "EfiBootServicesCode",
79 "EfiBootServicesData",
80 "EfiRuntimeServicesCode",
81 "EfiRuntimeServicesData",
82 "EfiConventionalMemory",
84 "EfiACPIReclaimMemory",
87 "EfiMemoryMappedIOPortSpace",
89 "EfiPersistentMemory",
94 CHAR8
*mSubsystemString
[] = {
106 "EFI_BOOT_SERVICE_DRIVER",
107 "EFI_RUNTIME_DRIVER",
113 CHAR8
*mFileTypeString
[] = {
122 "COMBINED_PEIM_DRIVER",
125 "FIRMWARE_VOLUME_IMAGE",
130 #define PROFILE_NAME_STRING_LENGTH 64
131 CHAR8 mNameString
[PROFILE_NAME_STRING_LENGTH
+ 1];
134 // Profile summary information
136 #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE SIGNATURE_32 ('M','P','A','S')
137 #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION 0x0001
140 MEMORY_PROFILE_COMMON_HEADER Header
;
141 PHYSICAL_ADDRESS CallerAddress
;
142 MEMORY_PROFILE_ACTION Action
;
144 UINT32 AllocateCount
;
146 } MEMORY_PROFILE_ALLOC_SUMMARY_INFO
;
150 MEMORY_PROFILE_ALLOC_SUMMARY_INFO AllocSummaryInfo
;
152 } MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
;
156 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
157 LIST_ENTRY
*AllocSummaryInfoList
;
159 } MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
;
163 MEMORY_PROFILE_CONTEXT
*Context
;
164 LIST_ENTRY
*DriverSummaryInfoList
;
165 } MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
;
167 LIST_ENTRY mImageSummaryQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mImageSummaryQueue
);
168 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA mMemoryProfileContextSummary
;
171 Get the file name portion of the Pdb File Name.
173 The portion of the Pdb File Name between the last backslash and
174 either a following period or the end of the string is copied into
175 AsciiBuffer. The name is truncated, if necessary, to ensure that
176 AsciiBuffer is not overrun.
178 @param[in] PdbFileName Pdb file name.
179 @param[out] AsciiBuffer The resultant Ascii File Name.
183 GetShortPdbFileName (
184 IN CHAR8
*PdbFileName
,
185 OUT CHAR8
*AsciiBuffer
188 UINTN IndexPdb
; // Current work location within a Pdb string.
189 UINTN IndexBuffer
; // Current work location within a Buffer string.
193 ZeroMem (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1);
195 if (PdbFileName
== NULL
) {
196 AsciiStrnCpyS (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1, " ", 1);
199 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++);
200 for (IndexPdb
= 0; PdbFileName
[IndexPdb
] != 0; IndexPdb
++) {
201 if ((PdbFileName
[IndexPdb
] == '\\') || (PdbFileName
[IndexPdb
] == '/')) {
202 StartIndex
= IndexPdb
+ 1;
205 if (PdbFileName
[IndexPdb
] == '.') {
211 for (IndexPdb
= StartIndex
; IndexPdb
< EndIndex
; IndexPdb
++) {
212 AsciiBuffer
[IndexBuffer
] = PdbFileName
[IndexPdb
];
214 if (IndexBuffer
>= PROFILE_NAME_STRING_LENGTH
) {
215 AsciiBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
223 Get a human readable name for an image.
224 The following methods will be tried orderly:
229 @param[in] DriverInfo Pointer to memory profile driver info.
231 @return The resulting Ascii name string is stored in the mNameString global array.
235 GetDriverNameString (
236 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
244 // Method 1: Get the name string from image PDB
246 if (DriverInfo
->PdbStringOffset
!= 0) {
247 GetShortPdbFileName ((CHAR8
*) ((UINTN
) DriverInfo
+ DriverInfo
->PdbStringOffset
), mNameString
);
251 if (!IsZeroGuid (&DriverInfo
->FileName
)) {
253 // Try to get the image's FFS UI section by image GUID
257 Status
= GetSectionFromAnyFv (
258 &DriverInfo
->FileName
,
259 EFI_SECTION_USER_INTERFACE
,
261 (VOID
**) &NameString
,
264 if (!EFI_ERROR (Status
)) {
266 // Method 2: Get the name string from FFS UI section
268 if (StrLen (NameString
) > PROFILE_NAME_STRING_LENGTH
) {
269 NameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
271 UnicodeStrToAsciiStrS (NameString
, mNameString
, sizeof (mNameString
));
272 FreePool (NameString
);
278 // Method 3: Get the name string from image GUID
280 AsciiSPrint (mNameString
, sizeof (mNameString
), "%g", &DriverInfo
->FileName
);
285 Memory type to string.
287 @param[in] MemoryType Memory type.
289 @return Pointer to string.
293 ProfileMemoryTypeToStr (
294 IN EFI_MEMORY_TYPE MemoryType
299 if ((UINT32
) MemoryType
>= 0x80000000) {
301 // OS reserved memory type.
303 Index
= EfiMaxMemoryType
;
304 } else if ((UINT32
) MemoryType
>= 0x70000000) {
306 // OEM reserved memory type.
308 Index
= EfiMaxMemoryType
+ 1;
313 return mMemoryTypeString
[Index
];
319 @param[in] Action Profile action.
320 @param[in] UserDefinedActionString Pointer to user defined action string.
321 @param[in] IsForSmm TRUE - SMRAM profile.
322 FALSE - UEFI memory profile.
324 @return Pointer to string.
329 IN MEMORY_PROFILE_ACTION Action
,
330 IN CHAR8
*UserDefinedActionString
,
335 UINTN ActionStringCount
;
336 CHAR8
**ActionString
;
339 ActionString
= mSmmActionString
;
340 ActionStringCount
= ARRAY_SIZE (mSmmActionString
);
342 ActionString
= mActionString
;
343 ActionStringCount
= ARRAY_SIZE (mActionString
);
346 if ((UINTN
) (UINT32
) Action
< ActionStringCount
) {
347 return ActionString
[Action
];
349 for (Index
= 0; Index
< ARRAY_SIZE (mExtActionString
); Index
++) {
350 if (mExtActionString
[Index
].Action
== Action
) {
351 return mExtActionString
[Index
].String
;
354 if ((Action
& MEMORY_PROFILE_ACTION_USER_DEFINED_MASK
) != 0) {
355 if (UserDefinedActionString
!= NULL
) {
356 return UserDefinedActionString
;
358 AsciiSPrint (mUserDefinedActionString
, sizeof (mUserDefinedActionString
), "UserDefined-0x%08x", Action
);
359 return mUserDefinedActionString
;
362 return ActionString
[0];
366 Dump memory profile allocate information.
368 @param[in] DriverInfo Pointer to memory profile driver info.
369 @param[in] AllocIndex Memory profile alloc info index.
370 @param[in] AllocInfo Pointer to memory profile alloc info.
371 @param[in] IsForSmm TRUE - SMRAM profile.
372 FALSE - UEFI memory profile.
374 @return Pointer to next memory profile alloc info.
377 MEMORY_PROFILE_ALLOC_INFO
*
378 DumpMemoryProfileAllocInfo (
379 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
381 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
,
387 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
391 if (AllocInfo
->ActionStringOffset
!= 0) {
392 ActionString
= (CHAR8
*) ((UINTN
) AllocInfo
+ AllocInfo
->ActionStringOffset
);
397 Print (L
" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
);
398 Print (L
" Signature - 0x%08x\n", AllocInfo
->Header
.Signature
);
399 Print (L
" Length - 0x%04x\n", AllocInfo
->Header
.Length
);
400 Print (L
" Revision - 0x%04x\n", AllocInfo
->Header
.Revision
);
401 Print (L
" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, (UINTN
) (AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
402 Print (L
" SequenceId - 0x%08x\n", AllocInfo
->SequenceId
);
403 Print (L
" Action - 0x%08x (%a)\n", AllocInfo
->Action
, ProfileActionToStr (AllocInfo
->Action
, ActionString
, IsForSmm
));
404 Print (L
" MemoryType - 0x%08x (%a)\n", AllocInfo
->MemoryType
, ProfileMemoryTypeToStr (AllocInfo
->MemoryType
));
405 Print (L
" Buffer - 0x%016lx\n", AllocInfo
->Buffer
);
406 Print (L
" Size - 0x%016lx\n", AllocInfo
->Size
);
408 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
412 Dump memory profile driver information.
414 @param[in] DriverIndex Memory profile driver info index.
415 @param[in] DriverInfo Pointer to memory profile driver info.
416 @param[in] IsForSmm TRUE - SMRAM profile.
417 FALSE - UEFI memory profile.
419 @return Pointer to next memory profile driver info.
422 MEMORY_PROFILE_DRIVER_INFO
*
423 DumpMemoryProfileDriverInfo (
424 IN UINTN DriverIndex
,
425 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
430 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
434 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
437 Print (L
" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
);
438 Print (L
" Signature - 0x%08x\n", DriverInfo
->Header
.Signature
);
439 Print (L
" Length - 0x%04x\n", DriverInfo
->Header
.Length
);
440 Print (L
" Revision - 0x%04x\n", DriverInfo
->Header
.Revision
);
441 NameString
= GetDriverNameString (DriverInfo
);
442 Print (L
" FileName - %a\n", NameString
);
443 if (DriverInfo
->PdbStringOffset
!= 0) {
444 Print (L
" Pdb - %a\n", (CHAR8
*) ((UINTN
) DriverInfo
+ DriverInfo
->PdbStringOffset
));
446 Print (L
" ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
);
447 Print (L
" ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
);
448 Print (L
" EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
);
449 Print (L
" ImageSubsystem - 0x%04x (%a)\n", DriverInfo
->ImageSubsystem
, mSubsystemString
[(DriverInfo
->ImageSubsystem
< sizeof(mSubsystemString
)/sizeof(mSubsystemString
[0])) ? DriverInfo
->ImageSubsystem
: 0]);
450 Print (L
" FileType - 0x%02x (%a)\n", DriverInfo
->FileType
, mFileTypeString
[(DriverInfo
->FileType
< sizeof(mFileTypeString
)/sizeof(mFileTypeString
[0])) ? DriverInfo
->FileType
: 0]);
451 Print (L
" CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
);
452 Print (L
" PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
);
453 for (TypeIndex
= 0; TypeIndex
< sizeof (DriverInfo
->CurrentUsageByType
) / sizeof (DriverInfo
->CurrentUsageByType
[0]); TypeIndex
++) {
454 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
455 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
456 Print (L
" CurrentUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
457 Print (L
" PeakUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
460 Print (L
" AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
);
462 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
463 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
464 AllocInfo
= DumpMemoryProfileAllocInfo (DriverInfo
, AllocIndex
, AllocInfo
, IsForSmm
);
465 if (AllocInfo
== NULL
) {
469 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
473 Dump memory profile context information.
475 @param[in] Context Pointer to memory profile context.
476 @param[in] IsForSmm TRUE - SMRAM profile.
477 FALSE - UEFI memory profile.
479 @return Pointer to the end of memory profile context buffer.
483 DumpMemoryProfileContext (
484 IN MEMORY_PROFILE_CONTEXT
*Context
,
489 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
492 if (Context
->Header
.Signature
!= MEMORY_PROFILE_CONTEXT_SIGNATURE
) {
495 Print (L
"MEMORY_PROFILE_CONTEXT\n");
496 Print (L
" Signature - 0x%08x\n", Context
->Header
.Signature
);
497 Print (L
" Length - 0x%04x\n", Context
->Header
.Length
);
498 Print (L
" Revision - 0x%04x\n", Context
->Header
.Revision
);
499 Print (L
" CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
);
500 Print (L
" PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
);
501 for (TypeIndex
= 0; TypeIndex
< sizeof (Context
->CurrentTotalUsageByType
) / sizeof (Context
->CurrentTotalUsageByType
[0]); TypeIndex
++) {
502 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
503 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
504 Print (L
" CurrentTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
505 Print (L
" PeakTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
508 Print (L
" TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
);
509 Print (L
" ImageCount - 0x%08x\n", Context
->ImageCount
);
510 Print (L
" SequenceCount - 0x%08x\n", Context
->SequenceCount
);
512 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
513 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
514 DriverInfo
= DumpMemoryProfileDriverInfo (DriverIndex
, DriverInfo
, IsForSmm
);
515 if (DriverInfo
== NULL
) {
519 return (VOID
*) DriverInfo
;
523 Dump memory profile descriptor information.
525 @param[in] DescriptorIndex Memory profile descriptor index.
526 @param[in] Descriptor Pointer to memory profile descriptor.
528 @return Pointer to next memory profile descriptor.
531 MEMORY_PROFILE_DESCRIPTOR
*
532 DumpMemoryProfileDescriptor (
533 IN UINTN DescriptorIndex
,
534 IN MEMORY_PROFILE_DESCRIPTOR
*Descriptor
537 if (Descriptor
->Header
.Signature
!= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
) {
540 Print (L
" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex
);
541 Print (L
" Signature - 0x%08x\n", Descriptor
->Header
.Signature
);
542 Print (L
" Length - 0x%04x\n", Descriptor
->Header
.Length
);
543 Print (L
" Revision - 0x%04x\n", Descriptor
->Header
.Revision
);
544 Print (L
" Address - 0x%016lx\n", Descriptor
->Address
);
545 Print (L
" Size - 0x%016lx\n", Descriptor
->Size
);
547 return (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) Descriptor
+ Descriptor
->Header
.Length
);
551 Dump memory profile free memory information.
553 @param[in] FreeMemory Pointer to memory profile free memory.
555 @return Pointer to the end of memory profile free memory buffer.
559 DumpMemoryProfileFreeMemory (
560 IN MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
563 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
564 UINTN DescriptorIndex
;
566 if (FreeMemory
->Header
.Signature
!= MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
) {
569 Print (L
"MEMORY_PROFILE_FREE_MEMORY\n");
570 Print (L
" Signature - 0x%08x\n", FreeMemory
->Header
.Signature
);
571 Print (L
" Length - 0x%04x\n", FreeMemory
->Header
.Length
);
572 Print (L
" Revision - 0x%04x\n", FreeMemory
->Header
.Revision
);
573 Print (L
" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory
->TotalFreeMemoryPages
);
574 Print (L
" FreeMemoryEntryCount - 0x%08x\n", FreeMemory
->FreeMemoryEntryCount
);
576 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) FreeMemory
+ FreeMemory
->Header
.Length
);
577 for (DescriptorIndex
= 0; DescriptorIndex
< FreeMemory
->FreeMemoryEntryCount
; DescriptorIndex
++) {
578 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
579 if (Descriptor
== NULL
) {
584 return (VOID
*) Descriptor
;
588 Dump memory profile memory range information.
590 @param[in] MemoryRange Pointer to memory profile memory range.
592 @return Pointer to the end of memory profile memory range buffer.
596 DumpMemoryProfileMemoryRange (
597 IN MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
600 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
601 UINTN DescriptorIndex
;
603 if (MemoryRange
->Header
.Signature
!= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
) {
606 Print (L
"MEMORY_PROFILE_MEMORY_RANGE\n");
607 Print (L
" Signature - 0x%08x\n", MemoryRange
->Header
.Signature
);
608 Print (L
" Length - 0x%04x\n", MemoryRange
->Header
.Length
);
609 Print (L
" Revision - 0x%04x\n", MemoryRange
->Header
.Revision
);
610 Print (L
" MemoryRangeCount - 0x%08x\n", MemoryRange
->MemoryRangeCount
);
612 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) MemoryRange
+ MemoryRange
->Header
.Length
);
613 for (DescriptorIndex
= 0; DescriptorIndex
< MemoryRange
->MemoryRangeCount
; DescriptorIndex
++) {
614 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
615 if (Descriptor
== NULL
) {
620 return (VOID
*) Descriptor
;
624 Scan memory profile by Signature.
626 @param[in] ProfileBuffer Memory profile base address.
627 @param[in] ProfileSize Memory profile size.
628 @param[in] Signature Signature.
630 @return Pointer to the structure with the signature.
634 ScanMemoryProfileBySignature (
635 IN PHYSICAL_ADDRESS ProfileBuffer
,
636 IN UINT64 ProfileSize
,
640 MEMORY_PROFILE_COMMON_HEADER
*CommonHeader
;
643 ProfileEnd
= (UINTN
) (ProfileBuffer
+ ProfileSize
);
644 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) (UINTN
) ProfileBuffer
;
645 while ((UINTN
) CommonHeader
< ProfileEnd
) {
646 if (CommonHeader
->Signature
== Signature
) {
650 return (VOID
*) CommonHeader
;
652 if (CommonHeader
->Length
== 0) {
656 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) ((UINTN
) CommonHeader
+ CommonHeader
->Length
);
663 Dump memory profile information.
665 @param[in] ProfileBuffer Memory profile base address.
666 @param[in] ProfileSize Memory profile size.
667 @param[in] IsForSmm TRUE - SMRAM profile.
668 FALSE - UEFI memory profile.
673 IN PHYSICAL_ADDRESS ProfileBuffer
,
674 IN UINT64 ProfileSize
,
678 MEMORY_PROFILE_CONTEXT
*Context
;
679 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
680 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
682 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
683 if (Context
!= NULL
) {
684 DumpMemoryProfileContext (Context
, IsForSmm
);
687 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
);
688 if (FreeMemory
!= NULL
) {
689 DumpMemoryProfileFreeMemory (FreeMemory
);
692 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
);
693 if (MemoryRange
!= NULL
) {
694 DumpMemoryProfileMemoryRange (MemoryRange
);
699 Get Allocate summary information structure by caller address.
701 @param[in] CallerAddress Caller address.
702 @param[in] DriverSummaryInfoData Driver summary information data structure.
704 @return Allocate summary information structure by caller address.
707 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*
708 GetAllocSummaryInfoByCallerAddress (
709 IN PHYSICAL_ADDRESS CallerAddress
,
710 IN MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
713 LIST_ENTRY
*AllocSummaryInfoList
;
714 LIST_ENTRY
*AllocSummaryLink
;
715 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
716 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
718 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
720 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
721 AllocSummaryLink
!= AllocSummaryInfoList
;
722 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
) {
723 AllocSummaryInfoData
= CR (
725 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
727 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
729 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
730 if (AllocSummaryInfo
->CallerAddress
== CallerAddress
) {
731 return AllocSummaryInfoData
;
738 Create Allocate summary information structure and
739 link to Driver summary information data structure.
741 @param[in, out] DriverSummaryInfoData Driver summary information data structure.
742 @param[in] AllocInfo Pointer to memory profile alloc info.
744 @return Pointer to next memory profile alloc info.
747 MEMORY_PROFILE_ALLOC_INFO
*
748 CreateAllocSummaryInfo (
749 IN OUT MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
,
750 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
753 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
754 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
756 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
760 AllocSummaryInfoData
= GetAllocSummaryInfoByCallerAddress (AllocInfo
->CallerAddress
, DriverSummaryInfoData
);
761 if (AllocSummaryInfoData
== NULL
) {
762 AllocSummaryInfoData
= AllocatePool (sizeof (*AllocSummaryInfoData
));
763 if (AllocSummaryInfoData
== NULL
) {
767 AllocSummaryInfoData
->Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
768 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
769 AllocSummaryInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
770 AllocSummaryInfo
->Header
.Length
= sizeof (*AllocSummaryInfo
);
771 AllocSummaryInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION
;
772 AllocSummaryInfo
->CallerAddress
= AllocInfo
->CallerAddress
;
773 AllocSummaryInfo
->Action
= AllocInfo
->Action
;
774 if (AllocInfo
->ActionStringOffset
!= 0) {
775 AllocSummaryInfo
->ActionString
= (CHAR8
*) ((UINTN
) AllocInfo
+ AllocInfo
->ActionStringOffset
);
777 AllocSummaryInfo
->ActionString
= NULL
;
779 AllocSummaryInfo
->AllocateCount
= 0;
780 AllocSummaryInfo
->TotalSize
= 0;
781 InsertTailList (DriverSummaryInfoData
->AllocSummaryInfoList
, &AllocSummaryInfoData
->Link
);
783 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
784 AllocSummaryInfo
->AllocateCount
++;
785 AllocSummaryInfo
->TotalSize
+= AllocInfo
->Size
;
787 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
791 Create Driver summary information structure and
792 link to Context summary information data structure.
794 @param[in, out] ContextSummaryData Context summary information data structure.
795 @param[in] DriverInfo Pointer to memory profile driver info.
797 @return Pointer to next memory profile driver info.
800 MEMORY_PROFILE_DRIVER_INFO
*
801 CreateDriverSummaryInfo (
802 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
803 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
806 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
807 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
810 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
814 DriverSummaryInfoData
= AllocatePool (sizeof (*DriverSummaryInfoData
) + sizeof (LIST_ENTRY
));
815 if (DriverSummaryInfoData
== NULL
) {
818 DriverSummaryInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
819 DriverSummaryInfoData
->DriverInfo
= DriverInfo
;
820 DriverSummaryInfoData
->AllocSummaryInfoList
= (LIST_ENTRY
*) (DriverSummaryInfoData
+ 1);
821 InitializeListHead (DriverSummaryInfoData
->AllocSummaryInfoList
);
822 InsertTailList (ContextSummaryData
->DriverSummaryInfoList
, &DriverSummaryInfoData
->Link
);
824 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
825 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
826 AllocInfo
= CreateAllocSummaryInfo (DriverSummaryInfoData
, AllocInfo
);
827 if (AllocInfo
== NULL
) {
831 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
835 Create Context summary information structure.
837 @param[in] ProfileBuffer Memory profile base address.
838 @param[in] ProfileSize Memory profile size.
840 @return Context summary information structure.
843 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*
844 CreateContextSummaryData (
845 IN PHYSICAL_ADDRESS ProfileBuffer
,
846 IN UINT64 ProfileSize
849 MEMORY_PROFILE_CONTEXT
*Context
;
850 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
853 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
854 if (Context
== NULL
) {
858 mMemoryProfileContextSummary
.Signature
= MEMORY_PROFILE_CONTEXT_SIGNATURE
;
859 mMemoryProfileContextSummary
.Context
= Context
;
860 mMemoryProfileContextSummary
.DriverSummaryInfoList
= &mImageSummaryQueue
;
862 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
863 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
864 DriverInfo
= CreateDriverSummaryInfo (&mMemoryProfileContextSummary
, DriverInfo
);
865 if (DriverInfo
== NULL
) {
870 return &mMemoryProfileContextSummary
;
874 Dump Context summary information.
876 @param[in] ContextSummaryData Context summary information data.
877 @param[in] IsForSmm TRUE - SMRAM profile.
878 FALSE - UEFI memory profile.
882 DumpContextSummaryData (
883 IN MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
887 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
888 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
889 LIST_ENTRY
*DriverSummaryInfoList
;
890 LIST_ENTRY
*DriverSummaryLink
;
891 LIST_ENTRY
*AllocSummaryInfoList
;
892 LIST_ENTRY
*AllocSummaryLink
;
893 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
894 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
897 if (ContextSummaryData
== NULL
) {
901 Print (L
"\nSummary Data:\n");
903 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
904 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
905 DriverSummaryLink
!= DriverSummaryInfoList
;
906 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
) {
907 DriverSummaryInfoData
= CR (
909 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
911 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
913 DriverInfo
= DriverSummaryInfoData
->DriverInfo
;
915 NameString
= GetDriverNameString (DriverInfo
);
916 Print (L
"\nDriver - %a (Usage - 0x%08x)", NameString
, DriverInfo
->CurrentUsage
);
917 if (DriverInfo
->CurrentUsage
== 0) {
922 if (DriverInfo
->PdbStringOffset
!= 0) {
923 Print (L
" (Pdb - %a)\n", (CHAR8
*) ((UINTN
) DriverInfo
+ DriverInfo
->PdbStringOffset
));
927 Print (L
"Caller List:\n");
928 Print(L
" Count Size RVA Action\n");
929 Print(L
"========== ================== ================== (================================)\n");
930 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
931 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
932 AllocSummaryLink
!= AllocSummaryInfoList
;
933 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
) {
934 AllocSummaryInfoData
= CR (
936 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
938 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
940 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
942 Print(L
"0x%08x 0x%016lx <== 0x%016lx",
943 AllocSummaryInfo
->AllocateCount
,
944 AllocSummaryInfo
->TotalSize
,
945 AllocSummaryInfo
->CallerAddress
- DriverInfo
->ImageBase
947 Print (L
" (%a)\n", ProfileActionToStr (AllocSummaryInfo
->Action
, AllocSummaryInfo
->ActionString
, IsForSmm
));
954 Destroy Context summary information.
956 @param[in, out] ContextSummaryData Context summary information data.
960 DestroyContextSummaryData (
961 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
964 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
965 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
966 LIST_ENTRY
*DriverSummaryInfoList
;
967 LIST_ENTRY
*DriverSummaryLink
;
968 LIST_ENTRY
*AllocSummaryInfoList
;
969 LIST_ENTRY
*AllocSummaryLink
;
971 if (ContextSummaryData
== NULL
) {
975 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
976 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
977 DriverSummaryLink
!= DriverSummaryInfoList
;
979 DriverSummaryInfoData
= CR (
981 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
983 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
985 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
;
987 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
988 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
989 AllocSummaryLink
!= AllocSummaryInfoList
;
991 AllocSummaryInfoData
= CR (
993 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
995 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
997 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
;
999 RemoveEntryList (&AllocSummaryInfoData
->Link
);
1000 FreePool (AllocSummaryInfoData
);
1003 RemoveEntryList (&DriverSummaryInfoData
->Link
);
1004 FreePool (DriverSummaryInfoData
);
1010 Get and dump UEFI memory profile data.
1012 @return EFI_SUCCESS Get the memory profile data successfully.
1013 @return other Fail to get the memory profile data.
1017 GetUefiMemoryProfileData (
1022 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
1025 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1026 BOOLEAN RecordingState
;
1028 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
1029 if (EFI_ERROR (Status
)) {
1030 DEBUG ((EFI_D_ERROR
, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status
));
1035 // Set recording state if needed.
1037 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1038 Status
= ProfileProtocol
->GetRecordingState (ProfileProtocol
, &RecordingState
);
1039 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1040 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_DISABLE
);
1045 Status
= ProfileProtocol
->GetData (
1050 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1051 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1055 Data
= AllocateZeroPool ((UINTN
) Size
);
1057 Status
= EFI_OUT_OF_RESOURCES
;
1058 Print (L
"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size
, Status
);
1062 Status
= ProfileProtocol
->GetData (
1067 if (EFI_ERROR (Status
)) {
1068 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1073 Print (L
"UefiMemoryProfileSize - 0x%x\n", Size
);
1074 Print (L
"======= UefiMemoryProfile begin =======\n");
1075 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
, FALSE
);
1078 // Dump summary information
1080 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
);
1081 if (MemoryProfileContextSummaryData
!= NULL
) {
1082 DumpContextSummaryData (MemoryProfileContextSummaryData
, FALSE
);
1083 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1086 Print (L
"======= UefiMemoryProfile end =======\n\n\n");
1094 // Restore recording state if needed.
1096 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1097 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_ENABLE
);
1104 Get and dump SMRAM profile data.
1106 @return EFI_SUCCESS Get the SMRAM profile data successfully.
1107 @return other Fail to get the SMRAM profile data.
1111 GetSmramProfileData (
1118 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
1119 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*CommGetProfileInfo
;
1120 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*CommGetProfileData
;
1121 SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*CommRecordingState
;
1123 VOID
*ProfileBuffer
;
1124 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
1125 UINTN MinimalSizeNeeded
;
1126 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
1128 EFI_MEMORY_DESCRIPTOR
*Entry
;
1132 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1133 BOOLEAN RecordingState
;
1135 ProfileBuffer
= NULL
;
1137 Status
= gBS
->LocateProtocol (&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**) &SmmCommunication
);
1138 if (EFI_ERROR (Status
)) {
1139 DEBUG ((EFI_D_ERROR
, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status
));
1143 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
1145 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
),
1146 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
),
1147 sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
)));
1148 MinimalSizeNeeded
+= MAX (sizeof (MEMORY_PROFILE_CONTEXT
),
1149 MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO
),
1150 MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO
),
1151 MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR
),
1152 MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY
),
1153 sizeof (MEMORY_PROFILE_MEMORY_RANGE
))))));
1155 Status
= EfiGetSystemConfigurationTable (
1156 &gEdkiiPiSmmCommunicationRegionTableGuid
,
1157 (VOID
**) &PiSmmCommunicationRegionTable
1159 if (EFI_ERROR (Status
)) {
1160 DEBUG ((EFI_D_ERROR
, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status
));
1163 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
1164 Entry
= (EFI_MEMORY_DESCRIPTOR
*) (PiSmmCommunicationRegionTable
+ 1);
1166 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
1167 if (Entry
->Type
== EfiConventionalMemory
) {
1168 Size
= EFI_PAGES_TO_SIZE ((UINTN
) Entry
->NumberOfPages
);
1169 if (Size
>= MinimalSizeNeeded
) {
1173 Entry
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
1175 ASSERT (Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
);
1176 CommBuffer
= (UINT8
*) (UINTN
) Entry
->PhysicalStart
;
1179 // Set recording state if needed.
1181 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1183 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1184 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1185 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1187 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1188 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE
;
1189 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1190 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1191 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1193 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1194 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1195 if (EFI_ERROR (Status
)) {
1196 DEBUG ((EFI_D_ERROR
, "SmramProfile: SmmCommunication - %r\n", Status
));
1200 if (CommRecordingState
->Header
.ReturnStatus
!= 0) {
1201 Print (L
"SmramProfile: GetRecordingState - 0x%0x\n", CommRecordingState
->Header
.ReturnStatus
);
1204 RecordingState
= CommRecordingState
->RecordingState
;
1205 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1206 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1207 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1208 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1210 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1211 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1212 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1213 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1214 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1216 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1217 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1223 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1224 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1225 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
);
1227 CommGetProfileInfo
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1228 CommGetProfileInfo
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
;
1229 CommGetProfileInfo
->Header
.DataLength
= sizeof (*CommGetProfileInfo
);
1230 CommGetProfileInfo
->Header
.ReturnStatus
= (UINT64
)-1;
1231 CommGetProfileInfo
->ProfileSize
= 0;
1233 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1234 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1235 ASSERT_EFI_ERROR (Status
);
1237 if (CommGetProfileInfo
->Header
.ReturnStatus
!= 0) {
1238 Status
= EFI_SUCCESS
;
1239 Print (L
"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo
->Header
.ReturnStatus
);
1243 ProfileSize
= (UINTN
) CommGetProfileInfo
->ProfileSize
;
1248 ProfileBuffer
= AllocateZeroPool (ProfileSize
);
1249 if (ProfileBuffer
== NULL
) {
1250 Status
= EFI_OUT_OF_RESOURCES
;
1251 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize
, Status
);
1255 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1256 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof(gEdkiiMemoryProfileGuid
));
1257 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
);
1259 CommGetProfileData
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1260 CommGetProfileData
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET
;
1261 CommGetProfileData
->Header
.DataLength
= sizeof (*CommGetProfileData
);
1262 CommGetProfileData
->Header
.ReturnStatus
= (UINT64
)-1;
1264 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1265 Buffer
= (UINT8
*) CommHeader
+ CommSize
;
1268 CommGetProfileData
->ProfileBuffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
1269 CommGetProfileData
->ProfileOffset
= 0;
1270 while (CommGetProfileData
->ProfileOffset
< ProfileSize
) {
1271 Offset
= (UINTN
) CommGetProfileData
->ProfileOffset
;
1272 if (Size
<= (ProfileSize
- CommGetProfileData
->ProfileOffset
)) {
1273 CommGetProfileData
->ProfileSize
= (UINT64
) Size
;
1275 CommGetProfileData
->ProfileSize
= (UINT64
) (ProfileSize
- CommGetProfileData
->ProfileOffset
);
1277 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1278 ASSERT_EFI_ERROR (Status
);
1280 if (CommGetProfileData
->Header
.ReturnStatus
!= 0) {
1281 Status
= EFI_SUCCESS
;
1282 Print (L
"GetProfileData - 0x%x\n", CommGetProfileData
->Header
.ReturnStatus
);
1285 CopyMem ((UINT8
*) ProfileBuffer
+ Offset
, (VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
, (UINTN
) CommGetProfileData
->ProfileSize
);
1289 Print (L
"SmramProfileSize - 0x%x\n", ProfileSize
);
1290 Print (L
"======= SmramProfile begin =======\n");
1291 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) ProfileBuffer
, ProfileSize
, TRUE
);
1294 // Dump summary information
1296 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
) (UINTN
) ProfileBuffer
, ProfileSize
);
1297 if (MemoryProfileContextSummaryData
!= NULL
) {
1298 DumpContextSummaryData (MemoryProfileContextSummaryData
, TRUE
);
1299 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1302 Print (L
"======= SmramProfile end =======\n\n\n");
1305 if (ProfileBuffer
!= NULL
) {
1306 FreePool (ProfileBuffer
);
1310 // Restore recording state if needed.
1312 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1313 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1314 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1315 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1317 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1318 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1319 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1320 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1321 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_ENABLE
;
1323 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1324 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1331 The user Entry Point for Application. The user code starts with this function
1332 as the real entry point for the image goes into a library that calls this function.
1334 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1335 @param[in] SystemTable A pointer to the EFI System Table.
1337 @retval EFI_SUCCESS The entry point is executed successfully.
1338 @retval other Some error occurs when executing this entry point.
1344 IN EFI_HANDLE ImageHandle
,
1345 IN EFI_SYSTEM_TABLE
*SystemTable
1350 Status
= GetUefiMemoryProfileData ();
1351 if (EFI_ERROR (Status
)) {
1352 DEBUG ((EFI_D_ERROR
, "GetUefiMemoryProfileData - %r\n", Status
));
1355 Status
= GetSmramProfileData ();
1356 if (EFI_ERROR (Status
)) {
1357 DEBUG ((EFI_D_ERROR
, "GetSmramProfileData - %r\n", Status
));