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.
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/UefiLib.h>
21 #include <Library/UefiApplicationEntryPoint.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Library/UefiRuntimeServicesTableLib.h>
24 #include <Library/DebugLib.h>
25 #include <Library/DxeServicesLib.h>
26 #include <Library/PeCoffGetEntryPointLib.h>
27 #include <Library/PrintLib.h>
29 #include <Protocol/SmmCommunication.h>
30 #include <Protocol/SmmAccess2.h>
32 #include <Guid/ZeroGuid.h>
33 #include <Guid/MemoryProfile.h>
34 #include <Guid/PiSmmCommunicationRegionTable.h>
36 CHAR16
*mActionString
[] = {
44 CHAR16
*mMemoryTypeString
[] = {
45 L
"EfiReservedMemoryType",
48 L
"EfiBootServicesCode",
49 L
"EfiBootServicesData",
50 L
"EfiRuntimeServicesCode",
51 L
"EfiRuntimeServicesData",
52 L
"EfiConventionalMemory",
54 L
"EfiACPIReclaimMemory",
57 L
"EfiMemoryMappedIOPortSpace",
59 L
"EfiPersistentMemory",
64 CHAR16
*mSubsystemString
[] = {
76 L
"EFI_BOOT_SERVICE_DRIVER",
77 L
"EFI_RUNTIME_DRIVER",
83 CHAR16
*mFileTypeString
[] = {
92 L
"COMBINED_PEIM_DRIVER",
95 L
"FIRMWARE_VOLUME_IMAGE",
100 #define PROFILE_NAME_STRING_LENGTH 36
101 CHAR16 mNameString
[PROFILE_NAME_STRING_LENGTH
+ 1];
104 Get the file name portion of the Pdb File Name.
106 The portion of the Pdb File Name between the last backslash and
107 either a following period or the end of the string is converted
108 to Unicode and copied into UnicodeBuffer. The name is truncated,
109 if necessary, to ensure that UnicodeBuffer is not overrun.
111 @param[in] PdbFileName Pdb file name.
112 @param[out] UnicodeBuffer The resultant Unicode File Name.
116 GetShortPdbFileName (
117 IN CHAR8
*PdbFileName
,
118 OUT CHAR16
*UnicodeBuffer
121 UINTN IndexA
; // Current work location within an ASCII string.
122 UINTN IndexU
; // Current work location within a Unicode string.
126 ZeroMem (UnicodeBuffer
, (PROFILE_NAME_STRING_LENGTH
+ 1) * sizeof (CHAR16
));
128 if (PdbFileName
== NULL
) {
129 StrnCpyS (UnicodeBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1, L
" ", 1);
132 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++);
133 for (IndexA
= 0; PdbFileName
[IndexA
] != 0; IndexA
++) {
134 if (PdbFileName
[IndexA
] == '\\') {
135 StartIndex
= IndexA
+ 1;
138 if (PdbFileName
[IndexA
] == '.') {
144 for (IndexA
= StartIndex
; IndexA
< EndIndex
; IndexA
++) {
145 UnicodeBuffer
[IndexU
] = (CHAR16
) PdbFileName
[IndexA
];
147 if (IndexU
>= PROFILE_NAME_STRING_LENGTH
) {
148 UnicodeBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
156 Get a human readable name for an image.
157 The following methods will be tried orderly:
162 @param[in] DriverInfo Pointer to memory profile driver info.
164 @post The resulting Unicode name string is stored in the mNameString global array.
168 GetDriverNameString (
169 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
178 // Method 1: Get the name string from image PDB
180 if ((DriverInfo
->ImageBase
!= 0) && (DriverInfo
->FileType
!= EFI_FV_FILETYPE_SMM
) && (DriverInfo
->FileType
!= EFI_FV_FILETYPE_SMM_CORE
)) {
181 PdbFileName
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) DriverInfo
->ImageBase
);
183 if (PdbFileName
!= NULL
) {
184 GetShortPdbFileName (PdbFileName
, mNameString
);
189 if (!CompareGuid (&DriverInfo
->FileName
, &gZeroGuid
)) {
191 // Try to get the image's FFS UI section by image GUID
195 Status
= GetSectionFromAnyFv (
196 &DriverInfo
->FileName
,
197 EFI_SECTION_USER_INTERFACE
,
199 (VOID
**) &NameString
,
202 if (!EFI_ERROR (Status
)) {
204 // Method 2: Get the name string from FFS UI section
206 StrnCpyS (mNameString
, PROFILE_NAME_STRING_LENGTH
+ 1, NameString
, PROFILE_NAME_STRING_LENGTH
);
207 mNameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
208 FreePool (NameString
);
214 // Method 3: Get the name string from image GUID
216 UnicodeSPrint (mNameString
, sizeof (mNameString
), L
"%g", &DriverInfo
->FileName
);
220 Memory type to string.
222 @param[in] MemoryType Memory type.
224 @return Pointer to string.
228 ProfileMemoryTypeToStr (
229 IN EFI_MEMORY_TYPE MemoryType
234 if ((UINT32
) MemoryType
>= 0x80000000) {
236 // OS reserved memory type.
238 Index
= EfiMaxMemoryType
;
239 } else if ((UINT32
) MemoryType
>= 0x70000000) {
241 // OEM reserved memory type.
243 Index
= EfiMaxMemoryType
+ 1;
248 return mMemoryTypeString
[Index
];
252 Dump memory profile allocate information.
254 @param[in] DriverInfo Pointer to memory profile driver info.
255 @param[in] AllocIndex Memory profile alloc info index.
256 @param[in] AllocInfo Pointer to memory profile alloc info.
258 @return Pointer to next memory profile alloc info.
261 MEMORY_PROFILE_ALLOC_INFO
*
262 DumpMemoryProfileAllocInfo (
263 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
,
265 IN MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
268 if (AllocInfo
->Header
.Signature
!= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
) {
271 Print (L
" MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
);
272 Print (L
" Signature - 0x%08x\n", AllocInfo
->Header
.Signature
);
273 Print (L
" Length - 0x%04x\n", AllocInfo
->Header
.Length
);
274 Print (L
" Revision - 0x%04x\n", AllocInfo
->Header
.Revision
);
275 Print (L
" CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, (UINTN
) (AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
276 Print (L
" SequenceId - 0x%08x\n", AllocInfo
->SequenceId
);
277 Print (L
" Action - 0x%08x (%s)\n", AllocInfo
->Action
, mActionString
[(AllocInfo
->Action
< sizeof(mActionString
)/sizeof(mActionString
[0])) ? AllocInfo
->Action
: 0]);
278 Print (L
" MemoryType - 0x%08x (%s)\n", AllocInfo
->MemoryType
, ProfileMemoryTypeToStr (AllocInfo
->MemoryType
));
279 Print (L
" Buffer - 0x%016lx\n", AllocInfo
->Buffer
);
280 Print (L
" Size - 0x%016lx\n", AllocInfo
->Size
);
282 return (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) AllocInfo
+ AllocInfo
->Header
.Length
);
286 Dump memory profile driver information.
288 @param[in] DriverIndex Memory profile driver info index.
289 @param[in] DriverInfo Pointer to memory profile driver info.
291 @return Pointer to next memory profile driver info.
294 MEMORY_PROFILE_DRIVER_INFO
*
295 DumpMemoryProfileDriverInfo (
296 IN UINTN DriverIndex
,
297 IN MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
301 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
304 if (DriverInfo
->Header
.Signature
!= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
) {
307 Print (L
" MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
);
308 Print (L
" Signature - 0x%08x\n", DriverInfo
->Header
.Signature
);
309 Print (L
" Length - 0x%04x\n", DriverInfo
->Header
.Length
);
310 Print (L
" Revision - 0x%04x\n", DriverInfo
->Header
.Revision
);
311 GetDriverNameString (DriverInfo
);
312 Print (L
" FileName - %s\n", &mNameString
);
313 Print (L
" ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
);
314 Print (L
" ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
);
315 Print (L
" EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
);
316 Print (L
" ImageSubsystem - 0x%04x (%s)\n", DriverInfo
->ImageSubsystem
, mSubsystemString
[(DriverInfo
->ImageSubsystem
< sizeof(mSubsystemString
)/sizeof(mSubsystemString
[0])) ? DriverInfo
->ImageSubsystem
: 0]);
317 Print (L
" FileType - 0x%02x (%s)\n", DriverInfo
->FileType
, mFileTypeString
[(DriverInfo
->FileType
< sizeof(mFileTypeString
)/sizeof(mFileTypeString
[0])) ? DriverInfo
->FileType
: 0]);
318 Print (L
" CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
);
319 Print (L
" PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
);
320 for (TypeIndex
= 0; TypeIndex
< sizeof (DriverInfo
->CurrentUsageByType
) / sizeof (DriverInfo
->CurrentUsageByType
[0]); TypeIndex
++) {
321 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
322 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
323 Print (L
" CurrentUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
324 Print (L
" PeakUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
327 Print (L
" AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
);
329 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) ((UINTN
) DriverInfo
+ DriverInfo
->Header
.Length
);
330 for (AllocIndex
= 0; AllocIndex
< DriverInfo
->AllocRecordCount
; AllocIndex
++) {
331 AllocInfo
= DumpMemoryProfileAllocInfo (DriverInfo
, AllocIndex
, AllocInfo
);
332 if (AllocInfo
== NULL
) {
336 return (MEMORY_PROFILE_DRIVER_INFO
*) AllocInfo
;
340 Dump memory profile context information.
342 @param[in] Context Pointer to memory profile context.
344 @return Pointer to the end of memory profile context buffer.
348 DumpMemoryProfileContext (
349 IN MEMORY_PROFILE_CONTEXT
*Context
353 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
356 if (Context
->Header
.Signature
!= MEMORY_PROFILE_CONTEXT_SIGNATURE
) {
359 Print (L
"MEMORY_PROFILE_CONTEXT\n");
360 Print (L
" Signature - 0x%08x\n", Context
->Header
.Signature
);
361 Print (L
" Length - 0x%04x\n", Context
->Header
.Length
);
362 Print (L
" Revision - 0x%04x\n", Context
->Header
.Revision
);
363 Print (L
" CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
);
364 Print (L
" PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
);
365 for (TypeIndex
= 0; TypeIndex
< sizeof (Context
->CurrentTotalUsageByType
) / sizeof (Context
->CurrentTotalUsageByType
[0]); TypeIndex
++) {
366 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
367 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
368 Print (L
" CurrentTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
369 Print (L
" PeakTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]);
372 Print (L
" TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
);
373 Print (L
" ImageCount - 0x%08x\n", Context
->ImageCount
);
374 Print (L
" SequenceCount - 0x%08x\n", Context
->SequenceCount
);
376 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) Context
+ Context
->Header
.Length
);
377 for (DriverIndex
= 0; DriverIndex
< Context
->ImageCount
; DriverIndex
++) {
378 DriverInfo
= DumpMemoryProfileDriverInfo (DriverIndex
, DriverInfo
);
379 if (DriverInfo
== NULL
) {
383 return (VOID
*) DriverInfo
;
387 Dump memory profile descriptor information.
389 @param[in] DescriptorIndex Memory profile descriptor index.
390 @param[in] Descriptor Pointer to memory profile descriptor.
392 @return Pointer to next memory profile descriptor.
395 MEMORY_PROFILE_DESCRIPTOR
*
396 DumpMemoryProfileDescriptor (
397 IN UINTN DescriptorIndex
,
398 IN MEMORY_PROFILE_DESCRIPTOR
*Descriptor
401 if (Descriptor
->Header
.Signature
!= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
) {
404 Print (L
" MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex
);
405 Print (L
" Signature - 0x%08x\n", Descriptor
->Header
.Signature
);
406 Print (L
" Length - 0x%04x\n", Descriptor
->Header
.Length
);
407 Print (L
" Revision - 0x%04x\n", Descriptor
->Header
.Revision
);
408 Print (L
" Address - 0x%016lx\n", Descriptor
->Address
);
409 Print (L
" Size - 0x%016lx\n", Descriptor
->Size
);
411 return (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) Descriptor
+ Descriptor
->Header
.Length
);
415 Dump memory profile free memory information.
417 @param[in] FreeMemory Pointer to memory profile free memory.
419 @return Pointer to the end of memory profile free memory buffer.
423 DumpMemoryProfileFreeMemory (
424 IN MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
427 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
428 UINTN DescriptorIndex
;
430 if (FreeMemory
->Header
.Signature
!= MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
) {
433 Print (L
"MEMORY_PROFILE_FREE_MEMORY\n");
434 Print (L
" Signature - 0x%08x\n", FreeMemory
->Header
.Signature
);
435 Print (L
" Length - 0x%04x\n", FreeMemory
->Header
.Length
);
436 Print (L
" Revision - 0x%04x\n", FreeMemory
->Header
.Revision
);
437 Print (L
" TotalFreeMemoryPages - 0x%016lx\n", FreeMemory
->TotalFreeMemoryPages
);
438 Print (L
" FreeMemoryEntryCount - 0x%08x\n", FreeMemory
->FreeMemoryEntryCount
);
440 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) FreeMemory
+ FreeMemory
->Header
.Length
);
441 for (DescriptorIndex
= 0; DescriptorIndex
< FreeMemory
->FreeMemoryEntryCount
; DescriptorIndex
++) {
442 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
443 if (Descriptor
== NULL
) {
448 return (VOID
*) Descriptor
;
452 Dump memory profile memory range information.
454 @param[in] MemoryRange Pointer to memory profile memory range.
456 @return Pointer to the end of memory profile memory range buffer.
460 DumpMemoryProfileMemoryRange (
461 IN MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
464 MEMORY_PROFILE_DESCRIPTOR
*Descriptor
;
465 UINTN DescriptorIndex
;
467 if (MemoryRange
->Header
.Signature
!= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
) {
470 Print (L
"MEMORY_PROFILE_MEMORY_RANGE\n");
471 Print (L
" Signature - 0x%08x\n", MemoryRange
->Header
.Signature
);
472 Print (L
" Length - 0x%04x\n", MemoryRange
->Header
.Length
);
473 Print (L
" Revision - 0x%04x\n", MemoryRange
->Header
.Revision
);
474 Print (L
" MemoryRangeCount - 0x%08x\n", MemoryRange
->MemoryRangeCount
);
476 Descriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) ((UINTN
) MemoryRange
+ MemoryRange
->Header
.Length
);
477 for (DescriptorIndex
= 0; DescriptorIndex
< MemoryRange
->MemoryRangeCount
; DescriptorIndex
++) {
478 Descriptor
= DumpMemoryProfileDescriptor (DescriptorIndex
, Descriptor
);
479 if (Descriptor
== NULL
) {
484 return (VOID
*) Descriptor
;
488 Scan memory profile by Signature.
490 @param[in] ProfileBuffer Memory profile base address.
491 @param[in] ProfileSize Memory profile size.
492 @param[in] Signature Signature.
494 @return Pointer to the stucture with the signature.
498 ScanMemoryProfileBySignature (
499 IN PHYSICAL_ADDRESS ProfileBuffer
,
500 IN UINT64 ProfileSize
,
504 MEMORY_PROFILE_COMMON_HEADER
*CommonHeader
;
507 ProfileEnd
= (UINTN
) (ProfileBuffer
+ ProfileSize
);
508 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) (UINTN
) ProfileBuffer
;
509 while ((UINTN
) CommonHeader
< ProfileEnd
) {
510 if (CommonHeader
->Signature
== Signature
) {
514 return (VOID
*) CommonHeader
;
516 CommonHeader
= (MEMORY_PROFILE_COMMON_HEADER
*) ((UINTN
) CommonHeader
+ CommonHeader
->Length
);
523 Dump memory profile information.
525 @param[in] ProfileBuffer Memory profile base address.
526 @param[in] ProfileSize Memory profile size.
531 IN PHYSICAL_ADDRESS ProfileBuffer
,
532 IN UINT64 ProfileSize
535 MEMORY_PROFILE_CONTEXT
*Context
;
536 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
537 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
539 Context
= (MEMORY_PROFILE_CONTEXT
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_CONTEXT_SIGNATURE
);
540 if (Context
!= NULL
) {
541 DumpMemoryProfileContext (Context
);
544 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
);
545 if (FreeMemory
!= NULL
) {
546 DumpMemoryProfileFreeMemory (FreeMemory
);
549 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) ScanMemoryProfileBySignature (ProfileBuffer
, ProfileSize
, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
);
550 if (MemoryRange
!= NULL
) {
551 DumpMemoryProfileMemoryRange (MemoryRange
);
556 Get and dump UEFI memory profile data.
558 @return EFI_SUCCESS Get the memory profile data successfully.
559 @return other Fail to get the memory profile data.
563 GetUefiMemoryProfileData (
568 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
572 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
573 if (EFI_ERROR (Status
)) {
574 DEBUG ((EFI_D_ERROR
, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status
));
580 Status
= ProfileProtocol
->GetData (
585 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
586 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
591 // Add one sizeof (MEMORY_PROFILE_ALLOC_INFO) to Size for this AllocatePool action.
593 Size
= Size
+ sizeof (MEMORY_PROFILE_ALLOC_INFO
);
594 Data
= AllocateZeroPool ((UINTN
) Size
);
596 Status
= EFI_OUT_OF_RESOURCES
;
597 Print (L
"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size
, Status
);
601 Status
= ProfileProtocol
->GetData (
606 if (EFI_ERROR (Status
)) {
608 Print (L
"UefiMemoryProfile: GetData - %r\n", Status
);
613 Print (L
"UefiMemoryProfileSize - 0x%x\n", Size
);
614 Print (L
"======= UefiMemoryProfile begin =======\n");
615 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) Data
, Size
);
616 Print (L
"======= UefiMemoryProfile end =======\n\n\n");
624 Get and dump SMRAM profile data.
626 @return EFI_SUCCESS Get the SMRAM profile data successfully.
627 @return other Fail to get the SMRAM profile data.
631 GetSmramProfileData (
638 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
639 SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*CommGetProfileInfo
;
640 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*CommGetProfileData
;
643 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
644 UINTN MinimalSizeNeeded
;
645 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
647 EFI_MEMORY_DESCRIPTOR
*Entry
;
652 Status
= gBS
->LocateProtocol (&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**) &SmmCommunication
);
653 if (EFI_ERROR (Status
)) {
654 DEBUG ((EFI_D_ERROR
, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status
));
658 MinimalSizeNeeded
= sizeof (EFI_GUID
) +
660 MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
),
661 sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
));
662 MinimalSizeNeeded
+= MAX (sizeof (MEMORY_PROFILE_CONTEXT
),
663 MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO
),
664 MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO
),
665 MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR
),
666 MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY
),
667 sizeof (MEMORY_PROFILE_MEMORY_RANGE
))))));
669 Status
= EfiGetSystemConfigurationTable (
670 &gEdkiiPiSmmCommunicationRegionTableGuid
,
671 (VOID
**) &PiSmmCommunicationRegionTable
673 if (EFI_ERROR (Status
)) {
674 DEBUG ((EFI_D_ERROR
, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status
));
677 ASSERT (PiSmmCommunicationRegionTable
!= NULL
);
678 Entry
= (EFI_MEMORY_DESCRIPTOR
*) (PiSmmCommunicationRegionTable
+ 1);
680 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
681 if (Entry
->Type
== EfiConventionalMemory
) {
682 Size
= EFI_PAGES_TO_SIZE ((UINTN
) Entry
->NumberOfPages
);
683 if (Size
>= MinimalSizeNeeded
) {
687 Entry
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
689 ASSERT (Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
);
690 CommBuffer
= (UINT8
*) (UINTN
) Entry
->PhysicalStart
;
695 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
696 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof (gEdkiiMemoryProfileGuid
));
697 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
);
699 CommGetProfileInfo
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
700 CommGetProfileInfo
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
;
701 CommGetProfileInfo
->Header
.DataLength
= sizeof (*CommGetProfileInfo
);
702 CommGetProfileInfo
->Header
.ReturnStatus
= (UINT64
)-1;
703 CommGetProfileInfo
->ProfileSize
= 0;
705 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
706 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
707 if (EFI_ERROR (Status
)) {
708 DEBUG ((EFI_D_ERROR
, "SmramProfile: SmmCommunication - %r\n", Status
));
712 if (CommGetProfileInfo
->Header
.ReturnStatus
!= 0) {
713 Print (L
"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo
->Header
.ReturnStatus
);
717 ProfileSize
= (UINTN
) CommGetProfileInfo
->ProfileSize
;
722 ProfileBuffer
= AllocateZeroPool (ProfileSize
);
723 if (ProfileBuffer
== 0) {
724 Status
= EFI_OUT_OF_RESOURCES
;
725 Print (L
"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize
, Status
);
729 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*) &CommBuffer
[0];
730 CopyMem (&CommHeader
->HeaderGuid
, &gEdkiiMemoryProfileGuid
, sizeof(gEdkiiMemoryProfileGuid
));
731 CommHeader
->MessageLength
= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
);
733 CommGetProfileData
= (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET
*) &CommBuffer
[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
)];
734 CommGetProfileData
->Header
.Command
= SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET
;
735 CommGetProfileData
->Header
.DataLength
= sizeof (*CommGetProfileData
);
736 CommGetProfileData
->Header
.ReturnStatus
= (UINT64
)-1;
738 CommSize
= sizeof (EFI_GUID
) + sizeof (UINTN
) + CommHeader
->MessageLength
;
739 Buffer
= (UINT8
*) CommHeader
+ CommSize
;
742 CommGetProfileData
->ProfileBuffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
743 CommGetProfileData
->ProfileOffset
= 0;
744 while (CommGetProfileData
->ProfileOffset
< ProfileSize
) {
745 Offset
= (UINTN
) CommGetProfileData
->ProfileOffset
;
746 if (Size
<= (ProfileSize
- CommGetProfileData
->ProfileOffset
)) {
747 CommGetProfileData
->ProfileSize
= (UINT64
) Size
;
749 CommGetProfileData
->ProfileSize
= (UINT64
) (ProfileSize
- CommGetProfileData
->ProfileOffset
);
751 Status
= SmmCommunication
->Communicate (SmmCommunication
, CommBuffer
, &CommSize
);
752 ASSERT_EFI_ERROR (Status
);
754 if (CommGetProfileData
->Header
.ReturnStatus
!= 0) {
755 FreePool (ProfileBuffer
);
756 Print (L
"GetProfileData - 0x%x\n", CommGetProfileData
->Header
.ReturnStatus
);
759 CopyMem ((UINT8
*) ProfileBuffer
+ Offset
, (VOID
*) (UINTN
) CommGetProfileData
->ProfileBuffer
, (UINTN
) CommGetProfileData
->ProfileSize
);
763 Print (L
"SmramProfileSize - 0x%x\n", ProfileSize
);
764 Print (L
"======= SmramProfile begin =======\n");
765 DumpMemoryProfile ((PHYSICAL_ADDRESS
) (UINTN
) ProfileBuffer
, ProfileSize
);
766 Print (L
"======= SmramProfile end =======\n\n\n");
768 FreePool (ProfileBuffer
);
774 The user Entry Point for Application. The user code starts with this function
775 as the real entry point for the image goes into a library that calls this function.
777 @param[in] ImageHandle The firmware allocated handle for the EFI image.
778 @param[in] SystemTable A pointer to the EFI System Table.
780 @retval EFI_SUCCESS The entry point is executed successfully.
781 @retval other Some error occurs when executing this entry point.
787 IN EFI_HANDLE ImageHandle
,
788 IN EFI_SYSTEM_TABLE
*SystemTable
793 Status
= GetUefiMemoryProfileData ();
794 if (EFI_ERROR (Status
)) {
795 DEBUG ((EFI_D_ERROR
, "GetUefiMemoryProfileData - %r\n", Status
));
798 Status
= GetSmramProfileData ();
799 if (EFI_ERROR (Status
)) {
800 DEBUG ((EFI_D_ERROR
, "GetSmramProfileData - %r\n", Status
));