3 Copyright (c) 2014 - 2015, 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/PeCoffGetEntryPointLib.h>
26 #include <Library/PrintLib.h>
28 #include <Protocol/SmmCommunication.h>
29 #include <Protocol/SmmAccess2.h>
31 #include <Guid/ZeroGuid.h>
32 #include <Guid/MemoryProfile.h>
34 CHAR16
*mActionString
[] = {
42 CHAR16
*mMemoryTypeString
[] = {
43 L
"EfiReservedMemoryType",
46 L
"EfiBootServicesCode",
47 L
"EfiBootServicesData",
48 L
"EfiRuntimeServicesCode",
49 L
"EfiRuntimeServicesData",
50 L
"EfiConventionalMemory",
52 L
"EfiACPIReclaimMemory",
55 L
"EfiMemoryMappedIOPortSpace",
57 L
"EfiPersistentMemory",
62 CHAR16
*mSubsystemString
[] = {
74 L
"EFI_BOOT_SERVICE_DRIVER",
75 L
"EFI_RUNTIME_DRIVER",
81 CHAR16
*mFileTypeString
[] = {
90 L
"COMBINED_PEIM_DRIVER",
93 L
"FIRMWARE_VOLUME_IMAGE",
98 #define PROFILE_NAME_STRING_LENGTH 36
99 CHAR16 mNameString
[PROFILE_NAME_STRING_LENGTH
+ 1];
102 Get the file name portion of the Pdb File Name.
104 The portion of the Pdb File Name between the last backslash and
105 either a following period or the end of the string is converted
106 to Unicode and copied into UnicodeBuffer. The name is truncated,
107 if necessary, to ensure that UnicodeBuffer is not overrun.
109 @param[in] PdbFileName Pdb file name.
110 @param[out] UnicodeBuffer The resultant Unicode File Name.
114 GetShortPdbFileName (
115 IN CHAR8
*PdbFileName
,
116 OUT CHAR16
*UnicodeBuffer
119 UINTN IndexA
; // Current work location within an ASCII string.
120 UINTN IndexU
; // Current work location within a Unicode string.
124 ZeroMem (UnicodeBuffer
, (PROFILE_NAME_STRING_LENGTH
+ 1) * sizeof (CHAR16
));
126 if (PdbFileName
== NULL
) {
127 StrnCpyS (UnicodeBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1, L
" ", 1);
130 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++);
131 for (IndexA
= 0; PdbFileName
[IndexA
] != 0; IndexA
++) {
132 if (PdbFileName
[IndexA
] == '\\') {
133 StartIndex
= IndexA
+ 1;
136 if (PdbFileName
[IndexA
] == '.') {
142 for (IndexA
= StartIndex
; IndexA
< EndIndex
; IndexA
++) {
143 UnicodeBuffer
[IndexU
] = (CHAR16
) PdbFileName
[IndexA
];
145 if (IndexU
>= PROFILE_NAME_STRING_LENGTH
) {
146 UnicodeBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
154 Get a human readable name for an image.
155 The following methods will be tried orderly:
160 @param[in] DriverInfo Pointer to memory profile driver info.
162 @post The resulting Unicode name string is stored in the mNameString global array.
166 GetDriverNameString (
167 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
176 // Method 1: Get the name string from image PDB
178 if ((DriverInfo
->ImageBase
!= 0) && (DriverInfo
->FileType
!= EFI_FV_FILETYPE_SMM
) && (DriverInfo
->FileType
!= EFI_FV_FILETYPE_SMM_CORE
)) {
179 PdbFileName
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) DriverInfo
->ImageBase
);
181 if (PdbFileName
!= NULL
) {
182 GetShortPdbFileName (PdbFileName
, mNameString
);
187 if (!CompareGuid (&DriverInfo
->FileName
, &gZeroGuid
)) {
189 // Try to get the image's FFS UI section by image GUID
193 Status
= GetSectionFromAnyFv (
194 &DriverInfo
->FileName
,
195 EFI_SECTION_USER_INTERFACE
,
197 (VOID
**) &NameString
,
200 if (!EFI_ERROR (Status
)) {
202 // Method 2: Get the name string from FFS UI section
204 StrnCpyS (mNameString
, PROFILE_NAME_STRING_LENGTH
+ 1, NameString
, PROFILE_NAME_STRING_LENGTH
);
205 mNameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
206 FreePool (NameString
);
212 // Method 3: Get the name string from image GUID
214 UnicodeSPrint (mNameString
, sizeof (mNameString
), L
"%g", &DriverInfo
->FileName
);
218 Memory type to string.
220 @param[in] MemoryType Memory type.
222 @return Pointer to string.
226 ProfileMemoryTypeToStr (
227 IN EFI_MEMORY_TYPE MemoryType
232 if ((UINT32
) MemoryType
>= 0x80000000) {
234 // OS reserved memory type.
236 Index
= EfiMaxMemoryType
;
237 } else if ((UINT32
) MemoryType
>= 0x70000000) {
239 // OEM reserved memory type.
241 Index
= EfiMaxMemoryType
+ 1;
246 return mMemoryTypeString
[Index
];
250 Dump memory profile allocate information.
252 @param[in] DriverInfo Pointer to memory profile driver info.
253 @param[in] AllocIndex Memory profile alloc info index.
254 @param[in] AllocInfo Pointer to memory profile alloc info.
256 @return Pointer to next memory profile alloc info.
259 MEMORY_PROFILE_ALLOC_INFO
*
260 DumpMemoryProfileAllocInfo (
261 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
263 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
266 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
269 Print (L
" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
);
270 Print (L
" Signature - 0x%08x\n", AllocInfo
->Header
.Signature
);
271 Print (L
" Length - 0x%04x\n", AllocInfo
->Header
.Length
);
272 Print (L
" Revision - 0x%04x\n", AllocInfo
->Header
.Revision
);
273 Print (L
" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, (UINTN
) (AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
274 Print (L
" SequenceId - 0x%08x\n", AllocInfo
->SequenceId
);
275 Print (L
" Action - 0x%08x (%s)\n", AllocInfo
->Action
, mActionString
[(AllocInfo
->Action
< sizeof(mActionString
)/sizeof(mActionString
[0])) ? AllocInfo
->Action
: 0]);
276 Print (L
" MemoryType - 0x%08x (%s)\n", AllocInfo
->MemoryType
, ProfileMemoryTypeToStr (AllocInfo
->MemoryType
));
277 Print (L
" Buffer - 0x%016lx\n", AllocInfo
->Buffer
);
278 Print (L
" Size - 0x%016lx\n", AllocInfo
->Size
);
280 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
284 Dump memory profile driver information.
286 @param[in] DriverIndex Memory profile driver info index.
287 @param[in] DriverInfo Pointer to memory profile driver info.
289 @return Pointer to next memory profile driver info.
292 MEMORY_PROFILE_DRIVER_INFO
*
293 DumpMemoryProfileDriverInfo (
294 IN UINTN DriverIndex
,
295 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
299 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
302 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
305 Print (L
" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
);
306 Print (L
" Signature - 0x%08x\n", DriverInfo
->Header
.Signature
);
307 Print (L
" Length - 0x%04x\n", DriverInfo
->Header
.Length
);
308 Print (L
" Revision - 0x%04x\n", DriverInfo
->Header
.Revision
);
309 GetDriverNameString (DriverInfo
);
310 Print (L
" FileName - %s\n", &mNameString
);
311 Print (L
" ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
);
312 Print (L
" ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
);
313 Print (L
" EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
);
314 Print (L
" ImageSubsystem - 0x%04x (%s)\n", DriverInfo
->ImageSubsystem
, mSubsystemString
[(DriverInfo
->ImageSubsystem
< sizeof(mSubsystemString
)/sizeof(mSubsystemString
[0])) ? DriverInfo
->ImageSubsystem
: 0]);
315 Print (L
" FileType - 0x%02x (%s)\n", DriverInfo
->FileType
, mFileTypeString
[(DriverInfo
->FileType
< sizeof(mFileTypeString
)/sizeof(mFileTypeString
[0])) ? DriverInfo
->FileType
: 0]);
316 Print (L
" CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
);
317 Print (L
" PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
);
318 for (TypeIndex
= 0; TypeIndex
< sizeof (DriverInfo
->CurrentUsageByType
) / sizeof (DriverInfo
->CurrentUsageByType
[0]); TypeIndex
++) {
319 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
320 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
321 Print (L
" CurrentUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
322 Print (L
" PeakUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
325 Print (L
" AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
);
327 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
328 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
329 AllocInfo
= DumpMemoryProfileAllocInfo (DriverInfo
, AllocIndex
, AllocInfo
);
330 if (AllocInfo
== NULL
) {
334 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
338 Dump memory profile context information.
340 @param[in] Context Pointer to memory profile context.
342 @return Pointer to the end of memory profile context buffer.
346 DumpMemoryProfileContext (
347 IN MEMORY_PROFILE_CONTEXT
*Context
351 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
354 if (Context
->Header
.Signature
!= MEMORY_PROFILE_CONTEXT_SIGNATURE
) {
357 Print (L
"MEMORY_PROFILE_CONTEXT\n");
358 Print (L
" Signature - 0x%08x\n", Context
->Header
.Signature
);
359 Print (L
" Length - 0x%04x\n", Context
->Header
.Length
);
360 Print (L
" Revision - 0x%04x\n", Context
->Header
.Revision
);
361 Print (L
" CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
);
362 Print (L
" PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
);
363 for (TypeIndex
= 0; TypeIndex
< sizeof (Context
->CurrentTotalUsageByType
) / sizeof (Context
->CurrentTotalUsageByType
[0]); TypeIndex
++) {
364 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
365 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
366 Print (L
" CurrentTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
367 Print (L
" PeakTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
370 Print (L
" TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
);
371 Print (L
" ImageCount - 0x%08x\n", Context
->ImageCount
);
372 Print (L
" SequenceCount - 0x%08x\n", Context
->SequenceCount
);
374 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
375 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
376 DriverInfo
= DumpMemoryProfileDriverInfo (DriverIndex
, DriverInfo
);
377 if (DriverInfo
== NULL
) {
381 return (VOID
*) DriverInfo
;
385 Dump memory profile descriptor information.
387 @param[in] DescriptorIndex Memory profile descriptor index.
388 @param[in] Descriptor Pointer to memory profile descriptor.
390 @return Pointer to next memory profile descriptor.
393 MEMORY_PROFILE_DESCRIPTOR
*
394 DumpMemoryProfileDescriptor (
395 IN UINTN DescriptorIndex
,
396 IN MEMORY_PROFILE_DESCRIPTOR
*Descriptor
399 if (Descriptor
->Header
.Signature
!= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
) {
402 Print (L
" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex
);
403 Print (L
" Signature - 0x%08x\n", Descriptor
->Header
.Signature
);
404 Print (L
" Length - 0x%04x\n", Descriptor
->Header
.Length
);
405 Print (L
" Revision - 0x%04x\n", Descriptor
->Header
.Revision
);
406 Print (L
" Address - 0x%016lx\n", Descriptor
->Address
);
407 Print (L
" Size - 0x%016lx\n", Descriptor
->Size
);
409 return (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) Descriptor
+ Descriptor
->Header
.Length
);
413 Dump memory profile free memory information.
415 @param[in] FreeMemory Pointer to memory profile free memory.
417 @return Pointer to the end of memory profile free memory buffer.
421 DumpMemoryProfileFreeMemory (
422 IN MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
425 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
426 UINTN DescriptorIndex
;
428 if (FreeMemory
->Header
.Signature
!= MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
) {
431 Print (L
"MEMORY_PROFILE_FREE_MEMORY\n");
432 Print (L
" Signature - 0x%08x\n", FreeMemory
->Header
.Signature
);
433 Print (L
" Length - 0x%04x\n", FreeMemory
->Header
.Length
);
434 Print (L
" Revision - 0x%04x\n", FreeMemory
->Header
.Revision
);
435 Print (L
" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory
->TotalFreeMemoryPages
);
436 Print (L
" FreeMemoryEntryCount - 0x%08x\n", FreeMemory
->FreeMemoryEntryCount
);
438 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) FreeMemory
+ FreeMemory
->Header
.Length
);
439 for (DescriptorIndex
= 0; DescriptorIndex
< FreeMemory
->FreeMemoryEntryCount
; DescriptorIndex
++) {
440 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
441 if (Descriptor
== NULL
) {
446 return (VOID
*) Descriptor
;
450 Dump memory profile memory range information.
452 @param[in] MemoryRange Pointer to memory profile memory range.
454 @return Pointer to the end of memory profile memory range buffer.
458 DumpMemoryProfileMemoryRange (
459 IN MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
462 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
463 UINTN DescriptorIndex
;
465 if (MemoryRange
->Header
.Signature
!= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
) {
468 Print (L
"MEMORY_PROFILE_MEMORY_RANGE\n");
469 Print (L
" Signature - 0x%08x\n", MemoryRange
->Header
.Signature
);
470 Print (L
" Length - 0x%04x\n", MemoryRange
->Header
.Length
);
471 Print (L
" Revision - 0x%04x\n", MemoryRange
->Header
.Revision
);
472 Print (L
" MemoryRangeCount - 0x%08x\n", MemoryRange
->MemoryRangeCount
);
474 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) MemoryRange
+ MemoryRange
->Header
.Length
);
475 for (DescriptorIndex
= 0; DescriptorIndex
< MemoryRange
->MemoryRangeCount
; DescriptorIndex
++) {
476 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
477 if (Descriptor
== NULL
) {
482 return (VOID
*) Descriptor
;
486 Scan memory profile by Signature.
488 @param[in] ProfileBuffer Memory profile base address.
489 @param[in] ProfileSize Memory profile size.
490 @param[in] Signature Signature.
492 @return Pointer to the stucture with the signature.
496 ScanMemoryProfileBySignature (
497 IN PHYSICAL_ADDRESS ProfileBuffer
,
498 IN UINT64 ProfileSize
,
502 MEMORY_PROFILE_COMMON_HEADER
*CommonHeader
;
505 ProfileEnd
= (UINTN
) (ProfileBuffer
+ ProfileSize
);
506 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) (UINTN
) ProfileBuffer
;
507 while ((UINTN
) CommonHeader
< ProfileEnd
) {
508 if (CommonHeader
->Signature
== Signature
) {
512 return (VOID
*) CommonHeader
;
514 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) ((UINTN
) CommonHeader
+ CommonHeader
->Length
);
521 Dump memory profile information.
523 @param[in] ProfileBuffer Memory profile base address.
524 @param[in] ProfileSize Memory profile size.
529 IN PHYSICAL_ADDRESS ProfileBuffer
,
530 IN UINT64 ProfileSize
533 MEMORY_PROFILE_CONTEXT
*Context
;
534 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
535 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
537 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
538 if (Context
!= NULL
) {
539 DumpMemoryProfileContext (Context
);
542 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
);
543 if (FreeMemory
!= NULL
) {
544 DumpMemoryProfileFreeMemory (FreeMemory
);
547 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
);
548 if (MemoryRange
!= NULL
) {
549 DumpMemoryProfileMemoryRange (MemoryRange
);
554 Get and dump UEFI memory profile data.
556 @return EFI_SUCCESS Get the memory profile data successfully.
557 @return other Fail to get the memory profile data.
561 GetUefiMemoryProfileData (
566 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
570 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
571 if (EFI_ERROR (Status
)) {
572 DEBUG ((EFI_D_ERROR
, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status
));
578 Status
= ProfileProtocol
->GetData (
583 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
584 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
589 // Add one sizeof (MEMORY_PROFILE_ALLOC_INFO) to Size for this AllocatePool action.
591 Size
= Size
+ sizeof (MEMORY_PROFILE_ALLOC_INFO
);
592 Data
= AllocateZeroPool ((UINTN
) Size
);
594 Status
= EFI_OUT_OF_RESOURCES
;
595 Print (L
"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size
, Status
);
599 Status
= ProfileProtocol
->GetData (
604 if (EFI_ERROR (Status
)) {
606 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
611 Print (L
"UefiMemoryProfileSize - 0x%x\n", Size
);
612 Print (L
"======= UefiMemoryProfile begin =======\n");
613 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
);
614 Print (L
"======= UefiMemoryProfile end =======\n\n\n");
622 Get and dump SMRAM profile data.
624 @return EFI_SUCCESS Get the SMRAM profile data successfully.
625 @return other Fail to get the SMRAM profile data.
629 GetSmramProfileData (
636 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
637 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*CommGetProfileInfo
;
638 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*CommGetProfileData
;
640 PHYSICAL_ADDRESS ProfileBuffer
;
641 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
643 Status
= gBS
->LocateProtocol (&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**) &SmmCommunication
);
644 if (EFI_ERROR (Status
)) {
645 DEBUG ((EFI_D_ERROR
, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status
));
649 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
);
650 CommBuffer
= AllocateZeroPool (CommSize
);
651 if (CommBuffer
== NULL
) {
652 Status
= EFI_OUT_OF_RESOURCES
;
653 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for comm buffer - %r\n", CommSize
, Status
);
660 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
661 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
662 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
);
664 CommGetProfileInfo
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
665 CommGetProfileInfo
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
;
666 CommGetProfileInfo
->Header
.DataLength
= sizeof (*CommGetProfileInfo
);
667 CommGetProfileInfo
->Header
.ReturnStatus
= (UINT64
)-1;
668 CommGetProfileInfo
->ProfileSize
= 0;
670 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
671 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
672 if (EFI_ERROR (Status
)) {
673 FreePool (CommBuffer
);
674 DEBUG ((EFI_D_ERROR
, "SmramProfile: SmmCommunication - %r\n", Status
));
678 if (CommGetProfileInfo
->Header
.ReturnStatus
!= 0) {
679 Print (L
"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo
->Header
.ReturnStatus
);
683 ProfileSize
= CommGetProfileInfo
->ProfileSize
;
688 ProfileBuffer
= (PHYSICAL_ADDRESS
) (UINTN
) AllocateZeroPool ((UINTN
) ProfileSize
);
689 if (ProfileBuffer
== 0) {
690 FreePool (CommBuffer
);
691 Status
= EFI_OUT_OF_RESOURCES
;
692 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", (UINTN
) ProfileSize
, Status
);
696 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
697 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof(gEdkiiMemoryProfileGuid
));
698 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
);
700 CommGetProfileData
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
701 CommGetProfileData
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA
;
702 CommGetProfileData
->Header
.DataLength
= sizeof (*CommGetProfileData
);
703 CommGetProfileData
->Header
.ReturnStatus
= (UINT64
)-1;
704 CommGetProfileData
->ProfileSize
= ProfileSize
;
705 CommGetProfileData
->ProfileBuffer
= ProfileBuffer
;
707 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
708 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
709 ASSERT_EFI_ERROR (Status
);
711 if (CommGetProfileData
->Header
.ReturnStatus
!= 0) {
712 FreePool ((VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
);
713 FreePool (CommBuffer
);
714 Print (L
"GetProfileData - 0x%x\n", CommGetProfileData
->Header
.ReturnStatus
);
719 Print (L
"SmramProfileSize - 0x%x\n", CommGetProfileData
->ProfileSize
);
720 Print (L
"======= SmramProfile begin =======\n");
721 DumpMemoryProfile (CommGetProfileData
->ProfileBuffer
, CommGetProfileData
->ProfileSize
);
722 Print (L
"======= SmramProfile end =======\n\n\n");
724 FreePool ((VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
);
725 FreePool (CommBuffer
);
731 The user Entry Point for Application. The user code starts with this function
732 as the real entry point for the image goes into a library that calls this function.
734 @param[in] ImageHandle The firmware allocated handle for the EFI image.
735 @param[in] SystemTable A pointer to the EFI System Table.
737 @retval EFI_SUCCESS The entry point is executed successfully.
738 @retval other Some error occurs when executing this entry point.
744 IN EFI_HANDLE ImageHandle
,
745 IN EFI_SYSTEM_TABLE
*SystemTable
750 Status
= GetUefiMemoryProfileData ();
751 if (EFI_ERROR (Status
)) {
752 DEBUG ((EFI_D_ERROR
, "GetUefiMemoryProfileData - %r\n", Status
));
755 Status
= GetSmramProfileData ();
756 if (EFI_ERROR (Status
)) {
757 DEBUG ((EFI_D_ERROR
, "GetSmramProfileData - %r\n", Status
));