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
,
359 if (CompareGuid (HandlerType
, &gEfiSmmSwDispatch2ProtocolGuid
)) {
360 DEBUG ((DEBUG_INFO
, " SwSmi - 0x%x\n", ((EFI_SMM_SW_REGISTER_CONTEXT
*)Context
)->SwSmiInputValue
));
361 } else if (CompareGuid (HandlerType
, &gEfiSmmSxDispatch2ProtocolGuid
)) {
362 DEBUG ((DEBUG_INFO
, " SxType - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Type
));
363 DEBUG ((DEBUG_INFO
, " SxPhase - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Phase
));
364 } else if (CompareGuid (HandlerType
, &gEfiSmmPowerButtonDispatch2ProtocolGuid
)) {
365 DEBUG ((DEBUG_INFO
, " PowerButtonPhase - 0x%x\n", ((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
366 } else if (CompareGuid (HandlerType
, &gEfiSmmStandbyButtonDispatch2ProtocolGuid
)) {
367 DEBUG ((DEBUG_INFO
, " StandbyButtonPhase - 0x%x\n", ((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
368 } else if (CompareGuid (HandlerType
, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid
)) {
369 DEBUG ((DEBUG_INFO
, " PeriodicTimerPeriod - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->Period
));
370 DEBUG ((DEBUG_INFO
, " PeriodicTimerSmiTickInterval - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->SmiTickInterval
));
371 } else if (CompareGuid (HandlerType
, &gEfiSmmGpiDispatch2ProtocolGuid
)) {
372 DEBUG ((DEBUG_INFO
, " GpiNum - 0x%lx\n", ((EFI_SMM_GPI_REGISTER_CONTEXT
*)Context
)->GpiNum
));
373 } else if (CompareGuid (HandlerType
, &gEfiSmmIoTrapDispatch2ProtocolGuid
)) {
374 DEBUG ((DEBUG_INFO
, " IoTrapAddress - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Address
));
375 DEBUG ((DEBUG_INFO
, " IoTrapLength - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Length
));
376 DEBUG ((DEBUG_INFO
, " IoTrapType - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Type
));
377 } else if (CompareGuid (HandlerType
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
378 DEBUG ((DEBUG_INFO
, " UsbType - 0x%x\n", ((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
)->Type
));
379 DEBUG ((DEBUG_INFO
, " UsbDevicePath - %s\n", ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL
*)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
) + 1), TRUE
, TRUE
)));
381 DEBUG ((DEBUG_INFO
, " Context - "));
382 InternalDumpData (Context
, ContextSize
);
383 DEBUG ((DEBUG_INFO
, "\n"));
388 Dump all SMI handlers associated with SmiEntry.
390 @param SmiEntry SMI entry.
393 DumpSmiHandlerOnSmiEntry(
394 IN SMI_ENTRY
*SmiEntry
397 LIST_ENTRY
*ListEntry
;
398 SMI_HANDLER
*SmiHandler
;
399 IMAGE_STRUCT
*ImageStruct
;
401 ListEntry
= &SmiEntry
->SmiHandlers
;
402 for (ListEntry
= ListEntry
->ForwardLink
;
403 ListEntry
!= &SmiEntry
->SmiHandlers
;
404 ListEntry
= ListEntry
->ForwardLink
) {
405 SmiHandler
= CR(ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
406 ImageStruct
= AddressToImageStruct((UINTN
)SmiHandler
->Handler
);
407 if (ImageStruct
!= NULL
) {
408 DEBUG ((DEBUG_INFO
, " Module - %g", &ImageStruct
->FileGuid
));
410 if ((ImageStruct
!= NULL
) && (ImageStruct
->PdbString
[0] != 0)) {
411 DEBUG ((DEBUG_INFO
, " (Pdb - %a)", ImageStruct
->PdbString
));
413 DEBUG ((DEBUG_INFO
, "\n"));
414 if (SmiHandler
->ContextSize
!= 0) {
415 DumpSmiChildContext (&SmiEntry
->HandlerType
, SmiHandler
->Context
, SmiHandler
->ContextSize
);
417 DEBUG ((DEBUG_INFO
, " Handler - 0x%x", SmiHandler
->Handler
));
418 if (ImageStruct
!= NULL
) {
419 DEBUG ((DEBUG_INFO
, " <== RVA - 0x%x", (UINTN
)SmiHandler
->Handler
- ImageStruct
->ImageBase
));
421 DEBUG ((DEBUG_INFO
, "\n"));
422 DEBUG ((DEBUG_INFO
, " CallerAddr - 0x%x", SmiHandler
->CallerAddr
));
423 if (ImageStruct
!= NULL
) {
424 DEBUG ((DEBUG_INFO
, " <== RVA - 0x%x", SmiHandler
->CallerAddr
- ImageStruct
->ImageBase
));
426 DEBUG ((DEBUG_INFO
, "\n"));
433 Dump all SMI entry on the list.
435 @param SmiEntryList a list of SMI entry.
439 IN LIST_ENTRY
*SmiEntryList
442 LIST_ENTRY
*ListEntry
;
445 ListEntry
= SmiEntryList
;
446 for (ListEntry
= ListEntry
->ForwardLink
;
447 ListEntry
!= SmiEntryList
;
448 ListEntry
= ListEntry
->ForwardLink
) {
449 SmiEntry
= CR(ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
450 DEBUG ((DEBUG_INFO
, "SmiEntry - %g\n", &SmiEntry
->HandlerType
));
451 DumpSmiHandlerOnSmiEntry(SmiEntry
);
458 SMM Ready To Lock event notification handler.
460 This function collects all SMM image information and build SmiHandleProfile database,
461 and register SmiHandlerProfile SMI handler.
463 @param[in] Protocol Points to the protocol's unique identifier.
464 @param[in] Interface Points to the interface instance.
465 @param[in] Handle The handle on which the interface was installed.
467 @retval EFI_SUCCESS Notification handler runs successfully.
471 SmmReadyToLockInSmiHandlerProfile (
472 IN CONST EFI_GUID
*Protocol
,
480 DEBUG ((DEBUG_INFO
, "##################\n"));
481 DEBUG ((DEBUG_INFO
, "# IMAGE DATABASE #\n"));
482 DEBUG ((DEBUG_INFO
, "##################\n"));
483 GetSmmLoadedImage ();
484 DEBUG ((DEBUG_INFO
, "\n"));
489 DEBUG ((DEBUG_INFO
, "########################\n"));
490 DEBUG ((DEBUG_INFO
, "# SMI Handler DATABASE #\n"));
491 DEBUG ((DEBUG_INFO
, "########################\n"));
493 DEBUG ((DEBUG_INFO
, "# 1. ROOT SMI Handler #\n"));
495 DumpSmiEntryList(mSmmCoreRootSmiEntryList
);
498 DEBUG ((DEBUG_INFO
, "# 2. GUID SMI Handler #\n"));
500 DumpSmiEntryList(mSmmCoreSmiEntryList
);
503 DEBUG ((DEBUG_INFO
, "# 3. Hardware SMI Handler #\n"));
505 DumpSmiEntryList(mSmmCoreHardwareSmiEntryList
);
508 DEBUG ((DEBUG_INFO
, "\n"));
510 RegisterSmiHandlerProfileHandler();
512 if (mImageStruct
!= NULL
) {
513 FreePool(mImageStruct
);
520 returns SMM image data base size.
522 @return SMM image data base size.
525 GetSmmImageDatabaseSize(
532 Size
= (sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
)) * mImageStructCount
;
533 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
534 Size
+= mImageStruct
[Index
].PdbStringSize
;
540 returns all SMI handlers' size associated with SmiEntry.
542 @param SmiEntry SMI entry.
544 @return all SMI handlers' size associated with SmiEntry.
547 GetSmmSmiHandlerSizeOnSmiEntry(
548 IN SMI_ENTRY
*SmiEntry
551 LIST_ENTRY
*ListEntry
;
552 SMI_HANDLER
*SmiHandler
;
556 ListEntry
= &SmiEntry
->SmiHandlers
;
557 for (ListEntry
= ListEntry
->ForwardLink
;
558 ListEntry
!= &SmiEntry
->SmiHandlers
;
559 ListEntry
= ListEntry
->ForwardLink
) {
560 SmiHandler
= CR(ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
561 Size
+= sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
;
568 return all SMI handler database size on the SMI entry list.
570 @param SmiEntryList a list of SMI entry.
572 @return all SMI handler database size on the SMI entry list.
575 GetSmmSmiDatabaseSize(
576 IN LIST_ENTRY
*SmiEntryList
579 LIST_ENTRY
*ListEntry
;
584 ListEntry
= SmiEntryList
;
585 for (ListEntry
= ListEntry
->ForwardLink
;
586 ListEntry
!= SmiEntryList
;
587 ListEntry
= ListEntry
->ForwardLink
) {
588 SmiEntry
= CR(ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
589 Size
+= sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
);
590 Size
+= GetSmmSmiHandlerSizeOnSmiEntry(SmiEntry
);
596 return SMI handler profile database size.
598 @return SMI handler profile database size.
601 GetSmiHandlerProfileDatabaseSize (
605 mSmmImageDatabaseSize
= GetSmmImageDatabaseSize();
606 mSmmRootSmiDatabaseSize
= GetSmmSmiDatabaseSize(mSmmCoreRootSmiEntryList
);
607 mSmmSmiDatabaseSize
= GetSmmSmiDatabaseSize(mSmmCoreSmiEntryList
);
608 mSmmHardwareSmiDatabaseSize
= GetSmmSmiDatabaseSize(mSmmCoreHardwareSmiEntryList
);
610 return mSmmImageDatabaseSize
+ mSmmSmiDatabaseSize
+ mSmmRootSmiDatabaseSize
+ mSmmHardwareSmiDatabaseSize
;
614 get SMM image database.
616 @param Data The buffer to hold SMM image database
617 @param ExpectedSize The expected size of the SMM image database
619 @return SMM image data base size.
622 GetSmmImageDatabaseData (
624 IN UINTN ExpectedSize
627 SMM_CORE_IMAGE_DATABASE_STRUCTURE
*ImageStruct
;
633 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
634 if (Size
>= ExpectedSize
) {
637 if (sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + mImageStruct
[Index
].PdbStringSize
> ExpectedSize
- Size
) {
640 ImageStruct
->Header
.Signature
= SMM_CORE_IMAGE_DATABASE_SIGNATURE
;
641 ImageStruct
->Header
.Length
= (UINT32
)(sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + mImageStruct
[Index
].PdbStringSize
);
642 ImageStruct
->Header
.Revision
= SMM_CORE_IMAGE_DATABASE_REVISION
;
643 CopyGuid(&ImageStruct
->FileGuid
, &mImageStruct
[Index
].FileGuid
);
644 ImageStruct
->ImageRef
= mImageStruct
[Index
].ImageRef
;
645 ImageStruct
->EntryPoint
= mImageStruct
[Index
].EntryPoint
;
646 ImageStruct
->ImageBase
= mImageStruct
[Index
].ImageBase
;
647 ImageStruct
->ImageSize
= mImageStruct
[Index
].ImageSize
;
648 ImageStruct
->PdbStringOffset
= sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
);
649 CopyMem ((VOID
*)((UINTN
)ImageStruct
+ ImageStruct
->PdbStringOffset
), mImageStruct
[Index
].PdbString
, mImageStruct
[Index
].PdbStringSize
);
650 ImageStruct
= (SMM_CORE_IMAGE_DATABASE_STRUCTURE
*)((UINTN
)ImageStruct
+ ImageStruct
->Header
.Length
);
651 Size
+= sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + mImageStruct
[Index
].PdbStringSize
;
654 if (ExpectedSize
!= Size
) {
661 get all SMI handler data associated with SmiEntry.
663 @param SmiEntry SMI entry.
664 @param Data The buffer to hold all SMI handler data
665 @param MaxSize The max size of the SMM image database
666 @param Count The count of the SMI handler.
668 @return SMM image data base size.
671 GetSmmSmiHandlerDataOnSmiEntry(
672 IN SMI_ENTRY
*SmiEntry
,
678 SMM_CORE_SMI_HANDLER_STRUCTURE
*SmiHandlerStruct
;
679 LIST_ENTRY
*ListEntry
;
680 SMI_HANDLER
*SmiHandler
;
683 SmiHandlerStruct
= Data
;
686 ListEntry
= &SmiEntry
->SmiHandlers
;
687 for (ListEntry
= ListEntry
->ForwardLink
;
688 ListEntry
!= &SmiEntry
->SmiHandlers
;
689 ListEntry
= ListEntry
->ForwardLink
) {
690 SmiHandler
= CR(ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
691 if (Size
>= MaxSize
) {
695 if (sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
> MaxSize
- Size
) {
699 SmiHandlerStruct
->Length
= (UINT32
)(sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
);
700 SmiHandlerStruct
->CallerAddr
= (UINTN
)SmiHandler
->CallerAddr
;
701 SmiHandlerStruct
->Handler
= (UINTN
)SmiHandler
->Handler
;
702 SmiHandlerStruct
->ImageRef
= AddressToImageRef((UINTN
)SmiHandler
->Handler
);
703 SmiHandlerStruct
->ContextBufferSize
= (UINT32
)SmiHandler
->ContextSize
;
704 if (SmiHandler
->ContextSize
!= 0) {
705 SmiHandlerStruct
->ContextBufferOffset
= sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
);
706 CopyMem ((UINT8
*)SmiHandlerStruct
+ SmiHandlerStruct
->ContextBufferOffset
, SmiHandler
->Context
, SmiHandler
->ContextSize
);
708 SmiHandlerStruct
->ContextBufferOffset
= 0;
710 Size
+= sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE
) + SmiHandler
->ContextSize
;
711 SmiHandlerStruct
= (SMM_CORE_SMI_HANDLER_STRUCTURE
*)((UINTN
)SmiHandlerStruct
+ SmiHandlerStruct
->Length
);
719 get all SMI handler database on the SMI entry list.
721 @param SmiEntryList a list of SMI entry.
722 @param HandlerCategory The handler category
723 @param Data The buffer to hold all SMI handler database
724 @param ExpectedSize The expected size of the SMM image database
726 @return all SMI database size on the SMI entry list.
729 GetSmmSmiDatabaseData(
730 IN LIST_ENTRY
*SmiEntryList
,
731 IN UINT32 HandlerCategory
,
733 IN UINTN ExpectedSize
736 SMM_CORE_SMI_DATABASE_STRUCTURE
*SmiStruct
;
737 LIST_ENTRY
*ListEntry
;
740 UINTN SmiHandlerSize
;
741 UINTN SmiHandlerCount
;
745 ListEntry
= SmiEntryList
;
746 for (ListEntry
= ListEntry
->ForwardLink
;
747 ListEntry
!= SmiEntryList
;
748 ListEntry
= ListEntry
->ForwardLink
) {
749 SmiEntry
= CR(ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
750 if (Size
>= ExpectedSize
) {
753 if (sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
) > ExpectedSize
- Size
) {
757 SmiStruct
->Header
.Signature
= SMM_CORE_SMI_DATABASE_SIGNATURE
;
758 SmiStruct
->Header
.Length
= sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
);
759 SmiStruct
->Header
.Revision
= SMM_CORE_SMI_DATABASE_REVISION
;
760 SmiStruct
->HandlerCategory
= HandlerCategory
;
761 CopyGuid(&SmiStruct
->HandlerType
, &SmiEntry
->HandlerType
);
762 Size
+= sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE
);
763 SmiHandlerSize
= GetSmmSmiHandlerDataOnSmiEntry(SmiEntry
, (UINT8
*)SmiStruct
+ SmiStruct
->Header
.Length
, ExpectedSize
- Size
, &SmiHandlerCount
);
764 SmiStruct
->HandlerCount
= SmiHandlerCount
;
765 Size
+= SmiHandlerSize
;
766 SmiStruct
->Header
.Length
+= (UINT32
)SmiHandlerSize
;
767 SmiStruct
= (VOID
*)((UINTN
)SmiStruct
+ SmiStruct
->Header
.Length
);
769 if (ExpectedSize
!= Size
) {
776 Get SMI handler profile database.
778 @param Data the buffer to hold SMI handler profile database
780 @retval EFI_SUCCESS the database is got.
781 @retval EFI_INVALID_PARAMETER the database size mismatch.
784 GetSmiHandlerProfileDatabaseData(
788 UINTN SmmImageDatabaseSize
;
789 UINTN SmmSmiDatabaseSize
;
790 UINTN SmmRootSmiDatabaseSize
;
791 UINTN SmmHardwareSmiDatabaseSize
;
793 DEBUG((DEBUG_VERBOSE
, "GetSmiHandlerProfileDatabaseData\n"));
794 SmmImageDatabaseSize
= GetSmmImageDatabaseData(Data
, mSmmImageDatabaseSize
);
795 if (SmmImageDatabaseSize
!= mSmmImageDatabaseSize
) {
796 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmImageDatabaseSize mismatch!\n"));
797 return EFI_INVALID_PARAMETER
;
799 SmmRootSmiDatabaseSize
= GetSmmSmiDatabaseData(mSmmCoreRootSmiEntryList
, SmmCoreSmiHandlerCategoryRootHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
, mSmmRootSmiDatabaseSize
);
800 if (SmmRootSmiDatabaseSize
!= mSmmRootSmiDatabaseSize
) {
801 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmRootSmiDatabaseSize mismatch!\n"));
802 return EFI_INVALID_PARAMETER
;
804 SmmSmiDatabaseSize
= GetSmmSmiDatabaseData(mSmmCoreSmiEntryList
, SmmCoreSmiHandlerCategoryGuidHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
+ mSmmRootSmiDatabaseSize
, mSmmSmiDatabaseSize
);
805 if (SmmSmiDatabaseSize
!= mSmmSmiDatabaseSize
) {
806 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmSmiDatabaseSize mismatch!\n"));
807 return EFI_INVALID_PARAMETER
;
809 SmmHardwareSmiDatabaseSize
= GetSmmSmiDatabaseData(mSmmCoreHardwareSmiEntryList
, SmmCoreSmiHandlerCategoryHardwareHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
+ SmmRootSmiDatabaseSize
+ SmmSmiDatabaseSize
, mSmmHardwareSmiDatabaseSize
);
810 if (SmmHardwareSmiDatabaseSize
!= mSmmHardwareSmiDatabaseSize
) {
811 DEBUG((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmHardwareSmiDatabaseSize mismatch!\n"));
812 return EFI_INVALID_PARAMETER
;
819 build SMI handler profile database.
822 BuildSmiHandlerProfileDatabase(
827 mSmiHandlerProfileDatabaseSize
= GetSmiHandlerProfileDatabaseSize();
828 mSmiHandlerProfileDatabase
= AllocatePool(mSmiHandlerProfileDatabaseSize
);
829 if (mSmiHandlerProfileDatabase
== NULL
) {
832 Status
= GetSmiHandlerProfileDatabaseData(mSmiHandlerProfileDatabase
);
833 if (EFI_ERROR(Status
)) {
834 FreePool(mSmiHandlerProfileDatabase
);
835 mSmiHandlerProfileDatabase
= NULL
;
840 Copy SMI handler profile data.
842 @param DataBuffer The buffer to hold SMI handler profile data.
843 @param DataSize On input, data buffer size.
844 On output, actual data buffer size copied.
845 @param DataOffset On input, data buffer offset to copy.
846 On output, next time data buffer offset to copy.
850 SmiHandlerProfileCopyData(
851 OUT VOID
*DataBuffer
,
852 IN OUT UINT64
*DataSize
,
853 IN OUT UINT64
*DataOffset
856 if (*DataOffset
>= mSmiHandlerProfileDatabaseSize
) {
857 *DataOffset
= mSmiHandlerProfileDatabaseSize
;
860 if (mSmiHandlerProfileDatabaseSize
- *DataOffset
< *DataSize
) {
861 *DataSize
= mSmiHandlerProfileDatabaseSize
- *DataOffset
;
866 (UINT8
*)mSmiHandlerProfileDatabase
+ *DataOffset
,
869 *DataOffset
= *DataOffset
+ *DataSize
;
873 SMI handler profile handler to get info.
875 @param SmiHandlerProfileParameterGetInfo The parameter of SMI handler profile get info.
879 SmiHandlerProfileHandlerGetInfo(
880 IN SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*SmiHandlerProfileParameterGetInfo
883 BOOLEAN SmiHandlerProfileRecordingStatus
;
885 SmiHandlerProfileRecordingStatus
= mSmiHandlerProfileRecordingStatus
;
886 mSmiHandlerProfileRecordingStatus
= FALSE
;
888 SmiHandlerProfileParameterGetInfo
->DataSize
= mSmiHandlerProfileDatabaseSize
;
889 SmiHandlerProfileParameterGetInfo
->Header
.ReturnStatus
= 0;
891 mSmiHandlerProfileRecordingStatus
= SmiHandlerProfileRecordingStatus
;
895 SMI handler profile handler to get data by offset.
897 @param SmiHandlerProfileParameterGetDataByOffset The parameter of SMI handler profile get data by offset.
901 SmiHandlerProfileHandlerGetDataByOffset(
902 IN SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*SmiHandlerProfileParameterGetDataByOffset
905 SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET SmiHandlerProfileGetDataByOffset
;
906 BOOLEAN SmiHandlerProfileRecordingStatus
;
908 SmiHandlerProfileRecordingStatus
= mSmiHandlerProfileRecordingStatus
;
909 mSmiHandlerProfileRecordingStatus
= FALSE
;
911 CopyMem(&SmiHandlerProfileGetDataByOffset
, SmiHandlerProfileParameterGetDataByOffset
, sizeof(SmiHandlerProfileGetDataByOffset
));
916 if (!SmmIsBufferOutsideSmmValid((UINTN
)SmiHandlerProfileGetDataByOffset
.DataBuffer
, (UINTN
)SmiHandlerProfileGetDataByOffset
.DataSize
)) {
917 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetDataByOffset: SMI handler profile get data in SMRAM or overflow!\n"));
918 SmiHandlerProfileParameterGetDataByOffset
->Header
.ReturnStatus
= (UINT64
)(INT64
)(INTN
)EFI_ACCESS_DENIED
;
922 SmiHandlerProfileCopyData((VOID
*)(UINTN
)SmiHandlerProfileGetDataByOffset
.DataBuffer
, &SmiHandlerProfileGetDataByOffset
.DataSize
, &SmiHandlerProfileGetDataByOffset
.DataOffset
);
923 CopyMem(SmiHandlerProfileParameterGetDataByOffset
, &SmiHandlerProfileGetDataByOffset
, sizeof(SmiHandlerProfileGetDataByOffset
));
924 SmiHandlerProfileParameterGetDataByOffset
->Header
.ReturnStatus
= 0;
927 mSmiHandlerProfileRecordingStatus
= SmiHandlerProfileRecordingStatus
;
931 Dispatch function for a Software SMI handler.
933 Caution: This function may receive untrusted input.
934 Communicate buffer and buffer size are external input, so this function will do basic validation.
936 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
937 @param Context Points to an optional handler context which was specified when the
938 handler was registered.
939 @param CommBuffer A pointer to a collection of data in memory that will
940 be conveyed from a non-SMM environment into an SMM environment.
941 @param CommBufferSize The size of the CommBuffer.
943 @retval EFI_SUCCESS Command is handled successfully.
947 SmiHandlerProfileHandler(
948 IN EFI_HANDLE DispatchHandle
,
949 IN CONST VOID
*Context OPTIONAL
,
950 IN OUT VOID
*CommBuffer OPTIONAL
,
951 IN OUT UINTN
*CommBufferSize OPTIONAL
954 SMI_HANDLER_PROFILE_PARAMETER_HEADER
*SmiHandlerProfileParameterHeader
;
955 UINTN TempCommBufferSize
;
957 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler Enter\n"));
959 if (mSmiHandlerProfileDatabase
== NULL
) {
964 // If input is invalid, stop processing this SMI
966 if (CommBuffer
== NULL
|| CommBufferSize
== NULL
) {
970 TempCommBufferSize
= *CommBufferSize
;
972 if (TempCommBufferSize
< sizeof(SMI_HANDLER_PROFILE_PARAMETER_HEADER
)) {
973 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
977 if (!SmmIsBufferOutsideSmmValid((UINTN
)CommBuffer
, TempCommBufferSize
)) {
978 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));
982 SmiHandlerProfileParameterHeader
= (SMI_HANDLER_PROFILE_PARAMETER_HEADER
*)((UINTN
)CommBuffer
);
983 SmiHandlerProfileParameterHeader
->ReturnStatus
= (UINT64
)-1;
985 switch (SmiHandlerProfileParameterHeader
->Command
) {
986 case SMI_HANDLER_PROFILE_COMMAND_GET_INFO
:
987 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetInfo\n"));
988 if (TempCommBufferSize
!= sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
)) {
989 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
992 SmiHandlerProfileHandlerGetInfo((SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*)(UINTN
)CommBuffer
);
994 case SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET
:
995 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetDataByOffset\n"));
996 if (TempCommBufferSize
!= sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
)) {
997 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
1000 SmiHandlerProfileHandlerGetDataByOffset((SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*)(UINTN
)CommBuffer
);
1006 DEBUG((DEBUG_ERROR
, "SmiHandlerProfileHandler Exit\n"));
1012 Register SMI handler profile handler.
1015 RegisterSmiHandlerProfileHandler (
1020 EFI_HANDLE DispatchHandle
;
1022 Status
= gSmst
->SmiHandlerRegister (
1023 SmiHandlerProfileHandler
,
1024 &gSmiHandlerProfileGuid
,
1027 ASSERT_EFI_ERROR (Status
);
1029 BuildSmiHandlerProfileDatabase();
1033 Finds the SMI entry for the requested handler type.
1035 @param HandlerType The type of the interrupt
1036 @param Create Create a new entry if not found
1041 SmmCoreFindHardwareSmiEntry (
1042 IN EFI_GUID
*HandlerType
,
1048 SMI_ENTRY
*SmiEntry
;
1051 // Search the SMI entry list for the matching GUID
1054 for (Link
= mHardwareSmiEntryList
.ForwardLink
;
1055 Link
!= &mHardwareSmiEntryList
;
1056 Link
= Link
->ForwardLink
) {
1058 Item
= CR (Link
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
1059 if (CompareGuid (&Item
->HandlerType
, HandlerType
)) {
1061 // This is the SMI entry
1069 // If the protocol entry was not found and Create is TRUE, then
1070 // allocate a new entry
1072 if ((SmiEntry
== NULL
) && Create
) {
1073 SmiEntry
= AllocatePool (sizeof(SMI_ENTRY
));
1074 if (SmiEntry
!= NULL
) {
1076 // Initialize new SMI entry structure
1078 SmiEntry
->Signature
= SMI_ENTRY_SIGNATURE
;
1079 CopyGuid ((VOID
*)&SmiEntry
->HandlerType
, HandlerType
);
1080 InitializeListHead (&SmiEntry
->SmiHandlers
);
1083 // Add it to SMI entry list
1085 InsertTailList (&mHardwareSmiEntryList
, &SmiEntry
->AllEntries
);
1092 Convert EFI_SMM_USB_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT.
1094 @param UsbContext A pointer to EFI_SMM_USB_REGISTER_CONTEXT
1095 @param UsbContextSize The size of EFI_SMM_USB_REGISTER_CONTEXT in bytes
1096 @param SmiHandlerUsbContextSize The size of SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT in bytes
1098 @return SmiHandlerUsbContext A pointer to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
1100 SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*
1101 ConvertSmiHandlerUsbContext (
1102 IN EFI_SMM_USB_REGISTER_CONTEXT
*UsbContext
,
1103 IN UINTN UsbContextSize
,
1104 OUT UINTN
*SmiHandlerUsbContextSize
1107 UINTN DevicePathSize
;
1108 SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*SmiHandlerUsbContext
;
1110 ASSERT (UsbContextSize
== sizeof(EFI_SMM_USB_REGISTER_CONTEXT
));
1112 DevicePathSize
= GetDevicePathSize (UsbContext
->Device
);
1113 SmiHandlerUsbContext
= AllocatePool (sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
) + DevicePathSize
);
1114 if (SmiHandlerUsbContext
== NULL
) {
1115 *SmiHandlerUsbContextSize
= 0;
1118 SmiHandlerUsbContext
->Type
= UsbContext
->Type
;
1119 SmiHandlerUsbContext
->DevicePathSize
= (UINT32
)DevicePathSize
;
1120 CopyMem (SmiHandlerUsbContext
+ 1, UsbContext
->Device
, DevicePathSize
);
1121 *SmiHandlerUsbContextSize
= sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
) + DevicePathSize
;
1122 return SmiHandlerUsbContext
;
1126 This function is called by SmmChildDispatcher module to report
1127 a new SMI handler is registered, to SmmCore.
1129 @param This The protocol instance
1130 @param HandlerGuid The GUID to identify the type of the handler.
1131 For the SmmChildDispatch protocol, the HandlerGuid
1132 must be the GUID of SmmChildDispatch protocol.
1133 @param Handler The SMI handler.
1134 @param CallerAddress The address of the module who registers the SMI handler.
1135 @param Context The context of the SMI handler.
1136 For the SmmChildDispatch protocol, the Context
1137 must match the one defined for SmmChildDispatch protocol.
1138 @param ContextSize The size of the context in bytes.
1139 For the SmmChildDispatch protocol, the Context
1140 must match the one defined for SmmChildDispatch protocol.
1142 @retval EFI_SUCCESS The information is recorded.
1143 @retval EFI_OUT_OF_RESOURCES There is no enough resource to record the information.
1147 SmiHandlerProfileRegisterHandler (
1148 IN SMI_HANDLER_PROFILE_PROTOCOL
*This
,
1149 IN EFI_GUID
*HandlerGuid
,
1150 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler
,
1151 IN PHYSICAL_ADDRESS CallerAddress
,
1152 IN VOID
*Context
, OPTIONAL
1153 IN UINTN ContextSize OPTIONAL
1156 SMI_HANDLER
*SmiHandler
;
1157 SMI_ENTRY
*SmiEntry
;
1160 if (((ContextSize
== 0) && (Context
!= NULL
)) ||
1161 ((ContextSize
!= 0) && (Context
== NULL
))) {
1162 return EFI_INVALID_PARAMETER
;
1165 SmiHandler
= AllocateZeroPool (sizeof (SMI_HANDLER
));
1166 if (SmiHandler
== NULL
) {
1167 return EFI_OUT_OF_RESOURCES
;
1170 SmiHandler
->Signature
= SMI_HANDLER_SIGNATURE
;
1171 SmiHandler
->Handler
= Handler
;
1172 SmiHandler
->CallerAddr
= (UINTN
)CallerAddress
;
1173 SmiHandler
->Context
= Context
;
1174 SmiHandler
->ContextSize
= ContextSize
;
1176 if (Context
!= NULL
) {
1177 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1178 SmiHandler
->Context
= ConvertSmiHandlerUsbContext (Context
, ContextSize
, &SmiHandler
->ContextSize
);
1180 SmiHandler
->Context
= AllocateCopyPool (ContextSize
, Context
);
1183 if (SmiHandler
->Context
== NULL
) {
1184 SmiHandler
->ContextSize
= 0;
1187 SmiEntry
= SmmCoreFindHardwareSmiEntry (HandlerGuid
, TRUE
);
1188 if (SmiEntry
== NULL
) {
1189 FreePool (SmiHandler
->Context
);
1190 FreePool (SmiHandler
);
1191 return EFI_OUT_OF_RESOURCES
;
1194 List
= &SmiEntry
->SmiHandlers
;
1196 SmiHandler
->SmiEntry
= SmiEntry
;
1197 InsertTailList (List
, &SmiHandler
->Link
);
1203 This function is called by SmmChildDispatcher module to report
1204 an existing SMI handler is unregistered, to SmmCore.
1206 @param This The protocol instance
1207 @param HandlerGuid The GUID to identify the type of the handler.
1208 For the SmmChildDispatch protocol, the HandlerGuid
1209 must be the GUID of SmmChildDispatch protocol.
1210 @param Handler The SMI handler.
1211 @param Context The context of the SMI handler.
1212 If it is NOT NULL, it will be used to check what is registered.
1213 @param ContextSize The size of the context in bytes.
1214 If Context is NOT NULL, it will be used to check what is registered.
1216 @retval EFI_SUCCESS The original record is removed.
1217 @retval EFI_NOT_FOUND There is no record for the HandlerGuid and handler.
1221 SmiHandlerProfileUnregisterHandler (
1222 IN SMI_HANDLER_PROFILE_PROTOCOL
*This
,
1223 IN EFI_GUID
*HandlerGuid
,
1224 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler
,
1225 IN VOID
*Context
, OPTIONAL
1226 IN UINTN ContextSize OPTIONAL
1231 SMI_HANDLER
*SmiHandler
;
1232 SMI_ENTRY
*SmiEntry
;
1233 SMI_HANDLER
*TargetSmiHandler
;
1234 VOID
*SearchContext
;
1235 UINTN SearchContextSize
;
1237 if (((ContextSize
== 0) && (Context
!= NULL
)) ||
1238 ((ContextSize
!= 0) && (Context
== NULL
))) {
1239 return EFI_INVALID_PARAMETER
;
1242 SmiEntry
= SmmCoreFindHardwareSmiEntry (HandlerGuid
, FALSE
);
1243 if (SmiEntry
== NULL
) {
1244 return EFI_NOT_FOUND
;
1247 SearchContext
= Context
;
1248 SearchContextSize
= ContextSize
;
1249 if (Context
!= NULL
) {
1250 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1251 SearchContext
= ConvertSmiHandlerUsbContext (Context
, ContextSize
, &SearchContextSize
);
1255 TargetSmiHandler
= NULL
;
1256 Head
= &SmiEntry
->SmiHandlers
;
1257 for (Link
= Head
->ForwardLink
; Link
!= Head
; Link
= Link
->ForwardLink
) {
1258 SmiHandler
= CR (Link
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
1259 if (SmiHandler
->Handler
== Handler
) {
1260 if ((SearchContext
== NULL
) ||
1261 ((SearchContextSize
== SmiHandler
->ContextSize
) && (CompareMem (SearchContext
, SmiHandler
->Context
, SearchContextSize
) == 0))) {
1262 TargetSmiHandler
= SmiHandler
;
1268 if (SearchContext
!= NULL
) {
1269 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1270 FreePool (SearchContext
);
1274 if (TargetSmiHandler
== NULL
) {
1275 return EFI_NOT_FOUND
;
1277 SmiHandler
= TargetSmiHandler
;
1279 RemoveEntryList (&SmiHandler
->Link
);
1280 FreePool (SmiHandler
);
1282 if (IsListEmpty (&SmiEntry
->SmiHandlers
)) {
1283 RemoveEntryList (&SmiEntry
->AllEntries
);
1284 FreePool (SmiEntry
);
1291 Initialize SmiHandler profile feature.
1294 SmmCoreInitializeSmiHandlerProfile (
1302 if ((PcdGet8 (PcdSmiHandlerProfilePropertyMask
) & 0x1) != 0) {
1303 InsertTailList (&mRootSmiEntryList
, &mRootSmiEntry
.AllEntries
);
1305 Status
= gSmst
->SmmRegisterProtocolNotify (
1306 &gEfiSmmReadyToLockProtocolGuid
,
1307 SmmReadyToLockInSmiHandlerProfile
,
1310 ASSERT_EFI_ERROR (Status
);
1313 Status
= gSmst
->SmmInstallProtocolInterface (
1315 &gSmiHandlerProfileGuid
,
1316 EFI_NATIVE_INTERFACE
,
1319 ASSERT_EFI_ERROR (Status
);