3 Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiLib.h>
20 #include <Library/UefiApplicationEntryPoint.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiRuntimeServicesTableLib.h>
23 #include <Library/DebugLib.h>
24 #include <Library/DxeServicesLib.h>
25 #include <Library/PrintLib.h>
27 #include <Protocol/SmmCommunication.h>
28 #include <Protocol/SmmAccess2.h>
30 #include <Guid/MemoryProfile.h>
31 #include <Guid/PiSmmCommunicationRegionTable.h>
33 CHAR8
*mActionString
[] = {
41 CHAR8
*mSmmActionString
[] = {
43 "gSmst->SmmAllocatePages",
44 "gSmst->SmmFreePages",
45 "gSmst->SmmAllocatePool",
50 MEMORY_PROFILE_ACTION Action
;
54 ACTION_STRING mExtActionString
[] = {
55 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES
, "Lib:AllocatePages"},
56 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES
, "Lib:AllocateRuntimePages"},
57 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES
, "Lib:AllocateReservedPages"},
58 {MEMORY_PROFILE_ACTION_LIB_FREE_PAGES
, "Lib:FreePages"},
59 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES
, "Lib:AllocateAlignedPages"},
60 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES
, "Lib:AllocateAlignedRuntimePages"},
61 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES
, "Lib:AllocateAlignedReservedPages"},
62 {MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES
, "Lib:FreeAlignedPages"},
63 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL
, "Lib:AllocatePool"},
64 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL
, "Lib:AllocateRuntimePool"},
65 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL
, "Lib:AllocateReservedPool"},
66 {MEMORY_PROFILE_ACTION_LIB_FREE_POOL
, "Lib:FreePool"},
67 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL
, "Lib:AllocateZeroPool"},
68 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL
, "Lib:AllocateRuntimeZeroPool"},
69 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL
, "Lib:AllocateReservedZeroPool"},
70 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL
, "Lib:AllocateCopyPool"},
71 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL
, "Lib:AllocateRuntimeCopyPool"},
72 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL
, "Lib:AllocateReservedCopyPool"},
73 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL
, "Lib:ReallocatePool"},
74 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL
, "Lib:ReallocateRuntimePool"},
75 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL
, "Lib:ReallocateReservedPool"},
78 CHAR8 mUserDefinedActionString
[] = {"UserDefined-0x80000000"};
80 CHAR8
*mMemoryTypeString
[] = {
81 "EfiReservedMemoryType",
84 "EfiBootServicesCode",
85 "EfiBootServicesData",
86 "EfiRuntimeServicesCode",
87 "EfiRuntimeServicesData",
88 "EfiConventionalMemory",
90 "EfiACPIReclaimMemory",
93 "EfiMemoryMappedIOPortSpace",
95 "EfiPersistentMemory",
100 CHAR8
*mSubsystemString
[] = {
112 "EFI_BOOT_SERVICE_DRIVER",
113 "EFI_RUNTIME_DRIVER",
119 CHAR8
*mFileTypeString
[] = {
128 "COMBINED_PEIM_DRIVER",
131 "FIRMWARE_VOLUME_IMAGE",
136 #define PROFILE_NAME_STRING_LENGTH 64
137 CHAR8 mNameString
[PROFILE_NAME_STRING_LENGTH
+ 1];
140 // Profile summary information
142 #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE SIGNATURE_32 ('M','P','A','S')
143 #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION 0x0001
146 MEMORY_PROFILE_COMMON_HEADER Header
;
147 PHYSICAL_ADDRESS CallerAddress
;
148 MEMORY_PROFILE_ACTION Action
;
150 UINT32 AllocateCount
;
152 } MEMORY_PROFILE_ALLOC_SUMMARY_INFO
;
156 MEMORY_PROFILE_ALLOC_SUMMARY_INFO AllocSummaryInfo
;
158 } MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
;
162 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
163 LIST_ENTRY
*AllocSummaryInfoList
;
165 } MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
;
169 MEMORY_PROFILE_CONTEXT
*Context
;
170 LIST_ENTRY
*DriverSummaryInfoList
;
171 } MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
;
173 LIST_ENTRY mImageSummaryQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mImageSummaryQueue
);
174 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA mMemoryProfileContextSummary
;
177 Get the file name portion of the Pdb File Name.
179 The portion of the Pdb File Name between the last backslash and
180 either a following period or the end of the string is copied into
181 AsciiBuffer. The name is truncated, if necessary, to ensure that
182 AsciiBuffer is not overrun.
184 @param[in] PdbFileName Pdb file name.
185 @param[out] AsciiBuffer The resultant Ascii File Name.
189 GetShortPdbFileName (
190 IN CHAR8
*PdbFileName
,
191 OUT CHAR8
*AsciiBuffer
194 UINTN IndexPdb
; // Current work location within a Pdb string.
195 UINTN IndexBuffer
; // Current work location within a Buffer string.
199 ZeroMem (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1);
201 if (PdbFileName
== NULL
) {
202 AsciiStrnCpyS (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1, " ", 1);
205 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++);
206 for (IndexPdb
= 0; PdbFileName
[IndexPdb
] != 0; IndexPdb
++) {
207 if ((PdbFileName
[IndexPdb
] == '\\') || (PdbFileName
[IndexPdb
] == '/')) {
208 StartIndex
= IndexPdb
+ 1;
211 if (PdbFileName
[IndexPdb
] == '.') {
217 for (IndexPdb
= StartIndex
; IndexPdb
< EndIndex
; IndexPdb
++) {
218 AsciiBuffer
[IndexBuffer
] = PdbFileName
[IndexPdb
];
220 if (IndexBuffer
>= PROFILE_NAME_STRING_LENGTH
) {
221 AsciiBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
229 Get a human readable name for an image.
230 The following methods will be tried orderly:
235 @param[in] DriverInfo Pointer to memory profile driver info.
237 @return The resulting Ascii name string is stored in the mNameString global array.
241 GetDriverNameString (
242 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
250 // Method 1: Get the name string from image PDB
252 if (DriverInfo
->PdbStringOffset
!= 0) {
253 GetShortPdbFileName ((CHAR8
*) ((UINTN
) DriverInfo
+ DriverInfo
->PdbStringOffset
), mNameString
);
257 if (!IsZeroGuid (&DriverInfo
->FileName
)) {
259 // Try to get the image's FFS UI section by image GUID
263 Status
= GetSectionFromAnyFv (
264 &DriverInfo
->FileName
,
265 EFI_SECTION_USER_INTERFACE
,
267 (VOID
**) &NameString
,
270 if (!EFI_ERROR (Status
)) {
272 // Method 2: Get the name string from FFS UI section
274 if (StrLen (NameString
) > PROFILE_NAME_STRING_LENGTH
) {
275 NameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
277 UnicodeStrToAsciiStrS (NameString
, mNameString
, sizeof (mNameString
));
278 FreePool (NameString
);
284 // Method 3: Get the name string from image GUID
286 AsciiSPrint (mNameString
, sizeof (mNameString
), "%g", &DriverInfo
->FileName
);
291 Memory type to string.
293 @param[in] MemoryType Memory type.
295 @return Pointer to string.
299 ProfileMemoryTypeToStr (
300 IN EFI_MEMORY_TYPE MemoryType
305 if ((UINT32
) MemoryType
>= 0x80000000) {
307 // OS reserved memory type.
309 Index
= EfiMaxMemoryType
;
310 } else if ((UINT32
) MemoryType
>= 0x70000000) {
312 // OEM reserved memory type.
314 Index
= EfiMaxMemoryType
+ 1;
319 return mMemoryTypeString
[Index
];
325 @param[in] Action Profile action.
326 @param[in] UserDefinedActionString Pointer to user defined action string.
327 @param[in] IsForSmm TRUE - SMRAM profile.
328 FALSE - UEFI memory profile.
330 @return Pointer to string.
335 IN MEMORY_PROFILE_ACTION Action
,
336 IN CHAR8
*UserDefinedActionString
,
341 UINTN ActionStringCount
;
342 CHAR8
**ActionString
;
345 ActionString
= mSmmActionString
;
346 ActionStringCount
= ARRAY_SIZE (mSmmActionString
);
348 ActionString
= mActionString
;
349 ActionStringCount
= ARRAY_SIZE (mActionString
);
352 if ((UINTN
) (UINT32
) Action
< ActionStringCount
) {
353 return ActionString
[Action
];
355 for (Index
= 0; Index
< ARRAY_SIZE (mExtActionString
); Index
++) {
356 if (mExtActionString
[Index
].Action
== Action
) {
357 return mExtActionString
[Index
].String
;
360 if ((Action
& MEMORY_PROFILE_ACTION_USER_DEFINED_MASK
) != 0) {
361 if (UserDefinedActionString
!= NULL
) {
362 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
) {
443 Print (L
" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
);
444 Print (L
" Signature - 0x%08x\n", DriverInfo
->Header
.Signature
);
445 Print (L
" Length - 0x%04x\n", DriverInfo
->Header
.Length
);
446 Print (L
" Revision - 0x%04x\n", DriverInfo
->Header
.Revision
);
447 NameString
= GetDriverNameString (DriverInfo
);
448 Print (L
" FileName - %a\n", NameString
);
449 if (DriverInfo
->PdbStringOffset
!= 0) {
450 Print (L
" Pdb - %a\n", (CHAR8
*) ((UINTN
) DriverInfo
+ DriverInfo
->PdbStringOffset
));
452 Print (L
" ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
);
453 Print (L
" ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
);
454 Print (L
" EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
);
455 Print (L
" ImageSubsystem - 0x%04x (%a)\n", DriverInfo
->ImageSubsystem
, mSubsystemString
[(DriverInfo
->ImageSubsystem
< sizeof(mSubsystemString
)/sizeof(mSubsystemString
[0])) ? DriverInfo
->ImageSubsystem
: 0]);
456 Print (L
" FileType - 0x%02x (%a)\n", DriverInfo
->FileType
, mFileTypeString
[(DriverInfo
->FileType
< sizeof(mFileTypeString
)/sizeof(mFileTypeString
[0])) ? DriverInfo
->FileType
: 0]);
457 Print (L
" CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
);
458 Print (L
" PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
);
459 for (TypeIndex
= 0; TypeIndex
< sizeof (DriverInfo
->CurrentUsageByType
) / sizeof (DriverInfo
->CurrentUsageByType
[0]); TypeIndex
++) {
460 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
461 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
462 Print (L
" CurrentUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
463 Print (L
" PeakUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
466 Print (L
" AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
);
468 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
469 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
470 AllocInfo
= DumpMemoryProfileAllocInfo (DriverInfo
, AllocIndex
, AllocInfo
, IsForSmm
);
471 if (AllocInfo
== NULL
) {
475 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
479 Dump memory profile context information.
481 @param[in] Context Pointer to memory profile context.
482 @param[in] IsForSmm TRUE - SMRAM profile.
483 FALSE - UEFI memory profile.
485 @return Pointer to the end of memory profile context buffer.
489 DumpMemoryProfileContext (
490 IN MEMORY_PROFILE_CONTEXT
*Context
,
495 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
498 if (Context
->Header
.Signature
!= MEMORY_PROFILE_CONTEXT_SIGNATURE
) {
501 Print (L
"MEMORY_PROFILE_CONTEXT\n");
502 Print (L
" Signature - 0x%08x\n", Context
->Header
.Signature
);
503 Print (L
" Length - 0x%04x\n", Context
->Header
.Length
);
504 Print (L
" Revision - 0x%04x\n", Context
->Header
.Revision
);
505 Print (L
" CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
);
506 Print (L
" PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
);
507 for (TypeIndex
= 0; TypeIndex
< sizeof (Context
->CurrentTotalUsageByType
) / sizeof (Context
->CurrentTotalUsageByType
[0]); TypeIndex
++) {
508 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
509 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
510 Print (L
" CurrentTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
511 Print (L
" PeakTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
514 Print (L
" TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
);
515 Print (L
" ImageCount - 0x%08x\n", Context
->ImageCount
);
516 Print (L
" SequenceCount - 0x%08x\n", Context
->SequenceCount
);
518 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
519 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
520 DriverInfo
= DumpMemoryProfileDriverInfo (DriverIndex
, DriverInfo
, IsForSmm
);
521 if (DriverInfo
== NULL
) {
525 return (VOID
*) DriverInfo
;
529 Dump memory profile descriptor information.
531 @param[in] DescriptorIndex Memory profile descriptor index.
532 @param[in] Descriptor Pointer to memory profile descriptor.
534 @return Pointer to next memory profile descriptor.
537 MEMORY_PROFILE_DESCRIPTOR
*
538 DumpMemoryProfileDescriptor (
539 IN UINTN DescriptorIndex
,
540 IN MEMORY_PROFILE_DESCRIPTOR
*Descriptor
543 if (Descriptor
->Header
.Signature
!= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
) {
546 Print (L
" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex
);
547 Print (L
" Signature - 0x%08x\n", Descriptor
->Header
.Signature
);
548 Print (L
" Length - 0x%04x\n", Descriptor
->Header
.Length
);
549 Print (L
" Revision - 0x%04x\n", Descriptor
->Header
.Revision
);
550 Print (L
" Address - 0x%016lx\n", Descriptor
->Address
);
551 Print (L
" Size - 0x%016lx\n", Descriptor
->Size
);
553 return (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) Descriptor
+ Descriptor
->Header
.Length
);
557 Dump memory profile free memory information.
559 @param[in] FreeMemory Pointer to memory profile free memory.
561 @return Pointer to the end of memory profile free memory buffer.
565 DumpMemoryProfileFreeMemory (
566 IN MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
569 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
570 UINTN DescriptorIndex
;
572 if (FreeMemory
->Header
.Signature
!= MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
) {
575 Print (L
"MEMORY_PROFILE_FREE_MEMORY\n");
576 Print (L
" Signature - 0x%08x\n", FreeMemory
->Header
.Signature
);
577 Print (L
" Length - 0x%04x\n", FreeMemory
->Header
.Length
);
578 Print (L
" Revision - 0x%04x\n", FreeMemory
->Header
.Revision
);
579 Print (L
" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory
->TotalFreeMemoryPages
);
580 Print (L
" FreeMemoryEntryCount - 0x%08x\n", FreeMemory
->FreeMemoryEntryCount
);
582 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) FreeMemory
+ FreeMemory
->Header
.Length
);
583 for (DescriptorIndex
= 0; DescriptorIndex
< FreeMemory
->FreeMemoryEntryCount
; DescriptorIndex
++) {
584 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
585 if (Descriptor
== NULL
) {
590 return (VOID
*) Descriptor
;
594 Dump memory profile memory range information.
596 @param[in] MemoryRange Pointer to memory profile memory range.
598 @return Pointer to the end of memory profile memory range buffer.
602 DumpMemoryProfileMemoryRange (
603 IN MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
606 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
607 UINTN DescriptorIndex
;
609 if (MemoryRange
->Header
.Signature
!= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
) {
612 Print (L
"MEMORY_PROFILE_MEMORY_RANGE\n");
613 Print (L
" Signature - 0x%08x\n", MemoryRange
->Header
.Signature
);
614 Print (L
" Length - 0x%04x\n", MemoryRange
->Header
.Length
);
615 Print (L
" Revision - 0x%04x\n", MemoryRange
->Header
.Revision
);
616 Print (L
" MemoryRangeCount - 0x%08x\n", MemoryRange
->MemoryRangeCount
);
618 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) MemoryRange
+ MemoryRange
->Header
.Length
);
619 for (DescriptorIndex
= 0; DescriptorIndex
< MemoryRange
->MemoryRangeCount
; DescriptorIndex
++) {
620 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
621 if (Descriptor
== NULL
) {
626 return (VOID
*) Descriptor
;
630 Scan memory profile by Signature.
632 @param[in] ProfileBuffer Memory profile base address.
633 @param[in] ProfileSize Memory profile size.
634 @param[in] Signature Signature.
636 @return Pointer to the stucture with the signature.
640 ScanMemoryProfileBySignature (
641 IN PHYSICAL_ADDRESS ProfileBuffer
,
642 IN UINT64 ProfileSize
,
646 MEMORY_PROFILE_COMMON_HEADER
*CommonHeader
;
649 ProfileEnd
= (UINTN
) (ProfileBuffer
+ ProfileSize
);
650 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) (UINTN
) ProfileBuffer
;
651 while ((UINTN
) CommonHeader
< ProfileEnd
) {
652 if (CommonHeader
->Signature
== Signature
) {
656 return (VOID
*) CommonHeader
;
658 if (CommonHeader
->Length
== 0) {
662 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) ((UINTN
) CommonHeader
+ CommonHeader
->Length
);
669 Dump memory profile information.
671 @param[in] ProfileBuffer Memory profile base address.
672 @param[in] ProfileSize Memory profile size.
673 @param[in] IsForSmm TRUE - SMRAM profile.
674 FALSE - UEFI memory profile.
679 IN PHYSICAL_ADDRESS ProfileBuffer
,
680 IN UINT64 ProfileSize
,
684 MEMORY_PROFILE_CONTEXT
*Context
;
685 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
686 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
688 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
689 if (Context
!= NULL
) {
690 DumpMemoryProfileContext (Context
, IsForSmm
);
693 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
);
694 if (FreeMemory
!= NULL
) {
695 DumpMemoryProfileFreeMemory (FreeMemory
);
698 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
);
699 if (MemoryRange
!= NULL
) {
700 DumpMemoryProfileMemoryRange (MemoryRange
);
705 Get Allocate summary information structure by caller address.
707 @param[in] CallerAddress Caller address.
708 @param[in] DriverSummaryInfoData Driver summary information data structure.
710 @return Allocate summary information structure by caller address.
713 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*
714 GetAllocSummaryInfoByCallerAddress (
715 IN PHYSICAL_ADDRESS CallerAddress
,
716 IN MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
719 LIST_ENTRY
*AllocSummaryInfoList
;
720 LIST_ENTRY
*AllocSummaryLink
;
721 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
722 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
724 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
726 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
727 AllocSummaryLink
!= AllocSummaryInfoList
;
728 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
) {
729 AllocSummaryInfoData
= CR (
731 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
733 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
735 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
736 if (AllocSummaryInfo
->CallerAddress
== CallerAddress
) {
737 return AllocSummaryInfoData
;
744 Create Allocate summary information structure and
745 link to Driver summary information data structure.
747 @param[in, out] DriverSummaryInfoData Driver summary information data structure.
748 @param[in] AllocInfo Pointer to memory profile alloc info.
750 @return Pointer to next memory profile alloc info.
753 MEMORY_PROFILE_ALLOC_INFO
*
754 CreateAllocSummaryInfo (
755 IN OUT MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
,
756 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
759 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
760 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
762 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
766 AllocSummaryInfoData
= GetAllocSummaryInfoByCallerAddress (AllocInfo
->CallerAddress
, DriverSummaryInfoData
);
767 if (AllocSummaryInfoData
== NULL
) {
768 AllocSummaryInfoData
= AllocatePool (sizeof (*AllocSummaryInfoData
));
769 if (AllocSummaryInfoData
== NULL
) {
773 AllocSummaryInfoData
->Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
774 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
775 AllocSummaryInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
776 AllocSummaryInfo
->Header
.Length
= sizeof (*AllocSummaryInfo
);
777 AllocSummaryInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION
;
778 AllocSummaryInfo
->CallerAddress
= AllocInfo
->CallerAddress
;
779 AllocSummaryInfo
->Action
= AllocInfo
->Action
;
780 if (AllocInfo
->ActionStringOffset
!= 0) {
781 AllocSummaryInfo
->ActionString
= (CHAR8
*) ((UINTN
) AllocInfo
+ AllocInfo
->ActionStringOffset
);
783 AllocSummaryInfo
->ActionString
= NULL
;
785 AllocSummaryInfo
->AllocateCount
= 0;
786 AllocSummaryInfo
->TotalSize
= 0;
787 InsertTailList (DriverSummaryInfoData
->AllocSummaryInfoList
, &AllocSummaryInfoData
->Link
);
789 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
790 AllocSummaryInfo
->AllocateCount
++;
791 AllocSummaryInfo
->TotalSize
+= AllocInfo
->Size
;
793 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
797 Create Driver summary information structure and
798 link to Context summary information data structure.
800 @param[in, out] ContextSummaryData Context summary information data structure.
801 @param[in] DriverInfo Pointer to memory profile driver info.
803 @return Pointer to next memory profile driver info.
806 MEMORY_PROFILE_DRIVER_INFO
*
807 CreateDriverSummaryInfo (
808 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
809 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
812 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
813 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
816 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
820 DriverSummaryInfoData
= AllocatePool (sizeof (*DriverSummaryInfoData
) + sizeof (LIST_ENTRY
));
821 if (DriverSummaryInfoData
== NULL
) {
824 DriverSummaryInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
825 DriverSummaryInfoData
->DriverInfo
= DriverInfo
;
826 DriverSummaryInfoData
->AllocSummaryInfoList
= (LIST_ENTRY
*) (DriverSummaryInfoData
+ 1);
827 InitializeListHead (DriverSummaryInfoData
->AllocSummaryInfoList
);
828 InsertTailList (ContextSummaryData
->DriverSummaryInfoList
, &DriverSummaryInfoData
->Link
);
830 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
831 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
832 AllocInfo
= CreateAllocSummaryInfo (DriverSummaryInfoData
, AllocInfo
);
833 if (AllocInfo
== NULL
) {
837 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
841 Create Context summary information structure.
843 @param[in] ProfileBuffer Memory profile base address.
844 @param[in] ProfileSize Memory profile size.
846 @return Context summary information structure.
849 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*
850 CreateContextSummaryData (
851 IN PHYSICAL_ADDRESS ProfileBuffer
,
852 IN UINT64 ProfileSize
855 MEMORY_PROFILE_CONTEXT
*Context
;
856 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
859 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
860 if (Context
== NULL
) {
864 mMemoryProfileContextSummary
.Signature
= MEMORY_PROFILE_CONTEXT_SIGNATURE
;
865 mMemoryProfileContextSummary
.Context
= Context
;
866 mMemoryProfileContextSummary
.DriverSummaryInfoList
= &mImageSummaryQueue
;
868 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
869 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
870 DriverInfo
= CreateDriverSummaryInfo (&mMemoryProfileContextSummary
, DriverInfo
);
871 if (DriverInfo
== NULL
) {
876 return &mMemoryProfileContextSummary
;
880 Dump Context summary information.
882 @param[in] ContextSummaryData Context summary information data.
883 @param[in] IsForSmm TRUE - SMRAM profile.
884 FALSE - UEFI memory profile.
888 DumpContextSummaryData (
889 IN MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
893 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
894 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
895 LIST_ENTRY
*DriverSummaryInfoList
;
896 LIST_ENTRY
*DriverSummaryLink
;
897 LIST_ENTRY
*AllocSummaryInfoList
;
898 LIST_ENTRY
*AllocSummaryLink
;
899 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
900 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
903 if (ContextSummaryData
== NULL
) {
907 Print (L
"\nSummary Data:\n");
909 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
910 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
911 DriverSummaryLink
!= DriverSummaryInfoList
;
912 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
) {
913 DriverSummaryInfoData
= CR (
915 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
917 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
919 DriverInfo
= DriverSummaryInfoData
->DriverInfo
;
921 NameString
= GetDriverNameString (DriverInfo
);
922 Print (L
"\nDriver - %a (Usage - 0x%08x)", NameString
, DriverInfo
->CurrentUsage
);
923 if (DriverInfo
->CurrentUsage
== 0) {
928 if (DriverInfo
->PdbStringOffset
!= 0) {
929 Print (L
" (Pdb - %a)\n", (CHAR8
*) ((UINTN
) DriverInfo
+ DriverInfo
->PdbStringOffset
));
933 Print (L
"Caller List:\n");
934 Print(L
" Count Size RVA Action\n");
935 Print(L
"========== ================== ================== (================================)\n");
936 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
937 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
938 AllocSummaryLink
!= AllocSummaryInfoList
;
939 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
) {
940 AllocSummaryInfoData
= CR (
942 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
944 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
946 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
948 Print(L
"0x%08x 0x%016lx <== 0x%016lx",
949 AllocSummaryInfo
->AllocateCount
,
950 AllocSummaryInfo
->TotalSize
,
951 AllocSummaryInfo
->CallerAddress
- DriverInfo
->ImageBase
953 Print (L
" (%a)\n", ProfileActionToStr (AllocSummaryInfo
->Action
, AllocSummaryInfo
->ActionString
, IsForSmm
));
960 Destroy Context summary information.
962 @param[in, out] ContextSummaryData Context summary information data.
966 DestroyContextSummaryData (
967 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
970 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
971 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
972 LIST_ENTRY
*DriverSummaryInfoList
;
973 LIST_ENTRY
*DriverSummaryLink
;
974 LIST_ENTRY
*AllocSummaryInfoList
;
975 LIST_ENTRY
*AllocSummaryLink
;
977 if (ContextSummaryData
== NULL
) {
981 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
982 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
983 DriverSummaryLink
!= DriverSummaryInfoList
;
985 DriverSummaryInfoData
= CR (
987 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
989 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
991 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
;
993 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
994 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
995 AllocSummaryLink
!= AllocSummaryInfoList
;
997 AllocSummaryInfoData
= CR (
999 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
1001 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
1003 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
;
1005 RemoveEntryList (&AllocSummaryInfoData
->Link
);
1006 FreePool (AllocSummaryInfoData
);
1009 RemoveEntryList (&DriverSummaryInfoData
->Link
);
1010 FreePool (DriverSummaryInfoData
);
1016 Get and dump UEFI memory profile data.
1018 @return EFI_SUCCESS Get the memory profile data successfully.
1019 @return other Fail to get the memory profile data.
1023 GetUefiMemoryProfileData (
1028 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
1031 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1032 BOOLEAN RecordingState
;
1034 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
1035 if (EFI_ERROR (Status
)) {
1036 DEBUG ((EFI_D_ERROR
, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status
));
1041 // Set recording state if needed.
1043 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1044 Status
= ProfileProtocol
->GetRecordingState (ProfileProtocol
, &RecordingState
);
1045 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1046 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_DISABLE
);
1051 Status
= ProfileProtocol
->GetData (
1056 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1057 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1061 Data
= AllocateZeroPool ((UINTN
) Size
);
1063 Status
= EFI_OUT_OF_RESOURCES
;
1064 Print (L
"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size
, Status
);
1068 Status
= ProfileProtocol
->GetData (
1073 if (EFI_ERROR (Status
)) {
1074 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1079 Print (L
"UefiMemoryProfileSize - 0x%x\n", Size
);
1080 Print (L
"======= UefiMemoryProfile begin =======\n");
1081 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
, FALSE
);
1084 // Dump summary information
1086 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
);
1087 if (MemoryProfileContextSummaryData
!= NULL
) {
1088 DumpContextSummaryData (MemoryProfileContextSummaryData
, FALSE
);
1089 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1092 Print (L
"======= UefiMemoryProfile end =======\n\n\n");
1100 // Restore recording state if needed.
1102 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1103 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_ENABLE
);
1110 Get and dump SMRAM profile data.
1112 @return EFI_SUCCESS Get the SMRAM profile data successfully.
1113 @return other Fail to get the SMRAM profile data.
1117 GetSmramProfileData (
1124 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
1125 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*CommGetProfileInfo
;
1126 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*CommGetProfileData
;
1127 SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*CommRecordingState
;
1129 VOID
*ProfileBuffer
;
1130 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
1131 UINTN MinimalSizeNeeded
;
1132 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
1134 EFI_MEMORY_DESCRIPTOR
*Entry
;
1138 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1139 BOOLEAN RecordingState
;
1141 ProfileBuffer
= NULL
;
1143 Status
= gBS
->LocateProtocol (&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**) &SmmCommunication
);
1144 if (EFI_ERROR (Status
)) {
1145 DEBUG ((EFI_D_ERROR
, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status
));
1149 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
1151 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
),
1152 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
),
1153 sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
)));
1154 MinimalSizeNeeded
+= MAX (sizeof (MEMORY_PROFILE_CONTEXT
),
1155 MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO
),
1156 MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO
),
1157 MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR
),
1158 MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY
),
1159 sizeof (MEMORY_PROFILE_MEMORY_RANGE
))))));
1161 Status
= EfiGetSystemConfigurationTable (
1162 &gEdkiiPiSmmCommunicationRegionTableGuid
,
1163 (VOID
**) &PiSmmCommunicationRegionTable
1165 if (EFI_ERROR (Status
)) {
1166 DEBUG ((EFI_D_ERROR
, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status
));
1169 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
1170 Entry
= (EFI_MEMORY_DESCRIPTOR
*) (PiSmmCommunicationRegionTable
+ 1);
1172 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
1173 if (Entry
->Type
== EfiConventionalMemory
) {
1174 Size
= EFI_PAGES_TO_SIZE ((UINTN
) Entry
->NumberOfPages
);
1175 if (Size
>= MinimalSizeNeeded
) {
1179 Entry
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
1181 ASSERT (Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
);
1182 CommBuffer
= (UINT8
*) (UINTN
) Entry
->PhysicalStart
;
1185 // Set recording state if needed.
1187 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1189 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1190 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1191 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1193 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1194 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE
;
1195 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1196 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1197 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1199 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1200 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1201 if (EFI_ERROR (Status
)) {
1202 DEBUG ((EFI_D_ERROR
, "SmramProfile: SmmCommunication - %r\n", Status
));
1206 if (CommRecordingState
->Header
.ReturnStatus
!= 0) {
1207 Print (L
"SmramProfile: GetRecordingState - 0x%0x\n", CommRecordingState
->Header
.ReturnStatus
);
1210 RecordingState
= CommRecordingState
->RecordingState
;
1211 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1212 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1213 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1214 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1216 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1217 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1218 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1219 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1220 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1222 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1223 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1229 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1230 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1231 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
);
1233 CommGetProfileInfo
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1234 CommGetProfileInfo
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
;
1235 CommGetProfileInfo
->Header
.DataLength
= sizeof (*CommGetProfileInfo
);
1236 CommGetProfileInfo
->Header
.ReturnStatus
= (UINT64
)-1;
1237 CommGetProfileInfo
->ProfileSize
= 0;
1239 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1240 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1241 ASSERT_EFI_ERROR (Status
);
1243 if (CommGetProfileInfo
->Header
.ReturnStatus
!= 0) {
1244 Status
= EFI_SUCCESS
;
1245 Print (L
"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo
->Header
.ReturnStatus
);
1249 ProfileSize
= (UINTN
) CommGetProfileInfo
->ProfileSize
;
1254 ProfileBuffer
= AllocateZeroPool (ProfileSize
);
1255 if (ProfileBuffer
== NULL
) {
1256 Status
= EFI_OUT_OF_RESOURCES
;
1257 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize
, Status
);
1261 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1262 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof(gEdkiiMemoryProfileGuid
));
1263 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
);
1265 CommGetProfileData
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1266 CommGetProfileData
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET
;
1267 CommGetProfileData
->Header
.DataLength
= sizeof (*CommGetProfileData
);
1268 CommGetProfileData
->Header
.ReturnStatus
= (UINT64
)-1;
1270 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1271 Buffer
= (UINT8
*) CommHeader
+ CommSize
;
1274 CommGetProfileData
->ProfileBuffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
1275 CommGetProfileData
->ProfileOffset
= 0;
1276 while (CommGetProfileData
->ProfileOffset
< ProfileSize
) {
1277 Offset
= (UINTN
) CommGetProfileData
->ProfileOffset
;
1278 if (Size
<= (ProfileSize
- CommGetProfileData
->ProfileOffset
)) {
1279 CommGetProfileData
->ProfileSize
= (UINT64
) Size
;
1281 CommGetProfileData
->ProfileSize
= (UINT64
) (ProfileSize
- CommGetProfileData
->ProfileOffset
);
1283 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1284 ASSERT_EFI_ERROR (Status
);
1286 if (CommGetProfileData
->Header
.ReturnStatus
!= 0) {
1287 Status
= EFI_SUCCESS
;
1288 Print (L
"GetProfileData - 0x%x\n", CommGetProfileData
->Header
.ReturnStatus
);
1291 CopyMem ((UINT8
*) ProfileBuffer
+ Offset
, (VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
, (UINTN
) CommGetProfileData
->ProfileSize
);
1295 Print (L
"SmramProfileSize - 0x%x\n", ProfileSize
);
1296 Print (L
"======= SmramProfile begin =======\n");
1297 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) ProfileBuffer
, ProfileSize
, TRUE
);
1300 // Dump summary information
1302 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
) (UINTN
) ProfileBuffer
, ProfileSize
);
1303 if (MemoryProfileContextSummaryData
!= NULL
) {
1304 DumpContextSummaryData (MemoryProfileContextSummaryData
, TRUE
);
1305 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1308 Print (L
"======= SmramProfile end =======\n\n\n");
1311 if (ProfileBuffer
!= NULL
) {
1312 FreePool (ProfileBuffer
);
1316 // Restore recording state if needed.
1318 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1319 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1320 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1321 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1323 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1324 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1325 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1326 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1327 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_ENABLE
;
1329 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1330 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1337 The user Entry Point for Application. The user code starts with this function
1338 as the real entry point for the image goes into a library that calls this function.
1340 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1341 @param[in] SystemTable A pointer to the EFI System Table.
1343 @retval EFI_SUCCESS The entry point is executed successfully.
1344 @retval other Some error occurs when executing this entry point.
1350 IN EFI_HANDLE ImageHandle
,
1351 IN EFI_SYSTEM_TABLE
*SystemTable
1356 Status
= GetUefiMemoryProfileData ();
1357 if (EFI_ERROR (Status
)) {
1358 DEBUG ((EFI_D_ERROR
, "GetUefiMemoryProfileData - %r\n", Status
));
1361 Status
= GetSmramProfileData ();
1362 if (EFI_ERROR (Status
)) {
1363 DEBUG ((EFI_D_ERROR
, "GetSmramProfileData - %r\n", Status
));