2 Support routines for SMRAM profile.
4 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "PiSmmCore.h"
17 #define IS_SMRAM_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) != 0)
21 MEMORY_PROFILE_CONTEXT Context
;
22 LIST_ENTRY
*DriverInfoList
;
23 } MEMORY_PROFILE_CONTEXT_DATA
;
27 MEMORY_PROFILE_DRIVER_INFO DriverInfo
;
28 LIST_ENTRY
*AllocInfoList
;
30 } MEMORY_PROFILE_DRIVER_INFO_DATA
;
34 MEMORY_PROFILE_ALLOC_INFO AllocInfo
;
36 } MEMORY_PROFILE_ALLOC_INFO_DATA
;
39 // When free memory less than 4 pages, dump it.
41 #define SMRAM_INFO_DUMP_PAGE_THRESHOLD 4
43 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_FREE_MEMORY mSmramFreeMemory
= {
45 MEMORY_PROFILE_FREE_MEMORY_SIGNATURE
,
46 sizeof (MEMORY_PROFILE_FREE_MEMORY
),
47 MEMORY_PROFILE_FREE_MEMORY_REVISION
53 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mImageQueue
= INITIALIZE_LIST_HEAD_VARIABLE (mImageQueue
);
54 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA mSmramProfileContext
= {
55 MEMORY_PROFILE_CONTEXT_SIGNATURE
,
58 MEMORY_PROFILE_CONTEXT_SIGNATURE
,
59 sizeof (MEMORY_PROFILE_CONTEXT
),
60 MEMORY_PROFILE_CONTEXT_REVISION
72 GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA
*mSmramProfileContextPtr
= NULL
;
74 BOOLEAN mSmramReadyToLock
;
75 BOOLEAN mSmramProfileRecordingStatus
= FALSE
;
78 Dump SMRAM infromation.
87 Return SMRAM profile context.
89 @return SMRAM profile context.
92 MEMORY_PROFILE_CONTEXT_DATA
*
93 GetSmramProfileContext (
97 return mSmramProfileContextPtr
;
101 Retrieves the magic value from the PE/COFF header.
103 @param Hdr The buffer in which to return the PE32, PE32+, or TE header.
105 @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32
106 @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+
110 InternalPeCoffGetPeHeaderMagicValue (
111 IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
115 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
116 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
117 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
118 // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
120 if (Hdr
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& Hdr
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
121 return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
124 // Return the magic value from the PC/COFF Optional Header
126 return Hdr
.Pe32
->OptionalHeader
.Magic
;
130 Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
131 If Pe32Data is NULL, then ASSERT().
133 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
135 @return The Subsystem of the PE/COFF image.
139 InternalPeCoffGetSubsystem (
143 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
144 EFI_IMAGE_DOS_HEADER
*DosHdr
;
147 ASSERT (Pe32Data
!= NULL
);
149 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
150 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
152 // DOS image header is present, so read the PE header after the DOS image header.
154 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
157 // DOS image header is not present, so PE header is at the image base.
159 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
162 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
163 return Hdr
.Te
->Subsystem
;
164 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
165 Magic
= InternalPeCoffGetPeHeaderMagicValue (Hdr
);
166 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
167 return Hdr
.Pe32
->OptionalHeader
.Subsystem
;
168 } else if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
169 return Hdr
.Pe32Plus
->OptionalHeader
.Subsystem
;
177 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
178 into system memory with the PE/COFF Loader Library functions.
180 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
181 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
182 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
183 If Pe32Data is NULL, then ASSERT().
184 If EntryPoint is NULL, then ASSERT().
186 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
187 @param EntryPoint The pointer to entry point to the PE/COFF image to return.
189 @retval RETURN_SUCCESS EntryPoint was returned.
190 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
194 InternalPeCoffGetEntryPoint (
196 OUT VOID
**EntryPoint
199 EFI_IMAGE_DOS_HEADER
*DosHdr
;
200 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
202 ASSERT (Pe32Data
!= NULL
);
203 ASSERT (EntryPoint
!= NULL
);
205 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
206 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
208 // DOS image header is present, so read the PE header after the DOS image header.
210 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
213 // DOS image header is not present, so PE header is at the image base.
215 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
219 // Calculate the entry point relative to the start of the image.
220 // AddressOfEntryPoint is common for PE32 & PE32+
222 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
223 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Te
->AddressOfEntryPoint
& 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER
) - Hdr
.Te
->StrippedSize
);
224 return RETURN_SUCCESS
;
225 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
226 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Pe32
->OptionalHeader
.AddressOfEntryPoint
& 0x0ffffffff));
227 return RETURN_SUCCESS
;
230 return RETURN_UNSUPPORTED
;
236 @param ContextData Memory profile context.
237 @param FileName File name of the image.
238 @param ImageBase Image base address.
239 @param ImageSize Image size.
240 @param EntryPoint Entry point of the image.
241 @param ImageSubsystem Image subsystem of the image.
243 @param FileType File type of the image.
245 @return Pointer to memory profile driver info.
248 MEMORY_PROFILE_DRIVER_INFO_DATA
*
250 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
251 IN EFI_GUID
*FileName
,
252 IN PHYSICAL_ADDRESS ImageBase
,
254 IN PHYSICAL_ADDRESS EntryPoint
,
255 IN UINT16 ImageSubsystem
,
256 IN EFI_FV_FILETYPE FileType
260 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
261 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
262 VOID
*EntryPointInImage
;
265 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.
267 Status
= SmmInternalAllocatePool (
268 EfiRuntimeServicesData
,
269 sizeof (*DriverInfoData
) + sizeof (LIST_ENTRY
),
270 (VOID
**) &DriverInfoData
272 if (EFI_ERROR (Status
)) {
276 ZeroMem (DriverInfoData
, sizeof (*DriverInfoData
));
278 DriverInfo
= &DriverInfoData
->DriverInfo
;
279 DriverInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
280 DriverInfo
->Header
.Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
281 DriverInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_DRIVER_INFO
);
282 DriverInfo
->Header
.Revision
= MEMORY_PROFILE_DRIVER_INFO_REVISION
;
283 if (FileName
!= NULL
) {
284 CopyMem (&DriverInfo
->FileName
, FileName
, sizeof (EFI_GUID
));
286 DriverInfo
->ImageBase
= ImageBase
;
287 DriverInfo
->ImageSize
= ImageSize
;
288 DriverInfo
->EntryPoint
= EntryPoint
;
289 DriverInfo
->ImageSubsystem
= ImageSubsystem
;
290 if ((EntryPoint
!= 0) && ((EntryPoint
< ImageBase
) || (EntryPoint
>= (ImageBase
+ ImageSize
)))) {
292 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
293 // So patch ImageBuffer here to align the EntryPoint.
295 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
296 ASSERT_EFI_ERROR (Status
);
297 DriverInfo
->ImageBase
= ImageBase
+ EntryPoint
- (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
299 DriverInfo
->FileType
= FileType
;
300 DriverInfoData
->AllocInfoList
= (LIST_ENTRY
*) (DriverInfoData
+ 1);
301 InitializeListHead (DriverInfoData
->AllocInfoList
);
302 DriverInfo
->CurrentUsage
= 0;
303 DriverInfo
->PeakUsage
= 0;
304 DriverInfo
->AllocRecordCount
= 0;
306 InsertTailList (ContextData
->DriverInfoList
, &DriverInfoData
->Link
);
307 ContextData
->Context
.ImageCount
++;
308 ContextData
->Context
.TotalImageSize
+= DriverInfo
->ImageSize
;
310 return DriverInfoData
;
314 Register image to DXE.
316 @param FileName File name of the image.
317 @param ImageBase Image base address.
318 @param ImageSize Image size.
319 @param FileType File type of the image.
324 IN EFI_GUID
*FileName
,
325 IN PHYSICAL_ADDRESS ImageBase
,
327 IN EFI_FV_FILETYPE FileType
331 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
332 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FilePath
;
333 UINT8 TempBuffer
[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
)];
335 if (IS_SMRAM_PROFILE_ENABLED
) {
337 FilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)TempBuffer
;
338 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
339 if (!EFI_ERROR (Status
)) {
340 EfiInitializeFwVolDevicepathNode (FilePath
, FileName
);
341 SetDevicePathEndNode (FilePath
+ 1);
343 Status
= ProfileProtocol
->RegisterImage (
345 (EFI_DEVICE_PATH_PROTOCOL
*) FilePath
,
355 Unregister image from DXE.
357 @param FileName File name of the image.
358 @param ImageBase Image base address.
359 @param ImageSize Image size.
363 UnregisterImageFromDxe (
364 IN EFI_GUID
*FileName
,
365 IN PHYSICAL_ADDRESS ImageBase
,
370 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
371 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FilePath
;
372 UINT8 TempBuffer
[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
)];
374 if (IS_SMRAM_PROFILE_ENABLED
) {
376 FilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)TempBuffer
;
377 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
*) &ProfileProtocol
);
378 if (!EFI_ERROR (Status
)) {
379 EfiInitializeFwVolDevicepathNode (FilePath
, FileName
);
380 SetDevicePathEndNode (FilePath
+ 1);
382 Status
= ProfileProtocol
->UnregisterImage (
384 (EFI_DEVICE_PATH_PROTOCOL
*) FilePath
,
393 Register SMM Core to SMRAM profile.
395 @param ContextData SMRAM profile context.
397 @retval TRUE Register success.
398 @retval FALSE Register fail.
403 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
406 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
407 PHYSICAL_ADDRESS ImageBase
;
409 ASSERT (ContextData
!= NULL
);
413 gSmmCorePrivate
->PiSmmCoreImageBase
,
414 gSmmCorePrivate
->PiSmmCoreImageSize
,
415 EFI_FV_FILETYPE_SMM_CORE
418 ImageBase
= gSmmCorePrivate
->PiSmmCoreImageBase
;
419 DriverInfoData
= BuildDriverInfo (
423 gSmmCorePrivate
->PiSmmCoreImageSize
,
424 gSmmCorePrivate
->PiSmmCoreEntryPoint
,
425 InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) ImageBase
),
426 EFI_FV_FILETYPE_SMM_CORE
428 if (DriverInfoData
== NULL
) {
436 Initialize SMRAM profile.
444 MEMORY_PROFILE_CONTEXT_DATA
*SmramProfileContext
;
446 if (!IS_SMRAM_PROFILE_ENABLED
) {
450 SmramProfileContext
= GetSmramProfileContext ();
451 if (SmramProfileContext
!= NULL
) {
455 mSmramProfileRecordingStatus
= TRUE
;
456 mSmramProfileContextPtr
= &mSmramProfileContext
;
458 RegisterSmmCore (&mSmramProfileContext
);
460 DEBUG ((EFI_D_INFO
, "SmramProfileInit SmramProfileContext - 0x%x\n", &mSmramProfileContext
));
464 Register SMM image to SMRAM profile.
466 @param DriverEntry SMM image info.
467 @param RegisterToDxe Register image to DXE.
469 @retval TRUE Register success.
470 @retval FALSE Register fail.
474 RegisterSmramProfileImage (
475 IN EFI_SMM_DRIVER_ENTRY
*DriverEntry
,
476 IN BOOLEAN RegisterToDxe
479 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
480 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
482 if (!IS_SMRAM_PROFILE_ENABLED
) {
488 &DriverEntry
->FileName
,
489 DriverEntry
->ImageBuffer
,
490 EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
),
495 ContextData
= GetSmramProfileContext ();
496 if (ContextData
== NULL
) {
500 DriverInfoData
= BuildDriverInfo (
502 &DriverEntry
->FileName
,
503 DriverEntry
->ImageBuffer
,
504 EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
),
505 DriverEntry
->ImageEntryPoint
,
506 InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) DriverEntry
->ImageBuffer
),
509 if (DriverInfoData
== NULL
) {
517 Search image from memory profile.
519 @param ContextData Memory profile context.
520 @param FileName Image file name.
521 @param Address Image Address.
523 @return Pointer to memory profile driver info.
526 MEMORY_PROFILE_DRIVER_INFO_DATA
*
527 GetMemoryProfileDriverInfoByFileNameAndAddress (
528 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
529 IN EFI_GUID
*FileName
,
530 IN PHYSICAL_ADDRESS Address
533 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
534 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
535 LIST_ENTRY
*DriverLink
;
536 LIST_ENTRY
*DriverInfoList
;
538 DriverInfoList
= ContextData
->DriverInfoList
;
540 for (DriverLink
= DriverInfoList
->ForwardLink
;
541 DriverLink
!= DriverInfoList
;
542 DriverLink
= DriverLink
->ForwardLink
) {
543 DriverInfoData
= CR (
545 MEMORY_PROFILE_DRIVER_INFO_DATA
,
547 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
549 DriverInfo
= &DriverInfoData
->DriverInfo
;
550 if ((CompareGuid (&DriverInfo
->FileName
, FileName
)) &&
551 (Address
>= DriverInfo
->ImageBase
) &&
552 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
553 return DriverInfoData
;
561 Search dummy image from SMRAM profile.
563 @param ContextData Memory profile context.
565 @return Pointer to memory profile driver info.
568 MEMORY_PROFILE_DRIVER_INFO_DATA
*
570 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
573 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
574 LIST_ENTRY
*DriverLink
;
575 LIST_ENTRY
*DriverInfoList
;
577 DriverInfoList
= ContextData
->DriverInfoList
;
579 for (DriverLink
= DriverInfoList
->ForwardLink
;
580 DriverLink
!= DriverInfoList
;
581 DriverLink
= DriverLink
->ForwardLink
) {
582 DriverInfoData
= CR (
584 MEMORY_PROFILE_DRIVER_INFO_DATA
,
586 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
588 if (CompareGuid (&gZeroGuid
, &DriverInfoData
->DriverInfo
.FileName
)) {
589 return DriverInfoData
;
593 return BuildDriverInfo (ContextData
, &gZeroGuid
, 0, 0, 0, 0, 0);
597 Search image from memory profile.
598 It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize)
600 @param ContextData Memory profile context.
601 @param Address Image or Function address.
603 @return Pointer to memory profile driver info.
606 MEMORY_PROFILE_DRIVER_INFO_DATA
*
607 GetMemoryProfileDriverInfoFromAddress (
608 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
609 IN PHYSICAL_ADDRESS Address
612 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
613 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
614 LIST_ENTRY
*DriverLink
;
615 LIST_ENTRY
*DriverInfoList
;
617 DriverInfoList
= ContextData
->DriverInfoList
;
619 for (DriverLink
= DriverInfoList
->ForwardLink
;
620 DriverLink
!= DriverInfoList
;
621 DriverLink
= DriverLink
->ForwardLink
) {
622 DriverInfoData
= CR (
624 MEMORY_PROFILE_DRIVER_INFO_DATA
,
626 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
628 DriverInfo
= &DriverInfoData
->DriverInfo
;
629 if ((Address
>= DriverInfo
->ImageBase
) &&
630 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
631 return DriverInfoData
;
636 // Should never come here.
638 return FindDummyImage (ContextData
);
642 Unregister image from SMRAM profile.
644 @param DriverEntry SMM image info.
645 @param UnregisterFromDxe Unregister image from DXE.
647 @retval TRUE Unregister success.
648 @retval FALSE Unregister fail.
652 UnregisterSmramProfileImage (
653 IN EFI_SMM_DRIVER_ENTRY
*DriverEntry
,
654 IN BOOLEAN UnregisterFromDxe
658 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
659 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
661 PHYSICAL_ADDRESS ImageAddress
;
662 VOID
*EntryPointInImage
;
664 if (!IS_SMRAM_PROFILE_ENABLED
) {
668 if (UnregisterFromDxe
) {
669 UnregisterImageFromDxe (
670 &DriverEntry
->FileName
,
671 DriverEntry
->ImageBuffer
,
672 EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
)
676 ContextData
= GetSmramProfileContext ();
677 if (ContextData
== NULL
) {
681 DriverInfoData
= NULL
;
682 FileName
= &DriverEntry
->FileName
;
683 ImageAddress
= DriverEntry
->ImageBuffer
;
684 if ((DriverEntry
->ImageEntryPoint
< ImageAddress
) || (DriverEntry
->ImageEntryPoint
>= (ImageAddress
+ EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
)))) {
686 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
687 // So patch ImageAddress here to align the EntryPoint.
689 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageAddress
, &EntryPointInImage
);
690 ASSERT_EFI_ERROR (Status
);
691 ImageAddress
= ImageAddress
+ (UINTN
) DriverEntry
->ImageEntryPoint
- (UINTN
) EntryPointInImage
;
693 if (FileName
!= NULL
) {
694 DriverInfoData
= GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData
, FileName
, ImageAddress
);
696 if (DriverInfoData
== NULL
) {
697 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, ImageAddress
);
699 if (DriverInfoData
== NULL
) {
703 ContextData
->Context
.TotalImageSize
-= DriverInfoData
->DriverInfo
.ImageSize
;
705 DriverInfoData
->DriverInfo
.ImageBase
= 0;
706 DriverInfoData
->DriverInfo
.ImageSize
= 0;
708 if (DriverInfoData
->DriverInfo
.PeakUsage
== 0) {
709 ContextData
->Context
.ImageCount
--;
710 RemoveEntryList (&DriverInfoData
->Link
);
712 // Use SmmInternalFreePool() that will not update profile for this FreePool action.
714 SmmInternalFreePool (DriverInfoData
);
721 Return if this memory type needs to be recorded into memory profile.
722 Only need to record EfiRuntimeServicesCode and EfiRuntimeServicesData for SMRAM profile.
724 @param MemoryType Memory type.
726 @retval TRUE This memory type need to be recorded.
727 @retval FALSE This memory type need not to be recorded.
731 SmmCoreNeedRecordProfile (
732 IN EFI_MEMORY_TYPE MemoryType
737 if (MemoryType
!= EfiRuntimeServicesCode
&&
738 MemoryType
!= EfiRuntimeServicesData
) {
742 TestBit
= LShiftU64 (1, MemoryType
);
744 if ((PcdGet64 (PcdMemoryProfileMemoryType
) & TestBit
) != 0) {
752 Convert EFI memory type to profile memory index. The rule is:
753 If BIOS memory type (0 ~ EfiMaxMemoryType - 1), ProfileMemoryIndex = MemoryType.
754 As SMRAM profile is only to record EfiRuntimeServicesCode and EfiRuntimeServicesData,
755 so return input memory type directly.
757 @param MemoryType Memory type.
759 @return EFI memory type as profile memory index.
763 GetProfileMemoryIndex (
764 IN EFI_MEMORY_TYPE MemoryType
771 Update SMRAM profile FreeMemoryPages information
773 @param ContextData Memory profile context.
777 SmramProfileUpdateFreePages (
778 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
782 FREE_PAGE_LIST
*Pages
;
783 LIST_ENTRY
*FreePageList
;
787 FreePageList
= &mSmmMemoryMap
;
788 for (Node
= FreePageList
->BackLink
;
789 Node
!= FreePageList
;
790 Node
= Node
->BackLink
) {
791 Pages
= BASE_CR (Node
, FREE_PAGE_LIST
, Link
);
792 NumberOfPages
+= Pages
->NumberOfPages
;
795 mSmramFreeMemory
.TotalFreeMemoryPages
= NumberOfPages
;
797 if (NumberOfPages
<= SMRAM_INFO_DUMP_PAGE_THRESHOLD
) {
803 Update SMRAM profile Allocate information.
805 @param CallerAddress Address of caller who call Allocate.
806 @param Action This Allocate action.
807 @param MemoryType Memory type.
808 @param Size Buffer size.
809 @param Buffer Buffer address.
811 @retval TRUE Profile udpate success.
812 @retval FALSE Profile update fail.
816 SmmCoreUpdateProfileAllocate (
817 IN PHYSICAL_ADDRESS CallerAddress
,
818 IN MEMORY_PROFILE_ACTION Action
,
819 IN EFI_MEMORY_TYPE MemoryType
,
825 MEMORY_PROFILE_CONTEXT
*Context
;
826 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
827 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
828 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
829 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
830 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
831 EFI_MEMORY_TYPE ProfileMemoryIndex
;
833 AllocInfoData
= NULL
;
835 ContextData
= GetSmramProfileContext ();
836 if (ContextData
== NULL
) {
840 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
841 ASSERT (DriverInfoData
!= NULL
);
844 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.
846 Status
= SmmInternalAllocatePool (
847 EfiRuntimeServicesData
,
848 sizeof (*AllocInfoData
),
849 (VOID
**) &AllocInfoData
851 if (EFI_ERROR (Status
)) {
854 AllocInfo
= &AllocInfoData
->AllocInfo
;
855 AllocInfoData
->Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
856 AllocInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
857 AllocInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_ALLOC_INFO
);
858 AllocInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_INFO_REVISION
;
859 AllocInfo
->CallerAddress
= CallerAddress
;
860 AllocInfo
->SequenceId
= ContextData
->Context
.SequenceCount
;
861 AllocInfo
->Action
= Action
;
862 AllocInfo
->MemoryType
= MemoryType
;
863 AllocInfo
->Buffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
864 AllocInfo
->Size
= Size
;
866 InsertTailList (DriverInfoData
->AllocInfoList
, &AllocInfoData
->Link
);
868 ProfileMemoryIndex
= GetProfileMemoryIndex (MemoryType
);
870 DriverInfo
= &DriverInfoData
->DriverInfo
;
871 DriverInfo
->CurrentUsage
+= Size
;
872 if (DriverInfo
->PeakUsage
< DriverInfo
->CurrentUsage
) {
873 DriverInfo
->PeakUsage
= DriverInfo
->CurrentUsage
;
875 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] += Size
;
876 if (DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] < DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
]) {
877 DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] = DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
];
879 DriverInfo
->AllocRecordCount
++;
881 Context
= &ContextData
->Context
;
882 Context
->CurrentTotalUsage
+= Size
;
883 if (Context
->PeakTotalUsage
< Context
->CurrentTotalUsage
) {
884 Context
->PeakTotalUsage
= Context
->CurrentTotalUsage
;
886 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] += Size
;
887 if (Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] < Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
]) {
888 Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] = Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
];
890 Context
->SequenceCount
++;
892 SmramProfileUpdateFreePages (ContextData
);
897 Get memory profile alloc info from memory profile
899 @param DriverInfoData Driver info
900 @param Action This Free action
901 @param Size Buffer size
902 @param Buffer Buffer address
904 @return Pointer to memory profile alloc info.
906 MEMORY_PROFILE_ALLOC_INFO_DATA
*
907 GetMemoryProfileAllocInfoFromAddress (
908 IN MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
,
909 IN MEMORY_PROFILE_ACTION Action
,
914 LIST_ENTRY
*AllocInfoList
;
915 LIST_ENTRY
*AllocLink
;
916 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
917 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
919 AllocInfoList
= DriverInfoData
->AllocInfoList
;
921 for (AllocLink
= AllocInfoList
->ForwardLink
;
922 AllocLink
!= AllocInfoList
;
923 AllocLink
= AllocLink
->ForwardLink
) {
926 MEMORY_PROFILE_ALLOC_INFO_DATA
,
928 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
930 AllocInfo
= &AllocInfoData
->AllocInfo
;
931 if (AllocInfo
->Action
!= Action
) {
935 case MemoryProfileActionAllocatePages
:
936 if ((AllocInfo
->Buffer
<= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) &&
937 ((AllocInfo
->Buffer
+ AllocInfo
->Size
) >= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
))) {
938 return AllocInfoData
;
941 case MemoryProfileActionAllocatePool
:
942 if (AllocInfo
->Buffer
== (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
943 return AllocInfoData
;
956 Update SMRAM profile Free information.
958 @param CallerAddress Address of caller who call Free.
959 @param Action This Free action.
960 @param Size Buffer size.
961 @param Buffer Buffer address.
963 @retval TRUE Profile udpate success.
964 @retval FALSE Profile update fail.
968 SmmCoreUpdateProfileFree (
969 IN PHYSICAL_ADDRESS CallerAddress
,
970 IN MEMORY_PROFILE_ACTION Action
,
975 MEMORY_PROFILE_CONTEXT
*Context
;
976 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
977 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
978 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
979 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
980 LIST_ENTRY
*DriverLink
;
981 LIST_ENTRY
*DriverInfoList
;
982 MEMORY_PROFILE_DRIVER_INFO_DATA
*ThisDriverInfoData
;
983 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
984 EFI_MEMORY_TYPE ProfileMemoryIndex
;
986 ContextData
= GetSmramProfileContext ();
987 if (ContextData
== NULL
) {
991 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
992 ASSERT (DriverInfoData
!= NULL
);
995 case MemoryProfileActionFreePages
:
996 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
998 case MemoryProfileActionFreePool
:
999 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
1003 AllocInfoData
= NULL
;
1006 if (AllocInfoData
== NULL
) {
1008 // Legal case, because driver A might free memory allocated by driver B, by some protocol.
1010 DriverInfoList
= ContextData
->DriverInfoList
;
1012 for (DriverLink
= DriverInfoList
->ForwardLink
;
1013 DriverLink
!= DriverInfoList
;
1014 DriverLink
= DriverLink
->ForwardLink
) {
1015 ThisDriverInfoData
= CR (
1017 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1019 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1022 case MemoryProfileActionFreePages
:
1023 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
1025 case MemoryProfileActionFreePool
:
1026 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
1030 AllocInfoData
= NULL
;
1033 if (AllocInfoData
!= NULL
) {
1034 DriverInfoData
= ThisDriverInfoData
;
1039 if (AllocInfoData
== NULL
) {
1041 // No matched allocate operation is found for this free operation.
1042 // It is because the specified memory type allocate operation has been
1043 // filtered by CoreNeedRecordProfile(), but free operations have no
1044 // memory type information, they can not be filtered by CoreNeedRecordProfile().
1045 // Then, they will be filtered here.
1051 Context
= &ContextData
->Context
;
1052 DriverInfo
= &DriverInfoData
->DriverInfo
;
1053 AllocInfo
= &AllocInfoData
->AllocInfo
;
1055 ProfileMemoryIndex
= GetProfileMemoryIndex (AllocInfo
->MemoryType
);
1057 Context
->CurrentTotalUsage
-= AllocInfo
->Size
;
1058 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1060 DriverInfo
->CurrentUsage
-= AllocInfo
->Size
;
1061 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1062 DriverInfo
->AllocRecordCount
--;
1064 RemoveEntryList (&AllocInfoData
->Link
);
1066 if (Action
== MemoryProfileActionFreePages
) {
1067 if (AllocInfo
->Buffer
!= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
1068 SmmCoreUpdateProfileAllocate (
1069 AllocInfo
->CallerAddress
,
1070 MemoryProfileActionAllocatePages
,
1071 AllocInfo
->MemoryType
,
1072 (UINTN
) ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
- AllocInfo
->Buffer
),
1073 (VOID
*) (UINTN
) AllocInfo
->Buffer
1076 if (AllocInfo
->Buffer
+ AllocInfo
->Size
!= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)) {
1077 SmmCoreUpdateProfileAllocate (
1078 AllocInfo
->CallerAddress
,
1079 MemoryProfileActionAllocatePages
,
1080 AllocInfo
->MemoryType
,
1081 (UINTN
) ((AllocInfo
->Buffer
+ AllocInfo
->Size
) - ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)),
1082 (VOID
*) ((UINTN
) Buffer
+ Size
)
1088 // Use SmmInternalFreePool() that will not update profile for this FreePool action.
1090 SmmInternalFreePool (AllocInfoData
);
1096 Update SMRAM profile information.
1098 @param CallerAddress Address of caller who call Allocate or Free.
1099 @param Action This Allocate or Free action.
1100 @param MemoryType Memory type.
1101 @param Size Buffer size.
1102 @param Buffer Buffer address.
1104 @retval TRUE Profile udpate success.
1105 @retval FALSE Profile update fail.
1109 SmmCoreUpdateProfile (
1110 IN PHYSICAL_ADDRESS CallerAddress
,
1111 IN MEMORY_PROFILE_ACTION Action
,
1112 IN EFI_MEMORY_TYPE MemoryType
, // Valid for AllocatePages/AllocatePool
1113 IN UINTN Size
, // Valid for AllocatePages/FreePages/AllocatePool
1117 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1119 if (!IS_SMRAM_PROFILE_ENABLED
) {
1123 if (!mSmramProfileRecordingStatus
) {
1128 // Free operations have no memory type information, so skip the check.
1130 if ((Action
== MemoryProfileActionAllocatePages
) || (Action
== MemoryProfileActionAllocatePool
)) {
1132 // Only record limited MemoryType.
1134 if (!SmmCoreNeedRecordProfile (MemoryType
)) {
1139 ContextData
= GetSmramProfileContext ();
1140 if (ContextData
== NULL
) {
1145 case MemoryProfileActionAllocatePages
:
1146 SmmCoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1148 case MemoryProfileActionFreePages
:
1149 SmmCoreUpdateProfileFree (CallerAddress
, Action
, Size
, Buffer
);
1151 case MemoryProfileActionAllocatePool
:
1152 SmmCoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1154 case MemoryProfileActionFreePool
:
1155 SmmCoreUpdateProfileFree (CallerAddress
, Action
, 0, Buffer
);
1166 SMRAM profile ready to lock callback function.
1170 SmramProfileReadyToLock (
1174 if (!IS_SMRAM_PROFILE_ENABLED
) {
1178 DEBUG ((EFI_D_INFO
, "SmramProfileReadyToLock\n"));
1179 mSmramReadyToLock
= TRUE
;
1182 ////////////////////
1185 Get SMRAM profile data size.
1187 @return SMRAM profile data size.
1191 SmramProfileGetDataSize (
1195 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1196 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1197 LIST_ENTRY
*DriverInfoList
;
1198 LIST_ENTRY
*DriverLink
;
1201 LIST_ENTRY
*FreePageList
;
1202 LIST_ENTRY
*FreePoolList
;
1203 FREE_POOL_HEADER
*Pool
;
1204 UINTN PoolListIndex
;
1207 ContextData
= GetSmramProfileContext ();
1208 if (ContextData
== NULL
) {
1212 TotalSize
= sizeof (MEMORY_PROFILE_CONTEXT
);
1213 TotalSize
+= sizeof (MEMORY_PROFILE_DRIVER_INFO
) * (UINTN
) ContextData
->Context
.ImageCount
;
1215 DriverInfoList
= ContextData
->DriverInfoList
;
1216 for (DriverLink
= DriverInfoList
->ForwardLink
;
1217 DriverLink
!= DriverInfoList
;
1218 DriverLink
= DriverLink
->ForwardLink
) {
1219 DriverInfoData
= CR (
1221 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1223 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1225 TotalSize
+= sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfoData
->DriverInfo
.AllocRecordCount
;
1230 FreePageList
= &mSmmMemoryMap
;
1231 for (Node
= FreePageList
->BackLink
;
1232 Node
!= FreePageList
;
1233 Node
= Node
->BackLink
) {
1236 for (PoolListIndex
= 0; PoolListIndex
< MAX_POOL_INDEX
; PoolListIndex
++) {
1237 FreePoolList
= &mSmmPoolLists
[PoolListIndex
];
1238 for (Node
= FreePoolList
->BackLink
;
1239 Node
!= FreePoolList
;
1240 Node
= Node
->BackLink
) {
1241 Pool
= BASE_CR (Node
, FREE_POOL_HEADER
, Link
);
1242 if (Pool
->Header
.Available
) {
1249 TotalSize
+= (sizeof (MEMORY_PROFILE_FREE_MEMORY
) + Index
* sizeof (MEMORY_PROFILE_DESCRIPTOR
));
1250 TotalSize
+= (sizeof (MEMORY_PROFILE_MEMORY_RANGE
) + mFullSmramRangeCount
* sizeof (MEMORY_PROFILE_DESCRIPTOR
));
1256 Copy SMRAM profile data.
1258 @param ProfileBuffer The buffer to hold SMRAM profile data.
1262 SmramProfileCopyData (
1263 IN VOID
*ProfileBuffer
1266 MEMORY_PROFILE_CONTEXT
*Context
;
1267 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
1268 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
1269 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1270 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1271 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
1272 LIST_ENTRY
*DriverInfoList
;
1273 LIST_ENTRY
*DriverLink
;
1274 LIST_ENTRY
*AllocInfoList
;
1275 LIST_ENTRY
*AllocLink
;
1277 FREE_PAGE_LIST
*Pages
;
1278 LIST_ENTRY
*FreePageList
;
1279 LIST_ENTRY
*FreePoolList
;
1280 FREE_POOL_HEADER
*Pool
;
1281 UINTN PoolListIndex
;
1283 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
1284 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
1285 MEMORY_PROFILE_DESCRIPTOR
*MemoryProfileDescriptor
;
1287 ContextData
= GetSmramProfileContext ();
1288 if (ContextData
== NULL
) {
1292 Context
= ProfileBuffer
;
1293 CopyMem (Context
, &ContextData
->Context
, sizeof (MEMORY_PROFILE_CONTEXT
));
1294 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) (Context
+ 1);
1296 DriverInfoList
= ContextData
->DriverInfoList
;
1297 for (DriverLink
= DriverInfoList
->ForwardLink
;
1298 DriverLink
!= DriverInfoList
;
1299 DriverLink
= DriverLink
->ForwardLink
) {
1300 DriverInfoData
= CR (
1302 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1304 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1306 CopyMem (DriverInfo
, &DriverInfoData
->DriverInfo
, sizeof (MEMORY_PROFILE_DRIVER_INFO
));
1307 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) (DriverInfo
+ 1);
1309 AllocInfoList
= DriverInfoData
->AllocInfoList
;
1310 for (AllocLink
= AllocInfoList
->ForwardLink
;
1311 AllocLink
!= AllocInfoList
;
1312 AllocLink
= AllocLink
->ForwardLink
) {
1313 AllocInfoData
= CR (
1315 MEMORY_PROFILE_ALLOC_INFO_DATA
,
1317 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1319 CopyMem (AllocInfo
, &AllocInfoData
->AllocInfo
, sizeof (MEMORY_PROFILE_ALLOC_INFO
));
1323 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) (DriverInfo
+ 1) + sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfo
->AllocRecordCount
);
1327 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) DriverInfo
;
1328 CopyMem (FreeMemory
, &mSmramFreeMemory
, sizeof (MEMORY_PROFILE_FREE_MEMORY
));
1329 MemoryProfileDescriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) (FreeMemory
+ 1);
1331 FreePageList
= &mSmmMemoryMap
;
1332 for (Node
= FreePageList
->BackLink
;
1333 Node
!= FreePageList
;
1334 Node
= Node
->BackLink
) {
1335 Pages
= BASE_CR (Node
, FREE_PAGE_LIST
, Link
);
1336 MemoryProfileDescriptor
->Header
.Signature
= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
;
1337 MemoryProfileDescriptor
->Header
.Length
= sizeof (MEMORY_PROFILE_DESCRIPTOR
);
1338 MemoryProfileDescriptor
->Header
.Revision
= MEMORY_PROFILE_DESCRIPTOR_REVISION
;
1339 MemoryProfileDescriptor
->Address
= (PHYSICAL_ADDRESS
) (UINTN
) Pages
;
1340 MemoryProfileDescriptor
->Size
= EFI_PAGES_TO_SIZE (Pages
->NumberOfPages
);
1341 MemoryProfileDescriptor
++;
1344 for (PoolListIndex
= 0; PoolListIndex
< MAX_POOL_INDEX
; PoolListIndex
++) {
1345 FreePoolList
= &mSmmPoolLists
[MAX_POOL_INDEX
- PoolListIndex
- 1];
1346 for (Node
= FreePoolList
->BackLink
;
1347 Node
!= FreePoolList
;
1348 Node
= Node
->BackLink
) {
1349 Pool
= BASE_CR (Node
, FREE_POOL_HEADER
, Link
);
1350 if (Pool
->Header
.Available
) {
1351 MemoryProfileDescriptor
->Header
.Signature
= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
;
1352 MemoryProfileDescriptor
->Header
.Length
= sizeof (MEMORY_PROFILE_DESCRIPTOR
);
1353 MemoryProfileDescriptor
->Header
.Revision
= MEMORY_PROFILE_DESCRIPTOR_REVISION
;
1354 MemoryProfileDescriptor
->Address
= (PHYSICAL_ADDRESS
) (UINTN
) Pool
;
1355 MemoryProfileDescriptor
->Size
= Pool
->Header
.Size
;
1356 MemoryProfileDescriptor
++;
1361 FreeMemory
->FreeMemoryEntryCount
= Index
;
1363 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) MemoryProfileDescriptor
;
1364 MemoryRange
->Header
.Signature
= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
;
1365 MemoryRange
->Header
.Length
= sizeof (MEMORY_PROFILE_MEMORY_RANGE
);
1366 MemoryRange
->Header
.Revision
= MEMORY_PROFILE_MEMORY_RANGE_REVISION
;
1367 MemoryRange
->MemoryRangeCount
= (UINT32
) mFullSmramRangeCount
;
1368 MemoryProfileDescriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) (MemoryRange
+ 1);
1369 for (Index
= 0; Index
< mFullSmramRangeCount
; Index
++) {
1370 MemoryProfileDescriptor
->Header
.Signature
= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
;
1371 MemoryProfileDescriptor
->Header
.Length
= sizeof (MEMORY_PROFILE_DESCRIPTOR
);
1372 MemoryProfileDescriptor
->Header
.Revision
= MEMORY_PROFILE_DESCRIPTOR_REVISION
;
1373 MemoryProfileDescriptor
->Address
= mFullSmramRanges
[Index
].PhysicalStart
;
1374 MemoryProfileDescriptor
->Size
= mFullSmramRanges
[Index
].PhysicalSize
;
1375 MemoryProfileDescriptor
++;
1380 SMRAM profile handler to get profile info.
1382 @param SmramProfileParameterGetInfo The parameter of SMM profile get size.
1386 SmramProfileHandlerGetInfo (
1387 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*SmramProfileParameterGetInfo
1390 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1391 BOOLEAN SmramProfileRecordingStatus
;
1393 ContextData
= GetSmramProfileContext ();
1394 if (ContextData
== NULL
) {
1398 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1399 mSmramProfileRecordingStatus
= FALSE
;
1401 SmramProfileParameterGetInfo
->ProfileSize
= SmramProfileGetDataSize();
1402 SmramProfileParameterGetInfo
->Header
.ReturnStatus
= 0;
1404 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1408 SMRAM profile handler to get profile data.
1410 @param SmramProfileParameterGetData The parameter of SMM profile get data.
1414 SmramProfileHandlerGetData (
1415 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*SmramProfileParameterGetData
1419 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA SmramProfileGetData
;
1420 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1421 BOOLEAN SmramProfileRecordingStatus
;
1423 ContextData
= GetSmramProfileContext ();
1424 if (ContextData
== NULL
) {
1428 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1429 mSmramProfileRecordingStatus
= FALSE
;
1432 CopyMem (&SmramProfileGetData
, SmramProfileParameterGetData
, sizeof (SmramProfileGetData
));
1434 ProfileSize
= SmramProfileGetDataSize();
1439 if (!SmmIsBufferOutsideSmmValid ((UINTN
) SmramProfileGetData
.ProfileBuffer
, (UINTN
) ProfileSize
)) {
1440 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerGetData: SMM ProfileBuffer in SMRAM or overflow!\n"));
1441 SmramProfileParameterGetData
->ProfileSize
= ProfileSize
;
1442 SmramProfileParameterGetData
->Header
.ReturnStatus
= (UINT64
) (INT64
) (INTN
) EFI_ACCESS_DENIED
;
1446 if (SmramProfileGetData
.ProfileSize
< ProfileSize
) {
1447 SmramProfileParameterGetData
->ProfileSize
= ProfileSize
;
1448 SmramProfileParameterGetData
->Header
.ReturnStatus
= (UINT64
) (INT64
) (INTN
) EFI_BUFFER_TOO_SMALL
;
1452 SmramProfileParameterGetData
->ProfileSize
= ProfileSize
;
1453 SmramProfileCopyData ((VOID
*) (UINTN
) SmramProfileGetData
.ProfileBuffer
);
1454 SmramProfileParameterGetData
->Header
.ReturnStatus
= 0;
1457 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1461 SMRAM profile handler to register SMM image.
1463 @param SmramProfileParameterRegisterImage The parameter of SMM profile register image.
1467 SmramProfileHandlerRegisterImage (
1468 IN SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE
*SmramProfileParameterRegisterImage
1472 EFI_SMM_DRIVER_ENTRY DriverEntry
;
1473 VOID
*EntryPointInImage
;
1476 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1477 CopyMem (&DriverEntry
.FileName
, &SmramProfileParameterRegisterImage
->FileName
, sizeof(EFI_GUID
));
1478 DriverEntry
.ImageBuffer
= SmramProfileParameterRegisterImage
->ImageBuffer
;
1479 DriverEntry
.NumberOfPage
= (UINTN
) SmramProfileParameterRegisterImage
->NumberOfPage
;
1480 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) DriverEntry
.ImageBuffer
, &EntryPointInImage
);
1481 ASSERT_EFI_ERROR (Status
);
1482 DriverEntry
.ImageEntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1484 Ret
= RegisterSmramProfileImage (&DriverEntry
, FALSE
);
1486 SmramProfileParameterRegisterImage
->Header
.ReturnStatus
= 0;
1491 SMRAM profile handler to unregister SMM image.
1493 @param SmramProfileParameterUnregisterImage The parameter of SMM profile unregister image.
1497 SmramProfileHandlerUnregisterImage (
1498 IN SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE
*SmramProfileParameterUnregisterImage
1502 EFI_SMM_DRIVER_ENTRY DriverEntry
;
1503 VOID
*EntryPointInImage
;
1506 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1507 CopyMem (&DriverEntry
.FileName
, &SmramProfileParameterUnregisterImage
->FileName
, sizeof (EFI_GUID
));
1508 DriverEntry
.ImageBuffer
= SmramProfileParameterUnregisterImage
->ImageBuffer
;
1509 DriverEntry
.NumberOfPage
= (UINTN
) SmramProfileParameterUnregisterImage
->NumberOfPage
;
1510 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) DriverEntry
.ImageBuffer
, &EntryPointInImage
);
1511 ASSERT_EFI_ERROR (Status
);
1512 DriverEntry
.ImageEntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1514 Ret
= UnregisterSmramProfileImage (&DriverEntry
, FALSE
);
1516 SmramProfileParameterUnregisterImage
->Header
.ReturnStatus
= 0;
1521 Dispatch function for a Software SMI handler.
1523 Caution: This function may receive untrusted input.
1524 Communicate buffer and buffer size are external input, so this function will do basic validation.
1526 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
1527 @param Context Points to an optional handler context which was specified when the
1528 handler was registered.
1529 @param CommBuffer A pointer to a collection of data in memory that will
1530 be conveyed from a non-SMM environment into an SMM environment.
1531 @param CommBufferSize The size of the CommBuffer.
1533 @retval EFI_SUCCESS Command is handled successfully.
1538 SmramProfileHandler (
1539 IN EFI_HANDLE DispatchHandle
,
1540 IN CONST VOID
*Context OPTIONAL
,
1541 IN OUT VOID
*CommBuffer OPTIONAL
,
1542 IN OUT UINTN
*CommBufferSize OPTIONAL
1545 SMRAM_PROFILE_PARAMETER_HEADER
*SmramProfileParameterHeader
;
1546 UINTN TempCommBufferSize
;
1548 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler Enter\n"));
1551 // If input is invalid, stop processing this SMI
1553 if (CommBuffer
== NULL
|| CommBufferSize
== NULL
) {
1557 TempCommBufferSize
= *CommBufferSize
;
1559 if (TempCommBufferSize
< sizeof (SMRAM_PROFILE_PARAMETER_HEADER
)) {
1560 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1564 if (mSmramReadyToLock
&& !SmmIsBufferOutsideSmmValid ((UINTN
)CommBuffer
, TempCommBufferSize
)) {
1565 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));
1569 SmramProfileParameterHeader
= (SMRAM_PROFILE_PARAMETER_HEADER
*) ((UINTN
) CommBuffer
);
1571 SmramProfileParameterHeader
->ReturnStatus
= (UINT64
)-1;
1573 if (GetSmramProfileContext () == NULL
) {
1574 SmramProfileParameterHeader
->ReturnStatus
= (UINT64
) (INT64
) (INTN
) EFI_UNSUPPORTED
;
1578 switch (SmramProfileParameterHeader
->Command
) {
1579 case SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
:
1580 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerGetInfo\n"));
1581 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
)) {
1582 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1585 SmramProfileHandlerGetInfo ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) (UINTN
) CommBuffer
);
1587 case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA
:
1588 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerGetData\n"));
1589 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
)) {
1590 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1593 SmramProfileHandlerGetData ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*) (UINTN
) CommBuffer
);
1595 case SMRAM_PROFILE_COMMAND_REGISTER_IMAGE
:
1596 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerRegisterImage\n"));
1597 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE
)) {
1598 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1601 if (mSmramReadyToLock
) {
1604 SmramProfileHandlerRegisterImage ((SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE
*) (UINTN
) CommBuffer
);
1606 case SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE
:
1607 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerUnregisterImage\n"));
1608 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE
)) {
1609 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1612 if (mSmramReadyToLock
) {
1615 SmramProfileHandlerUnregisterImage ((SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE
*) (UINTN
) CommBuffer
);
1621 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler Exit\n"));
1627 Register SMRAM profile handler.
1631 RegisterSmramProfileHandler (
1636 EFI_HANDLE DispatchHandle
;
1638 if (!IS_SMRAM_PROFILE_ENABLED
) {
1642 Status
= SmiHandlerRegister (
1643 SmramProfileHandler
,
1644 &gEdkiiMemoryProfileGuid
,
1647 ASSERT_EFI_ERROR (Status
);
1650 ////////////////////
1662 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1663 BOOLEAN SmramProfileRecordingStatus
;
1665 ContextData
= GetSmramProfileContext ();
1666 if (ContextData
== NULL
) {
1670 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1671 mSmramProfileRecordingStatus
= FALSE
;
1673 DEBUG ((EFI_D_INFO
, "FullSmramRange address - 0x%08x\n", mFullSmramRanges
));
1675 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1677 DEBUG ((EFI_D_INFO
, "FullSmramRange:\n"));
1678 for (Index
= 0; Index
< mFullSmramRangeCount
; Index
++) {
1679 DEBUG ((EFI_D_INFO
, " FullSmramRange (0x%x)\n", Index
));
1680 DEBUG ((EFI_D_INFO
, " PhysicalStart - 0x%016lx\n", mFullSmramRanges
[Index
].PhysicalStart
));
1681 DEBUG ((EFI_D_INFO
, " CpuStart - 0x%016lx\n", mFullSmramRanges
[Index
].CpuStart
));
1682 DEBUG ((EFI_D_INFO
, " PhysicalSize - 0x%016lx\n", mFullSmramRanges
[Index
].PhysicalSize
));
1683 DEBUG ((EFI_D_INFO
, " RegionState - 0x%016lx\n", mFullSmramRanges
[Index
].RegionState
));
1686 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1688 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1692 Dump SMRAM free page list.
1700 LIST_ENTRY
*FreePageList
;
1702 FREE_PAGE_LIST
*Pages
;
1704 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1705 BOOLEAN SmramProfileRecordingStatus
;
1707 ContextData
= GetSmramProfileContext ();
1708 if (ContextData
== NULL
) {
1712 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1713 mSmramProfileRecordingStatus
= FALSE
;
1715 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1717 DEBUG ((EFI_D_INFO
, "FreePagesList:\n"));
1718 FreePageList
= &mSmmMemoryMap
;
1719 for (Node
= FreePageList
->BackLink
, Index
= 0;
1720 Node
!= FreePageList
;
1721 Node
= Node
->BackLink
, Index
++) {
1722 Pages
= BASE_CR (Node
, FREE_PAGE_LIST
, Link
);
1723 DEBUG ((EFI_D_INFO
, " Index - 0x%x\n", Index
));
1724 DEBUG ((EFI_D_INFO
, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS
) (UINTN
) Pages
));
1725 DEBUG ((EFI_D_INFO
, " NumberOfPages - 0x%08x\n", Pages
->NumberOfPages
));
1728 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1730 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1734 Dump SMRAM free pool list.
1742 LIST_ENTRY
*FreePoolList
;
1744 FREE_POOL_HEADER
*Pool
;
1746 UINTN PoolListIndex
;
1747 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1748 BOOLEAN SmramProfileRecordingStatus
;
1750 ContextData
= GetSmramProfileContext ();
1751 if (ContextData
== NULL
) {
1755 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1756 mSmramProfileRecordingStatus
= FALSE
;
1758 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1760 for (PoolListIndex
= 0; PoolListIndex
< MAX_POOL_INDEX
; PoolListIndex
++) {
1761 DEBUG ((EFI_D_INFO
, "FreePoolList (%d):\n", PoolListIndex
));
1762 FreePoolList
= &mSmmPoolLists
[PoolListIndex
];
1763 for (Node
= FreePoolList
->BackLink
, Index
= 0;
1764 Node
!= FreePoolList
;
1765 Node
= Node
->BackLink
, Index
++) {
1766 Pool
= BASE_CR (Node
, FREE_POOL_HEADER
, Link
);
1767 DEBUG ((EFI_D_INFO
, " Index - 0x%x\n", Index
));
1768 DEBUG ((EFI_D_INFO
, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS
) (UINTN
) Pool
));
1769 DEBUG ((EFI_D_INFO
, " Size - 0x%08x\n", Pool
->Header
.Size
));
1770 DEBUG ((EFI_D_INFO
, " Available - 0x%02x\n", Pool
->Header
.Available
));
1774 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1776 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1779 GLOBAL_REMOVE_IF_UNREFERENCED CHAR16
*mActionString
[] = {
1788 EFI_MEMORY_TYPE MemoryType
;
1789 CHAR16
*MemoryTypeStr
;
1790 } PROFILE_MEMORY_TYPE_STRING
;
1792 GLOBAL_REMOVE_IF_UNREFERENCED PROFILE_MEMORY_TYPE_STRING mMemoryTypeString
[] = {
1793 {EfiRuntimeServicesCode
, L
"EfiRuntimeServicesCode"},
1794 {EfiRuntimeServicesData
, L
"EfiRuntimeServicesData"}
1798 Memory type to string.
1800 @param[in] MemoryType Memory type.
1802 @return Pointer to string.
1806 ProfileMemoryTypeToStr (
1807 IN EFI_MEMORY_TYPE MemoryType
1811 for (Index
= 0; Index
< sizeof (mMemoryTypeString
) / sizeof (mMemoryTypeString
[0]); Index
++) {
1812 if (mMemoryTypeString
[Index
].MemoryType
== MemoryType
) {
1813 return mMemoryTypeString
[Index
].MemoryTypeStr
;
1817 return L
"UnexpectedMemoryType";
1829 MEMORY_PROFILE_CONTEXT
*Context
;
1830 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
1831 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
1832 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1833 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1834 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
1835 LIST_ENTRY
*SmramDriverInfoList
;
1837 LIST_ENTRY
*DriverLink
;
1838 LIST_ENTRY
*AllocInfoList
;
1840 LIST_ENTRY
*AllocLink
;
1841 BOOLEAN SmramProfileRecordingStatus
;
1844 ContextData
= GetSmramProfileContext ();
1845 if (ContextData
== NULL
) {
1849 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1850 mSmramProfileRecordingStatus
= FALSE
;
1852 Context
= &ContextData
->Context
;
1853 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1854 DEBUG ((EFI_D_INFO
, "MEMORY_PROFILE_CONTEXT\n"));
1856 DEBUG ((EFI_D_INFO
, " CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
));
1857 DEBUG ((EFI_D_INFO
, " PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
));
1858 for (TypeIndex
= 0; TypeIndex
< sizeof (Context
->CurrentTotalUsageByType
) / sizeof (Context
->CurrentTotalUsageByType
[0]); TypeIndex
++) {
1859 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
1860 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
1861 DEBUG ((EFI_D_INFO
, " CurrentTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], ProfileMemoryTypeToStr (TypeIndex
)));
1862 DEBUG ((EFI_D_INFO
, " PeakTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], ProfileMemoryTypeToStr (TypeIndex
)));
1865 DEBUG ((EFI_D_INFO
, " TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
));
1866 DEBUG ((EFI_D_INFO
, " ImageCount - 0x%08x\n", Context
->ImageCount
));
1867 DEBUG ((EFI_D_INFO
, " SequenceCount - 0x%08x\n", Context
->SequenceCount
));
1869 SmramDriverInfoList
= ContextData
->DriverInfoList
;
1870 for (DriverLink
= SmramDriverInfoList
->ForwardLink
, DriverIndex
= 0;
1871 DriverLink
!= SmramDriverInfoList
;
1872 DriverLink
= DriverLink
->ForwardLink
, DriverIndex
++) {
1873 DriverInfoData
= CR (
1875 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1877 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1879 DriverInfo
= &DriverInfoData
->DriverInfo
;
1880 DEBUG ((EFI_D_INFO
, " MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
));
1881 DEBUG ((EFI_D_INFO
, " FileName - %g\n", &DriverInfo
->FileName
));
1882 DEBUG ((EFI_D_INFO
, " ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
));
1883 DEBUG ((EFI_D_INFO
, " ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
));
1884 DEBUG ((EFI_D_INFO
, " EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
));
1885 DEBUG ((EFI_D_INFO
, " ImageSubsystem - 0x%04x\n", DriverInfo
->ImageSubsystem
));
1886 DEBUG ((EFI_D_INFO
, " FileType - 0x%02x\n", DriverInfo
->FileType
));
1887 DEBUG ((EFI_D_INFO
, " CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
));
1888 DEBUG ((EFI_D_INFO
, " PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
));
1889 for (TypeIndex
= 0; TypeIndex
< sizeof (DriverInfo
->CurrentUsageByType
) / sizeof (DriverInfo
->CurrentUsageByType
[0]); TypeIndex
++) {
1890 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
1891 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
1892 DEBUG ((EFI_D_INFO
, " CurrentUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], ProfileMemoryTypeToStr (TypeIndex
)));
1893 DEBUG ((EFI_D_INFO
, " PeakUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], ProfileMemoryTypeToStr (TypeIndex
)));
1896 DEBUG ((EFI_D_INFO
, " AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
));
1898 AllocInfoList
= DriverInfoData
->AllocInfoList
;
1899 for (AllocLink
= AllocInfoList
->ForwardLink
, AllocIndex
= 0;
1900 AllocLink
!= AllocInfoList
;
1901 AllocLink
= AllocLink
->ForwardLink
, AllocIndex
++) {
1902 AllocInfoData
= CR (
1904 MEMORY_PROFILE_ALLOC_INFO_DATA
,
1906 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1908 AllocInfo
= &AllocInfoData
->AllocInfo
;
1909 DEBUG ((EFI_D_INFO
, " MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
));
1910 DEBUG ((EFI_D_INFO
, " CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
1911 DEBUG ((EFI_D_INFO
, " SequenceId - 0x%08x\n", AllocInfo
->SequenceId
));
1912 DEBUG ((EFI_D_INFO
, " Action - 0x%08x (%s)\n", AllocInfo
->Action
, mActionString
[(AllocInfo
->Action
< sizeof(mActionString
)/sizeof(mActionString
[0])) ? AllocInfo
->Action
: 0]));
1913 DEBUG ((EFI_D_INFO
, " MemoryType - 0x%08x\n", AllocInfo
->MemoryType
));
1914 DEBUG ((EFI_D_INFO
, " Buffer - 0x%016lx\n", AllocInfo
->Buffer
));
1915 DEBUG ((EFI_D_INFO
, " Size - 0x%016lx\n", AllocInfo
->Size
));
1919 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1921 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1925 Dump SMRAM infromation.
1934 if (IS_SMRAM_PROFILE_ENABLED
) {
1935 DumpSmramProfile ();
1936 DumpFreePagesList ();
1937 DumpFreePoolList ();