2 SMI handler profile support.
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/BaseLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/MemoryAllocationLib.h>
13 #include <Library/UefiBootServicesTableLib.h>
14 #include <Library/SmmServicesTableLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/PrintLib.h>
17 #include <Library/UefiLib.h>
18 #include <Library/DevicePathLib.h>
19 #include <Library/PeCoffGetEntryPointLib.h>
20 #include <Protocol/LoadedImage.h>
21 #include <Protocol/SmmAccess2.h>
22 #include <Protocol/SmmReadyToLock.h>
23 #include <Protocol/SmmEndOfDxe.h>
25 #include <Guid/SmiHandlerProfile.h>
27 #include "PiSmmCore.h"
29 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
30 ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)))
34 PHYSICAL_ADDRESS EntryPoint
;
35 PHYSICAL_ADDRESS ImageBase
;
43 Register SMI handler profile handler.
46 RegisterSmiHandlerProfileHandler (
51 Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded
52 into system memory with the PE/COFF Loader Library functions.
54 Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry
55 point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then
56 return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS.
57 If Pe32Data is NULL, then ASSERT().
58 If EntryPoint is NULL, then ASSERT().
60 @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory.
61 @param EntryPoint The pointer to entry point to the PE/COFF image to return.
63 @retval RETURN_SUCCESS EntryPoint was returned.
64 @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image.
68 InternalPeCoffGetEntryPoint (
73 extern LIST_ENTRY mSmiEntryList
;
74 extern LIST_ENTRY mHardwareSmiEntryList
;
75 extern SMI_ENTRY mRootSmiEntry
;
77 extern SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile
;
79 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mHardwareSmiEntryList
= INITIALIZE_LIST_HEAD_VARIABLE (mHardwareSmiEntryList
);
81 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mRootSmiEntryList
= INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntryList
);
83 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY
*mSmmCoreRootSmiEntryList
= &mRootSmiEntryList
;
84 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY
*mSmmCoreSmiEntryList
= &mSmiEntryList
;
85 GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY
*mSmmCoreHardwareSmiEntryList
= &mHardwareSmiEntryList
;
87 GLOBAL_REMOVE_IF_UNREFERENCED IMAGE_STRUCT
*mImageStruct
;
88 GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mImageStructCountMax
;
89 GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mImageStructCount
;
91 GLOBAL_REMOVE_IF_UNREFERENCED VOID
*mSmiHandlerProfileDatabase
;
92 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmiHandlerProfileDatabaseSize
;
94 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmImageDatabaseSize
;
95 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmRootSmiDatabaseSize
;
96 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmSmiDatabaseSize
;
97 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmHardwareSmiDatabaseSize
;
99 GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmiHandlerProfileRecordingStatus
;
101 GLOBAL_REMOVE_IF_UNREFERENCED SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile
= {
102 SmiHandlerProfileRegisterHandler
,
103 SmiHandlerProfileUnregisterHandler
,
107 This function dump raw data.
110 @param Size raw data size
120 for (Index
= 0; Index
< Size
; Index
++) {
121 DEBUG ((DEBUG_INFO
, "%02x ", (UINTN
)Data
[Index
]));
126 Get GUID name for an image.
128 @param[in] LoadedImage LoadedImage protocol.
129 @param[out] Guid Guid of the FFS
133 IN EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
,
140 if ((DevicePathType (LoadedImage
->FilePath
) == MEDIA_DEVICE_PATH
) &&
141 (DevicePathSubType (LoadedImage
->FilePath
) == MEDIA_PIWG_FW_FILE_DP
))
143 FileName
= &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)LoadedImage
->FilePath
)->FvFileName
;
146 if (FileName
!= NULL
) {
147 CopyGuid (Guid
, FileName
);
149 ZeroMem (Guid
, sizeof (EFI_GUID
));
156 @param ImageBase image base
157 @param ImageSize image size
158 @param EntryPoint image entry point
159 @param Guid FFS GUID of the image
160 @param PdbString image PDB string
164 IN PHYSICAL_ADDRESS ImageBase
,
166 IN PHYSICAL_ADDRESS EntryPoint
,
173 if (mImageStructCount
>= mImageStructCountMax
) {
178 CopyGuid (&mImageStruct
[mImageStructCount
].FileGuid
, Guid
);
179 mImageStruct
[mImageStructCount
].ImageRef
= mImageStructCount
;
180 mImageStruct
[mImageStructCount
].ImageBase
= ImageBase
;
181 mImageStruct
[mImageStructCount
].ImageSize
= ImageSize
;
182 mImageStruct
[mImageStructCount
].EntryPoint
= EntryPoint
;
183 if (PdbString
!= NULL
) {
184 PdbStringSize
= AsciiStrSize (PdbString
);
185 mImageStruct
[mImageStructCount
].PdbString
= AllocateCopyPool (PdbStringSize
, PdbString
);
186 if (mImageStruct
[mImageStructCount
].PdbString
!= NULL
) {
187 mImageStruct
[mImageStructCount
].PdbStringSize
= (UINT16
)PdbStringSize
;
195 return an image structure based upon image address.
197 @param Address image address
199 @return image structure
202 AddressToImageStruct (
208 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
209 if ((Address
>= mImageStruct
[Index
].ImageBase
) &&
210 (Address
< mImageStruct
[Index
].ImageBase
+ mImageStruct
[Index
].ImageSize
))
212 return &mImageStruct
[Index
];
220 return an image reference index based upon image address.
222 @param Address image address
224 @return image reference index
231 IMAGE_STRUCT
*ImageStruct
;
233 ImageStruct
= AddressToImageStruct (Address
);
234 if (ImageStruct
!= NULL
) {
235 return ImageStruct
->ImageRef
;
242 Collect SMM image information based upon loaded image protocol.
251 UINTN HandleBufferSize
;
252 EFI_HANDLE
*HandleBuffer
;
254 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
256 EFI_SMM_DRIVER_ENTRY
*LoadedImagePrivate
;
257 PHYSICAL_ADDRESS EntryPoint
;
258 VOID
*EntryPointInImage
;
261 PHYSICAL_ADDRESS RealImageBase
;
263 HandleBufferSize
= 0;
265 Status
= gSmst
->SmmLocateHandle (
267 &gEfiLoadedImageProtocolGuid
,
272 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
276 HandleBuffer
= AllocateZeroPool (HandleBufferSize
);
277 if (HandleBuffer
== NULL
) {
281 Status
= gSmst
->SmmLocateHandle (
283 &gEfiLoadedImageProtocolGuid
,
288 if (EFI_ERROR (Status
)) {
292 NoHandles
= HandleBufferSize
/sizeof (EFI_HANDLE
);
293 mImageStructCountMax
= (UINT32
)NoHandles
;
294 mImageStruct
= AllocateZeroPool (mImageStructCountMax
* sizeof (IMAGE_STRUCT
));
295 if (mImageStruct
== NULL
) {
299 for (Index
= 0; Index
< NoHandles
; Index
++) {
300 Status
= gSmst
->SmmHandleProtocol (
302 &gEfiLoadedImageProtocolGuid
,
303 (VOID
**)&LoadedImage
305 if (EFI_ERROR (Status
)) {
309 PathStr
= ConvertDevicePathToText (LoadedImage
->FilePath
, TRUE
, TRUE
);
310 GetDriverGuid (LoadedImage
, &Guid
);
311 DEBUG ((DEBUG_INFO
, "Image: %g ", &Guid
));
314 LoadedImagePrivate
= BASE_CR (LoadedImage
, EFI_SMM_DRIVER_ENTRY
, SmmLoadedImage
);
315 RealImageBase
= (UINTN
)LoadedImage
->ImageBase
;
316 if (LoadedImagePrivate
->Signature
== EFI_SMM_DRIVER_ENTRY_SIGNATURE
) {
317 EntryPoint
= LoadedImagePrivate
->ImageEntryPoint
;
318 if ((EntryPoint
!= 0) && ((EntryPoint
< (UINTN
)LoadedImage
->ImageBase
) || (EntryPoint
>= ((UINTN
)LoadedImage
->ImageBase
+ LoadedImage
->ImageSize
)))) {
320 // If the EntryPoint is not in the range of image buffer, it should come from emulation environment.
321 // So patch ImageBuffer here to align the EntryPoint.
323 Status
= InternalPeCoffGetEntryPoint (LoadedImage
->ImageBase
, &EntryPointInImage
);
324 ASSERT_EFI_ERROR (Status
);
325 RealImageBase
= (UINTN
)LoadedImage
->ImageBase
+ EntryPoint
- (UINTN
)EntryPointInImage
;
329 DEBUG ((DEBUG_INFO
, "(0x%lx - 0x%lx", RealImageBase
, LoadedImage
->ImageSize
));
330 if (EntryPoint
!= 0) {
331 DEBUG ((DEBUG_INFO
, ", EntryPoint:0x%lx", EntryPoint
));
334 DEBUG ((DEBUG_INFO
, ")\n"));
336 if (RealImageBase
!= 0) {
337 PdbString
= PeCoffLoaderGetPdbPointer ((VOID
*)(UINTN
)RealImageBase
);
338 DEBUG ((DEBUG_INFO
, " pdb - %a\n", PdbString
));
343 DEBUG ((DEBUG_INFO
, " (%s)\n", PathStr
));
345 AddImageStruct (RealImageBase
, LoadedImage
->ImageSize
, EntryPoint
, &Guid
, PdbString
);
349 FreePool (HandleBuffer
);
354 Dump SMI child context.
356 @param HandlerType the handler type
357 @param Context the handler context
358 @param ContextSize the handler context size
361 DumpSmiChildContext (
362 IN EFI_GUID
*HandlerType
,
369 if (CompareGuid (HandlerType
, &gEfiSmmSwDispatch2ProtocolGuid
)) {
370 DEBUG ((DEBUG_INFO
, " SwSmi - 0x%lx\n", ((SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT
*)Context
)->SwSmiInputValue
));
371 } else if (CompareGuid (HandlerType
, &gEfiSmmSxDispatch2ProtocolGuid
)) {
372 DEBUG ((DEBUG_INFO
, " SxType - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Type
));
373 DEBUG ((DEBUG_INFO
, " SxPhase - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Phase
));
374 } else if (CompareGuid (HandlerType
, &gEfiSmmPowerButtonDispatch2ProtocolGuid
)) {
375 DEBUG ((DEBUG_INFO
, " PowerButtonPhase - 0x%x\n", ((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
376 } else if (CompareGuid (HandlerType
, &gEfiSmmStandbyButtonDispatch2ProtocolGuid
)) {
377 DEBUG ((DEBUG_INFO
, " StandbyButtonPhase - 0x%x\n", ((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
378 } else if (CompareGuid (HandlerType
, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid
)) {
379 DEBUG ((DEBUG_INFO
, " PeriodicTimerPeriod - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->Period
));
380 DEBUG ((DEBUG_INFO
, " PeriodicTimerSmiTickInterval - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->SmiTickInterval
));
381 } else if (CompareGuid (HandlerType
, &gEfiSmmGpiDispatch2ProtocolGuid
)) {
382 DEBUG ((DEBUG_INFO
, " GpiNum - 0x%lx\n", ((EFI_SMM_GPI_REGISTER_CONTEXT
*)Context
)->GpiNum
));
383 } else if (CompareGuid (HandlerType
, &gEfiSmmIoTrapDispatch2ProtocolGuid
)) {
384 DEBUG ((DEBUG_INFO
, " IoTrapAddress - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Address
));
385 DEBUG ((DEBUG_INFO
, " IoTrapLength - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Length
));
386 DEBUG ((DEBUG_INFO
, " IoTrapType - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Type
));
387 } else if (CompareGuid (HandlerType
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
388 DEBUG ((DEBUG_INFO
, " UsbType - 0x%x\n", ((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
)->Type
));
389 Str
= ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL
*)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
) + 1), TRUE
, TRUE
);
390 DEBUG ((DEBUG_INFO
, " UsbDevicePath - %s\n", Str
));
395 DEBUG ((DEBUG_INFO
, " Context - "));
396 InternalDumpData (Context
, ContextSize
);
397 DEBUG ((DEBUG_INFO
, "\n"));
402 Dump all SMI handlers associated with SmiEntry.
404 @param SmiEntry SMI entry.
407 DumpSmiHandlerOnSmiEntry (
408 IN SMI_ENTRY
*SmiEntry
411 LIST_ENTRY
*ListEntry
;
412 SMI_HANDLER
*SmiHandler
;
413 IMAGE_STRUCT
*ImageStruct
;
415 ListEntry
= &SmiEntry
->SmiHandlers
;
416 for (ListEntry
= ListEntry
->ForwardLink
;
417 ListEntry
!= &SmiEntry
->SmiHandlers
;
418 ListEntry
= ListEntry
->ForwardLink
)
420 SmiHandler
= CR (ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
421 ImageStruct
= AddressToImageStruct ((UINTN
)SmiHandler
->Handler
);
422 if (ImageStruct
!= NULL
) {
423 DEBUG ((DEBUG_INFO
, " Module - %g", &ImageStruct
->FileGuid
));
426 if ((ImageStruct
!= NULL
) && (ImageStruct
->PdbString
[0] != 0)) {
427 DEBUG ((DEBUG_INFO
, " (Pdb - %a)", ImageStruct
->PdbString
));
430 DEBUG ((DEBUG_INFO
, "\n"));
431 if (SmiHandler
->ContextSize
!= 0) {
432 DumpSmiChildContext (&SmiEntry
->HandlerType
, SmiHandler
->Context
, SmiHandler
->ContextSize
);
435 DEBUG ((DEBUG_INFO
, " Handler - 0x%x", SmiHandler
->Handler
));
436 if (ImageStruct
!= NULL
) {
437 DEBUG ((DEBUG_INFO
, " <== RVA - 0x%x", (UINTN
)SmiHandler
->Handler
- (UINTN
)ImageStruct
->ImageBase
));
440 DEBUG ((DEBUG_INFO
, "\n"));
441 DEBUG ((DEBUG_INFO
, " CallerAddr - 0x%x", SmiHandler
->CallerAddr
));
442 if (ImageStruct
!= NULL
) {
443 DEBUG ((DEBUG_INFO
, " <== RVA - 0x%x", SmiHandler
->CallerAddr
- (UINTN
)ImageStruct
->ImageBase
));
446 DEBUG ((DEBUG_INFO
, "\n"));
453 Dump all SMI entry on the list.
455 @param SmiEntryList a list of SMI entry.
459 IN LIST_ENTRY
*SmiEntryList
462 LIST_ENTRY
*ListEntry
;
465 ListEntry
= SmiEntryList
;
466 for (ListEntry
= ListEntry
->ForwardLink
;
467 ListEntry
!= SmiEntryList
;
468 ListEntry
= ListEntry
->ForwardLink
)
470 SmiEntry
= CR (ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
471 DEBUG ((DEBUG_INFO
, "SmiEntry - %g\n", &SmiEntry
->HandlerType
));
472 DumpSmiHandlerOnSmiEntry (SmiEntry
);
479 SMM Ready To Lock event notification handler.
481 This function collects all SMM image information and build SmiHandleProfile database,
482 and register SmiHandlerProfile SMI handler.
484 @param[in] Protocol Points to the protocol's unique identifier.
485 @param[in] Interface Points to the interface instance.
486 @param[in] Handle The handle on which the interface was installed.
488 @retval EFI_SUCCESS Notification handler runs successfully.
492 SmmReadyToLockInSmiHandlerProfile (
493 IN CONST EFI_GUID
*Protocol
,
501 DEBUG ((DEBUG_INFO
, "##################\n"));
502 DEBUG ((DEBUG_INFO
, "# IMAGE DATABASE #\n"));
503 DEBUG ((DEBUG_INFO
, "##################\n"));
504 GetSmmLoadedImage ();
505 DEBUG ((DEBUG_INFO
, "\n"));
510 DEBUG ((DEBUG_INFO
, "########################\n"));
511 DEBUG ((DEBUG_INFO
, "# SMI Handler DATABASE #\n"));
512 DEBUG ((DEBUG_INFO
, "########################\n"));
514 DEBUG ((DEBUG_INFO
, "# 1. ROOT SMI Handler #\n"));
516 DumpSmiEntryList (mSmmCoreRootSmiEntryList
);
519 DEBUG ((DEBUG_INFO
, "# 2. GUID SMI Handler #\n"));
521 DumpSmiEntryList (mSmmCoreSmiEntryList
);
524 DEBUG ((DEBUG_INFO
, "# 3. Hardware SMI Handler #\n"));
526 DumpSmiEntryList (mSmmCoreHardwareSmiEntryList
);
529 DEBUG ((DEBUG_INFO
, "\n"));
531 RegisterSmiHandlerProfileHandler ();
533 if (mImageStruct
!= NULL
) {
534 FreePool (mImageStruct
);
541 returns SMM image data base size.
543 @return SMM image data base size.
546 GetSmmImageDatabaseSize (
554 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
555 Size
+= sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + GET_OCCUPIED_SIZE (mImageStruct
[Index
].PdbStringSize
, sizeof (UINT64
));
562 returns all SMI handlers' size associated with SmiEntry.
564 @param SmiEntry SMI entry.
566 @return all SMI handlers' size associated with SmiEntry.
569 GetSmmSmiHandlerSizeOnSmiEntry (
570 IN SMI_ENTRY
*SmiEntry
573 LIST_ENTRY
*ListEntry
;
574 SMI_HANDLER
*SmiHandler
;
578 ListEntry
= &SmiEntry
->SmiHandlers
;
579 for (ListEntry
= ListEntry
->ForwardLink
;
580 ListEntry
!= &SmiEntry
->SmiHandlers
;
581 ListEntry
= ListEntry
->ForwardLink
)
583 SmiHandler
= CR (ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
584 Size
+= sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE
) + GET_OCCUPIED_SIZE (SmiHandler
->ContextSize
, sizeof (UINT64
));
591 return all SMI handler database size on the SMI entry list.
593 @param SmiEntryList a list of SMI entry.
595 @return all SMI handler database size on the SMI entry list.
598 GetSmmSmiDatabaseSize (
599 IN LIST_ENTRY
*SmiEntryList
602 LIST_ENTRY
*ListEntry
;
607 ListEntry
= SmiEntryList
;
608 for (ListEntry
= ListEntry
->ForwardLink
;
609 ListEntry
!= SmiEntryList
;
610 ListEntry
= ListEntry
->ForwardLink
)
612 SmiEntry
= CR (ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
613 Size
+= sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE
);
614 Size
+= GetSmmSmiHandlerSizeOnSmiEntry (SmiEntry
);
621 return SMI handler profile database size.
623 @return SMI handler profile database size.
626 GetSmiHandlerProfileDatabaseSize (
630 mSmmImageDatabaseSize
= GetSmmImageDatabaseSize ();
631 mSmmRootSmiDatabaseSize
= GetSmmSmiDatabaseSize (mSmmCoreRootSmiEntryList
);
632 mSmmSmiDatabaseSize
= GetSmmSmiDatabaseSize (mSmmCoreSmiEntryList
);
633 mSmmHardwareSmiDatabaseSize
= GetSmmSmiDatabaseSize (mSmmCoreHardwareSmiEntryList
);
635 return mSmmImageDatabaseSize
+ mSmmSmiDatabaseSize
+ mSmmRootSmiDatabaseSize
+ mSmmHardwareSmiDatabaseSize
;
639 get SMM image database.
641 @param Data The buffer to hold SMM image database
642 @param ExpectedSize The expected size of the SMM image database
644 @return SMM image data base size.
647 GetSmmImageDatabaseData (
649 IN UINTN ExpectedSize
652 SMM_CORE_IMAGE_DATABASE_STRUCTURE
*ImageStruct
;
658 for (Index
= 0; Index
< mImageStructCount
; Index
++) {
659 if (Size
>= ExpectedSize
) {
663 if (sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + GET_OCCUPIED_SIZE (mImageStruct
[Index
].PdbStringSize
, sizeof (UINT64
)) > ExpectedSize
- Size
) {
667 ImageStruct
->Header
.Signature
= SMM_CORE_IMAGE_DATABASE_SIGNATURE
;
668 ImageStruct
->Header
.Length
= (UINT32
)(sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + GET_OCCUPIED_SIZE (mImageStruct
[Index
].PdbStringSize
, sizeof (UINT64
)));
669 ImageStruct
->Header
.Revision
= SMM_CORE_IMAGE_DATABASE_REVISION
;
670 CopyGuid (&ImageStruct
->FileGuid
, &mImageStruct
[Index
].FileGuid
);
671 ImageStruct
->ImageRef
= mImageStruct
[Index
].ImageRef
;
672 ImageStruct
->EntryPoint
= mImageStruct
[Index
].EntryPoint
;
673 ImageStruct
->ImageBase
= mImageStruct
[Index
].ImageBase
;
674 ImageStruct
->ImageSize
= mImageStruct
[Index
].ImageSize
;
675 if (mImageStruct
[Index
].PdbStringSize
!= 0) {
676 ImageStruct
->PdbStringOffset
= sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE
);
677 CopyMem ((VOID
*)((UINTN
)ImageStruct
+ ImageStruct
->PdbStringOffset
), mImageStruct
[Index
].PdbString
, mImageStruct
[Index
].PdbStringSize
);
679 ImageStruct
->PdbStringOffset
= 0;
682 ImageStruct
= (SMM_CORE_IMAGE_DATABASE_STRUCTURE
*)((UINTN
)ImageStruct
+ ImageStruct
->Header
.Length
);
683 Size
+= sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE
) + GET_OCCUPIED_SIZE (mImageStruct
[Index
].PdbStringSize
, sizeof (UINT64
));
686 if (ExpectedSize
!= Size
) {
694 get all SMI handler data associated with SmiEntry.
696 @param SmiEntry SMI entry.
697 @param Data The buffer to hold all SMI handler data
698 @param MaxSize The max size of the SMM image database
699 @param Count The count of the SMI handler.
701 @return SMM image data base size.
704 GetSmmSmiHandlerDataOnSmiEntry (
705 IN SMI_ENTRY
*SmiEntry
,
711 SMM_CORE_SMI_HANDLER_STRUCTURE
*SmiHandlerStruct
;
712 LIST_ENTRY
*ListEntry
;
713 SMI_HANDLER
*SmiHandler
;
716 SmiHandlerStruct
= Data
;
719 ListEntry
= &SmiEntry
->SmiHandlers
;
720 for (ListEntry
= ListEntry
->ForwardLink
;
721 ListEntry
!= &SmiEntry
->SmiHandlers
;
722 ListEntry
= ListEntry
->ForwardLink
)
724 SmiHandler
= CR (ListEntry
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
725 if (Size
>= MaxSize
) {
730 if (sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE
) + GET_OCCUPIED_SIZE (SmiHandler
->ContextSize
, sizeof (UINT64
)) > MaxSize
- Size
) {
735 SmiHandlerStruct
->Length
= (UINT32
)(sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE
) + GET_OCCUPIED_SIZE (SmiHandler
->ContextSize
, sizeof (UINT64
)));
736 SmiHandlerStruct
->CallerAddr
= (UINTN
)SmiHandler
->CallerAddr
;
737 SmiHandlerStruct
->Handler
= (UINTN
)SmiHandler
->Handler
;
738 SmiHandlerStruct
->ImageRef
= AddressToImageRef ((UINTN
)SmiHandler
->Handler
);
739 SmiHandlerStruct
->ContextBufferSize
= (UINT32
)SmiHandler
->ContextSize
;
740 if (SmiHandler
->ContextSize
!= 0) {
741 SmiHandlerStruct
->ContextBufferOffset
= sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE
);
742 CopyMem ((UINT8
*)SmiHandlerStruct
+ SmiHandlerStruct
->ContextBufferOffset
, SmiHandler
->Context
, SmiHandler
->ContextSize
);
744 SmiHandlerStruct
->ContextBufferOffset
= 0;
747 Size
+= sizeof (SMM_CORE_SMI_HANDLER_STRUCTURE
) + GET_OCCUPIED_SIZE (SmiHandler
->ContextSize
, sizeof (UINT64
));
748 SmiHandlerStruct
= (SMM_CORE_SMI_HANDLER_STRUCTURE
*)((UINTN
)SmiHandlerStruct
+ SmiHandlerStruct
->Length
);
756 get all SMI handler database on the SMI entry list.
758 @param SmiEntryList a list of SMI entry.
759 @param HandlerCategory The handler category
760 @param Data The buffer to hold all SMI handler database
761 @param ExpectedSize The expected size of the SMM image database
763 @return all SMI database size on the SMI entry list.
766 GetSmmSmiDatabaseData (
767 IN LIST_ENTRY
*SmiEntryList
,
768 IN UINT32 HandlerCategory
,
770 IN UINTN ExpectedSize
773 SMM_CORE_SMI_DATABASE_STRUCTURE
*SmiStruct
;
774 LIST_ENTRY
*ListEntry
;
777 UINTN SmiHandlerSize
;
778 UINT32 SmiHandlerCount
;
782 ListEntry
= SmiEntryList
;
783 for (ListEntry
= ListEntry
->ForwardLink
;
784 ListEntry
!= SmiEntryList
;
785 ListEntry
= ListEntry
->ForwardLink
)
787 SmiEntry
= CR (ListEntry
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
788 if (Size
>= ExpectedSize
) {
792 if (sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE
) > ExpectedSize
- Size
) {
796 SmiStruct
->Header
.Signature
= SMM_CORE_SMI_DATABASE_SIGNATURE
;
797 SmiStruct
->Header
.Length
= sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE
);
798 SmiStruct
->Header
.Revision
= SMM_CORE_SMI_DATABASE_REVISION
;
799 SmiStruct
->HandlerCategory
= HandlerCategory
;
800 CopyGuid (&SmiStruct
->HandlerType
, &SmiEntry
->HandlerType
);
801 Size
+= sizeof (SMM_CORE_SMI_DATABASE_STRUCTURE
);
802 SmiHandlerSize
= GetSmmSmiHandlerDataOnSmiEntry (SmiEntry
, (UINT8
*)SmiStruct
+ SmiStruct
->Header
.Length
, ExpectedSize
- Size
, &SmiHandlerCount
);
803 SmiStruct
->HandlerCount
= SmiHandlerCount
;
804 Size
+= SmiHandlerSize
;
805 SmiStruct
->Header
.Length
+= (UINT32
)SmiHandlerSize
;
806 SmiStruct
= (VOID
*)((UINTN
)SmiStruct
+ SmiStruct
->Header
.Length
);
809 if (ExpectedSize
!= Size
) {
817 Get SMI handler profile database.
819 @param Data the buffer to hold SMI handler profile database
821 @retval EFI_SUCCESS the database is got.
822 @retval EFI_INVALID_PARAMETER the database size mismatch.
825 GetSmiHandlerProfileDatabaseData (
829 UINTN SmmImageDatabaseSize
;
830 UINTN SmmSmiDatabaseSize
;
831 UINTN SmmRootSmiDatabaseSize
;
832 UINTN SmmHardwareSmiDatabaseSize
;
834 DEBUG ((DEBUG_VERBOSE
, "GetSmiHandlerProfileDatabaseData\n"));
835 SmmImageDatabaseSize
= GetSmmImageDatabaseData (Data
, mSmmImageDatabaseSize
);
836 if (SmmImageDatabaseSize
!= mSmmImageDatabaseSize
) {
837 DEBUG ((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmImageDatabaseSize mismatch!\n"));
838 return EFI_INVALID_PARAMETER
;
841 SmmRootSmiDatabaseSize
= GetSmmSmiDatabaseData (mSmmCoreRootSmiEntryList
, SmmCoreSmiHandlerCategoryRootHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
, mSmmRootSmiDatabaseSize
);
842 if (SmmRootSmiDatabaseSize
!= mSmmRootSmiDatabaseSize
) {
843 DEBUG ((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmRootSmiDatabaseSize mismatch!\n"));
844 return EFI_INVALID_PARAMETER
;
847 SmmSmiDatabaseSize
= GetSmmSmiDatabaseData (mSmmCoreSmiEntryList
, SmmCoreSmiHandlerCategoryGuidHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
+ mSmmRootSmiDatabaseSize
, mSmmSmiDatabaseSize
);
848 if (SmmSmiDatabaseSize
!= mSmmSmiDatabaseSize
) {
849 DEBUG ((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmSmiDatabaseSize mismatch!\n"));
850 return EFI_INVALID_PARAMETER
;
853 SmmHardwareSmiDatabaseSize
= GetSmmSmiDatabaseData (mSmmCoreHardwareSmiEntryList
, SmmCoreSmiHandlerCategoryHardwareHandler
, (UINT8
*)Data
+ SmmImageDatabaseSize
+ SmmRootSmiDatabaseSize
+ SmmSmiDatabaseSize
, mSmmHardwareSmiDatabaseSize
);
854 if (SmmHardwareSmiDatabaseSize
!= mSmmHardwareSmiDatabaseSize
) {
855 DEBUG ((DEBUG_ERROR
, "GetSmiHandlerProfileDatabaseData - SmmHardwareSmiDatabaseSize mismatch!\n"));
856 return EFI_INVALID_PARAMETER
;
863 build SMI handler profile database.
866 BuildSmiHandlerProfileDatabase (
872 mSmiHandlerProfileDatabaseSize
= GetSmiHandlerProfileDatabaseSize ();
873 mSmiHandlerProfileDatabase
= AllocatePool (mSmiHandlerProfileDatabaseSize
);
874 if (mSmiHandlerProfileDatabase
== NULL
) {
878 Status
= GetSmiHandlerProfileDatabaseData (mSmiHandlerProfileDatabase
);
879 if (EFI_ERROR (Status
)) {
880 FreePool (mSmiHandlerProfileDatabase
);
881 mSmiHandlerProfileDatabase
= NULL
;
886 Copy SMI handler profile data.
888 @param DataBuffer The buffer to hold SMI handler profile data.
889 @param DataSize On input, data buffer size.
890 On output, actual data buffer size copied.
891 @param DataOffset On input, data buffer offset to copy.
892 On output, next time data buffer offset to copy.
896 SmiHandlerProfileCopyData (
897 OUT VOID
*DataBuffer
,
898 IN OUT UINT64
*DataSize
,
899 IN OUT UINT64
*DataOffset
902 if (*DataOffset
>= mSmiHandlerProfileDatabaseSize
) {
903 *DataOffset
= mSmiHandlerProfileDatabaseSize
;
907 if (mSmiHandlerProfileDatabaseSize
- *DataOffset
< *DataSize
) {
908 *DataSize
= mSmiHandlerProfileDatabaseSize
- *DataOffset
;
913 (UINT8
*)mSmiHandlerProfileDatabase
+ *DataOffset
,
916 *DataOffset
= *DataOffset
+ *DataSize
;
920 SMI handler profile handler to get info.
922 @param SmiHandlerProfileParameterGetInfo The parameter of SMI handler profile get info.
926 SmiHandlerProfileHandlerGetInfo (
927 IN SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*SmiHandlerProfileParameterGetInfo
930 BOOLEAN SmiHandlerProfileRecordingStatus
;
932 SmiHandlerProfileRecordingStatus
= mSmiHandlerProfileRecordingStatus
;
933 mSmiHandlerProfileRecordingStatus
= FALSE
;
935 SmiHandlerProfileParameterGetInfo
->DataSize
= mSmiHandlerProfileDatabaseSize
;
936 SmiHandlerProfileParameterGetInfo
->Header
.ReturnStatus
= 0;
938 mSmiHandlerProfileRecordingStatus
= SmiHandlerProfileRecordingStatus
;
942 SMI handler profile handler to get data by offset.
944 @param SmiHandlerProfileParameterGetDataByOffset The parameter of SMI handler profile get data by offset.
948 SmiHandlerProfileHandlerGetDataByOffset (
949 IN SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*SmiHandlerProfileParameterGetDataByOffset
952 SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET SmiHandlerProfileGetDataByOffset
;
953 BOOLEAN SmiHandlerProfileRecordingStatus
;
955 SmiHandlerProfileRecordingStatus
= mSmiHandlerProfileRecordingStatus
;
956 mSmiHandlerProfileRecordingStatus
= FALSE
;
958 CopyMem (&SmiHandlerProfileGetDataByOffset
, SmiHandlerProfileParameterGetDataByOffset
, sizeof (SmiHandlerProfileGetDataByOffset
));
963 if (!SmmIsBufferOutsideSmmValid ((UINTN
)SmiHandlerProfileGetDataByOffset
.DataBuffer
, (UINTN
)SmiHandlerProfileGetDataByOffset
.DataSize
)) {
964 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetDataByOffset: SMI handler profile get data in SMRAM or overflow!\n"));
965 SmiHandlerProfileParameterGetDataByOffset
->Header
.ReturnStatus
= (UINT64
)(INT64
)(INTN
)EFI_ACCESS_DENIED
;
969 SmiHandlerProfileCopyData ((VOID
*)(UINTN
)SmiHandlerProfileGetDataByOffset
.DataBuffer
, &SmiHandlerProfileGetDataByOffset
.DataSize
, &SmiHandlerProfileGetDataByOffset
.DataOffset
);
970 CopyMem (SmiHandlerProfileParameterGetDataByOffset
, &SmiHandlerProfileGetDataByOffset
, sizeof (SmiHandlerProfileGetDataByOffset
));
971 SmiHandlerProfileParameterGetDataByOffset
->Header
.ReturnStatus
= 0;
974 mSmiHandlerProfileRecordingStatus
= SmiHandlerProfileRecordingStatus
;
978 Dispatch function for a Software SMI handler.
980 Caution: This function may receive untrusted input.
981 Communicate buffer and buffer size are external input, so this function will do basic validation.
983 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
984 @param Context Points to an optional handler context which was specified when the
985 handler was registered.
986 @param CommBuffer A pointer to a collection of data in memory that will
987 be conveyed from a non-SMM environment into an SMM environment.
988 @param CommBufferSize The size of the CommBuffer.
990 @retval EFI_SUCCESS Command is handled successfully.
994 SmiHandlerProfileHandler (
995 IN EFI_HANDLE DispatchHandle
,
996 IN CONST VOID
*Context OPTIONAL
,
997 IN OUT VOID
*CommBuffer OPTIONAL
,
998 IN OUT UINTN
*CommBufferSize OPTIONAL
1001 SMI_HANDLER_PROFILE_PARAMETER_HEADER
*SmiHandlerProfileParameterHeader
;
1002 UINTN TempCommBufferSize
;
1004 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandler Enter\n"));
1006 if (mSmiHandlerProfileDatabase
== NULL
) {
1011 // If input is invalid, stop processing this SMI
1013 if ((CommBuffer
== NULL
) || (CommBufferSize
== NULL
)) {
1017 TempCommBufferSize
= *CommBufferSize
;
1019 if (TempCommBufferSize
< sizeof (SMI_HANDLER_PROFILE_PARAMETER_HEADER
)) {
1020 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
1024 if (!SmmIsBufferOutsideSmmValid ((UINTN
)CommBuffer
, TempCommBufferSize
)) {
1025 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer in SMRAM or overflow!\n"));
1029 SmiHandlerProfileParameterHeader
= (SMI_HANDLER_PROFILE_PARAMETER_HEADER
*)((UINTN
)CommBuffer
);
1030 SmiHandlerProfileParameterHeader
->ReturnStatus
= (UINT64
)-1;
1032 switch (SmiHandlerProfileParameterHeader
->Command
) {
1033 case SMI_HANDLER_PROFILE_COMMAND_GET_INFO
:
1034 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetInfo\n"));
1035 if (TempCommBufferSize
!= sizeof (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
)) {
1036 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
1040 SmiHandlerProfileHandlerGetInfo ((SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*)(UINTN
)CommBuffer
);
1042 case SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET
:
1043 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandlerGetDataByOffset\n"));
1044 if (TempCommBufferSize
!= sizeof (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
)) {
1045 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n"));
1049 SmiHandlerProfileHandlerGetDataByOffset ((SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*)(UINTN
)CommBuffer
);
1055 DEBUG ((DEBUG_ERROR
, "SmiHandlerProfileHandler Exit\n"));
1061 Register SMI handler profile handler.
1064 RegisterSmiHandlerProfileHandler (
1069 EFI_HANDLE DispatchHandle
;
1071 Status
= gSmst
->SmiHandlerRegister (
1072 SmiHandlerProfileHandler
,
1073 &gSmiHandlerProfileGuid
,
1076 ASSERT_EFI_ERROR (Status
);
1078 BuildSmiHandlerProfileDatabase ();
1082 Finds the SMI entry for the requested handler type.
1084 @param HandlerType The type of the interrupt
1085 @param Create Create a new entry if not found
1090 SmmCoreFindHardwareSmiEntry (
1091 IN EFI_GUID
*HandlerType
,
1097 SMI_ENTRY
*SmiEntry
;
1100 // Search the SMI entry list for the matching GUID
1103 for (Link
= mHardwareSmiEntryList
.ForwardLink
;
1104 Link
!= &mHardwareSmiEntryList
;
1105 Link
= Link
->ForwardLink
)
1107 Item
= CR (Link
, SMI_ENTRY
, AllEntries
, SMI_ENTRY_SIGNATURE
);
1108 if (CompareGuid (&Item
->HandlerType
, HandlerType
)) {
1110 // This is the SMI entry
1118 // If the protocol entry was not found and Create is TRUE, then
1119 // allocate a new entry
1121 if ((SmiEntry
== NULL
) && Create
) {
1122 SmiEntry
= AllocatePool (sizeof (SMI_ENTRY
));
1123 if (SmiEntry
!= NULL
) {
1125 // Initialize new SMI entry structure
1127 SmiEntry
->Signature
= SMI_ENTRY_SIGNATURE
;
1128 CopyGuid ((VOID
*)&SmiEntry
->HandlerType
, HandlerType
);
1129 InitializeListHead (&SmiEntry
->SmiHandlers
);
1132 // Add it to SMI entry list
1134 InsertTailList (&mHardwareSmiEntryList
, &SmiEntry
->AllEntries
);
1142 Convert EFI_SMM_USB_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT.
1144 @param UsbContext A pointer to EFI_SMM_USB_REGISTER_CONTEXT
1145 @param UsbContextSize The size of EFI_SMM_USB_REGISTER_CONTEXT in bytes
1146 @param SmiHandlerUsbContextSize The size of SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT in bytes
1148 @return SmiHandlerUsbContext A pointer to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
1150 SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*
1151 ConvertSmiHandlerUsbContext (
1152 IN EFI_SMM_USB_REGISTER_CONTEXT
*UsbContext
,
1153 IN UINTN UsbContextSize
,
1154 OUT UINTN
*SmiHandlerUsbContextSize
1157 UINTN DevicePathSize
;
1158 SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*SmiHandlerUsbContext
;
1160 ASSERT (UsbContextSize
== sizeof (EFI_SMM_USB_REGISTER_CONTEXT
));
1162 DevicePathSize
= GetDevicePathSize (UsbContext
->Device
);
1163 SmiHandlerUsbContext
= AllocatePool (sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
) + DevicePathSize
);
1164 if (SmiHandlerUsbContext
== NULL
) {
1165 *SmiHandlerUsbContextSize
= 0;
1169 SmiHandlerUsbContext
->Type
= UsbContext
->Type
;
1170 SmiHandlerUsbContext
->DevicePathSize
= (UINT32
)DevicePathSize
;
1171 CopyMem (SmiHandlerUsbContext
+ 1, UsbContext
->Device
, DevicePathSize
);
1172 *SmiHandlerUsbContextSize
= sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
) + DevicePathSize
;
1173 return SmiHandlerUsbContext
;
1177 Convert EFI_SMM_SW_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT.
1179 @param SwContext A pointer to EFI_SMM_SW_REGISTER_CONTEXT
1180 @param SwContextSize The size of EFI_SMM_SW_REGISTER_CONTEXT in bytes
1181 @param SmiHandlerSwContextSize The size of SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT in bytes
1183 @return SmiHandlerSwContext A pointer to SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT
1185 SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT
*
1186 ConvertSmiHandlerSwContext (
1187 IN EFI_SMM_SW_REGISTER_CONTEXT
*SwContext
,
1188 IN UINTN SwContextSize
,
1189 OUT UINTN
*SmiHandlerSwContextSize
1192 SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT
*SmiHandlerSwContext
;
1194 ASSERT (SwContextSize
== sizeof (EFI_SMM_SW_REGISTER_CONTEXT
));
1196 SmiHandlerSwContext
= AllocatePool (sizeof (SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT
));
1197 if (SmiHandlerSwContext
== NULL
) {
1198 *SmiHandlerSwContextSize
= 0;
1202 SmiHandlerSwContext
->SwSmiInputValue
= SwContext
->SwSmiInputValue
;
1203 *SmiHandlerSwContextSize
= sizeof (SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT
);
1204 return SmiHandlerSwContext
;
1208 This function is called by SmmChildDispatcher module to report
1209 a new SMI handler is registered, to SmmCore.
1211 @param This The protocol instance
1212 @param HandlerGuid The GUID to identify the type of the handler.
1213 For the SmmChildDispatch protocol, the HandlerGuid
1214 must be the GUID of SmmChildDispatch protocol.
1215 @param Handler The SMI handler.
1216 @param CallerAddress The address of the module who registers the SMI handler.
1217 @param Context The context of the SMI handler.
1218 For the SmmChildDispatch protocol, the Context
1219 must match the one defined for SmmChildDispatch protocol.
1220 @param ContextSize The size of the context in bytes.
1221 For the SmmChildDispatch protocol, the Context
1222 must match the one defined for SmmChildDispatch protocol.
1224 @retval EFI_SUCCESS The information is recorded.
1225 @retval EFI_OUT_OF_RESOURCES There is no enough resource to record the information.
1229 SmiHandlerProfileRegisterHandler (
1230 IN SMI_HANDLER_PROFILE_PROTOCOL
*This
,
1231 IN EFI_GUID
*HandlerGuid
,
1232 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler
,
1233 IN PHYSICAL_ADDRESS CallerAddress
,
1234 IN VOID
*Context OPTIONAL
,
1235 IN UINTN ContextSize OPTIONAL
1238 SMI_HANDLER
*SmiHandler
;
1239 SMI_ENTRY
*SmiEntry
;
1242 if (((ContextSize
== 0) && (Context
!= NULL
)) ||
1243 ((ContextSize
!= 0) && (Context
== NULL
)))
1245 return EFI_INVALID_PARAMETER
;
1248 SmiHandler
= AllocateZeroPool (sizeof (SMI_HANDLER
));
1249 if (SmiHandler
== NULL
) {
1250 return EFI_OUT_OF_RESOURCES
;
1253 SmiHandler
->Signature
= SMI_HANDLER_SIGNATURE
;
1254 SmiHandler
->Handler
= Handler
;
1255 SmiHandler
->CallerAddr
= (UINTN
)CallerAddress
;
1256 SmiHandler
->Context
= Context
;
1257 SmiHandler
->ContextSize
= ContextSize
;
1259 if (Context
!= NULL
) {
1260 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1261 SmiHandler
->Context
= ConvertSmiHandlerUsbContext (Context
, ContextSize
, &SmiHandler
->ContextSize
);
1262 } else if (CompareGuid (HandlerGuid
, &gEfiSmmSwDispatch2ProtocolGuid
)) {
1263 SmiHandler
->Context
= ConvertSmiHandlerSwContext (Context
, ContextSize
, &SmiHandler
->ContextSize
);
1265 SmiHandler
->Context
= AllocateCopyPool (ContextSize
, Context
);
1269 if (SmiHandler
->Context
== NULL
) {
1270 SmiHandler
->ContextSize
= 0;
1273 SmiEntry
= SmmCoreFindHardwareSmiEntry (HandlerGuid
, TRUE
);
1274 if (SmiEntry
== NULL
) {
1275 if (SmiHandler
->Context
!= NULL
) {
1276 FreePool (SmiHandler
->Context
);
1279 FreePool (SmiHandler
);
1280 return EFI_OUT_OF_RESOURCES
;
1283 List
= &SmiEntry
->SmiHandlers
;
1285 SmiHandler
->SmiEntry
= SmiEntry
;
1286 InsertTailList (List
, &SmiHandler
->Link
);
1292 This function is called by SmmChildDispatcher module to report
1293 an existing SMI handler is unregistered, to SmmCore.
1295 @param This The protocol instance
1296 @param HandlerGuid The GUID to identify the type of the handler.
1297 For the SmmChildDispatch protocol, the HandlerGuid
1298 must be the GUID of SmmChildDispatch protocol.
1299 @param Handler The SMI handler.
1300 @param Context The context of the SMI handler.
1301 If it is NOT NULL, it will be used to check what is registered.
1302 @param ContextSize The size of the context in bytes.
1303 If Context is NOT NULL, it will be used to check what is registered.
1305 @retval EFI_SUCCESS The original record is removed.
1306 @retval EFI_NOT_FOUND There is no record for the HandlerGuid and handler.
1310 SmiHandlerProfileUnregisterHandler (
1311 IN SMI_HANDLER_PROFILE_PROTOCOL
*This
,
1312 IN EFI_GUID
*HandlerGuid
,
1313 IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler
,
1314 IN VOID
*Context OPTIONAL
,
1315 IN UINTN ContextSize OPTIONAL
1320 SMI_HANDLER
*SmiHandler
;
1321 SMI_ENTRY
*SmiEntry
;
1322 SMI_HANDLER
*TargetSmiHandler
;
1323 VOID
*SearchContext
;
1324 UINTN SearchContextSize
;
1326 if (((ContextSize
== 0) && (Context
!= NULL
)) ||
1327 ((ContextSize
!= 0) && (Context
== NULL
)))
1329 return EFI_INVALID_PARAMETER
;
1332 SmiEntry
= SmmCoreFindHardwareSmiEntry (HandlerGuid
, FALSE
);
1333 if (SmiEntry
== NULL
) {
1334 return EFI_NOT_FOUND
;
1337 SearchContext
= Context
;
1338 SearchContextSize
= ContextSize
;
1339 if (Context
!= NULL
) {
1340 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1341 SearchContext
= ConvertSmiHandlerUsbContext (Context
, ContextSize
, &SearchContextSize
);
1342 } else if (CompareGuid (HandlerGuid
, &gEfiSmmSwDispatch2ProtocolGuid
)) {
1343 SearchContext
= ConvertSmiHandlerSwContext (Context
, ContextSize
, &SearchContextSize
);
1347 TargetSmiHandler
= NULL
;
1348 Head
= &SmiEntry
->SmiHandlers
;
1349 for (Link
= Head
->ForwardLink
; Link
!= Head
; Link
= Link
->ForwardLink
) {
1350 SmiHandler
= CR (Link
, SMI_HANDLER
, Link
, SMI_HANDLER_SIGNATURE
);
1351 if (SmiHandler
->Handler
== Handler
) {
1352 if ((SearchContext
== NULL
) ||
1353 ((SearchContextSize
== SmiHandler
->ContextSize
) && (CompareMem (SearchContext
, SmiHandler
->Context
, SearchContextSize
) == 0)))
1355 TargetSmiHandler
= SmiHandler
;
1361 if (SearchContext
!= NULL
) {
1362 if (CompareGuid (HandlerGuid
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
1363 FreePool (SearchContext
);
1367 if (TargetSmiHandler
== NULL
) {
1368 return EFI_NOT_FOUND
;
1371 SmiHandler
= TargetSmiHandler
;
1373 RemoveEntryList (&SmiHandler
->Link
);
1374 if (SmiHandler
->Context
!= NULL
) {
1375 FreePool (SmiHandler
->Context
);
1378 FreePool (SmiHandler
);
1380 if (IsListEmpty (&SmiEntry
->SmiHandlers
)) {
1381 RemoveEntryList (&SmiEntry
->AllEntries
);
1382 FreePool (SmiEntry
);
1389 Initialize SmiHandler profile feature.
1392 SmmCoreInitializeSmiHandlerProfile (
1400 if ((PcdGet8 (PcdSmiHandlerProfilePropertyMask
) & 0x1) != 0) {
1401 InsertTailList (&mRootSmiEntryList
, &mRootSmiEntry
.AllEntries
);
1403 Status
= gSmst
->SmmRegisterProtocolNotify (
1404 &gEfiSmmReadyToLockProtocolGuid
,
1405 SmmReadyToLockInSmiHandlerProfile
,
1408 ASSERT_EFI_ERROR (Status
);
1411 Status
= gSmst
->SmmInstallProtocolInterface (
1413 &gSmiHandlerProfileGuid
,
1414 EFI_NATIVE_INTERFACE
,
1417 ASSERT_EFI_ERROR (Status
);