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
++) {
202 for (IndexPdb
= 0; PdbFileName
[IndexPdb
] != 0; IndexPdb
++) {
203 if ((PdbFileName
[IndexPdb
] == '\\') || (PdbFileName
[IndexPdb
] == '/')) {
204 StartIndex
= IndexPdb
+ 1;
207 if (PdbFileName
[IndexPdb
] == '.') {
213 for (IndexPdb
= StartIndex
; IndexPdb
< EndIndex
; IndexPdb
++) {
214 AsciiBuffer
[IndexBuffer
] = PdbFileName
[IndexPdb
];
216 if (IndexBuffer
>= PROFILE_NAME_STRING_LENGTH
) {
217 AsciiBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
225 Get a human readable name for an image.
226 The following methods will be tried orderly:
231 @param[in] DriverInfo Pointer to memory profile driver info.
233 @return The resulting Ascii name string is stored in the mNameString global array.
237 GetDriverNameString (
238 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
246 // Method 1: Get the name string from image PDB
248 if (DriverInfo
->PdbStringOffset
!= 0) {
249 GetShortPdbFileName ((CHAR8
*)((UINTN
)DriverInfo
+ DriverInfo
->PdbStringOffset
), mNameString
);
253 if (!IsZeroGuid (&DriverInfo
->FileName
)) {
255 // Try to get the image's FFS UI section by image GUID
259 Status
= GetSectionFromAnyFv (
260 &DriverInfo
->FileName
,
261 EFI_SECTION_USER_INTERFACE
,
263 (VOID
**)&NameString
,
266 if (!EFI_ERROR (Status
)) {
268 // Method 2: Get the name string from FFS UI section
270 if (StrLen (NameString
) > PROFILE_NAME_STRING_LENGTH
) {
271 NameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
274 UnicodeStrToAsciiStrS (NameString
, mNameString
, sizeof (mNameString
));
275 FreePool (NameString
);
281 // Method 3: Get the name string from image GUID
283 AsciiSPrint (mNameString
, sizeof (mNameString
), "%g", &DriverInfo
->FileName
);
288 Memory type to string.
290 @param[in] MemoryType Memory type.
292 @return Pointer to string.
296 ProfileMemoryTypeToStr (
297 IN EFI_MEMORY_TYPE MemoryType
302 if ((UINT32
)MemoryType
>= 0x80000000) {
304 // OS reserved memory type.
306 Index
= EfiMaxMemoryType
;
307 } else if ((UINT32
)MemoryType
>= 0x70000000) {
309 // OEM reserved memory type.
311 Index
= EfiMaxMemoryType
+ 1;
316 return mMemoryTypeString
[Index
];
322 @param[in] Action Profile action.
323 @param[in] UserDefinedActionString Pointer to user defined action string.
324 @param[in] IsForSmm TRUE - SMRAM profile.
325 FALSE - UEFI memory profile.
327 @return Pointer to string.
332 IN MEMORY_PROFILE_ACTION Action
,
333 IN CHAR8
*UserDefinedActionString
,
338 UINTN ActionStringCount
;
339 CHAR8
**ActionString
;
342 ActionString
= mSmmActionString
;
343 ActionStringCount
= ARRAY_SIZE (mSmmActionString
);
345 ActionString
= mActionString
;
346 ActionStringCount
= ARRAY_SIZE (mActionString
);
349 if ((UINTN
)(UINT32
)Action
< ActionStringCount
) {
350 return ActionString
[Action
];
353 for (Index
= 0; Index
< ARRAY_SIZE (mExtActionString
); Index
++) {
354 if (mExtActionString
[Index
].Action
== Action
) {
355 return mExtActionString
[Index
].String
;
359 if ((Action
& MEMORY_PROFILE_ACTION_USER_DEFINED_MASK
) != 0) {
360 if (UserDefinedActionString
!= NULL
) {
361 return UserDefinedActionString
;
364 AsciiSPrint (mUserDefinedActionString
, sizeof (mUserDefinedActionString
), "UserDefined-0x%08x", Action
);
365 return mUserDefinedActionString
;
368 return ActionString
[0];
372 Dump memory profile allocate information.
374 @param[in] DriverInfo Pointer to memory profile driver info.
375 @param[in] AllocIndex Memory profile alloc info index.
376 @param[in] AllocInfo Pointer to memory profile alloc info.
377 @param[in] IsForSmm TRUE - SMRAM profile.
378 FALSE - UEFI memory profile.
380 @return Pointer to next memory profile alloc info.
383 MEMORY_PROFILE_ALLOC_INFO
*
384 DumpMemoryProfileAllocInfo (
385 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
387 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
,
393 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
397 if (AllocInfo
->ActionStringOffset
!= 0) {
398 ActionString
= (CHAR8
*)((UINTN
)AllocInfo
+ AllocInfo
->ActionStringOffset
);
403 Print (L
" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
);
404 Print (L
" Signature - 0x%08x\n", AllocInfo
->Header
.Signature
);
405 Print (L
" Length - 0x%04x\n", AllocInfo
->Header
.Length
);
406 Print (L
" Revision - 0x%04x\n", AllocInfo
->Header
.Revision
);
407 Print (L
" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, (UINTN
)(AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
408 Print (L
" SequenceId - 0x%08x\n", AllocInfo
->SequenceId
);
409 Print (L
" Action - 0x%08x (%a)\n", AllocInfo
->Action
, ProfileActionToStr (AllocInfo
->Action
, ActionString
, IsForSmm
));
410 Print (L
" MemoryType - 0x%08x (%a)\n", AllocInfo
->MemoryType
, ProfileMemoryTypeToStr (AllocInfo
->MemoryType
));
411 Print (L
" Buffer - 0x%016lx\n", AllocInfo
->Buffer
);
412 Print (L
" Size - 0x%016lx\n", AllocInfo
->Size
);
414 return (MEMORY_PROFILE_ALLOC_INFO
*)((UINTN
)AllocInfo
+ AllocInfo
->Header
.Length
);
418 Dump memory profile driver information.
420 @param[in] DriverIndex Memory profile driver info index.
421 @param[in] DriverInfo Pointer to memory profile driver info.
422 @param[in] IsForSmm TRUE - SMRAM profile.
423 FALSE - UEFI memory profile.
425 @return Pointer to next memory profile driver info.
428 MEMORY_PROFILE_DRIVER_INFO
*
429 DumpMemoryProfileDriverInfo (
430 IN UINTN DriverIndex
,
431 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
436 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
440 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
444 Print (L
" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
);
445 Print (L
" Signature - 0x%08x\n", DriverInfo
->Header
.Signature
);
446 Print (L
" Length - 0x%04x\n", DriverInfo
->Header
.Length
);
447 Print (L
" Revision - 0x%04x\n", DriverInfo
->Header
.Revision
);
448 NameString
= GetDriverNameString (DriverInfo
);
449 Print (L
" FileName - %a\n", NameString
);
450 if (DriverInfo
->PdbStringOffset
!= 0) {
451 Print (L
" Pdb - %a\n", (CHAR8
*)((UINTN
)DriverInfo
+ DriverInfo
->PdbStringOffset
));
454 Print (L
" ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
);
455 Print (L
" ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
);
456 Print (L
" EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
);
457 Print (L
" ImageSubsystem - 0x%04x (%a)\n", DriverInfo
->ImageSubsystem
, mSubsystemString
[(DriverInfo
->ImageSubsystem
< sizeof (mSubsystemString
)/sizeof (mSubsystemString
[0])) ? DriverInfo
->ImageSubsystem
: 0]);
458 Print (L
" FileType - 0x%02x (%a)\n", DriverInfo
->FileType
, mFileTypeString
[(DriverInfo
->FileType
< sizeof (mFileTypeString
)/sizeof (mFileTypeString
[0])) ? DriverInfo
->FileType
: 0]);
459 Print (L
" CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
);
460 Print (L
" PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
);
461 for (TypeIndex
= 0; TypeIndex
< sizeof (DriverInfo
->CurrentUsageByType
) / sizeof (DriverInfo
->CurrentUsageByType
[0]); TypeIndex
++) {
462 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
463 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0))
465 Print (L
" CurrentUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
466 Print (L
" PeakUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
470 Print (L
" AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
);
472 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*)((UINTN
)DriverInfo
+ DriverInfo
->Header
.Length
);
473 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
474 AllocInfo
= DumpMemoryProfileAllocInfo (DriverInfo
, AllocIndex
, AllocInfo
, IsForSmm
);
475 if (AllocInfo
== NULL
) {
480 return (MEMORY_PROFILE_DRIVER_INFO
*)AllocInfo
;
484 Dump memory profile context information.
486 @param[in] Context Pointer to memory profile context.
487 @param[in] IsForSmm TRUE - SMRAM profile.
488 FALSE - UEFI memory profile.
490 @return Pointer to the end of memory profile context buffer.
494 DumpMemoryProfileContext (
495 IN MEMORY_PROFILE_CONTEXT
*Context
,
500 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
503 if (Context
->Header
.Signature
!= MEMORY_PROFILE_CONTEXT_SIGNATURE
) {
507 Print (L
"MEMORY_PROFILE_CONTEXT\n");
508 Print (L
" Signature - 0x%08x\n", Context
->Header
.Signature
);
509 Print (L
" Length - 0x%04x\n", Context
->Header
.Length
);
510 Print (L
" Revision - 0x%04x\n", Context
->Header
.Revision
);
511 Print (L
" CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
);
512 Print (L
" PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
);
513 for (TypeIndex
= 0; TypeIndex
< sizeof (Context
->CurrentTotalUsageByType
) / sizeof (Context
->CurrentTotalUsageByType
[0]); TypeIndex
++) {
514 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
515 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0))
517 Print (L
" CurrentTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
518 Print (L
" PeakTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
522 Print (L
" TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
);
523 Print (L
" ImageCount - 0x%08x\n", Context
->ImageCount
);
524 Print (L
" SequenceCount - 0x%08x\n", Context
->SequenceCount
);
526 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*)((UINTN
)Context
+ Context
->Header
.Length
);
527 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
528 DriverInfo
= DumpMemoryProfileDriverInfo (DriverIndex
, DriverInfo
, IsForSmm
);
529 if (DriverInfo
== NULL
) {
534 return (VOID
*)DriverInfo
;
538 Dump memory profile descriptor information.
540 @param[in] DescriptorIndex Memory profile descriptor index.
541 @param[in] Descriptor Pointer to memory profile descriptor.
543 @return Pointer to next memory profile descriptor.
546 MEMORY_PROFILE_DESCRIPTOR
*
547 DumpMemoryProfileDescriptor (
548 IN UINTN DescriptorIndex
,
549 IN MEMORY_PROFILE_DESCRIPTOR
*Descriptor
552 if (Descriptor
->Header
.Signature
!= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
) {
556 Print (L
" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex
);
557 Print (L
" Signature - 0x%08x\n", Descriptor
->Header
.Signature
);
558 Print (L
" Length - 0x%04x\n", Descriptor
->Header
.Length
);
559 Print (L
" Revision - 0x%04x\n", Descriptor
->Header
.Revision
);
560 Print (L
" Address - 0x%016lx\n", Descriptor
->Address
);
561 Print (L
" Size - 0x%016lx\n", Descriptor
->Size
);
563 return (MEMORY_PROFILE_DESCRIPTOR
*)((UINTN
)Descriptor
+ Descriptor
->Header
.Length
);
567 Dump memory profile free memory information.
569 @param[in] FreeMemory Pointer to memory profile free memory.
571 @return Pointer to the end of memory profile free memory buffer.
575 DumpMemoryProfileFreeMemory (
576 IN MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
579 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
580 UINTN DescriptorIndex
;
582 if (FreeMemory
->Header
.Signature
!= MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
) {
586 Print (L
"MEMORY_PROFILE_FREE_MEMORY\n");
587 Print (L
" Signature - 0x%08x\n", FreeMemory
->Header
.Signature
);
588 Print (L
" Length - 0x%04x\n", FreeMemory
->Header
.Length
);
589 Print (L
" Revision - 0x%04x\n", FreeMemory
->Header
.Revision
);
590 Print (L
" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory
->TotalFreeMemoryPages
);
591 Print (L
" FreeMemoryEntryCount - 0x%08x\n", FreeMemory
->FreeMemoryEntryCount
);
593 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*)((UINTN
)FreeMemory
+ FreeMemory
->Header
.Length
);
594 for (DescriptorIndex
= 0; DescriptorIndex
< FreeMemory
->FreeMemoryEntryCount
; DescriptorIndex
++) {
595 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
596 if (Descriptor
== NULL
) {
601 return (VOID
*)Descriptor
;
605 Dump memory profile memory range information.
607 @param[in] MemoryRange Pointer to memory profile memory range.
609 @return Pointer to the end of memory profile memory range buffer.
613 DumpMemoryProfileMemoryRange (
614 IN MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
617 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
618 UINTN DescriptorIndex
;
620 if (MemoryRange
->Header
.Signature
!= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
) {
624 Print (L
"MEMORY_PROFILE_MEMORY_RANGE\n");
625 Print (L
" Signature - 0x%08x\n", MemoryRange
->Header
.Signature
);
626 Print (L
" Length - 0x%04x\n", MemoryRange
->Header
.Length
);
627 Print (L
" Revision - 0x%04x\n", MemoryRange
->Header
.Revision
);
628 Print (L
" MemoryRangeCount - 0x%08x\n", MemoryRange
->MemoryRangeCount
);
630 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*)((UINTN
)MemoryRange
+ MemoryRange
->Header
.Length
);
631 for (DescriptorIndex
= 0; DescriptorIndex
< MemoryRange
->MemoryRangeCount
; DescriptorIndex
++) {
632 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
633 if (Descriptor
== NULL
) {
638 return (VOID
*)Descriptor
;
642 Scan memory profile by Signature.
644 @param[in] ProfileBuffer Memory profile base address.
645 @param[in] ProfileSize Memory profile size.
646 @param[in] Signature Signature.
648 @return Pointer to the structure with the signature.
652 ScanMemoryProfileBySignature (
653 IN PHYSICAL_ADDRESS ProfileBuffer
,
654 IN UINT64 ProfileSize
,
658 MEMORY_PROFILE_COMMON_HEADER
*CommonHeader
;
661 ProfileEnd
= (UINTN
)(ProfileBuffer
+ ProfileSize
);
662 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*)(UINTN
)ProfileBuffer
;
663 while ((UINTN
)CommonHeader
< ProfileEnd
) {
664 if (CommonHeader
->Signature
== Signature
) {
668 return (VOID
*)CommonHeader
;
671 if (CommonHeader
->Length
== 0) {
676 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*)((UINTN
)CommonHeader
+ CommonHeader
->Length
);
683 Dump memory profile information.
685 @param[in] ProfileBuffer Memory profile base address.
686 @param[in] ProfileSize Memory profile size.
687 @param[in] IsForSmm TRUE - SMRAM profile.
688 FALSE - UEFI memory profile.
693 IN PHYSICAL_ADDRESS ProfileBuffer
,
694 IN UINT64 ProfileSize
,
698 MEMORY_PROFILE_CONTEXT
*Context
;
699 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
700 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
702 Context
= (MEMORY_PROFILE_CONTEXT
*)ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
703 if (Context
!= NULL
) {
704 DumpMemoryProfileContext (Context
, IsForSmm
);
707 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*)ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
);
708 if (FreeMemory
!= NULL
) {
709 DumpMemoryProfileFreeMemory (FreeMemory
);
712 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*)ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
);
713 if (MemoryRange
!= NULL
) {
714 DumpMemoryProfileMemoryRange (MemoryRange
);
719 Get Allocate summary information structure by caller address.
721 @param[in] CallerAddress Caller address.
722 @param[in] DriverSummaryInfoData Driver summary information data structure.
724 @return Allocate summary information structure by caller address.
727 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*
728 GetAllocSummaryInfoByCallerAddress (
729 IN PHYSICAL_ADDRESS CallerAddress
,
730 IN MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
733 LIST_ENTRY
*AllocSummaryInfoList
;
734 LIST_ENTRY
*AllocSummaryLink
;
735 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
736 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
738 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
740 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
741 AllocSummaryLink
!= AllocSummaryInfoList
;
742 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
)
744 AllocSummaryInfoData
= CR (
746 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
748 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
750 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
751 if (AllocSummaryInfo
->CallerAddress
== CallerAddress
) {
752 return AllocSummaryInfoData
;
760 Create Allocate summary information structure and
761 link to Driver summary information data structure.
763 @param[in, out] DriverSummaryInfoData Driver summary information data structure.
764 @param[in] AllocInfo Pointer to memory profile alloc info.
766 @return Pointer to next memory profile alloc info.
769 MEMORY_PROFILE_ALLOC_INFO
*
770 CreateAllocSummaryInfo (
771 IN OUT MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
,
772 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
775 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
776 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
778 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
782 AllocSummaryInfoData
= GetAllocSummaryInfoByCallerAddress (AllocInfo
->CallerAddress
, DriverSummaryInfoData
);
783 if (AllocSummaryInfoData
== NULL
) {
784 AllocSummaryInfoData
= AllocatePool (sizeof (*AllocSummaryInfoData
));
785 if (AllocSummaryInfoData
== NULL
) {
789 AllocSummaryInfoData
->Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
790 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
791 AllocSummaryInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
792 AllocSummaryInfo
->Header
.Length
= sizeof (*AllocSummaryInfo
);
793 AllocSummaryInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION
;
794 AllocSummaryInfo
->CallerAddress
= AllocInfo
->CallerAddress
;
795 AllocSummaryInfo
->Action
= AllocInfo
->Action
;
796 if (AllocInfo
->ActionStringOffset
!= 0) {
797 AllocSummaryInfo
->ActionString
= (CHAR8
*)((UINTN
)AllocInfo
+ AllocInfo
->ActionStringOffset
);
799 AllocSummaryInfo
->ActionString
= NULL
;
802 AllocSummaryInfo
->AllocateCount
= 0;
803 AllocSummaryInfo
->TotalSize
= 0;
804 InsertTailList (DriverSummaryInfoData
->AllocSummaryInfoList
, &AllocSummaryInfoData
->Link
);
807 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
808 AllocSummaryInfo
->AllocateCount
++;
809 AllocSummaryInfo
->TotalSize
+= AllocInfo
->Size
;
811 return (MEMORY_PROFILE_ALLOC_INFO
*)((UINTN
)AllocInfo
+ AllocInfo
->Header
.Length
);
815 Create Driver summary information structure and
816 link to Context summary information data structure.
818 @param[in, out] ContextSummaryData Context summary information data structure.
819 @param[in] DriverInfo Pointer to memory profile driver info.
821 @return Pointer to next memory profile driver info.
824 MEMORY_PROFILE_DRIVER_INFO
*
825 CreateDriverSummaryInfo (
826 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
827 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
830 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
831 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
834 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
838 DriverSummaryInfoData
= AllocatePool (sizeof (*DriverSummaryInfoData
) + sizeof (LIST_ENTRY
));
839 if (DriverSummaryInfoData
== NULL
) {
843 DriverSummaryInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
844 DriverSummaryInfoData
->DriverInfo
= DriverInfo
;
845 DriverSummaryInfoData
->AllocSummaryInfoList
= (LIST_ENTRY
*)(DriverSummaryInfoData
+ 1);
846 InitializeListHead (DriverSummaryInfoData
->AllocSummaryInfoList
);
847 InsertTailList (ContextSummaryData
->DriverSummaryInfoList
, &DriverSummaryInfoData
->Link
);
849 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*)((UINTN
)DriverInfo
+ DriverInfo
->Header
.Length
);
850 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
851 AllocInfo
= CreateAllocSummaryInfo (DriverSummaryInfoData
, AllocInfo
);
852 if (AllocInfo
== NULL
) {
857 return (MEMORY_PROFILE_DRIVER_INFO
*)AllocInfo
;
861 Create Context summary information structure.
863 @param[in] ProfileBuffer Memory profile base address.
864 @param[in] ProfileSize Memory profile size.
866 @return Context summary information structure.
869 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*
870 CreateContextSummaryData (
871 IN PHYSICAL_ADDRESS ProfileBuffer
,
872 IN UINT64 ProfileSize
875 MEMORY_PROFILE_CONTEXT
*Context
;
876 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
879 Context
= (MEMORY_PROFILE_CONTEXT
*)ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
880 if (Context
== NULL
) {
884 mMemoryProfileContextSummary
.Signature
= MEMORY_PROFILE_CONTEXT_SIGNATURE
;
885 mMemoryProfileContextSummary
.Context
= Context
;
886 mMemoryProfileContextSummary
.DriverSummaryInfoList
= &mImageSummaryQueue
;
888 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*)((UINTN
)Context
+ Context
->Header
.Length
);
889 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
890 DriverInfo
= CreateDriverSummaryInfo (&mMemoryProfileContextSummary
, DriverInfo
);
891 if (DriverInfo
== NULL
) {
896 return &mMemoryProfileContextSummary
;
900 Dump Context summary information.
902 @param[in] ContextSummaryData Context summary information data.
903 @param[in] IsForSmm TRUE - SMRAM profile.
904 FALSE - UEFI memory profile.
908 DumpContextSummaryData (
909 IN MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
913 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
914 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
915 LIST_ENTRY
*DriverSummaryInfoList
;
916 LIST_ENTRY
*DriverSummaryLink
;
917 LIST_ENTRY
*AllocSummaryInfoList
;
918 LIST_ENTRY
*AllocSummaryLink
;
919 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
920 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
923 if (ContextSummaryData
== NULL
) {
927 Print (L
"\nSummary Data:\n");
929 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
930 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
931 DriverSummaryLink
!= DriverSummaryInfoList
;
932 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
)
934 DriverSummaryInfoData
= CR (
936 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
938 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
940 DriverInfo
= DriverSummaryInfoData
->DriverInfo
;
942 NameString
= GetDriverNameString (DriverInfo
);
943 Print (L
"\nDriver - %a (Usage - 0x%08x)", NameString
, DriverInfo
->CurrentUsage
);
944 if (DriverInfo
->CurrentUsage
== 0) {
949 if (DriverInfo
->PdbStringOffset
!= 0) {
950 Print (L
" (Pdb - %a)\n", (CHAR8
*)((UINTN
)DriverInfo
+ DriverInfo
->PdbStringOffset
));
955 Print (L
"Caller List:\n");
956 Print (L
" Count Size RVA Action\n");
957 Print (L
"========== ================== ================== (================================)\n");
958 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
959 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
960 AllocSummaryLink
!= AllocSummaryInfoList
;
961 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
)
963 AllocSummaryInfoData
= CR (
965 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
967 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
969 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
972 L
"0x%08x 0x%016lx <== 0x%016lx",
973 AllocSummaryInfo
->AllocateCount
,
974 AllocSummaryInfo
->TotalSize
,
975 AllocSummaryInfo
->CallerAddress
- DriverInfo
->ImageBase
977 Print (L
" (%a)\n", ProfileActionToStr (AllocSummaryInfo
->Action
, AllocSummaryInfo
->ActionString
, IsForSmm
));
985 Destroy Context summary information.
987 @param[in, out] ContextSummaryData Context summary information data.
991 DestroyContextSummaryData (
992 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
995 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
996 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
997 LIST_ENTRY
*DriverSummaryInfoList
;
998 LIST_ENTRY
*DriverSummaryLink
;
999 LIST_ENTRY
*AllocSummaryInfoList
;
1000 LIST_ENTRY
*AllocSummaryLink
;
1002 if (ContextSummaryData
== NULL
) {
1006 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
1007 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
1008 DriverSummaryLink
!= DriverSummaryInfoList
;
1011 DriverSummaryInfoData
= CR (
1013 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
1015 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1017 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
;
1019 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
1020 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
1021 AllocSummaryLink
!= AllocSummaryInfoList
;
1024 AllocSummaryInfoData
= CR (
1026 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
1028 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
1030 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
;
1032 RemoveEntryList (&AllocSummaryInfoData
->Link
);
1033 FreePool (AllocSummaryInfoData
);
1036 RemoveEntryList (&DriverSummaryInfoData
->Link
);
1037 FreePool (DriverSummaryInfoData
);
1044 Get and dump UEFI memory profile data.
1046 @return EFI_SUCCESS Get the memory profile data successfully.
1047 @return other Fail to get the memory profile data.
1051 GetUefiMemoryProfileData (
1056 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
1059 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1060 BOOLEAN RecordingState
;
1062 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**)&ProfileProtocol
);
1063 if (EFI_ERROR (Status
)) {
1064 DEBUG ((DEBUG_ERROR
, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status
));
1069 // Set recording state if needed.
1071 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1072 Status
= ProfileProtocol
->GetRecordingState (ProfileProtocol
, &RecordingState
);
1073 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1074 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_DISABLE
);
1079 Status
= ProfileProtocol
->GetData (
1084 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1085 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1089 Data
= AllocateZeroPool ((UINTN
)Size
);
1091 Status
= EFI_OUT_OF_RESOURCES
;
1092 Print (L
"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size
, Status
);
1096 Status
= ProfileProtocol
->GetData (
1101 if (EFI_ERROR (Status
)) {
1102 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1106 Print (L
"UefiMemoryProfileSize - 0x%x\n", Size
);
1107 Print (L
"======= UefiMemoryProfile begin =======\n");
1108 DumpMemoryProfile ((PHYSICAL_ADDRESS
)(UINTN
)Data
, Size
, FALSE
);
1111 // Dump summary information
1113 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
)(UINTN
)Data
, Size
);
1114 if (MemoryProfileContextSummaryData
!= NULL
) {
1115 DumpContextSummaryData (MemoryProfileContextSummaryData
, FALSE
);
1116 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1119 Print (L
"======= UefiMemoryProfile end =======\n\n\n");
1127 // Restore recording state if needed.
1129 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1130 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_ENABLE
);
1137 Get and dump SMRAM profile data.
1139 @return EFI_SUCCESS Get the SMRAM profile data successfully.
1140 @return other Fail to get the SMRAM profile data.
1144 GetSmramProfileData (
1151 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
1152 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*CommGetProfileInfo
;
1153 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*CommGetProfileData
;
1154 SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*CommRecordingState
;
1156 VOID
*ProfileBuffer
;
1157 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
1158 UINTN MinimalSizeNeeded
;
1159 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
1161 EFI_MEMORY_DESCRIPTOR
*Entry
;
1165 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1166 BOOLEAN RecordingState
;
1168 ProfileBuffer
= NULL
;
1170 Status
= gBS
->LocateProtocol (&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**)&SmmCommunication
);
1171 if (EFI_ERROR (Status
)) {
1172 DEBUG ((DEBUG_ERROR
, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status
));
1176 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
1179 sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
),
1181 sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
),
1182 sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
)
1185 MinimalSizeNeeded
+= MAX (
1186 sizeof (MEMORY_PROFILE_CONTEXT
),
1188 sizeof (MEMORY_PROFILE_DRIVER_INFO
),
1190 sizeof (MEMORY_PROFILE_ALLOC_INFO
),
1192 sizeof (MEMORY_PROFILE_DESCRIPTOR
),
1194 sizeof (MEMORY_PROFILE_FREE_MEMORY
),
1195 sizeof (MEMORY_PROFILE_MEMORY_RANGE
)
1202 Status
= EfiGetSystemConfigurationTable (
1203 &gEdkiiPiSmmCommunicationRegionTableGuid
,
1204 (VOID
**)&PiSmmCommunicationRegionTable
1206 if (EFI_ERROR (Status
)) {
1207 DEBUG ((DEBUG_ERROR
, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status
));
1211 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
1212 Entry
= (EFI_MEMORY_DESCRIPTOR
*)(PiSmmCommunicationRegionTable
+ 1);
1214 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
1215 if (Entry
->Type
== EfiConventionalMemory
) {
1216 Size
= EFI_PAGES_TO_SIZE ((UINTN
)Entry
->NumberOfPages
);
1217 if (Size
>= MinimalSizeNeeded
) {
1222 Entry
= (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
1225 ASSERT (Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
);
1226 CommBuffer
= (UINT8
*)(UINTN
)Entry
->PhysicalStart
;
1229 // Set recording state if needed.
1231 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1233 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
1234 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1235 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1237 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1238 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE
;
1239 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1240 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1241 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1243 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1244 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1245 if (EFI_ERROR (Status
)) {
1246 DEBUG ((DEBUG_ERROR
, "SmramProfile: SmmCommunication - %r\n", Status
));
1250 if (CommRecordingState
->Header
.ReturnStatus
!= 0) {
1251 Print (L
"SmramProfile: GetRecordingState - 0x%0x\n", CommRecordingState
->Header
.ReturnStatus
);
1255 RecordingState
= CommRecordingState
->RecordingState
;
1256 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1257 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
1258 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1259 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1261 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1262 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1263 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1264 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1265 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1267 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1268 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1274 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
1275 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1276 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
);
1278 CommGetProfileInfo
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1279 CommGetProfileInfo
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
;
1280 CommGetProfileInfo
->Header
.DataLength
= sizeof (*CommGetProfileInfo
);
1281 CommGetProfileInfo
->Header
.ReturnStatus
= (UINT64
)-1;
1282 CommGetProfileInfo
->ProfileSize
= 0;
1284 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1285 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1286 ASSERT_EFI_ERROR (Status
);
1288 if (CommGetProfileInfo
->Header
.ReturnStatus
!= 0) {
1289 Status
= EFI_SUCCESS
;
1290 Print (L
"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo
->Header
.ReturnStatus
);
1294 ProfileSize
= (UINTN
)CommGetProfileInfo
->ProfileSize
;
1299 ProfileBuffer
= AllocateZeroPool (ProfileSize
);
1300 if (ProfileBuffer
== NULL
) {
1301 Status
= EFI_OUT_OF_RESOURCES
;
1302 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize
, Status
);
1306 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
1307 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1308 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
);
1310 CommGetProfileData
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1311 CommGetProfileData
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET
;
1312 CommGetProfileData
->Header
.DataLength
= sizeof (*CommGetProfileData
);
1313 CommGetProfileData
->Header
.ReturnStatus
= (UINT64
)-1;
1315 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1316 Buffer
= (UINT8
*)CommHeader
+ CommSize
;
1319 CommGetProfileData
->ProfileBuffer
= (PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
1320 CommGetProfileData
->ProfileOffset
= 0;
1321 while (CommGetProfileData
->ProfileOffset
< ProfileSize
) {
1322 Offset
= (UINTN
)CommGetProfileData
->ProfileOffset
;
1323 if (Size
<= (ProfileSize
- CommGetProfileData
->ProfileOffset
)) {
1324 CommGetProfileData
->ProfileSize
= (UINT64
)Size
;
1326 CommGetProfileData
->ProfileSize
= (UINT64
)(ProfileSize
- CommGetProfileData
->ProfileOffset
);
1329 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1330 ASSERT_EFI_ERROR (Status
);
1332 if (CommGetProfileData
->Header
.ReturnStatus
!= 0) {
1333 Status
= EFI_SUCCESS
;
1334 Print (L
"GetProfileData - 0x%x\n", CommGetProfileData
->Header
.ReturnStatus
);
1338 CopyMem ((UINT8
*)ProfileBuffer
+ Offset
, (VOID
*)(UINTN
)CommGetProfileData
->ProfileBuffer
, (UINTN
)CommGetProfileData
->ProfileSize
);
1341 Print (L
"SmramProfileSize - 0x%x\n", ProfileSize
);
1342 Print (L
"======= SmramProfile begin =======\n");
1343 DumpMemoryProfile ((PHYSICAL_ADDRESS
)(UINTN
)ProfileBuffer
, ProfileSize
, TRUE
);
1346 // Dump summary information
1348 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
)(UINTN
)ProfileBuffer
, ProfileSize
);
1349 if (MemoryProfileContextSummaryData
!= NULL
) {
1350 DumpContextSummaryData (MemoryProfileContextSummaryData
, TRUE
);
1351 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1354 Print (L
"======= SmramProfile end =======\n\n\n");
1357 if (ProfileBuffer
!= NULL
) {
1358 FreePool (ProfileBuffer
);
1362 // Restore recording state if needed.
1364 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1365 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
1366 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1367 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1369 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*)&CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1370 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1371 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1372 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1373 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_ENABLE
;
1375 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1376 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1383 The user Entry Point for Application. The user code starts with this function
1384 as the real entry point for the image goes into a library that calls this function.
1386 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1387 @param[in] SystemTable A pointer to the EFI System Table.
1389 @retval EFI_SUCCESS The entry point is executed successfully.
1390 @retval other Some error occurs when executing this entry point.
1396 IN EFI_HANDLE ImageHandle
,
1397 IN EFI_SYSTEM_TABLE
*SystemTable
1402 Status
= GetUefiMemoryProfileData ();
1403 if (EFI_ERROR (Status
)) {
1404 DEBUG ((DEBUG_ERROR
, "GetUefiMemoryProfileData - %r\n", Status
));
1407 Status
= GetSmramProfileData ();
1408 if (EFI_ERROR (Status
)) {
1409 DEBUG ((DEBUG_ERROR
, "GetSmramProfileData - %r\n", Status
));