2 SMI handler profile support.
4 Copyright (c) 2017, 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.
16 #include <Library/BaseLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/SmmServicesTableLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/PrintLib.h>
23 #include <Library/UefiLib.h>
24 #include <Library/DevicePathLib.h>
25 #include <Library/PeCoffGetEntryPointLib.h>
26 #include <Library/DxeServicesLib.h>
27 #include <Protocol/LoadedImage.h>
28 #include <Protocol/SmmAccess2.h>
29 #include <Protocol/SmmReadyToLock.h>
30 #include <Protocol/SmmEndOfDxe.h>
32 #include <Guid/SmiHandlerProfile.h>
34 #include "PiSmmCore.h"
47 Register SMI handler profile handler.
50 RegisterSmiHandlerProfileHandler(
55 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
56 into system memory with the PE/COFF Loader Library functions.
58 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
59 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
60 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
61 If Pe32Data is NULL, then ASSERT().
62 If EntryPoint is NULL, then ASSERT().
64 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
65 @param EntryPoint The pointer to entry point to the PE/COFF image to return.
67 @retval RETURN_SUCCESS EntryPoint was returned.
68 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
72 InternalPeCoffGetEntryPoint (
77 extern LIST_ENTRY mSmiEntryList
;
78 extern LIST_ENTRY mHardwareSmiEntryList
;
79 extern SMI_ENTRY mRootSmiEntry
;
81 extern SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile
;
83 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mHardwareSmiEntryList
= INITIALIZE_LIST_HEAD_VARIABLE (mHardwareSmiEntryList
);
85 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mRootSmiEntryList
= INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntryList
);
87 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY
*mSmmCoreRootSmiEntryList
= &mRootSmiEntryList
;
88 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY
*mSmmCoreSmiEntryList
= &mSmiEntryList
;
89 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY
*mSmmCoreHardwareSmiEntryList
= &mHardwareSmiEntryList
;
91 GLOBAL_REMOVE_IF_UNREFERENCED IMAGE_STRUCT
*mImageStruct
;
92 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mImageStructCountMax
;
93 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mImageStructCount
;
95 GLOBAL_REMOVE_IF_UNREFERENCED VOID
*mSmiHandlerProfileDatabase
;
96 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmiHandlerProfileDatabaseSize
;
98 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmImageDatabaseSize
;
99 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmRootSmiDatabaseSize
;
100 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmSmiDatabaseSize
;
101 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmHardwareSmiDatabaseSize
;
103 GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmiHandlerProfileRecordingStatus
;
105 GLOBAL_REMOVE_IF_UNREFERENCED SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile
= {
106 SmiHandlerProfileRegisterHandler
,
107 SmiHandlerProfileUnregisterHandler
,
111 This function dump raw data.
114 @param Size raw data size
123 for (Index
= 0; Index
< Size
; Index
++) {
124 DEBUG ((DEBUG_INFO
, "%02x ", (UINTN
)Data
[Index
]));
129 Get GUID name for an image.
131 @param[in] LoadedImage LoadedImage protocol.
132 @param[out] Guid Guid of the FFS
136 IN EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
,
143 if ((DevicePathType(LoadedImage
->FilePath
) == MEDIA_DEVICE_PATH
) &&
144 (DevicePathSubType(LoadedImage
->FilePath
) == MEDIA_PIWG_FW_FILE_DP
)) {
145 FileName
= &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)LoadedImage
->FilePath
)->FvFileName
;
147 if (FileName
!= NULL
) {
148 CopyGuid(Guid
, FileName
);
150 ZeroMem(Guid
, sizeof(EFI_GUID
));
157 @param ImageBase image base
158 @param ImageSize image size
159 @param EntryPoint image entry point
160 @param Guid FFS GUID of the image
161 @param PdbString image PDB string
174 if (mImageStructCount
>= mImageStructCountMax
) {
179 CopyGuid(&mImageStruct
[mImageStructCount
].FileGuid
, Guid
);
180 mImageStruct
[mImageStructCount
].ImageRef
= mImageStructCount
;
181 mImageStruct
[mImageStructCount
].ImageBase
= ImageBase
;
182 mImageStruct
[mImageStructCount
].ImageSize
= ImageSize
;
183 mImageStruct
[mImageStructCount
].EntryPoint
= EntryPoint
;
184 if (PdbString
!= NULL
) {
185 PdbStringSize
= AsciiStrSize(PdbString
);
186 mImageStruct
[mImageStructCount
].PdbString
= AllocateCopyPool (PdbStringSize
, PdbString
);
187 if (mImageStruct
[mImageStructCount
].PdbString
!= NULL
) {
188 mImageStruct
[mImageStructCount
].PdbStringSize
= PdbStringSize
;
196 return an image structure based upon image address.
198 @param Address image address
200 @return image structure
203 AddressToImageStruct(
209 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
210 if ((Address
>= mImageStruct
[Index
].ImageBase
) &&
211 (Address
< mImageStruct
[Index
].ImageBase
+ mImageStruct
[Index
].ImageSize
)) {
212 return &mImageStruct
[Index
];
219 return an image reference index based upon image address.
221 @param Address image address
223 @return image reference index
230 IMAGE_STRUCT
*ImageStruct
;
232 ImageStruct
= AddressToImageStruct(Address
);
233 if (ImageStruct
!= NULL
) {
234 return ImageStruct
->ImageRef
;
240 Collect SMM image information based upon loaded image protocol.
249 UINTN HandleBufferSize
;
250 EFI_HANDLE
*HandleBuffer
;
252 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
254 EFI_SMM_DRIVER_ENTRY
*LoadedImagePrivate
;
256 VOID
*EntryPointInImage
;
261 HandleBufferSize
= 0;
263 Status
= gSmst
->SmmLocateHandle(
265 &gEfiLoadedImageProtocolGuid
,
270 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
273 HandleBuffer
= AllocateZeroPool (HandleBufferSize
);
274 if (HandleBuffer
== NULL
) {
277 Status
= gSmst
->SmmLocateHandle(
279 &gEfiLoadedImageProtocolGuid
,
284 if (EFI_ERROR(Status
)) {
288 NoHandles
= HandleBufferSize
/sizeof(EFI_HANDLE
);
289 mImageStructCountMax
= NoHandles
;
290 mImageStruct
= AllocateZeroPool(mImageStructCountMax
* sizeof(IMAGE_STRUCT
));
291 if (mImageStruct
== NULL
) {
295 for (Index
= 0; Index
< NoHandles
; Index
++) {
296 Status
= gSmst
->SmmHandleProtocol(
298 &gEfiLoadedImageProtocolGuid
,
299 (VOID
**)&LoadedImage
301 if (EFI_ERROR(Status
)) {
304 PathStr
= ConvertDevicePathToText(LoadedImage
->FilePath
, TRUE
, TRUE
);
305 GetDriverGuid(LoadedImage
, &Guid
);
306 DEBUG ((DEBUG_INFO
, "Image: %g ", &Guid
));
309 LoadedImagePrivate
= BASE_CR(LoadedImage
, EFI_SMM_DRIVER_ENTRY
, SmmLoadedImage
);
310 RealImageBase
= (UINTN
)LoadedImage
->ImageBase
;
311 if (LoadedImagePrivate
->Signature
== EFI_SMM_DRIVER_ENTRY_SIGNATURE
) {
312 EntryPoint
= (UINTN
)LoadedImagePrivate
->ImageEntryPoint
;
313 if ((EntryPoint
!= 0) && ((EntryPoint
< (UINTN
)LoadedImage
->ImageBase
) || (EntryPoint
>= ((UINTN
)LoadedImage
->ImageBase
+ (UINTN
)LoadedImage
->ImageSize
)))) {
315 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
316 // So patch ImageBuffer here to align the EntryPoint.
318 Status
= InternalPeCoffGetEntryPoint(LoadedImage
->ImageBase
, &EntryPointInImage
);
319 ASSERT_EFI_ERROR(Status
);
320 RealImageBase
= (UINTN
)LoadedImage
->ImageBase
+ EntryPoint
- (UINTN
)EntryPointInImage
;
323 DEBUG ((DEBUG_INFO
, "(0x%x - 0x%x", RealImageBase
, (UINTN
)LoadedImage
->ImageSize
));
324 if (EntryPoint
!= 0) {
325 DEBUG ((DEBUG_INFO
, ", EntryPoint:0x%x", EntryPoint
));
327 DEBUG ((DEBUG_INFO
, ")\n"));
329 if (RealImageBase
!= 0) {
330 PdbString
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) RealImageBase
);
331 DEBUG ((DEBUG_INFO
, " pdb - %a\n", PdbString
));
335 DEBUG ((DEBUG_INFO
, " (%s)\n", PathStr
));
337 AddImageStruct((UINTN
)RealImageBase
, (UINTN
)LoadedImage
->ImageSize
, EntryPoint
, &Guid
, PdbString
);
341 FreePool(HandleBuffer
);
346 Dump SMI child context.
348 @param HandlerType the handler type
349 @param Context the handler context
350 @param ContextSize the handler context size
353 DumpSmiChildContext (
354 IN EFI_GUID
*HandlerType
,
361 if (CompareGuid (HandlerType
, &gEfiSmmSwDispatch2ProtocolGuid
)) {
362 DEBUG ((DEBUG_INFO
, " SwSmi - 0x%x\n", ((EFI_SMM_SW_REGISTER_CONTEXT
*)Context
)->SwSmiInputValue
));
363 } else if (CompareGuid (HandlerType
, &gEfiSmmSxDispatch2ProtocolGuid
)) {
364 DEBUG ((DEBUG_INFO
, " SxType - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Type
));
365 DEBUG ((DEBUG_INFO
, " SxPhase - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Phase
));
366 } else if (CompareGuid (HandlerType
, &gEfiSmmPowerButtonDispatch2ProtocolGuid
)) {
367 DEBUG ((DEBUG_INFO
, " PowerButtonPhase - 0x%x\n", ((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
368 } else if (CompareGuid (HandlerType
, &gEfiSmmStandbyButtonDispatch2ProtocolGuid
)) {
369 DEBUG ((DEBUG_INFO
, " StandbyButtonPhase - 0x%x\n", ((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
370 } else if (CompareGuid (HandlerType
, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid
)) {
371 DEBUG ((DEBUG_INFO
, " PeriodicTimerPeriod - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->Period
));
372 DEBUG ((DEBUG_INFO
, " PeriodicTimerSmiTickInterval - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->SmiTickInterval
));
373 } else if (CompareGuid (HandlerType
, &gEfiSmmGpiDispatch2ProtocolGuid
)) {
374 DEBUG ((DEBUG_INFO
, " GpiNum - 0x%lx\n", ((EFI_SMM_GPI_REGISTER_CONTEXT
*)Context
)->GpiNum
));
375 } else if (CompareGuid (HandlerType
, &gEfiSmmIoTrapDispatch2ProtocolGuid
)) {
376 DEBUG ((DEBUG_INFO
, " IoTrapAddress - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Address
));
377 DEBUG ((DEBUG_INFO
, " IoTrapLength - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Length
));
378 DEBUG ((DEBUG_INFO
, " IoTrapType - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Type
));
379 } else if (CompareGuid (HandlerType
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
380 DEBUG ((DEBUG_INFO
, " UsbType - 0x%x\n", ((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
)->Type
));
381 Str
= ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL
*)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
) + 1), TRUE
, TRUE
);
382 DEBUG ((DEBUG_INFO
, " UsbDevicePath - %s\n", Str
));
387 DEBUG ((DEBUG_INFO
, " Context - "));
388 InternalDumpData (Context
, ContextSize
);
389 DEBUG ((DEBUG_INFO
, "\n"));
394 Dump all SMI handlers associated with SmiEntry.
396 @param SmiEntry SMI entry.
399 DumpSmiHandlerOnSmiEntry(
400 IN SMI_ENTRY
*SmiEntry
403 LIST_ENTRY
*ListEntry
;
404 SMI_HANDLER
*SmiHandler
;
405 IMAGE_STRUCT
*ImageStruct
;
407 ListEntry
= &SmiEntry
->SmiHandlers
;
408 for (ListEntry
= ListEntry
->ForwardLink
;
409 ListEntry
!= &SmiEntry
->SmiHandlers
;
410 ListEntry
= ListEntry
->ForwardLink
) {
411 SmiHandler
= CR(ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
412 ImageStruct
= AddressToImageStruct((UINTN
)SmiHandler
->Handler
);
413 if (ImageStruct
!= NULL
) {
414 DEBUG ((DEBUG_INFO
, " Module - %g", &ImageStruct
->FileGuid
));
416 if ((ImageStruct
!= NULL
) && (ImageStruct
->PdbString
[0] != 0)) {
417 DEBUG ((DEBUG_INFO
, " (Pdb - %a)", ImageStruct
->PdbString
));
419 DEBUG ((DEBUG_INFO
, "\n"));
420 if (SmiHandler
->ContextSize
!= 0) {
421 DumpSmiChildContext (&SmiEntry
->HandlerType
, SmiHandler
->Context
, SmiHandler
->ContextSize
);
423 DEBUG ((DEBUG_INFO
, " Handler - 0x%x", SmiHandler
->Handler
));
424 if (ImageStruct
!= NULL
) {
425 DEBUG ((DEBUG_INFO
, " <== RVA - 0x%x", (UINTN
)SmiHandler
->Handler
- ImageStruct
->ImageBase
));
427 DEBUG ((DEBUG_INFO
, "\n"));
428 DEBUG ((DEBUG_INFO
, " CallerAddr - 0x%x", SmiHandler
->CallerAddr
));
429 if (ImageStruct
!= NULL
) {
430 DEBUG ((DEBUG_INFO
, " <== RVA - 0x%x", SmiHandler
->CallerAddr
- ImageStruct
->ImageBase
));
432 DEBUG ((DEBUG_INFO
, "\n"));
439 Dump all SMI entry on the list.
441 @param SmiEntryList a list of SMI entry.
445 IN LIST_ENTRY
*SmiEntryList
448 LIST_ENTRY
*ListEntry
;
451 ListEntry
= SmiEntryList
;
452 for (ListEntry
= ListEntry
->ForwardLink
;
453 ListEntry
!= SmiEntryList
;
454 ListEntry
= ListEntry
->ForwardLink
) {
455 SmiEntry
= CR(ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
456 DEBUG ((DEBUG_INFO
, "SmiEntry - %g\n", &SmiEntry
->HandlerType
));
457 DumpSmiHandlerOnSmiEntry(SmiEntry
);
464 SMM Ready To Lock event notification handler.
466 This function collects all SMM image information and build SmiHandleProfile database,
467 and register SmiHandlerProfile SMI handler.
469 @param[in] Protocol Points to the protocol's unique identifier.
470 @param[in] Interface Points to the interface instance.
471 @param[in] Handle The handle on which the interface was installed.
473 @retval EFI_SUCCESS Notification handler runs successfully.
477 SmmReadyToLockInSmiHandlerProfile (
478 IN CONST EFI_GUID
*Protocol
,
486 DEBUG ((DEBUG_INFO
, "##################\n"));
487 DEBUG ((DEBUG_INFO
, "# IMAGE DATABASE #\n"));
488 DEBUG ((DEBUG_INFO
, "##################\n"));
489 GetSmmLoadedImage ();
490 DEBUG ((DEBUG_INFO
, "\n"));
495 DEBUG ((DEBUG_INFO
, "########################\n"));
496 DEBUG ((DEBUG_INFO
, "# SMI Handler DATABASE #\n"));
497 DEBUG ((DEBUG_INFO
, "########################\n"));
499 DEBUG ((DEBUG_INFO
, "# 1. ROOT SMI Handler #\n"));
501 DumpSmiEntryList(mSmmCoreRootSmiEntryList
);
504 DEBUG ((DEBUG_INFO
, "# 2. GUID SMI Handler #\n"));
506 DumpSmiEntryList(mSmmCoreSmiEntryList
);
509 DEBUG ((DEBUG_INFO
, "# 3. Hardware SMI Handler #\n"));
511 DumpSmiEntryList(mSmmCoreHardwareSmiEntryList
);
514 DEBUG ((DEBUG_INFO
, "\n"));
516 RegisterSmiHandlerProfileHandler();
518 if (mImageStruct
!= NULL
) {
519 FreePool(mImageStruct
);
526 returns SMM image data base size.
528 @return SMM image data base size.
531 GetSmmImageDatabaseSize(
538 Size
= (sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
)) * mImageStructCount
;
539 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
540 Size
+= mImageStruct
[Index
].PdbStringSize
;
546 returns all SMI handlers' size associated with SmiEntry.
548 @param SmiEntry SMI entry.
550 @return all SMI handlers' size associated with SmiEntry.
553 GetSmmSmiHandlerSizeOnSmiEntry(
554 IN SMI_ENTRY
*SmiEntry
557 LIST_ENTRY
*ListEntry
;
558 SMI_HANDLER
*SmiHandler
;
562 ListEntry
= &SmiEntry
->SmiHandlers
;
563 for (ListEntry
= ListEntry
->ForwardLink
;
564 ListEntry
!= &SmiEntry
->SmiHandlers
;
565 ListEntry
= ListEntry
->ForwardLink
) {
566 SmiHandler
= CR(ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
567 Size
+= sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
;
574 return all SMI handler database size on the SMI entry list.
576 @param SmiEntryList a list of SMI entry.
578 @return all SMI handler database size on the SMI entry list.
581 GetSmmSmiDatabaseSize(
582 IN LIST_ENTRY
*SmiEntryList
585 LIST_ENTRY
*ListEntry
;
590 ListEntry
= SmiEntryList
;
591 for (ListEntry
= ListEntry
->ForwardLink
;
592 ListEntry
!= SmiEntryList
;
593 ListEntry
= ListEntry
->ForwardLink
) {
594 SmiEntry
= CR(ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
595 Size
+= sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
);
596 Size
+= GetSmmSmiHandlerSizeOnSmiEntry(SmiEntry
);
602 return SMI handler profile database size.
604 @return SMI handler profile database size.
607 GetSmiHandlerProfileDatabaseSize (
611 mSmmImageDatabaseSize
= GetSmmImageDatabaseSize();
612 mSmmRootSmiDatabaseSize
= GetSmmSmiDatabaseSize(mSmmCoreRootSmiEntryList
);
613 mSmmSmiDatabaseSize
= GetSmmSmiDatabaseSize(mSmmCoreSmiEntryList
);
614 mSmmHardwareSmiDatabaseSize
= GetSmmSmiDatabaseSize(mSmmCoreHardwareSmiEntryList
);
616 return mSmmImageDatabaseSize
+ mSmmSmiDatabaseSize
+ mSmmRootSmiDatabaseSize
+ mSmmHardwareSmiDatabaseSize
;
620 get SMM image database.
622 @param Data The buffer to hold SMM image database
623 @param ExpectedSize The expected size of the SMM image database
625 @return SMM image data base size.
628 GetSmmImageDatabaseData (
630 IN UINTN ExpectedSize
633 SMM_CORE_IMAGE_DATABASE_STRUCTURE
*ImageStruct
;
639 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
640 if (Size
>= ExpectedSize
) {
643 if (sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + mImageStruct
[Index
].PdbStringSize
> ExpectedSize
- Size
) {
646 ImageStruct
->Header
.Signature
= SMM_CORE_IMAGE_DATABASE_SIGNATURE
;
647 ImageStruct
->Header
.Length
= (UINT32
)(sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + mImageStruct
[Index
].PdbStringSize
);
648 ImageStruct
->Header
.Revision
= SMM_CORE_IMAGE_DATABASE_REVISION
;
649 CopyGuid(&ImageStruct
->FileGuid
, &mImageStruct
[Index
].FileGuid
);
650 ImageStruct
->ImageRef
= mImageStruct
[Index
].ImageRef
;
651 ImageStruct
->EntryPoint
= mImageStruct
[Index
].EntryPoint
;
652 ImageStruct
->ImageBase
= mImageStruct
[Index
].ImageBase
;
653 ImageStruct
->ImageSize
= mImageStruct
[Index
].ImageSize
;
654 ImageStruct
->PdbStringOffset
= sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
);
655 CopyMem ((VOID
*)((UINTN
)ImageStruct
+ ImageStruct
->PdbStringOffset
), mImageStruct
[Index
].PdbString
, mImageStruct
[Index
].PdbStringSize
);
656 ImageStruct
= (SMM_CORE_IMAGE_DATABASE_STRUCTURE
*)((UINTN
)ImageStruct
+ ImageStruct
->Header
.Length
);
657 Size
+= sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + mImageStruct
[Index
].PdbStringSize
;
660 if (ExpectedSize
!= Size
) {
667 get all SMI handler data associated with SmiEntry.
669 @param SmiEntry SMI entry.
670 @param Data The buffer to hold all SMI handler data
671 @param MaxSize The max size of the SMM image database
672 @param Count The count of the SMI handler.
674 @return SMM image data base size.
677 GetSmmSmiHandlerDataOnSmiEntry(
678 IN SMI_ENTRY
*SmiEntry
,
684 SMM_CORE_SMI_HANDLER_STRUCTURE
*SmiHandlerStruct
;
685 LIST_ENTRY
*ListEntry
;
686 SMI_HANDLER
*SmiHandler
;
689 SmiHandlerStruct
= Data
;
692 ListEntry
= &SmiEntry
->SmiHandlers
;
693 for (ListEntry
= ListEntry
->ForwardLink
;
694 ListEntry
!= &SmiEntry
->SmiHandlers
;
695 ListEntry
= ListEntry
->ForwardLink
) {
696 SmiHandler
= CR(ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
697 if (Size
>= MaxSize
) {
701 if (sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
> MaxSize
- Size
) {
705 SmiHandlerStruct
->Length
= (UINT32
)(sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
);
706 SmiHandlerStruct
->CallerAddr
= (UINTN
)SmiHandler
->CallerAddr
;
707 SmiHandlerStruct
->Handler
= (UINTN
)SmiHandler
->Handler
;
708 SmiHandlerStruct
->ImageRef
= AddressToImageRef((UINTN
)SmiHandler
->Handler
);
709 SmiHandlerStruct
->ContextBufferSize
= (UINT32
)SmiHandler
->ContextSize
;
710 if (SmiHandler
->ContextSize
!= 0) {
711 SmiHandlerStruct
->ContextBufferOffset
= sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
);
712 CopyMem ((UINT8
*)SmiHandlerStruct
+ SmiHandlerStruct
->ContextBufferOffset
, SmiHandler
->Context
, SmiHandler
->ContextSize
);
714 SmiHandlerStruct
->ContextBufferOffset
= 0;
716 Size
+= sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
;
717 SmiHandlerStruct
= (SMM_CORE_SMI_HANDLER_STRUCTURE
*)((UINTN
)SmiHandlerStruct
+ SmiHandlerStruct
->Length
);
725 get all SMI handler database on the SMI entry list.
727 @param SmiEntryList a list of SMI entry.
728 @param HandlerCategory The handler category
729 @param Data The buffer to hold all SMI handler database
730 @param ExpectedSize The expected size of the SMM image database
732 @return all SMI database size on the SMI entry list.
735 GetSmmSmiDatabaseData(
736 IN LIST_ENTRY
*SmiEntryList
,
737 IN UINT32 HandlerCategory
,
739 IN UINTN ExpectedSize
742 SMM_CORE_SMI_DATABASE_STRUCTURE
*SmiStruct
;
743 LIST_ENTRY
*ListEntry
;
746 UINTN SmiHandlerSize
;
747 UINTN SmiHandlerCount
;
751 ListEntry
= SmiEntryList
;
752 for (ListEntry
= ListEntry
->ForwardLink
;
753 ListEntry
!= SmiEntryList
;
754 ListEntry
= ListEntry
->ForwardLink
) {
755 SmiEntry
= CR(ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
756 if (Size
>= ExpectedSize
) {
759 if (sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
) > ExpectedSize
- Size
) {
763 SmiStruct
->Header
.Signature
= SMM_CORE_SMI_DATABASE_SIGNATURE
;
764 SmiStruct
->Header
.Length
= sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
);
765 SmiStruct
->Header
.Revision
= SMM_CORE_SMI_DATABASE_REVISION
;
766 SmiStruct
->HandlerCategory
= HandlerCategory
;
767 CopyGuid(&SmiStruct
->HandlerType
, &SmiEntry
->HandlerType
);
768 Size
+= sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
);
769 SmiHandlerSize
= GetSmmSmiHandlerDataOnSmiEntry(SmiEntry
, (UINT8
*)SmiStruct
+ SmiStruct
->Header
.Length
, ExpectedSize
- Size
, &SmiHandlerCount
);
770 SmiStruct
->HandlerCount
= SmiHandlerCount
;
771 Size
+= SmiHandlerSize
;
772 SmiStruct
->Header
.Length
+= (UINT32
)SmiHandlerSize
;
773 SmiStruct
= (VOID
*)((UINTN
)SmiStruct
+ SmiStruct
->Header
.Length
);
775 if (ExpectedSize
!= Size
) {
782 Get SMI handler profile database.
784 @param Data the buffer to hold SMI handler profile database
786 @retval EFI_SUCCESS the database is got.
787 @retval EFI_INVALID_PARAMETER the database size mismatch.
790 GetSmiHandlerProfileDatabaseData(
794 UINTN SmmImageDatabaseSize
;
795 UINTN SmmSmiDatabaseSize
;
796 UINTN SmmRootSmiDatabaseSize
;
797 UINTN SmmHardwareSmiDatabaseSize
;
799 DEBUG((DEBUG_VERBOSE
, "GetSmiHandlerProfileDatabaseData\n"));
800 SmmImageDatabaseSize
= GetSmmImageDatabaseData(Data
, mSmmImageDatabaseSize
);
801 if (SmmImageDatabaseSize
!= mSmmImageDatabaseSize
) {
802 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmImageDatabaseSize mismatch!\n"));
803 return EFI_INVALID_PARAMETER
;
805 SmmRootSmiDatabaseSize
= GetSmmSmiDatabaseData(mSmmCoreRootSmiEntryList
, SmmCoreSmiHandlerCategoryRootHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
, mSmmRootSmiDatabaseSize
);
806 if (SmmRootSmiDatabaseSize
!= mSmmRootSmiDatabaseSize
) {
807 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmRootSmiDatabaseSize mismatch!\n"));
808 return EFI_INVALID_PARAMETER
;
810 SmmSmiDatabaseSize
= GetSmmSmiDatabaseData(mSmmCoreSmiEntryList
, SmmCoreSmiHandlerCategoryGuidHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
+ mSmmRootSmiDatabaseSize
, mSmmSmiDatabaseSize
);
811 if (SmmSmiDatabaseSize
!= mSmmSmiDatabaseSize
) {
812 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmSmiDatabaseSize mismatch!\n"));
813 return EFI_INVALID_PARAMETER
;
815 SmmHardwareSmiDatabaseSize
= GetSmmSmiDatabaseData(mSmmCoreHardwareSmiEntryList
, SmmCoreSmiHandlerCategoryHardwareHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
+ SmmRootSmiDatabaseSize
+ SmmSmiDatabaseSize
, mSmmHardwareSmiDatabaseSize
);
816 if (SmmHardwareSmiDatabaseSize
!= mSmmHardwareSmiDatabaseSize
) {
817 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmHardwareSmiDatabaseSize mismatch!\n"));
818 return EFI_INVALID_PARAMETER
;
825 build SMI handler profile database.
828 BuildSmiHandlerProfileDatabase(
833 mSmiHandlerProfileDatabaseSize
= GetSmiHandlerProfileDatabaseSize();
834 mSmiHandlerProfileDatabase
= AllocatePool(mSmiHandlerProfileDatabaseSize
);
835 if (mSmiHandlerProfileDatabase
== NULL
) {
838 Status
= GetSmiHandlerProfileDatabaseData(mSmiHandlerProfileDatabase
);
839 if (EFI_ERROR(Status
)) {
840 FreePool(mSmiHandlerProfileDatabase
);
841 mSmiHandlerProfileDatabase
= NULL
;
846 Copy SMI handler profile data.
848 @param DataBuffer The buffer to hold SMI handler profile data.
849 @param DataSize On input, data buffer size.
850 On output, actual data buffer size copied.
851 @param DataOffset On input, data buffer offset to copy.
852 On output, next time data buffer offset to copy.
856 SmiHandlerProfileCopyData(
857 OUT VOID
*DataBuffer
,
858 IN OUT UINT64
*DataSize
,
859 IN OUT UINT64
*DataOffset
862 if (*DataOffset
>= mSmiHandlerProfileDatabaseSize
) {
863 *DataOffset
= mSmiHandlerProfileDatabaseSize
;
866 if (mSmiHandlerProfileDatabaseSize
- *DataOffset
< *DataSize
) {
867 *DataSize
= mSmiHandlerProfileDatabaseSize
- *DataOffset
;
872 (UINT8
*)mSmiHandlerProfileDatabase
+ *DataOffset
,
875 *DataOffset
= *DataOffset
+ *DataSize
;
879 SMI handler profile handler to get info.
881 @param SmiHandlerProfileParameterGetInfo The parameter of SMI handler profile get info.
885 SmiHandlerProfileHandlerGetInfo(
886 IN SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*SmiHandlerProfileParameterGetInfo
889 BOOLEAN SmiHandlerProfileRecordingStatus
;
891 SmiHandlerProfileRecordingStatus
= mSmiHandlerProfileRecordingStatus
;
892 mSmiHandlerProfileRecordingStatus
= FALSE
;
894 SmiHandlerProfileParameterGetInfo
->DataSize
= mSmiHandlerProfileDatabaseSize
;
895 SmiHandlerProfileParameterGetInfo
->Header
.ReturnStatus
= 0;
897 mSmiHandlerProfileRecordingStatus
= SmiHandlerProfileRecordingStatus
;
901 SMI handler profile handler to get data by offset.
903 @param SmiHandlerProfileParameterGetDataByOffset The parameter of SMI handler profile get data by offset.
907 SmiHandlerProfileHandlerGetDataByOffset(
908 IN SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*SmiHandlerProfileParameterGetDataByOffset
911 SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET SmiHandlerProfileGetDataByOffset
;
912 BOOLEAN SmiHandlerProfileRecordingStatus
;
914 SmiHandlerProfileRecordingStatus
= mSmiHandlerProfileRecordingStatus
;
915 mSmiHandlerProfileRecordingStatus
= FALSE
;
917 CopyMem(&SmiHandlerProfileGetDataByOffset
, SmiHandlerProfileParameterGetDataByOffset
, sizeof(SmiHandlerProfileGetDataByOffset
));
922 if (!SmmIsBufferOutsideSmmValid((UINTN
)SmiHandlerProfileGetDataByOffset
.DataBuffer
, (UINTN
)SmiHandlerProfileGetDataByOffset
.DataSize
)) {
923 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetDataByOffset: SMI handler profile get data in SMRAM or overflow!\n"));
924 SmiHandlerProfileParameterGetDataByOffset
->Header
.ReturnStatus
= (UINT64
)(INT64
)(INTN
)EFI_ACCESS_DENIED
;
928 SmiHandlerProfileCopyData((VOID
*)(UINTN
)SmiHandlerProfileGetDataByOffset
.DataBuffer
, &SmiHandlerProfileGetDataByOffset
.DataSize
, &SmiHandlerProfileGetDataByOffset
.DataOffset
);
929 CopyMem(SmiHandlerProfileParameterGetDataByOffset
, &SmiHandlerProfileGetDataByOffset
, sizeof(SmiHandlerProfileGetDataByOffset
));
930 SmiHandlerProfileParameterGetDataByOffset
->Header
.ReturnStatus
= 0;
933 mSmiHandlerProfileRecordingStatus
= SmiHandlerProfileRecordingStatus
;
937 Dispatch function for a Software SMI handler.
939 Caution: This function may receive untrusted input.
940 Communicate buffer and buffer size are external input, so this function will do basic validation.
942 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
943 @param Context Points to an optional handler context which was specified when the
944 handler was registered.
945 @param CommBuffer A pointer to a collection of data in memory that will
946 be conveyed from a non-SMM environment into an SMM environment.
947 @param CommBufferSize The size of the CommBuffer.
949 @retval EFI_SUCCESS Command is handled successfully.
953 SmiHandlerProfileHandler(
954 IN EFI_HANDLE DispatchHandle
,
955 IN CONST VOID
*Context OPTIONAL
,
956 IN OUT VOID
*CommBuffer OPTIONAL
,
957 IN OUT UINTN
*CommBufferSize OPTIONAL
960 SMI_HANDLER_PROFILE_PARAMETER_HEADER
*SmiHandlerProfileParameterHeader
;
961 UINTN TempCommBufferSize
;
963 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler Enter\n"));
965 if (mSmiHandlerProfileDatabase
== NULL
) {
970 // If input is invalid, stop processing this SMI
972 if (CommBuffer
== NULL
|| CommBufferSize
== NULL
) {
976 TempCommBufferSize
= *CommBufferSize
;
978 if (TempCommBufferSize
< sizeof(SMI_HANDLER_PROFILE_PARAMETER_HEADER
)) {
979 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
983 if (!SmmIsBufferOutsideSmmValid((UINTN
)CommBuffer
, TempCommBufferSize
)) {
984 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));
988 SmiHandlerProfileParameterHeader
= (SMI_HANDLER_PROFILE_PARAMETER_HEADER
*)((UINTN
)CommBuffer
);
989 SmiHandlerProfileParameterHeader
->ReturnStatus
= (UINT64
)-1;
991 switch (SmiHandlerProfileParameterHeader
->Command
) {
992 case SMI_HANDLER_PROFILE_COMMAND_GET_INFO
:
993 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetInfo\n"));
994 if (TempCommBufferSize
!= sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
)) {
995 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
998 SmiHandlerProfileHandlerGetInfo((SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*)(UINTN
)CommBuffer
);
1000 case SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET
:
1001 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetDataByOffset\n"));
1002 if (TempCommBufferSize
!= sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
)) {
1003 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
1006 SmiHandlerProfileHandlerGetDataByOffset((SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*)(UINTN
)CommBuffer
);
1012 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler Exit\n"));
1018 Register SMI handler profile handler.
1021 RegisterSmiHandlerProfileHandler (
1026 EFI_HANDLE DispatchHandle
;
1028 Status
= gSmst
->SmiHandlerRegister (
1029 SmiHandlerProfileHandler
,
1030 &gSmiHandlerProfileGuid
,
1033 ASSERT_EFI_ERROR (Status
);
1035 BuildSmiHandlerProfileDatabase();
1039 Finds the SMI entry for the requested handler type.
1041 @param HandlerType The type of the interrupt
1042 @param Create Create a new entry if not found
1047 SmmCoreFindHardwareSmiEntry (
1048 IN EFI_GUID
*HandlerType
,
1054 SMI_ENTRY
*SmiEntry
;
1057 // Search the SMI entry list for the matching GUID
1060 for (Link
= mHardwareSmiEntryList
.ForwardLink
;
1061 Link
!= &mHardwareSmiEntryList
;
1062 Link
= Link
->ForwardLink
) {
1064 Item
= CR (Link
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
1065 if (CompareGuid (&Item
->HandlerType
, HandlerType
)) {
1067 // This is the SMI entry
1075 // If the protocol entry was not found and Create is TRUE, then
1076 // allocate a new entry
1078 if ((SmiEntry
== NULL
) && Create
) {
1079 SmiEntry
= AllocatePool (sizeof(SMI_ENTRY
));
1080 if (SmiEntry
!= NULL
) {
1082 // Initialize new SMI entry structure
1084 SmiEntry
->Signature
= SMI_ENTRY_SIGNATURE
;
1085 CopyGuid ((VOID
*)&SmiEntry
->HandlerType
, HandlerType
);
1086 InitializeListHead (&SmiEntry
->SmiHandlers
);
1089 // Add it to SMI entry list
1091 InsertTailList (&mHardwareSmiEntryList
, &SmiEntry
->AllEntries
);
1098 Convert EFI_SMM_USB_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT.
1100 @param UsbContext A pointer to EFI_SMM_USB_REGISTER_CONTEXT
1101 @param UsbContextSize The size of EFI_SMM_USB_REGISTER_CONTEXT in bytes
1102 @param SmiHandlerUsbContextSize The size of SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT in bytes
1104 @return SmiHandlerUsbContext A pointer to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
1106 SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*
1107 ConvertSmiHandlerUsbContext (
1108 IN EFI_SMM_USB_REGISTER_CONTEXT
*UsbContext
,
1109 IN UINTN UsbContextSize
,
1110 OUT UINTN
*SmiHandlerUsbContextSize
1113 UINTN DevicePathSize
;
1114 SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*SmiHandlerUsbContext
;
1116 ASSERT (UsbContextSize
== sizeof(EFI_SMM_USB_REGISTER_CONTEXT
));
1118 DevicePathSize
= GetDevicePathSize (UsbContext
->Device
);
1119 SmiHandlerUsbContext
= AllocatePool (sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
) + DevicePathSize
);
1120 if (SmiHandlerUsbContext
== NULL
) {
1121 *SmiHandlerUsbContextSize
= 0;
1124 SmiHandlerUsbContext
->Type
= UsbContext
->Type
;
1125 SmiHandlerUsbContext
->DevicePathSize
= (UINT32
)DevicePathSize
;
1126 CopyMem (SmiHandlerUsbContext
+ 1, UsbContext
->Device
, DevicePathSize
);
1127 *SmiHandlerUsbContextSize
= sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
) + DevicePathSize
;
1128 return SmiHandlerUsbContext
;
1132 This function is called by SmmChildDispatcher module to report
1133 a new SMI handler is registered, to SmmCore.
1135 @param This The protocol instance
1136 @param HandlerGuid The GUID to identify the type of the handler.
1137 For the SmmChildDispatch protocol, the HandlerGuid
1138 must be the GUID of SmmChildDispatch protocol.
1139 @param Handler The SMI handler.
1140 @param CallerAddress The address of the module who registers the SMI handler.
1141 @param Context The context of the SMI handler.
1142 For the SmmChildDispatch protocol, the Context
1143 must match the one defined for SmmChildDispatch protocol.
1144 @param ContextSize The size of the context in bytes.
1145 For the SmmChildDispatch protocol, the Context
1146 must match the one defined for SmmChildDispatch protocol.
1148 @retval EFI_SUCCESS The information is recorded.
1149 @retval EFI_OUT_OF_RESOURCES There is no enough resource to record the information.
1153 SmiHandlerProfileRegisterHandler (
1154 IN SMI_HANDLER_PROFILE_PROTOCOL
*This
,
1155 IN EFI_GUID
*HandlerGuid
,
1156 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler
,
1157 IN PHYSICAL_ADDRESS CallerAddress
,
1158 IN VOID
*Context
, OPTIONAL
1159 IN UINTN ContextSize OPTIONAL
1162 SMI_HANDLER
*SmiHandler
;
1163 SMI_ENTRY
*SmiEntry
;
1166 if (((ContextSize
== 0) && (Context
!= NULL
)) ||
1167 ((ContextSize
!= 0) && (Context
== NULL
))) {
1168 return EFI_INVALID_PARAMETER
;
1171 SmiHandler
= AllocateZeroPool (sizeof (SMI_HANDLER
));
1172 if (SmiHandler
== NULL
) {
1173 return EFI_OUT_OF_RESOURCES
;
1176 SmiHandler
->Signature
= SMI_HANDLER_SIGNATURE
;
1177 SmiHandler
->Handler
= Handler
;
1178 SmiHandler
->CallerAddr
= (UINTN
)CallerAddress
;
1179 SmiHandler
->Context
= Context
;
1180 SmiHandler
->ContextSize
= ContextSize
;
1182 if (Context
!= NULL
) {
1183 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1184 SmiHandler
->Context
= ConvertSmiHandlerUsbContext (Context
, ContextSize
, &SmiHandler
->ContextSize
);
1186 SmiHandler
->Context
= AllocateCopyPool (ContextSize
, Context
);
1189 if (SmiHandler
->Context
== NULL
) {
1190 SmiHandler
->ContextSize
= 0;
1193 SmiEntry
= SmmCoreFindHardwareSmiEntry (HandlerGuid
, TRUE
);
1194 if (SmiEntry
== NULL
) {
1195 if (SmiHandler
->Context
!= NULL
) {
1196 FreePool (SmiHandler
->Context
);
1198 FreePool (SmiHandler
);
1199 return EFI_OUT_OF_RESOURCES
;
1202 List
= &SmiEntry
->SmiHandlers
;
1204 SmiHandler
->SmiEntry
= SmiEntry
;
1205 InsertTailList (List
, &SmiHandler
->Link
);
1211 This function is called by SmmChildDispatcher module to report
1212 an existing SMI handler is unregistered, to SmmCore.
1214 @param This The protocol instance
1215 @param HandlerGuid The GUID to identify the type of the handler.
1216 For the SmmChildDispatch protocol, the HandlerGuid
1217 must be the GUID of SmmChildDispatch protocol.
1218 @param Handler The SMI handler.
1219 @param Context The context of the SMI handler.
1220 If it is NOT NULL, it will be used to check what is registered.
1221 @param ContextSize The size of the context in bytes.
1222 If Context is NOT NULL, it will be used to check what is registered.
1224 @retval EFI_SUCCESS The original record is removed.
1225 @retval EFI_NOT_FOUND There is no record for the HandlerGuid and handler.
1229 SmiHandlerProfileUnregisterHandler (
1230 IN SMI_HANDLER_PROFILE_PROTOCOL
*This
,
1231 IN EFI_GUID
*HandlerGuid
,
1232 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler
,
1233 IN VOID
*Context
, OPTIONAL
1234 IN UINTN ContextSize OPTIONAL
1239 SMI_HANDLER
*SmiHandler
;
1240 SMI_ENTRY
*SmiEntry
;
1241 SMI_HANDLER
*TargetSmiHandler
;
1242 VOID
*SearchContext
;
1243 UINTN SearchContextSize
;
1245 if (((ContextSize
== 0) && (Context
!= NULL
)) ||
1246 ((ContextSize
!= 0) && (Context
== NULL
))) {
1247 return EFI_INVALID_PARAMETER
;
1250 SmiEntry
= SmmCoreFindHardwareSmiEntry (HandlerGuid
, FALSE
);
1251 if (SmiEntry
== NULL
) {
1252 return EFI_NOT_FOUND
;
1255 SearchContext
= Context
;
1256 SearchContextSize
= ContextSize
;
1257 if (Context
!= NULL
) {
1258 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1259 SearchContext
= ConvertSmiHandlerUsbContext (Context
, ContextSize
, &SearchContextSize
);
1263 TargetSmiHandler
= NULL
;
1264 Head
= &SmiEntry
->SmiHandlers
;
1265 for (Link
= Head
->ForwardLink
; Link
!= Head
; Link
= Link
->ForwardLink
) {
1266 SmiHandler
= CR (Link
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
1267 if (SmiHandler
->Handler
== Handler
) {
1268 if ((SearchContext
== NULL
) ||
1269 ((SearchContextSize
== SmiHandler
->ContextSize
) && (CompareMem (SearchContext
, SmiHandler
->Context
, SearchContextSize
) == 0))) {
1270 TargetSmiHandler
= SmiHandler
;
1276 if (SearchContext
!= NULL
) {
1277 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1278 FreePool (SearchContext
);
1282 if (TargetSmiHandler
== NULL
) {
1283 return EFI_NOT_FOUND
;
1285 SmiHandler
= TargetSmiHandler
;
1287 RemoveEntryList (&SmiHandler
->Link
);
1288 if (SmiHandler
->Context
!= NULL
) {
1289 FreePool (SmiHandler
->Context
);
1291 FreePool (SmiHandler
);
1293 if (IsListEmpty (&SmiEntry
->SmiHandlers
)) {
1294 RemoveEntryList (&SmiEntry
->AllEntries
);
1295 FreePool (SmiEntry
);
1302 Initialize SmiHandler profile feature.
1305 SmmCoreInitializeSmiHandlerProfile (
1313 if ((PcdGet8 (PcdSmiHandlerProfilePropertyMask
) & 0x1) != 0) {
1314 InsertTailList (&mRootSmiEntryList
, &mRootSmiEntry
.AllEntries
);
1316 Status
= gSmst
->SmmRegisterProtocolNotify (
1317 &gEfiSmmReadyToLockProtocolGuid
,
1318 SmmReadyToLockInSmiHandlerProfile
,
1321 ASSERT_EFI_ERROR (Status
);
1324 Status
= gSmst
->SmmInstallProtocolInterface (
1326 &gSmiHandlerProfileGuid
,
1327 EFI_NATIVE_INTERFACE
,
1330 ASSERT_EFI_ERROR (Status
);