3 Copyright (c) 2014 - 2016, 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/ZeroGuid.h>
31 #include <Guid/MemoryProfile.h>
32 #include <Guid/PiSmmCommunicationRegionTable.h>
34 CHAR8
*mActionString
[] = {
42 CHAR8
*mSmmActionString
[] = {
44 "gSmst->SmmAllocatePages",
45 "gSmst->SmmFreePages",
46 "gSmst->SmmAllocatePool",
51 MEMORY_PROFILE_ACTION Action
;
55 ACTION_STRING mExtActionString
[] = {
56 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES
, "Lib:AllocatePages"},
57 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES
, "Lib:AllocateRuntimePages"},
58 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES
, "Lib:AllocateReservedPages"},
59 {MEMORY_PROFILE_ACTION_LIB_FREE_PAGES
, "Lib:FreePages"},
60 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES
, "Lib:AllocateAlignedPages"},
61 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES
, "Lib:AllocateAlignedRuntimePages"},
62 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES
, "Lib:AllocateAlignedReservedPages"},
63 {MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES
, "Lib:FreeAlignedPages"},
64 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL
, "Lib:AllocatePool"},
65 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL
, "Lib:AllocateRuntimePool"},
66 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL
, "Lib:AllocateReservedPool"},
67 {MEMORY_PROFILE_ACTION_LIB_FREE_POOL
, "Lib:FreePool"},
68 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL
, "Lib:AllocateZeroPool"},
69 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL
, "Lib:AllocateRuntimeZeroPool"},
70 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL
, "Lib:AllocateReservedZeroPool"},
71 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL
, "Lib:AllocateCopyPool"},
72 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL
, "Lib:AllocateRuntimeCopyPool"},
73 {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL
, "Lib:AllocateReservedCopyPool"},
74 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL
, "Lib:ReallocatePool"},
75 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL
, "Lib:ReallocateRuntimePool"},
76 {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL
, "Lib:ReallocateReservedPool"},
79 CHAR8 mUserDefinedActionString
[] = {"UserDefined-0x80000000"};
81 CHAR8
*mMemoryTypeString
[] = {
82 "EfiReservedMemoryType",
85 "EfiBootServicesCode",
86 "EfiBootServicesData",
87 "EfiRuntimeServicesCode",
88 "EfiRuntimeServicesData",
89 "EfiConventionalMemory",
91 "EfiACPIReclaimMemory",
94 "EfiMemoryMappedIOPortSpace",
96 "EfiPersistentMemory",
101 CHAR8
*mSubsystemString
[] = {
113 "EFI_BOOT_SERVICE_DRIVER",
114 "EFI_RUNTIME_DRIVER",
120 CHAR8
*mFileTypeString
[] = {
129 "COMBINED_PEIM_DRIVER",
132 "FIRMWARE_VOLUME_IMAGE",
137 #define PROFILE_NAME_STRING_LENGTH 64
138 CHAR8 mNameString
[PROFILE_NAME_STRING_LENGTH
+ 1];
141 // Profile summary information
143 #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE SIGNATURE_32 ('M','P','A','S')
144 #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION 0x0001
147 MEMORY_PROFILE_COMMON_HEADER Header
;
148 PHYSICAL_ADDRESS CallerAddress
;
149 MEMORY_PROFILE_ACTION Action
;
151 UINT32 AllocateCount
;
153 } MEMORY_PROFILE_ALLOC_SUMMARY_INFO
;
157 MEMORY_PROFILE_ALLOC_SUMMARY_INFO AllocSummaryInfo
;
159 } MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
;
163 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
164 LIST_ENTRY
*AllocSummaryInfoList
;
166 } MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
;
170 MEMORY_PROFILE_CONTEXT
*Context
;
171 LIST_ENTRY
*DriverSummaryInfoList
;
172 } MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
;
174 LIST_ENTRY mImageSummaryQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mImageSummaryQueue
);
175 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA mMemoryProfileContextSummary
;
178 Get the file name portion of the Pdb File Name.
180 The portion of the Pdb File Name between the last backslash and
181 either a following period or the end of the string is copied into
182 AsciiBuffer. The name is truncated, if necessary, to ensure that
183 AsciiBuffer is not overrun.
185 @param[in] PdbFileName Pdb file name.
186 @param[out] AsciiBuffer The resultant Ascii File Name.
190 GetShortPdbFileName (
191 IN CHAR8
*PdbFileName
,
192 OUT CHAR8
*AsciiBuffer
195 UINTN IndexPdb
; // Current work location within a Pdb string.
196 UINTN IndexBuffer
; // Current work location within a Buffer string.
200 ZeroMem (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1);
202 if (PdbFileName
== NULL
) {
203 AsciiStrnCpyS (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1, " ", 1);
206 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++);
207 for (IndexPdb
= 0; PdbFileName
[IndexPdb
] != 0; IndexPdb
++) {
208 if ((PdbFileName
[IndexPdb
] == '\\') || (PdbFileName
[IndexPdb
] == '/')) {
209 StartIndex
= IndexPdb
+ 1;
212 if (PdbFileName
[IndexPdb
] == '.') {
218 for (IndexPdb
= StartIndex
; IndexPdb
< EndIndex
; IndexPdb
++) {
219 AsciiBuffer
[IndexBuffer
] = PdbFileName
[IndexPdb
];
221 if (IndexBuffer
>= PROFILE_NAME_STRING_LENGTH
) {
222 AsciiBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
230 Get a human readable name for an image.
231 The following methods will be tried orderly:
236 @param[in] DriverInfo Pointer to memory profile driver info.
238 @return The resulting Ascii name string is stored in the mNameString global array.
242 GetDriverNameString (
243 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
251 // Method 1: Get the name string from image PDB
253 if (DriverInfo
->Header
.Length
> sizeof (MEMORY_PROFILE_DRIVER_INFO
)) {
254 GetShortPdbFileName ((CHAR8
*) (DriverInfo
+ 1), mNameString
);
258 if (!CompareGuid (&DriverInfo
->FileName
, &gZeroGuid
)) {
260 // Try to get the image's FFS UI section by image GUID
264 Status
= GetSectionFromAnyFv (
265 &DriverInfo
->FileName
,
266 EFI_SECTION_USER_INTERFACE
,
268 (VOID
**) &NameString
,
271 if (!EFI_ERROR (Status
)) {
273 // Method 2: Get the name string from FFS UI section
275 if (StrLen (NameString
) > PROFILE_NAME_STRING_LENGTH
) {
276 NameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
278 UnicodeStrToAsciiStrS (NameString
, mNameString
, sizeof (mNameString
));
279 FreePool (NameString
);
285 // Method 3: Get the name string from image GUID
287 AsciiSPrint (mNameString
, sizeof (mNameString
), "%g", &DriverInfo
->FileName
);
292 Memory type to string.
294 @param[in] MemoryType Memory type.
296 @return Pointer to string.
300 ProfileMemoryTypeToStr (
301 IN EFI_MEMORY_TYPE MemoryType
306 if ((UINT32
) MemoryType
>= 0x80000000) {
308 // OS reserved memory type.
310 Index
= EfiMaxMemoryType
;
311 } else if ((UINT32
) MemoryType
>= 0x70000000) {
313 // OEM reserved memory type.
315 Index
= EfiMaxMemoryType
+ 1;
320 return mMemoryTypeString
[Index
];
326 @param[in] Action Profile action.
327 @param[in] UserDefinedActionString Pointer to user defined action string.
328 @param[in] IsForSmm TRUE - SMRAM profile.
329 FALSE - UEFI memory profile.
331 @return Pointer to string.
336 IN MEMORY_PROFILE_ACTION Action
,
337 IN CHAR8
*UserDefinedActionString
,
342 UINTN ActionStringCount
;
343 CHAR8
**ActionString
;
346 ActionString
= mSmmActionString
;
347 ActionStringCount
= sizeof (mSmmActionString
) / sizeof (mSmmActionString
[0]);
349 ActionString
= mActionString
;
350 ActionStringCount
= sizeof (mActionString
) / sizeof (mActionString
[0]);
353 if ((UINTN
) (UINT32
) Action
< ActionStringCount
) {
354 return ActionString
[Action
];
356 for (Index
= 0; Index
< sizeof (mExtActionString
) / sizeof (mExtActionString
[0]); Index
++) {
357 if (mExtActionString
[Index
].Action
== Action
) {
358 return mExtActionString
[Index
].String
;
361 if ((Action
& MEMORY_PROFILE_ACTION_USER_DEFINED_MASK
) != 0) {
362 if (UserDefinedActionString
!= NULL
) {
363 return UserDefinedActionString
;
365 AsciiSPrint (mUserDefinedActionString
, sizeof (mUserDefinedActionString
), "UserDefined-0x%08x", Action
);
366 return mUserDefinedActionString
;
369 return ActionString
[0];
373 Dump memory profile allocate information.
375 @param[in] DriverInfo Pointer to memory profile driver info.
376 @param[in] AllocIndex Memory profile alloc info index.
377 @param[in] AllocInfo Pointer to memory profile alloc info.
378 @param[in] IsForSmm TRUE - SMRAM profile.
379 FALSE - UEFI memory profile.
381 @return Pointer to next memory profile alloc info.
384 MEMORY_PROFILE_ALLOC_INFO
*
385 DumpMemoryProfileAllocInfo (
386 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
388 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
,
394 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
398 if (AllocInfo
->ActionStringOffset
!= 0) {
399 ActionString
= (CHAR8
*) ((UINTN
) AllocInfo
+ AllocInfo
->ActionStringOffset
);
404 Print (L
" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
);
405 Print (L
" Signature - 0x%08x\n", AllocInfo
->Header
.Signature
);
406 Print (L
" Length - 0x%04x\n", AllocInfo
->Header
.Length
);
407 Print (L
" Revision - 0x%04x\n", AllocInfo
->Header
.Revision
);
408 Print (L
" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, (UINTN
) (AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
409 Print (L
" SequenceId - 0x%08x\n", AllocInfo
->SequenceId
);
410 Print (L
" Action - 0x%08x (%a)\n", AllocInfo
->Action
, ProfileActionToStr (AllocInfo
->Action
, ActionString
, IsForSmm
));
411 Print (L
" MemoryType - 0x%08x (%a)\n", AllocInfo
->MemoryType
, ProfileMemoryTypeToStr (AllocInfo
->MemoryType
));
412 Print (L
" Buffer - 0x%016lx\n", AllocInfo
->Buffer
);
413 Print (L
" Size - 0x%016lx\n", AllocInfo
->Size
);
415 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
419 Dump memory profile driver information.
421 @param[in] DriverIndex Memory profile driver info index.
422 @param[in] DriverInfo Pointer to memory profile driver info.
423 @param[in] IsForSmm TRUE - SMRAM profile.
424 FALSE - UEFI memory profile.
426 @return Pointer to next memory profile driver info.
429 MEMORY_PROFILE_DRIVER_INFO
*
430 DumpMemoryProfileDriverInfo (
431 IN UINTN DriverIndex
,
432 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
437 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
441 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
));
453 Print (L
" ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
);
454 Print (L
" ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
);
455 Print (L
" EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
);
456 Print (L
" ImageSubsystem - 0x%04x (%a)\n", DriverInfo
->ImageSubsystem
, mSubsystemString
[(DriverInfo
->ImageSubsystem
< sizeof(mSubsystemString
)/sizeof(mSubsystemString
[0])) ? DriverInfo
->ImageSubsystem
: 0]);
457 Print (L
" FileType - 0x%02x (%a)\n", DriverInfo
->FileType
, mFileTypeString
[(DriverInfo
->FileType
< sizeof(mFileTypeString
)/sizeof(mFileTypeString
[0])) ? DriverInfo
->FileType
: 0]);
458 Print (L
" CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
);
459 Print (L
" PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
);
460 for (TypeIndex
= 0; TypeIndex
< sizeof (DriverInfo
->CurrentUsageByType
) / sizeof (DriverInfo
->CurrentUsageByType
[0]); TypeIndex
++) {
461 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
462 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
463 Print (L
" CurrentUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
464 Print (L
" PeakUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
467 Print (L
" AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
);
469 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
470 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
471 AllocInfo
= DumpMemoryProfileAllocInfo (DriverInfo
, AllocIndex
, AllocInfo
, IsForSmm
);
472 if (AllocInfo
== NULL
) {
476 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
480 Dump memory profile context information.
482 @param[in] Context Pointer to memory profile context.
483 @param[in] IsForSmm TRUE - SMRAM profile.
484 FALSE - UEFI memory profile.
486 @return Pointer to the end of memory profile context buffer.
490 DumpMemoryProfileContext (
491 IN MEMORY_PROFILE_CONTEXT
*Context
,
496 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
499 if (Context
->Header
.Signature
!= MEMORY_PROFILE_CONTEXT_SIGNATURE
) {
502 Print (L
"MEMORY_PROFILE_CONTEXT\n");
503 Print (L
" Signature - 0x%08x\n", Context
->Header
.Signature
);
504 Print (L
" Length - 0x%04x\n", Context
->Header
.Length
);
505 Print (L
" Revision - 0x%04x\n", Context
->Header
.Revision
);
506 Print (L
" CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
);
507 Print (L
" PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
);
508 for (TypeIndex
= 0; TypeIndex
< sizeof (Context
->CurrentTotalUsageByType
) / sizeof (Context
->CurrentTotalUsageByType
[0]); TypeIndex
++) {
509 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
510 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
511 Print (L
" CurrentTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
512 Print (L
" PeakTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
515 Print (L
" TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
);
516 Print (L
" ImageCount - 0x%08x\n", Context
->ImageCount
);
517 Print (L
" SequenceCount - 0x%08x\n", Context
->SequenceCount
);
519 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
520 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
521 DriverInfo
= DumpMemoryProfileDriverInfo (DriverIndex
, DriverInfo
, IsForSmm
);
522 if (DriverInfo
== NULL
) {
526 return (VOID
*) DriverInfo
;
530 Dump memory profile descriptor information.
532 @param[in] DescriptorIndex Memory profile descriptor index.
533 @param[in] Descriptor Pointer to memory profile descriptor.
535 @return Pointer to next memory profile descriptor.
538 MEMORY_PROFILE_DESCRIPTOR
*
539 DumpMemoryProfileDescriptor (
540 IN UINTN DescriptorIndex
,
541 IN MEMORY_PROFILE_DESCRIPTOR
*Descriptor
544 if (Descriptor
->Header
.Signature
!= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
) {
547 Print (L
" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex
);
548 Print (L
" Signature - 0x%08x\n", Descriptor
->Header
.Signature
);
549 Print (L
" Length - 0x%04x\n", Descriptor
->Header
.Length
);
550 Print (L
" Revision - 0x%04x\n", Descriptor
->Header
.Revision
);
551 Print (L
" Address - 0x%016lx\n", Descriptor
->Address
);
552 Print (L
" Size - 0x%016lx\n", Descriptor
->Size
);
554 return (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) Descriptor
+ Descriptor
->Header
.Length
);
558 Dump memory profile free memory information.
560 @param[in] FreeMemory Pointer to memory profile free memory.
562 @return Pointer to the end of memory profile free memory buffer.
566 DumpMemoryProfileFreeMemory (
567 IN MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
570 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
571 UINTN DescriptorIndex
;
573 if (FreeMemory
->Header
.Signature
!= MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
) {
576 Print (L
"MEMORY_PROFILE_FREE_MEMORY\n");
577 Print (L
" Signature - 0x%08x\n", FreeMemory
->Header
.Signature
);
578 Print (L
" Length - 0x%04x\n", FreeMemory
->Header
.Length
);
579 Print (L
" Revision - 0x%04x\n", FreeMemory
->Header
.Revision
);
580 Print (L
" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory
->TotalFreeMemoryPages
);
581 Print (L
" FreeMemoryEntryCount - 0x%08x\n", FreeMemory
->FreeMemoryEntryCount
);
583 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) FreeMemory
+ FreeMemory
->Header
.Length
);
584 for (DescriptorIndex
= 0; DescriptorIndex
< FreeMemory
->FreeMemoryEntryCount
; DescriptorIndex
++) {
585 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
586 if (Descriptor
== NULL
) {
591 return (VOID
*) Descriptor
;
595 Dump memory profile memory range information.
597 @param[in] MemoryRange Pointer to memory profile memory range.
599 @return Pointer to the end of memory profile memory range buffer.
603 DumpMemoryProfileMemoryRange (
604 IN MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
607 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
608 UINTN DescriptorIndex
;
610 if (MemoryRange
->Header
.Signature
!= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
) {
613 Print (L
"MEMORY_PROFILE_MEMORY_RANGE\n");
614 Print (L
" Signature - 0x%08x\n", MemoryRange
->Header
.Signature
);
615 Print (L
" Length - 0x%04x\n", MemoryRange
->Header
.Length
);
616 Print (L
" Revision - 0x%04x\n", MemoryRange
->Header
.Revision
);
617 Print (L
" MemoryRangeCount - 0x%08x\n", MemoryRange
->MemoryRangeCount
);
619 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) MemoryRange
+ MemoryRange
->Header
.Length
);
620 for (DescriptorIndex
= 0; DescriptorIndex
< MemoryRange
->MemoryRangeCount
; DescriptorIndex
++) {
621 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
622 if (Descriptor
== NULL
) {
627 return (VOID
*) Descriptor
;
631 Scan memory profile by Signature.
633 @param[in] ProfileBuffer Memory profile base address.
634 @param[in] ProfileSize Memory profile size.
635 @param[in] Signature Signature.
637 @return Pointer to the stucture with the signature.
641 ScanMemoryProfileBySignature (
642 IN PHYSICAL_ADDRESS ProfileBuffer
,
643 IN UINT64 ProfileSize
,
647 MEMORY_PROFILE_COMMON_HEADER
*CommonHeader
;
650 ProfileEnd
= (UINTN
) (ProfileBuffer
+ ProfileSize
);
651 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) (UINTN
) ProfileBuffer
;
652 while ((UINTN
) CommonHeader
< ProfileEnd
) {
653 if (CommonHeader
->Signature
== Signature
) {
657 return (VOID
*) CommonHeader
;
659 if (CommonHeader
->Length
== 0) {
663 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) ((UINTN
) CommonHeader
+ CommonHeader
->Length
);
670 Dump memory profile information.
672 @param[in] ProfileBuffer Memory profile base address.
673 @param[in] ProfileSize Memory profile size.
674 @param[in] IsForSmm TRUE - SMRAM profile.
675 FALSE - UEFI memory profile.
680 IN PHYSICAL_ADDRESS ProfileBuffer
,
681 IN UINT64 ProfileSize
,
685 MEMORY_PROFILE_CONTEXT
*Context
;
686 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
687 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
689 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
690 if (Context
!= NULL
) {
691 DumpMemoryProfileContext (Context
, IsForSmm
);
694 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
);
695 if (FreeMemory
!= NULL
) {
696 DumpMemoryProfileFreeMemory (FreeMemory
);
699 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
);
700 if (MemoryRange
!= NULL
) {
701 DumpMemoryProfileMemoryRange (MemoryRange
);
706 Get Allocate summary information structure by caller address.
708 @param[in] CallerAddress Caller address.
709 @param[in] DriverSummaryInfoData Driver summary information data structure.
711 @return Allocate summary information structure by caller address.
714 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*
715 GetAllocSummaryInfoByCallerAddress (
716 IN PHYSICAL_ADDRESS CallerAddress
,
717 IN MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
720 LIST_ENTRY
*AllocSummaryInfoList
;
721 LIST_ENTRY
*AllocSummaryLink
;
722 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
723 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
725 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
727 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
728 AllocSummaryLink
!= AllocSummaryInfoList
;
729 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
) {
730 AllocSummaryInfoData
= CR (
732 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
734 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
736 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
737 if (AllocSummaryInfo
->CallerAddress
== CallerAddress
) {
738 return AllocSummaryInfoData
;
745 Create Allocate summary information structure and
746 link to Driver summary information data structure.
748 @param[in, out] DriverSummaryInfoData Driver summary information data structure.
749 @param[in] AllocInfo Pointer to memory profile alloc info.
751 @return Pointer to next memory profile alloc info.
754 MEMORY_PROFILE_ALLOC_INFO
*
755 CreateAllocSummaryInfo (
756 IN OUT MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
,
757 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
760 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
761 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
763 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
767 AllocSummaryInfoData
= GetAllocSummaryInfoByCallerAddress (AllocInfo
->CallerAddress
, DriverSummaryInfoData
);
768 if (AllocSummaryInfoData
== NULL
) {
769 AllocSummaryInfoData
= AllocatePool (sizeof (*AllocSummaryInfoData
));
770 if (AllocSummaryInfoData
== NULL
) {
774 AllocSummaryInfoData
->Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
775 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
776 AllocSummaryInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
;
777 AllocSummaryInfo
->Header
.Length
= sizeof (*AllocSummaryInfo
);
778 AllocSummaryInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION
;
779 AllocSummaryInfo
->CallerAddress
= AllocInfo
->CallerAddress
;
780 AllocSummaryInfo
->Action
= AllocInfo
->Action
;
781 if (AllocInfo
->ActionStringOffset
!= 0) {
782 AllocSummaryInfo
->ActionString
= (CHAR8
*) ((UINTN
) AllocInfo
+ AllocInfo
->ActionStringOffset
);
784 AllocSummaryInfo
->ActionString
= NULL
;
786 AllocSummaryInfo
->AllocateCount
= 0;
787 AllocSummaryInfo
->TotalSize
= 0;
788 InsertTailList (DriverSummaryInfoData
->AllocSummaryInfoList
, &AllocSummaryInfoData
->Link
);
790 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
791 AllocSummaryInfo
->AllocateCount
++;
792 AllocSummaryInfo
->TotalSize
+= AllocInfo
->Size
;
794 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
798 Create Driver summary information structure and
799 link to Context summary information data structure.
801 @param[in, out] ContextSummaryData Context summary information data structure.
802 @param[in] DriverInfo Pointer to memory profile driver info.
804 @return Pointer to next memory profile driver info.
807 MEMORY_PROFILE_DRIVER_INFO
*
808 CreateDriverSummaryInfo (
809 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
810 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
813 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
814 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
817 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
821 DriverSummaryInfoData
= AllocatePool (sizeof (*DriverSummaryInfoData
) + sizeof (LIST_ENTRY
));
822 if (DriverSummaryInfoData
== NULL
) {
825 DriverSummaryInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
826 DriverSummaryInfoData
->DriverInfo
= DriverInfo
;
827 DriverSummaryInfoData
->AllocSummaryInfoList
= (LIST_ENTRY
*) (DriverSummaryInfoData
+ 1);
828 InitializeListHead (DriverSummaryInfoData
->AllocSummaryInfoList
);
829 InsertTailList (ContextSummaryData
->DriverSummaryInfoList
, &DriverSummaryInfoData
->Link
);
831 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
832 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
833 AllocInfo
= CreateAllocSummaryInfo (DriverSummaryInfoData
, AllocInfo
);
834 if (AllocInfo
== NULL
) {
838 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
842 Create Context summary information structure.
844 @param[in] ProfileBuffer Memory profile base address.
845 @param[in] ProfileSize Memory profile size.
847 @return Context summary information structure.
850 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*
851 CreateContextSummaryData (
852 IN PHYSICAL_ADDRESS ProfileBuffer
,
853 IN UINT64 ProfileSize
856 MEMORY_PROFILE_CONTEXT
*Context
;
857 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
860 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
861 if (Context
== NULL
) {
865 mMemoryProfileContextSummary
.Signature
= MEMORY_PROFILE_CONTEXT_SIGNATURE
;
866 mMemoryProfileContextSummary
.Context
= Context
;
867 mMemoryProfileContextSummary
.DriverSummaryInfoList
= &mImageSummaryQueue
;
869 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
870 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
871 DriverInfo
= CreateDriverSummaryInfo (&mMemoryProfileContextSummary
, DriverInfo
);
872 if (DriverInfo
== NULL
) {
877 return &mMemoryProfileContextSummary
;
881 Dump Context summary information.
883 @param[in] ContextSummaryData Context summary information data.
884 @param[in] IsForSmm TRUE - SMRAM profile.
885 FALSE - UEFI memory profile.
889 DumpContextSummaryData (
890 IN MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
,
894 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
895 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
896 LIST_ENTRY
*DriverSummaryInfoList
;
897 LIST_ENTRY
*DriverSummaryLink
;
898 LIST_ENTRY
*AllocSummaryInfoList
;
899 LIST_ENTRY
*AllocSummaryLink
;
900 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
901 MEMORY_PROFILE_ALLOC_SUMMARY_INFO
*AllocSummaryInfo
;
904 if (ContextSummaryData
== NULL
) {
908 Print (L
"\nSummary Data:\n");
910 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
911 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
912 DriverSummaryLink
!= DriverSummaryInfoList
;
913 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
) {
914 DriverSummaryInfoData
= CR (
916 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
918 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
920 DriverInfo
= DriverSummaryInfoData
->DriverInfo
;
922 NameString
= GetDriverNameString (DriverInfo
);
923 Print (L
"\nDriver - %a (Usage - 0x%08x)", NameString
, DriverInfo
->CurrentUsage
);
924 if (DriverInfo
->CurrentUsage
== 0) {
929 if (DriverInfo
->PdbStringOffset
!= 0) {
930 Print (L
" (Pdb - %a)\n", (CHAR8
*) ((UINTN
) DriverInfo
+ DriverInfo
->PdbStringOffset
));
934 Print (L
"Caller List:\n");
935 Print(L
" Count Size RVA Action\n");
936 Print(L
"========== ================== ================== (================================)\n");
937 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
938 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
939 AllocSummaryLink
!= AllocSummaryInfoList
;
940 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
) {
941 AllocSummaryInfoData
= CR (
943 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
945 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
947 AllocSummaryInfo
= &AllocSummaryInfoData
->AllocSummaryInfo
;
949 Print(L
"0x%08x 0x%016lx <== 0x%016lx",
950 AllocSummaryInfo
->AllocateCount
,
951 AllocSummaryInfo
->TotalSize
,
952 AllocSummaryInfo
->CallerAddress
- DriverInfo
->ImageBase
954 Print (L
" (%a)\n", ProfileActionToStr (AllocSummaryInfo
->Action
, AllocSummaryInfo
->ActionString
, IsForSmm
));
961 Destroy Context summary information.
963 @param[in, out] ContextSummaryData Context summary information data.
967 DestroyContextSummaryData (
968 IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*ContextSummaryData
971 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
*DriverSummaryInfoData
;
972 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
*AllocSummaryInfoData
;
973 LIST_ENTRY
*DriverSummaryInfoList
;
974 LIST_ENTRY
*DriverSummaryLink
;
975 LIST_ENTRY
*AllocSummaryInfoList
;
976 LIST_ENTRY
*AllocSummaryLink
;
978 if (ContextSummaryData
== NULL
) {
982 DriverSummaryInfoList
= ContextSummaryData
->DriverSummaryInfoList
;
983 for (DriverSummaryLink
= DriverSummaryInfoList
->ForwardLink
;
984 DriverSummaryLink
!= DriverSummaryInfoList
;
986 DriverSummaryInfoData
= CR (
988 MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA
,
990 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
992 DriverSummaryLink
= DriverSummaryLink
->ForwardLink
;
994 AllocSummaryInfoList
= DriverSummaryInfoData
->AllocSummaryInfoList
;
995 for (AllocSummaryLink
= AllocSummaryInfoList
->ForwardLink
;
996 AllocSummaryLink
!= AllocSummaryInfoList
;
998 AllocSummaryInfoData
= CR (
1000 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA
,
1002 MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
1004 AllocSummaryLink
= AllocSummaryLink
->ForwardLink
;
1006 RemoveEntryList (&AllocSummaryInfoData
->Link
);
1007 FreePool (AllocSummaryInfoData
);
1010 RemoveEntryList (&DriverSummaryInfoData
->Link
);
1011 FreePool (DriverSummaryInfoData
);
1017 Get and dump UEFI memory profile data.
1019 @return EFI_SUCCESS Get the memory profile data successfully.
1020 @return other Fail to get the memory profile data.
1024 GetUefiMemoryProfileData (
1029 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
1032 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1033 BOOLEAN RecordingState
;
1035 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
1036 if (EFI_ERROR (Status
)) {
1037 DEBUG ((EFI_D_ERROR
, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status
));
1042 // Set recording state if needed.
1044 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1045 Status
= ProfileProtocol
->GetRecordingState (ProfileProtocol
, &RecordingState
);
1046 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1047 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_DISABLE
);
1052 Status
= ProfileProtocol
->GetData (
1057 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1058 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1062 Data
= AllocateZeroPool ((UINTN
) Size
);
1064 Status
= EFI_OUT_OF_RESOURCES
;
1065 Print (L
"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size
, Status
);
1069 Status
= ProfileProtocol
->GetData (
1074 if (EFI_ERROR (Status
)) {
1075 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
1080 Print (L
"UefiMemoryProfileSize - 0x%x\n", Size
);
1081 Print (L
"======= UefiMemoryProfile begin =======\n");
1082 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
, FALSE
);
1085 // Dump summary information
1087 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
);
1088 if (MemoryProfileContextSummaryData
!= NULL
) {
1089 DumpContextSummaryData (MemoryProfileContextSummaryData
, FALSE
);
1090 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1093 Print (L
"======= UefiMemoryProfile end =======\n\n\n");
1101 // Restore recording state if needed.
1103 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1104 ProfileProtocol
->SetRecordingState (ProfileProtocol
, MEMORY_PROFILE_RECORDING_ENABLE
);
1111 Get and dump SMRAM profile data.
1113 @return EFI_SUCCESS Get the SMRAM profile data successfully.
1114 @return other Fail to get the SMRAM profile data.
1118 GetSmramProfileData (
1125 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
1126 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*CommGetProfileInfo
;
1127 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*CommGetProfileData
;
1128 SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*CommRecordingState
;
1130 VOID
*ProfileBuffer
;
1131 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
1132 UINTN MinimalSizeNeeded
;
1133 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
1135 EFI_MEMORY_DESCRIPTOR
*Entry
;
1139 MEMORY_PROFILE_CONTEXT_SUMMARY_DATA
*MemoryProfileContextSummaryData
;
1140 BOOLEAN RecordingState
;
1142 ProfileBuffer
= NULL
;
1144 Status
= gBS
->LocateProtocol (&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**) &SmmCommunication
);
1145 if (EFI_ERROR (Status
)) {
1146 DEBUG ((EFI_D_ERROR
, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status
));
1150 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
1152 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
),
1153 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
),
1154 sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
)));
1155 MinimalSizeNeeded
+= MAX (sizeof (MEMORY_PROFILE_CONTEXT
),
1156 MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO
),
1157 MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO
),
1158 MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR
),
1159 MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY
),
1160 sizeof (MEMORY_PROFILE_MEMORY_RANGE
))))));
1162 Status
= EfiGetSystemConfigurationTable (
1163 &gEdkiiPiSmmCommunicationRegionTableGuid
,
1164 (VOID
**) &PiSmmCommunicationRegionTable
1166 if (EFI_ERROR (Status
)) {
1167 DEBUG ((EFI_D_ERROR
, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status
));
1170 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
1171 Entry
= (EFI_MEMORY_DESCRIPTOR
*) (PiSmmCommunicationRegionTable
+ 1);
1173 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
1174 if (Entry
->Type
== EfiConventionalMemory
) {
1175 Size
= EFI_PAGES_TO_SIZE ((UINTN
) Entry
->NumberOfPages
);
1176 if (Size
>= MinimalSizeNeeded
) {
1180 Entry
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
1182 ASSERT (Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
);
1183 CommBuffer
= (UINT8
*) (UINTN
) Entry
->PhysicalStart
;
1186 // Set recording state if needed.
1188 RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1190 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1191 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1192 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1194 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1195 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE
;
1196 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1197 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1198 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1200 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1201 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1202 if (EFI_ERROR (Status
)) {
1203 DEBUG ((EFI_D_ERROR
, "SmramProfile: SmmCommunication - %r\n", Status
));
1207 if (CommRecordingState
->Header
.ReturnStatus
!= 0) {
1208 Print (L
"SmramProfile: GetRecordingState - 0x%0x\n", CommRecordingState
->Header
.ReturnStatus
);
1211 RecordingState
= CommRecordingState
->RecordingState
;
1212 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1213 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1214 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1215 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1217 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1218 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1219 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1220 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1221 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_DISABLE
;
1223 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1224 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1230 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1231 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1232 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
);
1234 CommGetProfileInfo
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1235 CommGetProfileInfo
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
;
1236 CommGetProfileInfo
->Header
.DataLength
= sizeof (*CommGetProfileInfo
);
1237 CommGetProfileInfo
->Header
.ReturnStatus
= (UINT64
)-1;
1238 CommGetProfileInfo
->ProfileSize
= 0;
1240 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1241 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1242 ASSERT_EFI_ERROR (Status
);
1244 if (CommGetProfileInfo
->Header
.ReturnStatus
!= 0) {
1245 Status
= EFI_SUCCESS
;
1246 Print (L
"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo
->Header
.ReturnStatus
);
1250 ProfileSize
= (UINTN
) CommGetProfileInfo
->ProfileSize
;
1255 ProfileBuffer
= AllocateZeroPool (ProfileSize
);
1256 if (ProfileBuffer
== NULL
) {
1257 Status
= EFI_OUT_OF_RESOURCES
;
1258 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize
, Status
);
1262 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1263 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof(gEdkiiMemoryProfileGuid
));
1264 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
);
1266 CommGetProfileData
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1267 CommGetProfileData
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET
;
1268 CommGetProfileData
->Header
.DataLength
= sizeof (*CommGetProfileData
);
1269 CommGetProfileData
->Header
.ReturnStatus
= (UINT64
)-1;
1271 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1272 Buffer
= (UINT8
*) CommHeader
+ CommSize
;
1275 CommGetProfileData
->ProfileBuffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
1276 CommGetProfileData
->ProfileOffset
= 0;
1277 while (CommGetProfileData
->ProfileOffset
< ProfileSize
) {
1278 Offset
= (UINTN
) CommGetProfileData
->ProfileOffset
;
1279 if (Size
<= (ProfileSize
- CommGetProfileData
->ProfileOffset
)) {
1280 CommGetProfileData
->ProfileSize
= (UINT64
) Size
;
1282 CommGetProfileData
->ProfileSize
= (UINT64
) (ProfileSize
- CommGetProfileData
->ProfileOffset
);
1284 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1285 ASSERT_EFI_ERROR (Status
);
1287 if (CommGetProfileData
->Header
.ReturnStatus
!= 0) {
1288 Status
= EFI_SUCCESS
;
1289 Print (L
"GetProfileData - 0x%x\n", CommGetProfileData
->Header
.ReturnStatus
);
1292 CopyMem ((UINT8
*) ProfileBuffer
+ Offset
, (VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
, (UINTN
) CommGetProfileData
->ProfileSize
);
1296 Print (L
"SmramProfileSize - 0x%x\n", ProfileSize
);
1297 Print (L
"======= SmramProfile begin =======\n");
1298 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) ProfileBuffer
, ProfileSize
, TRUE
);
1301 // Dump summary information
1303 MemoryProfileContextSummaryData
= CreateContextSummaryData ((PHYSICAL_ADDRESS
) (UINTN
) ProfileBuffer
, ProfileSize
);
1304 if (MemoryProfileContextSummaryData
!= NULL
) {
1305 DumpContextSummaryData (MemoryProfileContextSummaryData
, TRUE
);
1306 DestroyContextSummaryData (MemoryProfileContextSummaryData
);
1309 Print (L
"======= SmramProfile end =======\n\n\n");
1312 if (ProfileBuffer
!= NULL
) {
1313 FreePool (ProfileBuffer
);
1317 // Restore recording state if needed.
1319 if (RecordingState
== MEMORY_PROFILE_RECORDING_ENABLE
) {
1320 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
1321 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
1322 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
);
1324 CommRecordingState
= (SMRAM_PROFILE_PARAMETER_RECORDING_STATE
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
1325 CommRecordingState
->Header
.Command
= SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE
;
1326 CommRecordingState
->Header
.DataLength
= sizeof (*CommRecordingState
);
1327 CommRecordingState
->Header
.ReturnStatus
= (UINT64
)-1;
1328 CommRecordingState
->RecordingState
= MEMORY_PROFILE_RECORDING_ENABLE
;
1330 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
1331 SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
1338 The user Entry Point for Application. The user code starts with this function
1339 as the real entry point for the image goes into a library that calls this function.
1341 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1342 @param[in] SystemTable A pointer to the EFI System Table.
1344 @retval EFI_SUCCESS The entry point is executed successfully.
1345 @retval other Some error occurs when executing this entry point.
1351 IN EFI_HANDLE ImageHandle
,
1352 IN EFI_SYSTEM_TABLE
*SystemTable
1357 Status
= GetUefiMemoryProfileData ();
1358 if (EFI_ERROR (Status
)) {
1359 DEBUG ((EFI_D_ERROR
, "GetUefiMemoryProfileData - %r\n", Status
));
1362 Status
= GetSmramProfileData ();
1363 if (EFI_ERROR (Status
)) {
1364 DEBUG ((EFI_D_ERROR
, "GetSmramProfileData - %r\n", Status
));