2 Support routines for SMRAM profile.
4 Copyright (c) 2014, 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
;
74 BOOLEAN mSmramReadyToLock
;
75 BOOLEAN mSmramProfileRecordingStatus
= FALSE
;
78 Return SMRAM profile context.
80 @return SMRAM profile context.
83 MEMORY_PROFILE_CONTEXT_DATA
*
84 GetSmramProfileContext (
88 return mSmramProfileContextPtr
;
92 Retrieves the magic value from the PE/COFF header.
94 @param Hdr The buffer in which to return the PE32, PE32+, or TE header.
96 @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32
97 @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+
101 InternalPeCoffGetPeHeaderMagicValue (
102 IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
106 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
107 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
108 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
109 // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
111 if (Hdr
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& Hdr
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
112 return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
115 // Return the magic value from the PC/COFF Optional Header
117 return Hdr
.Pe32
->OptionalHeader
.Magic
;
121 Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory.
122 If Pe32Data is NULL, then ASSERT().
124 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
126 @return The Subsystem of the PE/COFF image.
130 InternalPeCoffGetSubsystem (
134 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
135 EFI_IMAGE_DOS_HEADER
*DosHdr
;
138 ASSERT (Pe32Data
!= NULL
);
140 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
141 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
143 // DOS image header is present, so read the PE header after the DOS image header.
145 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
148 // DOS image header is not present, so PE header is at the image base.
150 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
153 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
154 return Hdr
.Te
->Subsystem
;
155 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
156 Magic
= InternalPeCoffGetPeHeaderMagicValue (Hdr
);
157 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
158 return Hdr
.Pe32
->OptionalHeader
.Subsystem
;
159 } else if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
) {
160 return Hdr
.Pe32Plus
->OptionalHeader
.Subsystem
;
168 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
169 into system memory with the PE/COFF Loader Library functions.
171 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
172 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
173 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
174 If Pe32Data is NULL, then ASSERT().
175 If EntryPoint is NULL, then ASSERT().
177 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
178 @param EntryPoint The pointer to entry point to the PE/COFF image to return.
180 @retval RETURN_SUCCESS EntryPoint was returned.
181 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
185 InternalPeCoffGetEntryPoint (
187 OUT VOID
**EntryPoint
190 EFI_IMAGE_DOS_HEADER
*DosHdr
;
191 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
193 ASSERT (Pe32Data
!= NULL
);
194 ASSERT (EntryPoint
!= NULL
);
196 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) Pe32Data
;
197 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
199 // DOS image header is present, so read the PE header after the DOS image header.
201 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) ((UINTN
) Pe32Data
+ (UINTN
) ((DosHdr
->e_lfanew
) & 0x0ffff));
204 // DOS image header is not present, so PE header is at the image base.
206 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*) Pe32Data
;
210 // Calculate the entry point relative to the start of the image.
211 // AddressOfEntryPoint is common for PE32 & PE32+
213 if (Hdr
.Te
->Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
214 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Te
->AddressOfEntryPoint
& 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER
) - Hdr
.Te
->StrippedSize
);
215 return RETURN_SUCCESS
;
216 } else if (Hdr
.Pe32
->Signature
== EFI_IMAGE_NT_SIGNATURE
) {
217 *EntryPoint
= (VOID
*) ((UINTN
) Pe32Data
+ (UINTN
) (Hdr
.Pe32
->OptionalHeader
.AddressOfEntryPoint
& 0x0ffffffff));
218 return RETURN_SUCCESS
;
221 return RETURN_UNSUPPORTED
;
227 @param ContextData Memory profile context.
228 @param FileName File name of the image.
229 @param ImageBase Image base address.
230 @param ImageSize Image size.
231 @param EntryPoint Entry point of the image.
232 @param ImageSubsystem Image subsystem of the image.
234 @param FileType File type of the image.
236 @return Pointer to memory profile driver info.
239 MEMORY_PROFILE_DRIVER_INFO_DATA
*
241 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
242 IN EFI_GUID
*FileName
,
243 IN PHYSICAL_ADDRESS ImageBase
,
245 IN PHYSICAL_ADDRESS EntryPoint
,
246 IN UINT16 ImageSubsystem
,
247 IN EFI_FV_FILETYPE FileType
251 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
252 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
253 VOID
*EntryPointInImage
;
256 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.
258 Status
= SmmInternalAllocatePool (
259 EfiRuntimeServicesData
,
260 sizeof (*DriverInfoData
) + sizeof (LIST_ENTRY
),
261 (VOID
**) &DriverInfoData
263 if (EFI_ERROR (Status
)) {
267 ZeroMem (DriverInfoData
, sizeof (*DriverInfoData
));
269 DriverInfo
= &DriverInfoData
->DriverInfo
;
270 DriverInfoData
->Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
271 DriverInfo
->Header
.Signature
= MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
;
272 DriverInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_DRIVER_INFO
);
273 DriverInfo
->Header
.Revision
= MEMORY_PROFILE_DRIVER_INFO_REVISION
;
274 if (FileName
!= NULL
) {
275 CopyMem (&DriverInfo
->FileName
, FileName
, sizeof (EFI_GUID
));
277 DriverInfo
->ImageBase
= ImageBase
;
278 DriverInfo
->ImageSize
= ImageSize
;
279 DriverInfo
->EntryPoint
= EntryPoint
;
280 DriverInfo
->ImageSubsystem
= ImageSubsystem
;
281 if ((EntryPoint
!= 0) && ((EntryPoint
< ImageBase
) || (EntryPoint
>= (ImageBase
+ ImageSize
)))) {
283 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
284 // So patch ImageBuffer here to align the EntryPoint.
286 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageBase
, &EntryPointInImage
);
287 ASSERT_EFI_ERROR (Status
);
288 DriverInfo
->ImageBase
= ImageBase
+ EntryPoint
- (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
290 DriverInfo
->FileType
= FileType
;
291 DriverInfoData
->AllocInfoList
= (LIST_ENTRY
*) (DriverInfoData
+ 1);
292 InitializeListHead (DriverInfoData
->AllocInfoList
);
293 DriverInfo
->CurrentUsage
= 0;
294 DriverInfo
->PeakUsage
= 0;
295 DriverInfo
->AllocRecordCount
= 0;
297 InsertTailList (ContextData
->DriverInfoList
, &DriverInfoData
->Link
);
298 ContextData
->Context
.ImageCount
++;
299 ContextData
->Context
.TotalImageSize
+= DriverInfo
->ImageSize
;
301 return DriverInfoData
;
305 Register image to DXE.
307 @param FileName File name of the image.
308 @param ImageBase Image base address.
309 @param ImageSize Image size.
310 @param FileType File type of the image.
315 IN EFI_GUID
*FileName
,
316 IN PHYSICAL_ADDRESS ImageBase
,
318 IN EFI_FV_FILETYPE FileType
322 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
323 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FilePath
;
324 UINT8 TempBuffer
[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
)];
326 if (IS_SMRAM_PROFILE_ENABLED
) {
328 FilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)TempBuffer
;
329 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
**) &ProfileProtocol
);
330 if (!EFI_ERROR (Status
)) {
331 EfiInitializeFwVolDevicepathNode (FilePath
, FileName
);
332 SetDevicePathEndNode (FilePath
+ 1);
334 Status
= ProfileProtocol
->RegisterImage (
336 (EFI_DEVICE_PATH_PROTOCOL
*) FilePath
,
346 Unregister image from DXE.
348 @param FileName File name of the image.
349 @param ImageBase Image base address.
350 @param ImageSize Image size.
354 UnregisterImageFromDxe (
355 IN EFI_GUID
*FileName
,
356 IN PHYSICAL_ADDRESS ImageBase
,
361 EDKII_MEMORY_PROFILE_PROTOCOL
*ProfileProtocol
;
362 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FilePath
;
363 UINT8 TempBuffer
[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
)];
365 if (IS_SMRAM_PROFILE_ENABLED
) {
367 FilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)TempBuffer
;
368 Status
= gBS
->LocateProtocol (&gEdkiiMemoryProfileGuid
, NULL
, (VOID
*) &ProfileProtocol
);
369 if (!EFI_ERROR (Status
)) {
370 EfiInitializeFwVolDevicepathNode (FilePath
, FileName
);
371 SetDevicePathEndNode (FilePath
+ 1);
373 Status
= ProfileProtocol
->UnregisterImage (
375 (EFI_DEVICE_PATH_PROTOCOL
*) FilePath
,
384 Register SMM Core to SMRAM profile.
386 @param ContextData SMRAM profile context.
388 @retval TRUE Register success.
389 @retval FALSE Register fail.
394 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
397 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
398 PHYSICAL_ADDRESS ImageBase
;
400 ASSERT (ContextData
!= NULL
);
404 gSmmCorePrivate
->PiSmmCoreImageBase
,
405 gSmmCorePrivate
->PiSmmCoreImageSize
,
406 EFI_FV_FILETYPE_SMM_CORE
409 ImageBase
= gSmmCorePrivate
->PiSmmCoreImageBase
;
410 DriverInfoData
= BuildDriverInfo (
414 gSmmCorePrivate
->PiSmmCoreImageSize
,
415 gSmmCorePrivate
->PiSmmCoreEntryPoint
,
416 InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) ImageBase
),
417 EFI_FV_FILETYPE_SMM_CORE
419 if (DriverInfoData
== NULL
) {
427 Initialize SMRAM profile.
435 MEMORY_PROFILE_CONTEXT_DATA
*SmramProfileContext
;
437 if (!IS_SMRAM_PROFILE_ENABLED
) {
441 SmramProfileContext
= GetSmramProfileContext ();
442 if (SmramProfileContext
!= NULL
) {
446 mSmramProfileRecordingStatus
= TRUE
;
447 mSmramProfileContextPtr
= &mSmramProfileContext
;
449 RegisterSmmCore (&mSmramProfileContext
);
451 DEBUG ((EFI_D_INFO
, "SmramProfileInit SmramProfileContext - 0x%x\n", &mSmramProfileContext
));
455 Register SMM image to SMRAM profile.
457 @param DriverEntry SMM image info.
458 @param RegisterToDxe Register image to DXE.
460 @retval TRUE Register success.
461 @retval FALSE Register fail.
465 RegisterSmramProfileImage (
466 IN EFI_SMM_DRIVER_ENTRY
*DriverEntry
,
467 IN BOOLEAN RegisterToDxe
470 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
471 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
473 if (!IS_SMRAM_PROFILE_ENABLED
) {
479 &DriverEntry
->FileName
,
480 DriverEntry
->ImageBuffer
,
481 EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
),
486 ContextData
= GetSmramProfileContext ();
487 if (ContextData
== NULL
) {
491 DriverInfoData
= BuildDriverInfo (
493 &DriverEntry
->FileName
,
494 DriverEntry
->ImageBuffer
,
495 EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
),
496 DriverEntry
->ImageEntryPoint
,
497 InternalPeCoffGetSubsystem ((VOID
*) (UINTN
) DriverEntry
->ImageBuffer
),
500 if (DriverInfoData
== NULL
) {
508 Search image from memory profile.
510 @param ContextData Memory profile context.
511 @param FileName Image file name.
512 @param Address Image Address.
514 @return Pointer to memory profile driver info.
517 MEMORY_PROFILE_DRIVER_INFO_DATA
*
518 GetMemoryProfileDriverInfoByFileNameAndAddress (
519 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
520 IN EFI_GUID
*FileName
,
521 IN PHYSICAL_ADDRESS Address
524 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
525 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
526 LIST_ENTRY
*DriverLink
;
527 LIST_ENTRY
*DriverInfoList
;
529 DriverInfoList
= ContextData
->DriverInfoList
;
531 for (DriverLink
= DriverInfoList
->ForwardLink
;
532 DriverLink
!= DriverInfoList
;
533 DriverLink
= DriverLink
->ForwardLink
) {
534 DriverInfoData
= CR (
536 MEMORY_PROFILE_DRIVER_INFO_DATA
,
538 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
540 DriverInfo
= &DriverInfoData
->DriverInfo
;
541 if ((CompareGuid (&DriverInfo
->FileName
, FileName
)) &&
542 (Address
>= DriverInfo
->ImageBase
) &&
543 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
544 return DriverInfoData
;
552 Search dummy image from SMRAM profile.
554 @param ContextData Memory profile context.
556 @return Pointer to memory profile driver info.
559 MEMORY_PROFILE_DRIVER_INFO_DATA
*
561 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
564 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
565 LIST_ENTRY
*DriverLink
;
566 LIST_ENTRY
*DriverInfoList
;
568 DriverInfoList
= ContextData
->DriverInfoList
;
570 for (DriverLink
= DriverInfoList
->ForwardLink
;
571 DriverLink
!= DriverInfoList
;
572 DriverLink
= DriverLink
->ForwardLink
) {
573 DriverInfoData
= CR (
575 MEMORY_PROFILE_DRIVER_INFO_DATA
,
577 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
579 if (CompareGuid (&gZeroGuid
, &DriverInfoData
->DriverInfo
.FileName
)) {
580 return DriverInfoData
;
584 return BuildDriverInfo (ContextData
, &gZeroGuid
, 0, 0, 0, 0, 0);
588 Search image from memory profile.
589 It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize)
591 @param ContextData Memory profile context.
592 @param Address Image or Function address.
594 @return Pointer to memory profile driver info.
597 MEMORY_PROFILE_DRIVER_INFO_DATA
*
598 GetMemoryProfileDriverInfoFromAddress (
599 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
,
600 IN PHYSICAL_ADDRESS Address
603 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
604 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
605 LIST_ENTRY
*DriverLink
;
606 LIST_ENTRY
*DriverInfoList
;
608 DriverInfoList
= ContextData
->DriverInfoList
;
610 for (DriverLink
= DriverInfoList
->ForwardLink
;
611 DriverLink
!= DriverInfoList
;
612 DriverLink
= DriverLink
->ForwardLink
) {
613 DriverInfoData
= CR (
615 MEMORY_PROFILE_DRIVER_INFO_DATA
,
617 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
619 DriverInfo
= &DriverInfoData
->DriverInfo
;
620 if ((Address
>= DriverInfo
->ImageBase
) &&
621 (Address
< (DriverInfo
->ImageBase
+ DriverInfo
->ImageSize
))) {
622 return DriverInfoData
;
627 // Should never come here.
629 return FindDummyImage (ContextData
);
633 Unregister image from SMRAM profile.
635 @param DriverEntry SMM image info.
636 @param UnregisterFromDxe Unregister image from DXE.
638 @retval TRUE Unregister success.
639 @retval FALSE Unregister fail.
643 UnregisterSmramProfileImage (
644 IN EFI_SMM_DRIVER_ENTRY
*DriverEntry
,
645 IN BOOLEAN UnregisterFromDxe
649 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
650 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
652 PHYSICAL_ADDRESS ImageAddress
;
653 VOID
*EntryPointInImage
;
655 if (!IS_SMRAM_PROFILE_ENABLED
) {
659 if (UnregisterFromDxe
) {
660 UnregisterImageFromDxe (
661 &DriverEntry
->FileName
,
662 DriverEntry
->ImageBuffer
,
663 EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
)
667 ContextData
= GetSmramProfileContext ();
668 if (ContextData
== NULL
) {
672 DriverInfoData
= NULL
;
673 FileName
= &DriverEntry
->FileName
;
674 ImageAddress
= DriverEntry
->ImageBuffer
;
675 if ((DriverEntry
->ImageEntryPoint
< ImageAddress
) || (DriverEntry
->ImageEntryPoint
>= (ImageAddress
+ EFI_PAGES_TO_SIZE (DriverEntry
->NumberOfPage
)))) {
677 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
678 // So patch ImageAddress here to align the EntryPoint.
680 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) ImageAddress
, &EntryPointInImage
);
681 ASSERT_EFI_ERROR (Status
);
682 ImageAddress
= ImageAddress
+ (UINTN
) DriverEntry
->ImageEntryPoint
- (UINTN
) EntryPointInImage
;
684 if (FileName
!= NULL
) {
685 DriverInfoData
= GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData
, FileName
, ImageAddress
);
687 if (DriverInfoData
== NULL
) {
688 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, ImageAddress
);
690 if (DriverInfoData
== NULL
) {
694 ContextData
->Context
.TotalImageSize
-= DriverInfoData
->DriverInfo
.ImageSize
;
696 DriverInfoData
->DriverInfo
.ImageBase
= 0;
697 DriverInfoData
->DriverInfo
.ImageSize
= 0;
699 if (DriverInfoData
->DriverInfo
.PeakUsage
== 0) {
700 ContextData
->Context
.ImageCount
--;
701 RemoveEntryList (&DriverInfoData
->Link
);
703 // Use SmmInternalFreePool() that will not update profile for this FreePool action.
705 SmmInternalFreePool (DriverInfoData
);
712 Return if this memory type needs to be recorded into memory profile.
713 If BIOS memory type (0 ~ EfiMaxMemoryType), it checks bit (1 << MemoryType).
714 If OS memory type (0x80000000 ~ 0xFFFFFFFF), it checks bit63 - 0x8000000000000000.
716 @param MemoryType Memory type.
718 @retval TRUE This memory type need to be recorded.
719 @retval FALSE This memory type need not to be recorded.
723 SmmCoreNeedRecordProfile (
724 IN EFI_MEMORY_TYPE MemoryType
729 if ((UINT32
) MemoryType
>= 0x80000000) {
732 TestBit
= LShiftU64 (1, MemoryType
);
735 if ((PcdGet64 (PcdMemoryProfileMemoryType
) & TestBit
) != 0) {
743 Convert EFI memory type to profile memory index. The rule is:
744 If BIOS memory type (0 ~ EfiMaxMemoryType), ProfileMemoryIndex = MemoryType.
745 If OS memory type (0x80000000 ~ 0xFFFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType.
747 @param MemoryType Memory type.
749 @return EFI memory type as profile memory index.
753 GetProfileMemoryIndex (
754 IN EFI_MEMORY_TYPE MemoryType
757 if ((UINT32
) MemoryType
>= 0x80000000) {
758 return EfiMaxMemoryType
;
765 Update SMRAM profile FreeMemoryPages information
767 @param ContextData Memory profile context.
771 SmramProfileUpdateFreePages (
772 IN MEMORY_PROFILE_CONTEXT_DATA
*ContextData
776 FREE_PAGE_LIST
*Pages
;
777 LIST_ENTRY
*FreePageList
;
781 FreePageList
= &mSmmMemoryMap
;
782 for (Node
= FreePageList
->BackLink
;
783 Node
!= FreePageList
;
784 Node
= Node
->BackLink
) {
785 Pages
= BASE_CR (Node
, FREE_PAGE_LIST
, Link
);
786 NumberOfPages
+= Pages
->NumberOfPages
;
789 mSmramFreeMemory
.TotalFreeMemoryPages
= NumberOfPages
;
791 if (NumberOfPages
<= SMRAM_INFO_DUMP_PAGE_THRESHOLD
) {
797 Update SMRAM profile Allocate information.
799 @param CallerAddress Address of caller who call Allocate.
800 @param Action This Allocate action.
801 @param MemoryType Memory type.
802 @param Size Buffer size.
803 @param Buffer Buffer address.
805 @retval TRUE Profile udpate success.
806 @retval FALSE Profile update fail.
810 SmmCoreUpdateProfileAllocate (
811 IN PHYSICAL_ADDRESS CallerAddress
,
812 IN MEMORY_PROFILE_ACTION Action
,
813 IN EFI_MEMORY_TYPE MemoryType
,
819 MEMORY_PROFILE_CONTEXT
*Context
;
820 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
821 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
822 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
823 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
824 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
825 EFI_MEMORY_TYPE ProfileMemoryIndex
;
827 AllocInfoData
= NULL
;
829 ContextData
= GetSmramProfileContext ();
830 if (ContextData
== NULL
) {
834 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
835 ASSERT (DriverInfoData
!= NULL
);
838 // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action.
840 Status
= SmmInternalAllocatePool (
841 EfiRuntimeServicesData
,
842 sizeof (*AllocInfoData
),
843 (VOID
**) &AllocInfoData
845 if (EFI_ERROR (Status
)) {
848 AllocInfo
= &AllocInfoData
->AllocInfo
;
849 AllocInfoData
->Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
850 AllocInfo
->Header
.Signature
= MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
;
851 AllocInfo
->Header
.Length
= sizeof (MEMORY_PROFILE_ALLOC_INFO
);
852 AllocInfo
->Header
.Revision
= MEMORY_PROFILE_ALLOC_INFO_REVISION
;
853 AllocInfo
->CallerAddress
= CallerAddress
;
854 AllocInfo
->SequenceId
= ContextData
->Context
.SequenceCount
;
855 AllocInfo
->Action
= Action
;
856 AllocInfo
->MemoryType
= MemoryType
;
857 AllocInfo
->Buffer
= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
;
858 AllocInfo
->Size
= Size
;
860 InsertTailList (DriverInfoData
->AllocInfoList
, &AllocInfoData
->Link
);
862 ProfileMemoryIndex
= GetProfileMemoryIndex (MemoryType
);
864 DriverInfo
= &DriverInfoData
->DriverInfo
;
865 DriverInfo
->CurrentUsage
+= Size
;
866 if (DriverInfo
->PeakUsage
< DriverInfo
->CurrentUsage
) {
867 DriverInfo
->PeakUsage
= DriverInfo
->CurrentUsage
;
869 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] += Size
;
870 if (DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] < DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
]) {
871 DriverInfo
->PeakUsageByType
[ProfileMemoryIndex
] = DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
];
873 DriverInfo
->AllocRecordCount
++;
875 Context
= &ContextData
->Context
;
876 Context
->CurrentTotalUsage
+= Size
;
877 if (Context
->PeakTotalUsage
< Context
->CurrentTotalUsage
) {
878 Context
->PeakTotalUsage
= Context
->CurrentTotalUsage
;
880 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] += Size
;
881 if (Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] < Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
]) {
882 Context
->PeakTotalUsageByType
[ProfileMemoryIndex
] = Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
];
884 Context
->SequenceCount
++;
886 SmramProfileUpdateFreePages (ContextData
);
891 Get memory profile alloc info from memory profile
893 @param DriverInfoData Driver info
894 @param Action This Free action
895 @param Size Buffer size
896 @param Buffer Buffer address
898 @return Pointer to memory profile alloc info.
900 MEMORY_PROFILE_ALLOC_INFO_DATA
*
901 GetMemoryProfileAllocInfoFromAddress (
902 IN MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
,
903 IN MEMORY_PROFILE_ACTION Action
,
908 LIST_ENTRY
*AllocInfoList
;
909 LIST_ENTRY
*AllocLink
;
910 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
911 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
913 AllocInfoList
= DriverInfoData
->AllocInfoList
;
915 for (AllocLink
= AllocInfoList
->ForwardLink
;
916 AllocLink
!= AllocInfoList
;
917 AllocLink
= AllocLink
->ForwardLink
) {
920 MEMORY_PROFILE_ALLOC_INFO_DATA
,
922 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
924 AllocInfo
= &AllocInfoData
->AllocInfo
;
925 if (AllocInfo
->Action
!= Action
) {
929 case MemoryProfileActionAllocatePages
:
930 if ((AllocInfo
->Buffer
<= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) &&
931 ((AllocInfo
->Buffer
+ AllocInfo
->Size
) >= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
))) {
932 return AllocInfoData
;
935 case MemoryProfileActionAllocatePool
:
936 if (AllocInfo
->Buffer
== (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
937 return AllocInfoData
;
950 Update SMRAM profile Free information.
952 @param CallerAddress Address of caller who call Free.
953 @param Action This Free action.
954 @param Size Buffer size.
955 @param Buffer Buffer address.
957 @retval TRUE Profile udpate success.
958 @retval FALSE Profile update fail.
962 SmmCoreUpdateProfileFree (
963 IN PHYSICAL_ADDRESS CallerAddress
,
964 IN MEMORY_PROFILE_ACTION Action
,
969 MEMORY_PROFILE_CONTEXT
*Context
;
970 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
971 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
972 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
973 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
974 LIST_ENTRY
*DriverLink
;
975 LIST_ENTRY
*DriverInfoList
;
976 MEMORY_PROFILE_DRIVER_INFO_DATA
*ThisDriverInfoData
;
977 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
978 EFI_MEMORY_TYPE ProfileMemoryIndex
;
980 ContextData
= GetSmramProfileContext ();
981 if (ContextData
== NULL
) {
985 DriverInfoData
= GetMemoryProfileDriverInfoFromAddress (ContextData
, CallerAddress
);
986 ASSERT (DriverInfoData
!= NULL
);
989 case MemoryProfileActionFreePages
:
990 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
992 case MemoryProfileActionFreePool
:
993 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (DriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
997 AllocInfoData
= NULL
;
1000 if (AllocInfoData
== NULL
) {
1002 // Legal case, because driver A might free memory allocated by driver B, by some protocol.
1004 DriverInfoList
= ContextData
->DriverInfoList
;
1006 for (DriverLink
= DriverInfoList
->ForwardLink
;
1007 DriverLink
!= DriverInfoList
;
1008 DriverLink
= DriverLink
->ForwardLink
) {
1009 ThisDriverInfoData
= CR (
1011 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1013 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1016 case MemoryProfileActionFreePages
:
1017 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePages
, Size
, Buffer
);
1019 case MemoryProfileActionFreePool
:
1020 AllocInfoData
= GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData
, MemoryProfileActionAllocatePool
, 0, Buffer
);
1024 AllocInfoData
= NULL
;
1027 if (AllocInfoData
!= NULL
) {
1028 DriverInfoData
= ThisDriverInfoData
;
1033 if (AllocInfoData
== NULL
) {
1035 // No matched allocate operation is found for this free operation.
1036 // It is because the specified memory type allocate operation has been
1037 // filtered by CoreNeedRecordProfile(), but free operations have no
1038 // memory type information, they can not be filtered by CoreNeedRecordProfile().
1039 // Then, they will be filtered here.
1045 Context
= &ContextData
->Context
;
1046 DriverInfo
= &DriverInfoData
->DriverInfo
;
1047 AllocInfo
= &AllocInfoData
->AllocInfo
;
1049 ProfileMemoryIndex
= GetProfileMemoryIndex (AllocInfo
->MemoryType
);
1051 Context
->CurrentTotalUsage
-= AllocInfo
->Size
;
1052 Context
->CurrentTotalUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1054 DriverInfo
->CurrentUsage
-= AllocInfo
->Size
;
1055 DriverInfo
->CurrentUsageByType
[ProfileMemoryIndex
] -= AllocInfo
->Size
;
1056 DriverInfo
->AllocRecordCount
--;
1058 RemoveEntryList (&AllocInfoData
->Link
);
1060 if (Action
== MemoryProfileActionFreePages
) {
1061 if (AllocInfo
->Buffer
!= (PHYSICAL_ADDRESS
) (UINTN
) Buffer
) {
1062 SmmCoreUpdateProfileAllocate (
1063 AllocInfo
->CallerAddress
,
1064 MemoryProfileActionAllocatePages
,
1065 AllocInfo
->MemoryType
,
1066 (UINTN
) ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
- AllocInfo
->Buffer
),
1067 (VOID
*) (UINTN
) AllocInfo
->Buffer
1070 if (AllocInfo
->Buffer
+ AllocInfo
->Size
!= ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)) {
1071 SmmCoreUpdateProfileAllocate (
1072 AllocInfo
->CallerAddress
,
1073 MemoryProfileActionAllocatePages
,
1074 AllocInfo
->MemoryType
,
1075 (UINTN
) ((AllocInfo
->Buffer
+ AllocInfo
->Size
) - ((PHYSICAL_ADDRESS
) (UINTN
) Buffer
+ Size
)),
1076 (VOID
*) ((UINTN
) Buffer
+ Size
)
1082 // Use SmmInternalFreePool() that will not update profile for this FreePool action.
1084 SmmInternalFreePool (AllocInfoData
);
1090 Update SMRAM profile information.
1092 @param CallerAddress Address of caller who call Allocate or Free.
1093 @param Action This Allocate or Free action.
1094 @param MemoryType Memory type.
1095 @param Size Buffer size.
1096 @param Buffer Buffer address.
1098 @retval TRUE Profile udpate success.
1099 @retval FALSE Profile update fail.
1103 SmmCoreUpdateProfile (
1104 IN PHYSICAL_ADDRESS CallerAddress
,
1105 IN MEMORY_PROFILE_ACTION Action
,
1106 IN EFI_MEMORY_TYPE MemoryType
, // Valid for AllocatePages/AllocatePool
1107 IN UINTN Size
, // Valid for AllocatePages/FreePages/AllocatePool
1111 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1113 if (!IS_SMRAM_PROFILE_ENABLED
) {
1117 if (!mSmramProfileRecordingStatus
) {
1122 // Free operations have no memory type information, so skip the check.
1124 if ((Action
== MemoryProfileActionAllocatePages
) || (Action
== MemoryProfileActionAllocatePool
)) {
1126 // Only record limited MemoryType.
1128 if (!SmmCoreNeedRecordProfile (MemoryType
)) {
1133 ContextData
= GetSmramProfileContext ();
1134 if (ContextData
== NULL
) {
1139 case MemoryProfileActionAllocatePages
:
1140 SmmCoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1142 case MemoryProfileActionFreePages
:
1143 SmmCoreUpdateProfileFree (CallerAddress
, Action
, Size
, Buffer
);
1145 case MemoryProfileActionAllocatePool
:
1146 SmmCoreUpdateProfileAllocate (CallerAddress
, Action
, MemoryType
, Size
, Buffer
);
1148 case MemoryProfileActionFreePool
:
1149 SmmCoreUpdateProfileFree (CallerAddress
, Action
, 0, Buffer
);
1160 SMRAM profile ready to lock callback function.
1164 SmramProfileReadyToLock (
1168 if (!IS_SMRAM_PROFILE_ENABLED
) {
1172 DEBUG ((EFI_D_INFO
, "SmramProfileReadyToLock\n"));
1173 mSmramReadyToLock
= TRUE
;
1176 ////////////////////
1179 This function check if the address is in SMRAM.
1181 @param Buffer the buffer address to be checked.
1182 @param Length the buffer length to be checked.
1184 @retval TRUE this address is in SMRAM.
1185 @retval FALSE this address is NOT in SMRAM.
1189 InternalIsAddressInSmram (
1190 IN PHYSICAL_ADDRESS Buffer
,
1196 for (Index
= 0; Index
< mFullSmramRangeCount
; Index
++) {
1197 if (((Buffer
>= mFullSmramRanges
[Index
].CpuStart
) && (Buffer
< mFullSmramRanges
[Index
].CpuStart
+ mFullSmramRanges
[Index
].PhysicalSize
)) ||
1198 ((mFullSmramRanges
[Index
].CpuStart
>= Buffer
) && (mFullSmramRanges
[Index
].CpuStart
< Buffer
+ Length
))) {
1207 This function check if the address refered by Buffer and Length is valid.
1209 @param Buffer the buffer address to be checked.
1210 @param Length the buffer length to be checked.
1212 @retval TRUE this address is valid.
1213 @retval FALSE this address is NOT valid.
1216 InternalIsAddressValid (
1221 if (Buffer
> (MAX_ADDRESS
- Length
)) {
1227 if (InternalIsAddressInSmram ((PHYSICAL_ADDRESS
) Buffer
, (UINT64
)Length
)) {
1234 Get SMRAM profile data size.
1236 @return SMRAM profile data size.
1240 SmramProfileGetDataSize (
1244 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1245 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1246 LIST_ENTRY
*DriverInfoList
;
1247 LIST_ENTRY
*DriverLink
;
1250 LIST_ENTRY
*FreePageList
;
1251 LIST_ENTRY
*FreePoolList
;
1252 FREE_POOL_HEADER
*Pool
;
1253 UINTN PoolListIndex
;
1256 ContextData
= GetSmramProfileContext ();
1257 if (ContextData
== NULL
) {
1261 TotalSize
= sizeof (MEMORY_PROFILE_CONTEXT
);
1262 TotalSize
+= sizeof (MEMORY_PROFILE_DRIVER_INFO
) * (UINTN
) ContextData
->Context
.ImageCount
;
1264 DriverInfoList
= ContextData
->DriverInfoList
;
1265 for (DriverLink
= DriverInfoList
->ForwardLink
;
1266 DriverLink
!= DriverInfoList
;
1267 DriverLink
= DriverLink
->ForwardLink
) {
1268 DriverInfoData
= CR (
1270 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1272 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1274 TotalSize
+= sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfoData
->DriverInfo
.AllocRecordCount
;
1279 FreePageList
= &mSmmMemoryMap
;
1280 for (Node
= FreePageList
->BackLink
;
1281 Node
!= FreePageList
;
1282 Node
= Node
->BackLink
) {
1285 for (PoolListIndex
= 0; PoolListIndex
< MAX_POOL_INDEX
; PoolListIndex
++) {
1286 FreePoolList
= &mSmmPoolLists
[PoolListIndex
];
1287 for (Node
= FreePoolList
->BackLink
;
1288 Node
!= FreePoolList
;
1289 Node
= Node
->BackLink
) {
1290 Pool
= BASE_CR (Node
, FREE_POOL_HEADER
, Link
);
1291 if (Pool
->Header
.Available
) {
1298 TotalSize
+= (sizeof (MEMORY_PROFILE_FREE_MEMORY
) + Index
* sizeof (MEMORY_PROFILE_DESCRIPTOR
));
1299 TotalSize
+= (sizeof (MEMORY_PROFILE_MEMORY_RANGE
) + mFullSmramRangeCount
* sizeof (MEMORY_PROFILE_DESCRIPTOR
));
1305 Copy SMRAM profile data.
1307 @param ProfileBuffer The buffer to hold SMRAM profile data.
1311 SmramProfileCopyData (
1312 IN VOID
*ProfileBuffer
1315 MEMORY_PROFILE_CONTEXT
*Context
;
1316 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
1317 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
1318 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1319 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1320 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
1321 LIST_ENTRY
*DriverInfoList
;
1322 LIST_ENTRY
*DriverLink
;
1323 LIST_ENTRY
*AllocInfoList
;
1324 LIST_ENTRY
*AllocLink
;
1326 FREE_PAGE_LIST
*Pages
;
1327 LIST_ENTRY
*FreePageList
;
1328 LIST_ENTRY
*FreePoolList
;
1329 FREE_POOL_HEADER
*Pool
;
1330 UINTN PoolListIndex
;
1332 MEMORY_PROFILE_FREE_MEMORY
*FreeMemory
;
1333 MEMORY_PROFILE_MEMORY_RANGE
*MemoryRange
;
1334 MEMORY_PROFILE_DESCRIPTOR
*MemoryProfileDescriptor
;
1336 ContextData
= GetSmramProfileContext ();
1337 if (ContextData
== NULL
) {
1341 Context
= ProfileBuffer
;
1342 CopyMem (Context
, &ContextData
->Context
, sizeof (MEMORY_PROFILE_CONTEXT
));
1343 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) (Context
+ 1);
1345 DriverInfoList
= ContextData
->DriverInfoList
;
1346 for (DriverLink
= DriverInfoList
->ForwardLink
;
1347 DriverLink
!= DriverInfoList
;
1348 DriverLink
= DriverLink
->ForwardLink
) {
1349 DriverInfoData
= CR (
1351 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1353 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1355 CopyMem (DriverInfo
, &DriverInfoData
->DriverInfo
, sizeof (MEMORY_PROFILE_DRIVER_INFO
));
1356 AllocInfo
= (MEMORY_PROFILE_ALLOC_INFO
*) (DriverInfo
+ 1);
1358 AllocInfoList
= DriverInfoData
->AllocInfoList
;
1359 for (AllocLink
= AllocInfoList
->ForwardLink
;
1360 AllocLink
!= AllocInfoList
;
1361 AllocLink
= AllocLink
->ForwardLink
) {
1362 AllocInfoData
= CR (
1364 MEMORY_PROFILE_ALLOC_INFO_DATA
,
1366 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1368 CopyMem (AllocInfo
, &AllocInfoData
->AllocInfo
, sizeof (MEMORY_PROFILE_ALLOC_INFO
));
1372 DriverInfo
= (MEMORY_PROFILE_DRIVER_INFO
*) ((UINTN
) (DriverInfo
+ 1) + sizeof (MEMORY_PROFILE_ALLOC_INFO
) * (UINTN
) DriverInfo
->AllocRecordCount
);
1376 FreeMemory
= (MEMORY_PROFILE_FREE_MEMORY
*) DriverInfo
;
1377 CopyMem (FreeMemory
, &mSmramFreeMemory
, sizeof (MEMORY_PROFILE_FREE_MEMORY
));
1378 MemoryProfileDescriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) (FreeMemory
+ 1);
1380 FreePageList
= &mSmmMemoryMap
;
1381 for (Node
= FreePageList
->BackLink
;
1382 Node
!= FreePageList
;
1383 Node
= Node
->BackLink
) {
1384 Pages
= BASE_CR (Node
, FREE_PAGE_LIST
, Link
);
1385 MemoryProfileDescriptor
->Header
.Signature
= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
;
1386 MemoryProfileDescriptor
->Header
.Length
= sizeof (MEMORY_PROFILE_DESCRIPTOR
);
1387 MemoryProfileDescriptor
->Header
.Revision
= MEMORY_PROFILE_DESCRIPTOR_REVISION
;
1388 MemoryProfileDescriptor
->Address
= (PHYSICAL_ADDRESS
) (UINTN
) Pages
;
1389 MemoryProfileDescriptor
->Size
= EFI_PAGES_TO_SIZE (Pages
->NumberOfPages
);
1390 MemoryProfileDescriptor
++;
1393 for (PoolListIndex
= 0; PoolListIndex
< MAX_POOL_INDEX
; PoolListIndex
++) {
1394 FreePoolList
= &mSmmPoolLists
[MAX_POOL_INDEX
- PoolListIndex
- 1];
1395 for (Node
= FreePoolList
->BackLink
;
1396 Node
!= FreePoolList
;
1397 Node
= Node
->BackLink
) {
1398 Pool
= BASE_CR (Node
, FREE_POOL_HEADER
, Link
);
1399 if (Pool
->Header
.Available
) {
1400 MemoryProfileDescriptor
->Header
.Signature
= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
;
1401 MemoryProfileDescriptor
->Header
.Length
= sizeof (MEMORY_PROFILE_DESCRIPTOR
);
1402 MemoryProfileDescriptor
->Header
.Revision
= MEMORY_PROFILE_DESCRIPTOR_REVISION
;
1403 MemoryProfileDescriptor
->Address
= (PHYSICAL_ADDRESS
) (UINTN
) Pool
;
1404 MemoryProfileDescriptor
->Size
= Pool
->Header
.Size
;
1405 MemoryProfileDescriptor
++;
1410 FreeMemory
->FreeMemoryEntryCount
= Index
;
1412 MemoryRange
= (MEMORY_PROFILE_MEMORY_RANGE
*) MemoryProfileDescriptor
;
1413 MemoryRange
->Header
.Signature
= MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE
;
1414 MemoryRange
->Header
.Length
= sizeof (MEMORY_PROFILE_MEMORY_RANGE
);
1415 MemoryRange
->Header
.Revision
= MEMORY_PROFILE_MEMORY_RANGE_REVISION
;
1416 MemoryRange
->MemoryRangeCount
= (UINT32
) mFullSmramRangeCount
;
1417 MemoryProfileDescriptor
= (MEMORY_PROFILE_DESCRIPTOR
*) (MemoryRange
+ 1);
1418 for (Index
= 0; Index
< mFullSmramRangeCount
; Index
++) {
1419 MemoryProfileDescriptor
->Header
.Signature
= MEMORY_PROFILE_DESCRIPTOR_SIGNATURE
;
1420 MemoryProfileDescriptor
->Header
.Length
= sizeof (MEMORY_PROFILE_DESCRIPTOR
);
1421 MemoryProfileDescriptor
->Header
.Revision
= MEMORY_PROFILE_DESCRIPTOR_REVISION
;
1422 MemoryProfileDescriptor
->Address
= mFullSmramRanges
[Index
].PhysicalStart
;
1423 MemoryProfileDescriptor
->Size
= mFullSmramRanges
[Index
].PhysicalSize
;
1424 MemoryProfileDescriptor
++;
1429 SMRAM profile handler to get profile info.
1431 @param SmramProfileParameterGetInfo The parameter of SMM profile get size.
1435 SmramProfileHandlerGetInfo (
1436 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*SmramProfileParameterGetInfo
1439 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1440 BOOLEAN SmramProfileRecordingStatus
;
1442 ContextData
= GetSmramProfileContext ();
1443 if (ContextData
== NULL
) {
1447 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1448 mSmramProfileRecordingStatus
= FALSE
;
1450 SmramProfileParameterGetInfo
->ProfileSize
= SmramProfileGetDataSize();
1451 SmramProfileParameterGetInfo
->Header
.ReturnStatus
= 0;
1453 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1457 SMRAM profile handler to get profile data.
1459 @param SmramProfileParameterGetData The parameter of SMM profile get data.
1463 SmramProfileHandlerGetData (
1464 IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*SmramProfileParameterGetData
1468 SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA SmramProfileGetData
;
1469 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1470 BOOLEAN SmramProfileRecordingStatus
;
1472 ContextData
= GetSmramProfileContext ();
1473 if (ContextData
== NULL
) {
1477 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1478 mSmramProfileRecordingStatus
= FALSE
;
1481 CopyMem (&SmramProfileGetData
, SmramProfileParameterGetData
, sizeof (SmramProfileGetData
));
1483 ProfileSize
= SmramProfileGetDataSize();
1488 if (!InternalIsAddressValid ((UINTN
) SmramProfileGetData
.ProfileBuffer
, (UINTN
) ProfileSize
)) {
1489 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerGetData: SMM ProfileBuffer in SMRAM or overflow!\n"));
1490 SmramProfileParameterGetData
->ProfileSize
= ProfileSize
;
1491 SmramProfileParameterGetData
->Header
.ReturnStatus
= (UINT64
) (INT64
) (INTN
) EFI_ACCESS_DENIED
;
1495 if (SmramProfileGetData
.ProfileSize
< ProfileSize
) {
1496 SmramProfileParameterGetData
->ProfileSize
= ProfileSize
;
1497 SmramProfileParameterGetData
->Header
.ReturnStatus
= (UINT64
) (INT64
) (INTN
) EFI_BUFFER_TOO_SMALL
;
1501 SmramProfileParameterGetData
->ProfileSize
= ProfileSize
;
1502 SmramProfileCopyData ((VOID
*) (UINTN
) SmramProfileGetData
.ProfileBuffer
);
1503 SmramProfileParameterGetData
->Header
.ReturnStatus
= 0;
1506 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1510 SMRAM profile handler to register SMM image.
1512 @param SmramProfileParameterRegisterImage The parameter of SMM profile register image.
1516 SmramProfileHandlerRegisterImage (
1517 IN SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE
*SmramProfileParameterRegisterImage
1521 EFI_SMM_DRIVER_ENTRY DriverEntry
;
1522 VOID
*EntryPointInImage
;
1525 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1526 CopyMem (&DriverEntry
.FileName
, &SmramProfileParameterRegisterImage
->FileName
, sizeof(EFI_GUID
));
1527 DriverEntry
.ImageBuffer
= SmramProfileParameterRegisterImage
->ImageBuffer
;
1528 DriverEntry
.NumberOfPage
= (UINTN
) SmramProfileParameterRegisterImage
->NumberOfPage
;
1529 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) DriverEntry
.ImageBuffer
, &EntryPointInImage
);
1530 ASSERT_EFI_ERROR (Status
);
1531 DriverEntry
.ImageEntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1533 Ret
= RegisterSmramProfileImage (&DriverEntry
, FALSE
);
1535 SmramProfileParameterRegisterImage
->Header
.ReturnStatus
= 0;
1540 SMRAM profile handler to unregister SMM image.
1542 @param SmramProfileParameterUnregisterImage The parameter of SMM profile unregister image.
1546 SmramProfileHandlerUnregisterImage (
1547 IN SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE
*SmramProfileParameterUnregisterImage
1551 EFI_SMM_DRIVER_ENTRY DriverEntry
;
1552 VOID
*EntryPointInImage
;
1555 ZeroMem (&DriverEntry
, sizeof (DriverEntry
));
1556 CopyMem (&DriverEntry
.FileName
, &SmramProfileParameterUnregisterImage
->FileName
, sizeof (EFI_GUID
));
1557 DriverEntry
.ImageBuffer
= SmramProfileParameterUnregisterImage
->ImageBuffer
;
1558 DriverEntry
.NumberOfPage
= (UINTN
) SmramProfileParameterUnregisterImage
->NumberOfPage
;
1559 Status
= InternalPeCoffGetEntryPoint ((VOID
*) (UINTN
) DriverEntry
.ImageBuffer
, &EntryPointInImage
);
1560 ASSERT_EFI_ERROR (Status
);
1561 DriverEntry
.ImageEntryPoint
= (PHYSICAL_ADDRESS
) (UINTN
) EntryPointInImage
;
1563 Ret
= UnregisterSmramProfileImage (&DriverEntry
, FALSE
);
1565 SmramProfileParameterUnregisterImage
->Header
.ReturnStatus
= 0;
1570 Dispatch function for a Software SMI handler.
1572 Caution: This function may receive untrusted input.
1573 Communicate buffer and buffer size are external input, so this function will do basic validation.
1575 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
1576 @param Context Points to an optional handler context which was specified when the
1577 handler was registered.
1578 @param CommBuffer A pointer to a collection of data in memory that will
1579 be conveyed from a non-SMM environment into an SMM environment.
1580 @param CommBufferSize The size of the CommBuffer.
1582 @retval EFI_SUCCESS Command is handled successfully.
1587 SmramProfileHandler (
1588 IN EFI_HANDLE DispatchHandle
,
1589 IN CONST VOID
*Context OPTIONAL
,
1590 IN OUT VOID
*CommBuffer OPTIONAL
,
1591 IN OUT UINTN
*CommBufferSize OPTIONAL
1594 SMRAM_PROFILE_PARAMETER_HEADER
*SmramProfileParameterHeader
;
1595 UINTN TempCommBufferSize
;
1597 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler Enter\n"));
1600 // If input is invalid, stop processing this SMI
1602 if (CommBuffer
== NULL
|| CommBufferSize
== NULL
) {
1606 TempCommBufferSize
= *CommBufferSize
;
1608 if (TempCommBufferSize
< sizeof (SMRAM_PROFILE_PARAMETER_HEADER
)) {
1609 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1613 if (mSmramReadyToLock
&& !InternalIsAddressValid ((UINTN
)CommBuffer
, TempCommBufferSize
)) {
1614 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));
1618 SmramProfileParameterHeader
= (SMRAM_PROFILE_PARAMETER_HEADER
*) ((UINTN
) CommBuffer
);
1620 SmramProfileParameterHeader
->ReturnStatus
= (UINT64
)-1;
1622 if (GetSmramProfileContext () == NULL
) {
1623 SmramProfileParameterHeader
->ReturnStatus
= (UINT64
) (INT64
) (INTN
) EFI_UNSUPPORTED
;
1627 switch (SmramProfileParameterHeader
->Command
) {
1628 case SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO
:
1629 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerGetInfo\n"));
1630 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
)) {
1631 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1634 SmramProfileHandlerGetInfo ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO
*) (UINTN
) CommBuffer
);
1636 case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA
:
1637 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerGetData\n"));
1638 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
)) {
1639 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1642 SmramProfileHandlerGetData ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA
*) (UINTN
) CommBuffer
);
1644 case SMRAM_PROFILE_COMMAND_REGISTER_IMAGE
:
1645 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerRegisterImage\n"));
1646 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE
)) {
1647 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1650 if (mSmramReadyToLock
) {
1653 SmramProfileHandlerRegisterImage ((SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE
*) (UINTN
) CommBuffer
);
1655 case SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE
:
1656 DEBUG ((EFI_D_ERROR
, "SmramProfileHandlerUnregisterImage\n"));
1657 if (TempCommBufferSize
!= sizeof (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE
)) {
1658 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler: SMM communication buffer size invalid!\n"));
1661 if (mSmramReadyToLock
) {
1664 SmramProfileHandlerUnregisterImage ((SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE
*) (UINTN
) CommBuffer
);
1670 DEBUG ((EFI_D_ERROR
, "SmramProfileHandler Exit\n"));
1676 Register SMRAM profile handler.
1680 RegisterSmramProfileHandler (
1685 EFI_HANDLE DispatchHandle
;
1687 if (!IS_SMRAM_PROFILE_ENABLED
) {
1691 Status
= SmiHandlerRegister (
1692 SmramProfileHandler
,
1693 &gEdkiiMemoryProfileGuid
,
1696 ASSERT_EFI_ERROR (Status
);
1699 ////////////////////
1711 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1712 BOOLEAN SmramProfileRecordingStatus
;
1714 ContextData
= GetSmramProfileContext ();
1715 if (ContextData
== NULL
) {
1719 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1720 mSmramProfileRecordingStatus
= FALSE
;
1722 DEBUG ((EFI_D_INFO
, "FullSmramRange address - 0x%08x\n", mFullSmramRanges
));
1724 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1726 DEBUG ((EFI_D_INFO
, "FullSmramRange:\n"));
1727 for (Index
= 0; Index
< mFullSmramRangeCount
; Index
++) {
1728 DEBUG ((EFI_D_INFO
, " FullSmramRange (0x%x)\n", Index
));
1729 DEBUG ((EFI_D_INFO
, " PhysicalStart - 0x%016lx\n", mFullSmramRanges
[Index
].PhysicalStart
));
1730 DEBUG ((EFI_D_INFO
, " CpuStart - 0x%016lx\n", mFullSmramRanges
[Index
].CpuStart
));
1731 DEBUG ((EFI_D_INFO
, " PhysicalSize - 0x%016lx\n", mFullSmramRanges
[Index
].PhysicalSize
));
1732 DEBUG ((EFI_D_INFO
, " RegionState - 0x%016lx\n", mFullSmramRanges
[Index
].RegionState
));
1735 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1737 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1741 Dump SMRAM free page list.
1749 LIST_ENTRY
*FreePageList
;
1751 FREE_PAGE_LIST
*Pages
;
1753 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1754 BOOLEAN SmramProfileRecordingStatus
;
1756 ContextData
= GetSmramProfileContext ();
1757 if (ContextData
== NULL
) {
1761 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1762 mSmramProfileRecordingStatus
= FALSE
;
1764 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1766 DEBUG ((EFI_D_INFO
, "FreePagesList:\n"));
1767 FreePageList
= &mSmmMemoryMap
;
1768 for (Node
= FreePageList
->BackLink
, Index
= 0;
1769 Node
!= FreePageList
;
1770 Node
= Node
->BackLink
, Index
++) {
1771 Pages
= BASE_CR (Node
, FREE_PAGE_LIST
, Link
);
1772 DEBUG ((EFI_D_INFO
, " Index - 0x%x\n", Index
));
1773 DEBUG ((EFI_D_INFO
, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS
) (UINTN
) Pages
));
1774 DEBUG ((EFI_D_INFO
, " NumberOfPages - 0x%08x\n", Pages
->NumberOfPages
));
1777 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1779 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1783 Dump SMRAM free pool list.
1791 LIST_ENTRY
*FreePoolList
;
1793 FREE_POOL_HEADER
*Pool
;
1795 UINTN PoolListIndex
;
1796 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1797 BOOLEAN SmramProfileRecordingStatus
;
1799 ContextData
= GetSmramProfileContext ();
1800 if (ContextData
== NULL
) {
1804 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1805 mSmramProfileRecordingStatus
= FALSE
;
1807 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1809 for (PoolListIndex
= 0; PoolListIndex
< MAX_POOL_INDEX
; PoolListIndex
++) {
1810 DEBUG ((EFI_D_INFO
, "FreePoolList (%d):\n", PoolListIndex
));
1811 FreePoolList
= &mSmmPoolLists
[PoolListIndex
];
1812 for (Node
= FreePoolList
->BackLink
, Index
= 0;
1813 Node
!= FreePoolList
;
1814 Node
= Node
->BackLink
, Index
++) {
1815 Pool
= BASE_CR (Node
, FREE_POOL_HEADER
, Link
);
1816 DEBUG ((EFI_D_INFO
, " Index - 0x%x\n", Index
));
1817 DEBUG ((EFI_D_INFO
, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS
) (UINTN
) Pool
));
1818 DEBUG ((EFI_D_INFO
, " Size - 0x%08x\n", Pool
->Header
.Size
));
1819 DEBUG ((EFI_D_INFO
, " Available - 0x%02x\n", Pool
->Header
.Available
));
1823 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1825 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1828 GLOBAL_REMOVE_IF_UNREFERENCED CHAR16
*mActionString
[] = {
1836 GLOBAL_REMOVE_IF_UNREFERENCED CHAR16
*mMemoryTypeString
[] = {
1837 L
"EfiReservedMemoryType",
1840 L
"EfiBootServicesCode",
1841 L
"EfiBootServicesData",
1842 L
"EfiRuntimeServicesCode",
1843 L
"EfiRuntimeServicesData",
1844 L
"EfiConventionalMemory",
1845 L
"EfiUnusableMemory",
1846 L
"EfiACPIReclaimMemory",
1847 L
"EfiACPIMemoryNVS",
1848 L
"EfiMemoryMappedIO",
1849 L
"EfiMemoryMappedIOPortSpace",
1864 MEMORY_PROFILE_CONTEXT
*Context
;
1865 MEMORY_PROFILE_DRIVER_INFO
*DriverInfo
;
1866 MEMORY_PROFILE_ALLOC_INFO
*AllocInfo
;
1867 MEMORY_PROFILE_CONTEXT_DATA
*ContextData
;
1868 MEMORY_PROFILE_DRIVER_INFO_DATA
*DriverInfoData
;
1869 MEMORY_PROFILE_ALLOC_INFO_DATA
*AllocInfoData
;
1870 LIST_ENTRY
*SmramDriverInfoList
;
1872 LIST_ENTRY
*DriverLink
;
1873 LIST_ENTRY
*AllocInfoList
;
1875 LIST_ENTRY
*AllocLink
;
1876 BOOLEAN SmramProfileRecordingStatus
;
1879 ContextData
= GetSmramProfileContext ();
1880 if (ContextData
== NULL
) {
1884 SmramProfileRecordingStatus
= mSmramProfileRecordingStatus
;
1885 mSmramProfileRecordingStatus
= FALSE
;
1887 Context
= &ContextData
->Context
;
1888 DEBUG ((EFI_D_INFO
, "======= SmramProfile begin =======\n"));
1889 DEBUG ((EFI_D_INFO
, "MEMORY_PROFILE_CONTEXT\n"));
1891 DEBUG ((EFI_D_INFO
, " CurrentTotalUsage - 0x%016lx\n", Context
->CurrentTotalUsage
));
1892 DEBUG ((EFI_D_INFO
, " PeakTotalUsage - 0x%016lx\n", Context
->PeakTotalUsage
));
1893 for (TypeIndex
= 0; TypeIndex
<= EfiMaxMemoryType
; TypeIndex
++) {
1894 if ((Context
->CurrentTotalUsageByType
[TypeIndex
] != 0) ||
1895 (Context
->PeakTotalUsageByType
[TypeIndex
] != 0)) {
1896 DEBUG ((EFI_D_INFO
, " CurrentTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->CurrentTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]));
1897 DEBUG ((EFI_D_INFO
, " PeakTotalUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, Context
->PeakTotalUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]));
1900 DEBUG ((EFI_D_INFO
, " TotalImageSize - 0x%016lx\n", Context
->TotalImageSize
));
1901 DEBUG ((EFI_D_INFO
, " ImageCount - 0x%08x\n", Context
->ImageCount
));
1902 DEBUG ((EFI_D_INFO
, " SequenceCount - 0x%08x\n", Context
->SequenceCount
));
1904 SmramDriverInfoList
= ContextData
->DriverInfoList
;
1905 for (DriverLink
= SmramDriverInfoList
->ForwardLink
, DriverIndex
= 0;
1906 DriverLink
!= SmramDriverInfoList
;
1907 DriverLink
= DriverLink
->ForwardLink
, DriverIndex
++) {
1908 DriverInfoData
= CR (
1910 MEMORY_PROFILE_DRIVER_INFO_DATA
,
1912 MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
1914 DriverInfo
= &DriverInfoData
->DriverInfo
;
1915 DEBUG ((EFI_D_INFO
, " MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex
));
1916 DEBUG ((EFI_D_INFO
, " FileName - %g\n", &DriverInfo
->FileName
));
1917 DEBUG ((EFI_D_INFO
, " ImageBase - 0x%016lx\n", DriverInfo
->ImageBase
));
1918 DEBUG ((EFI_D_INFO
, " ImageSize - 0x%016lx\n", DriverInfo
->ImageSize
));
1919 DEBUG ((EFI_D_INFO
, " EntryPoint - 0x%016lx\n", DriverInfo
->EntryPoint
));
1920 DEBUG ((EFI_D_INFO
, " ImageSubsystem - 0x%04x\n", DriverInfo
->ImageSubsystem
));
1921 DEBUG ((EFI_D_INFO
, " FileType - 0x%02x\n", DriverInfo
->FileType
));
1922 DEBUG ((EFI_D_INFO
, " CurrentUsage - 0x%016lx\n", DriverInfo
->CurrentUsage
));
1923 DEBUG ((EFI_D_INFO
, " PeakUsage - 0x%016lx\n", DriverInfo
->PeakUsage
));
1924 for (TypeIndex
= 0; TypeIndex
<= EfiMaxMemoryType
; TypeIndex
++) {
1925 if ((DriverInfo
->CurrentUsageByType
[TypeIndex
] != 0) ||
1926 (DriverInfo
->PeakUsageByType
[TypeIndex
] != 0)) {
1927 DEBUG ((EFI_D_INFO
, " CurrentUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->CurrentUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]));
1928 DEBUG ((EFI_D_INFO
, " PeakUsage[0x%02x] - 0x%016lx (%s)\n", TypeIndex
, DriverInfo
->PeakUsageByType
[TypeIndex
], mMemoryTypeString
[TypeIndex
]));
1931 DEBUG ((EFI_D_INFO
, " AllocRecordCount - 0x%08x\n", DriverInfo
->AllocRecordCount
));
1933 AllocInfoList
= DriverInfoData
->AllocInfoList
;
1934 for (AllocLink
= AllocInfoList
->ForwardLink
, AllocIndex
= 0;
1935 AllocLink
!= AllocInfoList
;
1936 AllocLink
= AllocLink
->ForwardLink
, AllocIndex
++) {
1937 AllocInfoData
= CR (
1939 MEMORY_PROFILE_ALLOC_INFO_DATA
,
1941 MEMORY_PROFILE_ALLOC_INFO_SIGNATURE
1943 AllocInfo
= &AllocInfoData
->AllocInfo
;
1944 DEBUG ((EFI_D_INFO
, " MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex
));
1945 DEBUG ((EFI_D_INFO
, " CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo
->CallerAddress
, AllocInfo
->CallerAddress
- DriverInfo
->ImageBase
));
1946 DEBUG ((EFI_D_INFO
, " SequenceId - 0x%08x\n", AllocInfo
->SequenceId
));
1947 DEBUG ((EFI_D_INFO
, " Action - 0x%08x (%s)\n", AllocInfo
->Action
, mActionString
[(AllocInfo
->Action
< sizeof(mActionString
)/sizeof(mActionString
[0])) ? AllocInfo
->Action
: 0]));
1948 DEBUG ((EFI_D_INFO
, " MemoryType - 0x%08x\n", AllocInfo
->MemoryType
));
1949 DEBUG ((EFI_D_INFO
, " Buffer - 0x%016lx\n", AllocInfo
->Buffer
));
1950 DEBUG ((EFI_D_INFO
, " Size - 0x%016lx\n", AllocInfo
->Size
));
1954 DEBUG ((EFI_D_INFO
, "======= SmramProfile end =======\n"));
1956 mSmramProfileRecordingStatus
= SmramProfileRecordingStatus
;
1960 Dump SMRAM infromation.
1969 if (IS_SMRAM_PROFILE_ENABLED
) {
1970 DumpSmramProfile ();
1971 DumpFreePagesList ();
1972 DumpFreePoolList ();