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",
61 CHAR16
*mSubsystemString
[] = {
73 L
"EFI_BOOT_SERVICE_DRIVER",
74 L
"EFI_RUNTIME_DRIVER",
80 CHAR16
*mFileTypeString
[] = {
89 L
"COMBINED_PEIM_DRIVER",
92 L
"FIRMWARE_VOLUME_IMAGE",
97 #define PROFILE_NAME_STRING_LENGTH 36
98 CHAR16 mNameString
[PROFILE_NAME_STRING_LENGTH
+ 1];
101 Get the file name portion of the Pdb File Name.
103 The portion of the Pdb File Name between the last backslash and
104 either a following period or the end of the string is converted
105 to Unicode and copied into UnicodeBuffer. The name is truncated,
106 if necessary, to ensure that UnicodeBuffer is not overrun.
108 @param[in] PdbFileName Pdb file name.
109 @param[out] UnicodeBuffer The resultant Unicode File Name.
113 GetShortPdbFileName (
114 IN CHAR8
*PdbFileName
,
115 OUT CHAR16
*UnicodeBuffer
118 UINTN IndexA
; // Current work location within an ASCII string.
119 UINTN IndexU
; // Current work location within a Unicode string.
123 ZeroMem (UnicodeBuffer
, PROFILE_NAME_STRING_LENGTH
* sizeof (CHAR16
));
125 if (PdbFileName
== NULL
) {
126 StrnCpy (UnicodeBuffer
, L
" ", 1);
129 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++);
130 for (IndexA
= 0; PdbFileName
[IndexA
] != 0; IndexA
++) {
131 if (PdbFileName
[IndexA
] == '\\') {
132 StartIndex
= IndexA
+ 1;
135 if (PdbFileName
[IndexA
] == '.') {
141 for (IndexA
= StartIndex
; IndexA
< EndIndex
; IndexA
++) {
142 UnicodeBuffer
[IndexU
] = (CHAR16
) PdbFileName
[IndexA
];
144 if (IndexU
>= PROFILE_NAME_STRING_LENGTH
) {
145 UnicodeBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
153 Get a human readable name for an image.
154 The following methods will be tried orderly:
159 @param[in] DriverInfo Pointer to memory profile driver info.
161 @post The resulting Unicode name string is stored in the mNameString global array.
165 GetDriverNameString (
166 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
175 // Method 1: Get the name string from image PDB
177 if ((DriverInfo
->ImageBase
!= 0) && (DriverInfo
->FileType
!= EFI_FV_FILETYPE_SMM
) && (DriverInfo
->FileType
!= EFI_FV_FILETYPE_SMM_CORE
)) {
178 PdbFileName
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) DriverInfo
->ImageBase
);
180 if (PdbFileName
!= NULL
) {
181 GetShortPdbFileName (PdbFileName
, mNameString
);
186 if (!CompareGuid (&DriverInfo
->FileName
, &gZeroGuid
)) {
188 // Try to get the image's FFS UI section by image GUID
192 Status
= GetSectionFromAnyFv (
193 &DriverInfo
->FileName
,
194 EFI_SECTION_USER_INTERFACE
,
196 (VOID
**) &NameString
,
199 if (!EFI_ERROR (Status
)) {
201 // Method 2: Get the name string from FFS UI section
203 StrnCpy (mNameString
, NameString
, PROFILE_NAME_STRING_LENGTH
);
204 mNameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
205 FreePool (NameString
);
211 // Method 3: Get the name string from image GUID
213 UnicodeSPrint (mNameString
, sizeof (mNameString
), L
"%g", &DriverInfo
->FileName
);
217 Dump memory profile allocate information.
219 @param[in] DriverInfo Pointer to memory profile driver info.
220 @param[in] AllocIndex Memory profile alloc info index.
221 @param[in] AllocInfo Pointer to memory profile alloc info.
223 @return Pointer to next memory profile alloc info.
226 MEMORY_PROFILE_ALLOC_INFO
*
227 DumpMemoryProfileAllocInfo (
228 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
230 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
233 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
236 Print (L
" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
);
237 Print (L
" Signature - 0x%08x\n", AllocInfo
->Header
.Signature
);
238 Print (L
" Length - 0x%04x\n", AllocInfo
->Header
.Length
);
239 Print (L
" Revision - 0x%04x\n", AllocInfo
->Header
.Revision
);
240 Print (L
" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, (UINTN
) (AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
241 Print (L
" SequenceId - 0x%08x\n", AllocInfo
->SequenceId
);
242 Print (L
" Action - 0x%08x (%s)\n", AllocInfo
->Action
, mActionString
[(AllocInfo
->Action
< sizeof(mActionString
)/sizeof(mActionString
[0])) ? AllocInfo
->Action
: 0]);
243 Print (L
" MemoryType - 0x%08x (%s)\n", AllocInfo
->MemoryType
, mMemoryTypeString
[(AllocInfo
->MemoryType
< sizeof(mMemoryTypeString
)/sizeof(mMemoryTypeString
[0])) ? AllocInfo
->MemoryType
: (sizeof(mMemoryTypeString
)/sizeof(mMemoryTypeString
[0]) - 1)]);
244 Print (L
" Buffer - 0x%016lx\n", AllocInfo
->Buffer
);
245 Print (L
" Size - 0x%016lx\n", AllocInfo
->Size
);
247 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
251 Dump memory profile driver information.
253 @param[in] DriverIndex Memory profile driver info index.
254 @param[in] DriverInfo Pointer to memory profile driver info.
256 @return Pointer to next memory profile driver info.
259 MEMORY_PROFILE_DRIVER_INFO
*
260 DumpMemoryProfileDriverInfo (
261 IN UINTN DriverIndex
,
262 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
266 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
269 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
272 Print (L
" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
);
273 Print (L
" Signature - 0x%08x\n", DriverInfo
->Header
.Signature
);
274 Print (L
" Length - 0x%04x\n", DriverInfo
->Header
.Length
);
275 Print (L
" Revision - 0x%04x\n", DriverInfo
->Header
.Revision
);
276 GetDriverNameString (DriverInfo
);
277 Print (L
" FileName - %s\n", &mNameString
);
278 Print (L
" ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
);
279 Print (L
" ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
);
280 Print (L
" EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
);
281 Print (L
" ImageSubsystem - 0x%04x (%s)\n", DriverInfo
->ImageSubsystem
, mSubsystemString
[(DriverInfo
->ImageSubsystem
< sizeof(mSubsystemString
)/sizeof(mSubsystemString
[0])) ? DriverInfo
->ImageSubsystem
: 0]);
282 Print (L
" FileType - 0x%02x (%s)\n", DriverInfo
->FileType
, mFileTypeString
[(DriverInfo
->FileType
< sizeof(mFileTypeString
)/sizeof(mFileTypeString
[0])) ? DriverInfo
->FileType
: 0]);
283 Print (L
" CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
);
284 Print (L
" PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
);
285 for (TypeIndex
= 0; TypeIndex
<= EfiMaxMemoryType
; TypeIndex
++) {
286 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
287 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
288 Print (L
" CurrentUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
289 Print (L
" PeakUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
292 Print (L
" AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
);
294 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
295 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
296 AllocInfo
= DumpMemoryProfileAllocInfo (DriverInfo
, AllocIndex
, AllocInfo
);
297 if (AllocInfo
== NULL
) {
301 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
305 Dump memory profile context information.
307 @param[in] Context Pointer to memory profile context.
309 @return Pointer to the end of memory profile context buffer.
313 DumpMemoryProfileContext (
314 IN MEMORY_PROFILE_CONTEXT
*Context
318 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
321 if (Context
->Header
.Signature
!= MEMORY_PROFILE_CONTEXT_SIGNATURE
) {
324 Print (L
"MEMORY_PROFILE_CONTEXT\n");
325 Print (L
" Signature - 0x%08x\n", Context
->Header
.Signature
);
326 Print (L
" Length - 0x%04x\n", Context
->Header
.Length
);
327 Print (L
" Revision - 0x%04x\n", Context
->Header
.Revision
);
328 Print (L
" CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
);
329 Print (L
" PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
);
330 for (TypeIndex
= 0; TypeIndex
<= EfiMaxMemoryType
; TypeIndex
++) {
331 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
332 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
333 Print (L
" CurrentTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
334 Print (L
" PeakTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
337 Print (L
" TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
);
338 Print (L
" ImageCount - 0x%08x\n", Context
->ImageCount
);
339 Print (L
" SequenceCount - 0x%08x\n", Context
->SequenceCount
);
341 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
342 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
343 DriverInfo
= DumpMemoryProfileDriverInfo (DriverIndex
, DriverInfo
);
344 if (DriverInfo
== NULL
) {
348 return (VOID
*) DriverInfo
;
352 Dump memory profile descriptor information.
354 @param[in] DescriptorIndex Memory profile descriptor index.
355 @param[in] Descriptor Pointer to memory profile descriptor.
357 @return Pointer to next memory profile descriptor.
360 MEMORY_PROFILE_DESCRIPTOR
*
361 DumpMemoryProfileDescriptor (
362 IN UINTN DescriptorIndex
,
363 IN MEMORY_PROFILE_DESCRIPTOR
*Descriptor
366 if (Descriptor
->Header
.Signature
!= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
) {
369 Print (L
" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex
);
370 Print (L
" Signature - 0x%08x\n", Descriptor
->Header
.Signature
);
371 Print (L
" Length - 0x%04x\n", Descriptor
->Header
.Length
);
372 Print (L
" Revision - 0x%04x\n", Descriptor
->Header
.Revision
);
373 Print (L
" Address - 0x%016lx\n", Descriptor
->Address
);
374 Print (L
" Size - 0x%016lx\n", Descriptor
->Size
);
376 return (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) Descriptor
+ Descriptor
->Header
.Length
);
380 Dump memory profile free memory information.
382 @param[in] FreeMemory Pointer to memory profile free memory.
384 @return Pointer to the end of memory profile free memory buffer.
388 DumpMemoryProfileFreeMemory (
389 IN MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
392 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
393 UINTN DescriptorIndex
;
395 if (FreeMemory
->Header
.Signature
!= MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
) {
398 Print (L
"MEMORY_PROFILE_FREE_MEMORY\n");
399 Print (L
" Signature - 0x%08x\n", FreeMemory
->Header
.Signature
);
400 Print (L
" Length - 0x%04x\n", FreeMemory
->Header
.Length
);
401 Print (L
" Revision - 0x%04x\n", FreeMemory
->Header
.Revision
);
402 Print (L
" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory
->TotalFreeMemoryPages
);
403 Print (L
" FreeMemoryEntryCount - 0x%08x\n", FreeMemory
->FreeMemoryEntryCount
);
405 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) FreeMemory
+ FreeMemory
->Header
.Length
);
406 for (DescriptorIndex
= 0; DescriptorIndex
< FreeMemory
->FreeMemoryEntryCount
; DescriptorIndex
++) {
407 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
408 if (Descriptor
== NULL
) {
413 return (VOID
*) Descriptor
;
417 Dump memory profile memory range information.
419 @param[in] MemoryRange Pointer to memory profile memory range.
421 @return Pointer to the end of memory profile memory range buffer.
425 DumpMemoryProfileMemoryRange (
426 IN MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
429 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
430 UINTN DescriptorIndex
;
432 if (MemoryRange
->Header
.Signature
!= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
) {
435 Print (L
"MEMORY_PROFILE_MEMORY_RANGE\n");
436 Print (L
" Signature - 0x%08x\n", MemoryRange
->Header
.Signature
);
437 Print (L
" Length - 0x%04x\n", MemoryRange
->Header
.Length
);
438 Print (L
" Revision - 0x%04x\n", MemoryRange
->Header
.Revision
);
439 Print (L
" MemoryRangeCount - 0x%08x\n", MemoryRange
->MemoryRangeCount
);
441 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) MemoryRange
+ MemoryRange
->Header
.Length
);
442 for (DescriptorIndex
= 0; DescriptorIndex
< MemoryRange
->MemoryRangeCount
; DescriptorIndex
++) {
443 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
444 if (Descriptor
== NULL
) {
449 return (VOID
*) Descriptor
;
453 Scan memory profile by Signature.
455 @param[in] ProfileBuffer Memory profile base address.
456 @param[in] ProfileSize Memory profile size.
457 @param[in] Signature Signature.
459 @return Pointer to the stucture with the signature.
463 ScanMemoryProfileBySignature (
464 IN PHYSICAL_ADDRESS ProfileBuffer
,
465 IN UINT64 ProfileSize
,
469 MEMORY_PROFILE_COMMON_HEADER
*CommonHeader
;
472 ProfileEnd
= (UINTN
) (ProfileBuffer
+ ProfileSize
);
473 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) (UINTN
) ProfileBuffer
;
474 while ((UINTN
) CommonHeader
< ProfileEnd
) {
475 if (CommonHeader
->Signature
== Signature
) {
479 return (VOID
*) CommonHeader
;
481 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) ((UINTN
) CommonHeader
+ CommonHeader
->Length
);
488 Dump memory profile information.
490 @param[in] ProfileBuffer Memory profile base address.
491 @param[in] ProfileSize Memory profile size.
496 IN PHYSICAL_ADDRESS ProfileBuffer
,
497 IN UINT64 ProfileSize
500 MEMORY_PROFILE_CONTEXT
*Context
;
501 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
502 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
504 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
505 if (Context
!= NULL
) {
506 DumpMemoryProfileContext (Context
);
509 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
);
510 if (FreeMemory
!= NULL
) {
511 DumpMemoryProfileFreeMemory (FreeMemory
);
514 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
);
515 if (MemoryRange
!= NULL
) {
516 DumpMemoryProfileMemoryRange (MemoryRange
);
521 Get and dump UEFI memory profile data.
523 @return EFI_SUCCESS Get the memory profile data successfully.
524 @return other Fail to get the memory profile data.
528 GetUefiMemoryProfileData (
533 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
537 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
538 if (EFI_ERROR (Status
)) {
539 DEBUG ((EFI_D_ERROR
, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status
));
545 Status
= ProfileProtocol
->GetData (
550 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
551 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
556 // Add one sizeof (MEMORY_PROFILE_ALLOC_INFO) to Size for this AllocatePool action.
558 Size
= Size
+ sizeof (MEMORY_PROFILE_ALLOC_INFO
);
559 Data
= AllocateZeroPool ((UINTN
) Size
);
561 Status
= EFI_OUT_OF_RESOURCES
;
562 Print (L
"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size
, Status
);
566 Status
= ProfileProtocol
->GetData (
571 if (EFI_ERROR (Status
)) {
573 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
578 Print (L
"UefiMemoryProfileSize - 0x%x\n", Size
);
579 Print (L
"======= UefiMemoryProfile begin =======\n");
580 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
);
581 Print (L
"======= UefiMemoryProfile end =======\n\n\n");
589 Get and dump SMRAM profile data.
591 @return EFI_SUCCESS Get the SMRAM profile data successfully.
592 @return other Fail to get the SMRAM profile data.
596 GetSmramProfileData (
603 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
604 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*CommGetProfileInfo
;
605 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*CommGetProfileData
;
607 PHYSICAL_ADDRESS ProfileBuffer
;
608 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
610 Status
= gBS
->LocateProtocol (&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**) &SmmCommunication
);
611 if (EFI_ERROR (Status
)) {
612 DEBUG ((EFI_D_ERROR
, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status
));
616 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
);
617 CommBuffer
= AllocateZeroPool (CommSize
);
618 if (CommBuffer
== NULL
) {
619 Status
= EFI_OUT_OF_RESOURCES
;
620 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for comm buffer - %r\n", CommSize
, Status
);
627 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
628 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
629 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
);
631 CommGetProfileInfo
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
632 CommGetProfileInfo
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
;
633 CommGetProfileInfo
->Header
.DataLength
= sizeof (*CommGetProfileInfo
);
634 CommGetProfileInfo
->Header
.ReturnStatus
= (UINT64
)-1;
635 CommGetProfileInfo
->ProfileSize
= 0;
637 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
638 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
639 if (EFI_ERROR (Status
)) {
640 FreePool (CommBuffer
);
641 DEBUG ((EFI_D_ERROR
, "SmramProfile: SmmCommunication - %r\n", Status
));
645 if (CommGetProfileInfo
->Header
.ReturnStatus
!= 0) {
646 Print (L
"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo
->Header
.ReturnStatus
);
650 ProfileSize
= CommGetProfileInfo
->ProfileSize
;
655 ProfileBuffer
= (PHYSICAL_ADDRESS
) (UINTN
) AllocateZeroPool ((UINTN
) ProfileSize
);
656 if (ProfileBuffer
== 0) {
657 FreePool (CommBuffer
);
658 Status
= EFI_OUT_OF_RESOURCES
;
659 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", (UINTN
) ProfileSize
, Status
);
663 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
664 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof(gEdkiiMemoryProfileGuid
));
665 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
);
667 CommGetProfileData
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
668 CommGetProfileData
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA
;
669 CommGetProfileData
->Header
.DataLength
= sizeof (*CommGetProfileData
);
670 CommGetProfileData
->Header
.ReturnStatus
= (UINT64
)-1;
671 CommGetProfileData
->ProfileSize
= ProfileSize
;
672 CommGetProfileData
->ProfileBuffer
= ProfileBuffer
;
674 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
675 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
676 ASSERT_EFI_ERROR (Status
);
678 if (CommGetProfileData
->Header
.ReturnStatus
!= 0) {
679 FreePool ((VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
);
680 FreePool (CommBuffer
);
681 Print (L
"GetProfileData - 0x%x\n", CommGetProfileData
->Header
.ReturnStatus
);
686 Print (L
"SmramProfileSize - 0x%x\n", CommGetProfileData
->ProfileSize
);
687 Print (L
"======= SmramProfile begin =======\n");
688 DumpMemoryProfile (CommGetProfileData
->ProfileBuffer
, CommGetProfileData
->ProfileSize
);
689 Print (L
"======= SmramProfile end =======\n\n\n");
691 FreePool ((VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
);
692 FreePool (CommBuffer
);
698 The user Entry Point for Application. The user code starts with this function
699 as the real entry point for the image goes into a library that calls this function.
701 @param[in] ImageHandle The firmware allocated handle for the EFI image.
702 @param[in] SystemTable A pointer to the EFI System Table.
704 @retval EFI_SUCCESS The entry point is executed successfully.
705 @retval other Some error occurs when executing this entry point.
711 IN EFI_HANDLE ImageHandle
,
712 IN EFI_SYSTEM_TABLE
*SystemTable
717 Status
= GetUefiMemoryProfileData ();
718 if (EFI_ERROR (Status
)) {
719 DEBUG ((EFI_D_ERROR
, "GetUefiMemoryProfileData - %r\n", Status
));
722 Status
= GetSmramProfileData ();
723 if (EFI_ERROR (Status
)) {
724 DEBUG ((EFI_D_ERROR
, "GetSmramProfileData - %r\n", Status
));