2010-02-26 00:41:19 +01:00
|
|
|
/** @file
|
|
|
|
SMI management.
|
|
|
|
|
2018-02-01 11:14:24 +01:00
|
|
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
2019-04-04 01:05:13 +02:00
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
2010-02-26 00:41:19 +01:00
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include "PiSmmCore.h"
|
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
//
|
|
|
|
// mSmiManageCallingDepth is used to track the depth of recursive calls of SmiManage.
|
|
|
|
//
|
|
|
|
UINTN mSmiManageCallingDepth = 0;
|
|
|
|
|
2024-03-08 06:46:21 +01:00
|
|
|
LIST_ENTRY mSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mSmiEntryList);
|
2010-02-26 00:41:19 +01:00
|
|
|
|
2017-01-20 15:14:40 +01:00
|
|
|
SMI_ENTRY mRootSmiEntry = {
|
|
|
|
SMI_ENTRY_SIGNATURE,
|
|
|
|
INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntry.AllEntries),
|
|
|
|
{ 0 },
|
|
|
|
INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntry.SmiHandlers),
|
|
|
|
};
|
|
|
|
|
2010-02-26 00:41:19 +01:00
|
|
|
/**
|
|
|
|
Finds the SMI entry for the requested handler type.
|
|
|
|
|
|
|
|
@param HandlerType The type of the interrupt
|
|
|
|
@param Create Create a new entry if not found
|
|
|
|
|
|
|
|
@return SMI entry
|
|
|
|
|
|
|
|
**/
|
|
|
|
SMI_ENTRY *
|
|
|
|
EFIAPI
|
|
|
|
SmmCoreFindSmiEntry (
|
|
|
|
IN EFI_GUID *HandlerType,
|
|
|
|
IN BOOLEAN Create
|
|
|
|
)
|
|
|
|
{
|
|
|
|
LIST_ENTRY *Link;
|
|
|
|
SMI_ENTRY *Item;
|
|
|
|
SMI_ENTRY *SmiEntry;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Search the SMI entry list for the matching GUID
|
|
|
|
//
|
|
|
|
SmiEntry = NULL;
|
|
|
|
for (Link = mSmiEntryList.ForwardLink;
|
|
|
|
Link != &mSmiEntryList;
|
|
|
|
Link = Link->ForwardLink)
|
|
|
|
{
|
|
|
|
Item = CR (Link, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);
|
|
|
|
if (CompareGuid (&Item->HandlerType, HandlerType)) {
|
|
|
|
//
|
|
|
|
// This is the SMI entry
|
|
|
|
//
|
|
|
|
SmiEntry = Item;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// If the protocol entry was not found and Create is TRUE, then
|
|
|
|
// allocate a new entry
|
|
|
|
//
|
|
|
|
if ((SmiEntry == NULL) && Create) {
|
|
|
|
SmiEntry = AllocatePool (sizeof (SMI_ENTRY));
|
|
|
|
if (SmiEntry != NULL) {
|
|
|
|
//
|
|
|
|
// Initialize new SMI entry structure
|
|
|
|
//
|
|
|
|
SmiEntry->Signature = SMI_ENTRY_SIGNATURE;
|
|
|
|
CopyGuid ((VOID *)&SmiEntry->HandlerType, HandlerType);
|
|
|
|
InitializeListHead (&SmiEntry->SmiHandlers);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Add it to SMI entry list
|
|
|
|
//
|
|
|
|
InsertTailList (&mSmiEntryList, &SmiEntry->AllEntries);
|
|
|
|
}
|
|
|
|
}
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2010-02-26 00:41:19 +01:00
|
|
|
return SmiEntry;
|
|
|
|
}
|
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
/**
|
|
|
|
Remove SmiHandler and free the memory it used.
|
|
|
|
If SmiEntry is empty, remove SmiEntry and free the memory it used.
|
|
|
|
|
|
|
|
@param SmiHandler Points to SMI handler.
|
|
|
|
@param SmiEntry Points to SMI Entry or NULL for root SMI handlers.
|
|
|
|
|
|
|
|
@retval TRUE SmiEntry is removed.
|
|
|
|
@retval FALSE SmiEntry is not removed.
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
RemoveSmiHandler (
|
|
|
|
IN SMI_HANDLER *SmiHandler,
|
|
|
|
IN SMI_ENTRY *SmiEntry
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ASSERT (SmiHandler->ToRemove);
|
|
|
|
RemoveEntryList (&SmiHandler->Link);
|
|
|
|
FreePool (SmiHandler);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Remove the SMI_ENTRY if all handlers have been removed.
|
|
|
|
//
|
|
|
|
if (SmiEntry != NULL) {
|
|
|
|
if (IsListEmpty (&SmiEntry->SmiHandlers)) {
|
|
|
|
RemoveEntryList (&SmiEntry->AllEntries);
|
|
|
|
FreePool (SmiEntry);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-02-26 00:41:19 +01:00
|
|
|
/**
|
|
|
|
Manage SMI of a particular type.
|
|
|
|
|
|
|
|
@param HandlerType Points to the handler type or NULL for root SMI handlers.
|
|
|
|
@param Context Points to an optional context buffer.
|
|
|
|
@param CommBuffer Points to the optional communication buffer.
|
|
|
|
@param CommBufferSize Points to the size of the optional communication buffer.
|
|
|
|
|
2012-05-31 06:06:13 +02:00
|
|
|
@retval EFI_WARN_INTERRUPT_SOURCE_PENDING Interrupt source was processed successfully but not quiesced.
|
2010-02-26 00:41:19 +01:00
|
|
|
@retval EFI_INTERRUPT_PENDING One or more SMI sources could not be quiesced.
|
2012-05-31 06:06:13 +02:00
|
|
|
@retval EFI_NOT_FOUND Interrupt source was not handled or quiesced.
|
|
|
|
@retval EFI_SUCCESS Interrupt source was handled and quiesced.
|
2010-02-26 00:41:19 +01:00
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SmiManage (
|
|
|
|
IN CONST EFI_GUID *HandlerType,
|
|
|
|
IN CONST VOID *Context OPTIONAL,
|
|
|
|
IN OUT VOID *CommBuffer OPTIONAL,
|
|
|
|
IN OUT UINTN *CommBufferSize OPTIONAL
|
|
|
|
)
|
|
|
|
{
|
|
|
|
LIST_ENTRY *Link;
|
|
|
|
LIST_ENTRY *Head;
|
2024-03-11 08:32:19 +01:00
|
|
|
LIST_ENTRY *EntryLink;
|
2010-02-26 00:41:19 +01:00
|
|
|
SMI_ENTRY *SmiEntry;
|
|
|
|
SMI_HANDLER *SmiHandler;
|
2024-03-11 08:32:19 +01:00
|
|
|
EFI_STATUS ReturnStatus;
|
|
|
|
BOOLEAN WillReturn;
|
2010-02-26 00:41:19 +01:00
|
|
|
EFI_STATUS Status;
|
2018-06-27 15:08:52 +02:00
|
|
|
|
2023-05-26 16:32:00 +02:00
|
|
|
PERF_FUNCTION_BEGIN ();
|
2024-03-11 08:32:19 +01:00
|
|
|
mSmiManageCallingDepth++;
|
|
|
|
Status = EFI_NOT_FOUND;
|
|
|
|
ReturnStatus = Status;
|
2010-02-26 00:41:19 +01:00
|
|
|
if (HandlerType == NULL) {
|
|
|
|
//
|
|
|
|
// Root SMI handler
|
|
|
|
//
|
2017-01-20 15:14:40 +01:00
|
|
|
SmiEntry = &mRootSmiEntry;
|
2012-05-31 06:06:13 +02:00
|
|
|
} else {
|
2010-02-26 00:41:19 +01:00
|
|
|
//
|
2012-05-31 06:06:13 +02:00
|
|
|
// Non-root SMI handler
|
2010-02-26 00:41:19 +01:00
|
|
|
//
|
2012-05-31 06:06:13 +02:00
|
|
|
SmiEntry = SmmCoreFindSmiEntry ((EFI_GUID *)HandlerType, FALSE);
|
|
|
|
if (SmiEntry == NULL) {
|
|
|
|
//
|
|
|
|
// There is no handler registered for this interrupt source
|
|
|
|
//
|
2023-05-26 16:32:00 +02:00
|
|
|
PERF_FUNCTION_END ();
|
2012-05-31 06:06:13 +02:00
|
|
|
return Status;
|
|
|
|
}
|
2010-02-26 00:41:19 +01:00
|
|
|
}
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2017-01-20 15:14:40 +01:00
|
|
|
Head = &SmiEntry->SmiHandlers;
|
2010-02-26 00:41:19 +01:00
|
|
|
|
2024-03-08 06:46:23 +01:00
|
|
|
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
|
2010-02-26 00:41:19 +01:00
|
|
|
SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);
|
2024-03-08 06:46:21 +01:00
|
|
|
|
|
|
|
Status = SmiHandler->Handler (
|
|
|
|
(EFI_HANDLE)SmiHandler,
|
|
|
|
Context,
|
|
|
|
CommBuffer,
|
|
|
|
CommBufferSize
|
|
|
|
);
|
2010-02-26 00:41:19 +01:00
|
|
|
|
|
|
|
switch (Status) {
|
|
|
|
case EFI_INTERRUPT_PENDING:
|
|
|
|
//
|
2013-02-20 04:38:10 +01:00
|
|
|
// If a handler returns EFI_INTERRUPT_PENDING and HandlerType is not NULL then
|
|
|
|
// no additional handlers will be processed and EFI_INTERRUPT_PENDING will be returned.
|
2010-02-26 00:41:19 +01:00
|
|
|
//
|
2012-10-16 10:57:52 +02:00
|
|
|
if (HandlerType != NULL) {
|
2023-05-26 16:32:00 +02:00
|
|
|
PERF_FUNCTION_END ();
|
2024-03-11 08:32:19 +01:00
|
|
|
ReturnStatus = EFI_INTERRUPT_PENDING;
|
|
|
|
WillReturn = TRUE;
|
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// If any other handler's result sets ReturnStatus as EFI_SUCCESS, the return status
|
|
|
|
// will be EFI_SUCCESS.
|
|
|
|
//
|
|
|
|
if (ReturnStatus != EFI_SUCCESS) {
|
|
|
|
ReturnStatus = Status;
|
|
|
|
}
|
2012-10-16 10:57:52 +02:00
|
|
|
}
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2012-10-16 10:57:52 +02:00
|
|
|
break;
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2010-02-26 00:41:19 +01:00
|
|
|
case EFI_SUCCESS:
|
|
|
|
//
|
2013-02-20 04:38:10 +01:00
|
|
|
// If at least one of the handlers returns EFI_SUCCESS then the function will return
|
|
|
|
// EFI_SUCCESS. If a handler returns EFI_SUCCESS and HandlerType is not NULL then no
|
|
|
|
// additional handlers will be processed.
|
2010-02-26 00:41:19 +01:00
|
|
|
//
|
2012-10-16 10:57:52 +02:00
|
|
|
if (HandlerType != NULL) {
|
2023-05-26 16:32:00 +02:00
|
|
|
PERF_FUNCTION_END ();
|
2024-03-11 08:32:19 +01:00
|
|
|
WillReturn = TRUE;
|
2012-10-16 10:57:52 +02:00
|
|
|
}
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
ReturnStatus = EFI_SUCCESS;
|
2012-10-16 10:57:52 +02:00
|
|
|
break;
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2010-02-26 00:41:19 +01:00
|
|
|
case EFI_WARN_INTERRUPT_SOURCE_QUIESCED:
|
|
|
|
//
|
2012-05-31 06:06:13 +02:00
|
|
|
// If at least one of the handlers returns EFI_WARN_INTERRUPT_SOURCE_QUIESCED
|
2018-06-27 15:08:52 +02:00
|
|
|
// then the function will return EFI_SUCCESS.
|
2010-02-26 00:41:19 +01:00
|
|
|
//
|
2024-03-11 08:32:19 +01:00
|
|
|
ReturnStatus = EFI_SUCCESS;
|
2010-02-26 00:41:19 +01:00
|
|
|
break;
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2012-05-31 06:06:13 +02:00
|
|
|
case EFI_WARN_INTERRUPT_SOURCE_PENDING:
|
|
|
|
//
|
|
|
|
// If all the handlers returned EFI_WARN_INTERRUPT_SOURCE_PENDING
|
|
|
|
// then EFI_WARN_INTERRUPT_SOURCE_PENDING will be returned.
|
|
|
|
//
|
2024-03-11 08:32:19 +01:00
|
|
|
if (ReturnStatus != EFI_SUCCESS) {
|
|
|
|
ReturnStatus = Status;
|
|
|
|
}
|
|
|
|
|
2012-05-31 06:06:13 +02:00
|
|
|
break;
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2010-02-26 00:41:19 +01:00
|
|
|
default:
|
2012-05-31 06:06:13 +02:00
|
|
|
//
|
|
|
|
// Unexpected status code returned.
|
|
|
|
//
|
|
|
|
ASSERT (FALSE);
|
2010-02-26 00:41:19 +01:00
|
|
|
break;
|
|
|
|
}
|
2024-03-11 08:32:19 +01:00
|
|
|
|
|
|
|
if (WillReturn) {
|
|
|
|
break;
|
|
|
|
}
|
2010-02-26 00:41:19 +01:00
|
|
|
}
|
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
ASSERT (mSmiManageCallingDepth > 0);
|
|
|
|
mSmiManageCallingDepth--;
|
|
|
|
|
|
|
|
//
|
|
|
|
// SmiHandlerUnRegister() calls from SMI handlers are deferred till this point.
|
|
|
|
// Before returned from SmiManage, delete the SmiHandler which is
|
|
|
|
// marked as ToRemove.
|
|
|
|
// Note that SmiManage can be called recursively.
|
|
|
|
//
|
|
|
|
if (mSmiManageCallingDepth == 0) {
|
|
|
|
//
|
|
|
|
// Go through all SmiHandler in root SMI handlers
|
|
|
|
//
|
|
|
|
for ( Link = GetFirstNode (&mRootSmiEntry.SmiHandlers)
|
|
|
|
; !IsNull (&mRootSmiEntry.SmiHandlers, Link);
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// SmiHandler might be removed in below, so cache the next link in Link
|
|
|
|
//
|
|
|
|
SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);
|
|
|
|
Link = GetNextNode (&mRootSmiEntry.SmiHandlers, Link);
|
|
|
|
if (SmiHandler->ToRemove) {
|
|
|
|
//
|
|
|
|
// Remove SmiHandler if the ToRemove is set.
|
|
|
|
//
|
|
|
|
RemoveSmiHandler (SmiHandler, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Go through all SmiHandler in non-root SMI handlers
|
|
|
|
//
|
|
|
|
for ( EntryLink = GetFirstNode (&mSmiEntryList)
|
|
|
|
; !IsNull (&mSmiEntryList, EntryLink);
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// SmiEntry might be removed in below, so cache the next link in EntryLink
|
|
|
|
//
|
|
|
|
SmiEntry = CR (EntryLink, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);
|
|
|
|
EntryLink = GetNextNode (&mSmiEntryList, EntryLink);
|
|
|
|
for ( Link = GetFirstNode (&SmiEntry->SmiHandlers)
|
|
|
|
; !IsNull (&SmiEntry->SmiHandlers, Link);
|
|
|
|
)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// SmiHandler might be removed in below, so cache the next link in Link
|
|
|
|
//
|
|
|
|
SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);
|
|
|
|
Link = GetNextNode (&SmiEntry->SmiHandlers, Link);
|
|
|
|
if (SmiHandler->ToRemove) {
|
|
|
|
if (RemoveSmiHandler (SmiHandler, SmiEntry)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-02-26 00:41:19 +01:00
|
|
|
}
|
2012-05-31 06:06:13 +02:00
|
|
|
|
2023-05-26 16:32:00 +02:00
|
|
|
PERF_FUNCTION_END ();
|
2024-03-11 08:32:19 +01:00
|
|
|
return ReturnStatus;
|
2010-02-26 00:41:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Registers a handler to execute within SMM.
|
|
|
|
|
2020-02-07 02:07:30 +01:00
|
|
|
@param Handler Handler service function pointer.
|
2010-02-26 00:41:19 +01:00
|
|
|
@param HandlerType Points to the handler type or NULL for root SMI handlers.
|
|
|
|
@param DispatchHandle On return, contains a unique handle which can be used to later unregister the handler function.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Handler register success.
|
|
|
|
@retval EFI_INVALID_PARAMETER Handler or DispatchHandle is NULL.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SmiHandlerRegister (
|
|
|
|
IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler,
|
|
|
|
IN CONST EFI_GUID *HandlerType OPTIONAL,
|
|
|
|
OUT EFI_HANDLE *DispatchHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SMI_HANDLER *SmiHandler;
|
|
|
|
SMI_ENTRY *SmiEntry;
|
|
|
|
LIST_ENTRY *List;
|
|
|
|
|
|
|
|
if ((Handler == NULL) || (DispatchHandle == NULL)) {
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
SmiHandler = AllocateZeroPool (sizeof (SMI_HANDLER));
|
|
|
|
if (SmiHandler == NULL) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
SmiHandler->Signature = SMI_HANDLER_SIGNATURE;
|
|
|
|
SmiHandler->Handler = Handler;
|
2017-01-20 15:14:40 +01:00
|
|
|
SmiHandler->CallerAddr = (UINTN)RETURN_ADDRESS (0);
|
2024-03-11 08:32:19 +01:00
|
|
|
SmiHandler->ToRemove = FALSE;
|
2010-02-26 00:41:19 +01:00
|
|
|
|
|
|
|
if (HandlerType == NULL) {
|
|
|
|
//
|
|
|
|
// This is root SMI handler
|
|
|
|
//
|
2017-01-20 15:14:40 +01:00
|
|
|
SmiEntry = &mRootSmiEntry;
|
2010-02-26 00:41:19 +01:00
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// None root SMI handler
|
|
|
|
//
|
|
|
|
SmiEntry = SmmCoreFindSmiEntry ((EFI_GUID *)HandlerType, TRUE);
|
|
|
|
if (SmiEntry == NULL) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
}
|
2021-12-05 23:54:02 +01:00
|
|
|
|
2017-01-20 15:14:40 +01:00
|
|
|
List = &SmiEntry->SmiHandlers;
|
2010-02-26 00:41:19 +01:00
|
|
|
|
|
|
|
SmiHandler->SmiEntry = SmiEntry;
|
|
|
|
InsertTailList (List, &SmiHandler->Link);
|
|
|
|
|
|
|
|
*DispatchHandle = (EFI_HANDLE)SmiHandler;
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Unregister a handler in SMM.
|
|
|
|
|
|
|
|
@param DispatchHandle The handle that was specified when the handler was registered.
|
|
|
|
|
|
|
|
@retval EFI_SUCCESS Handler function was successfully unregistered.
|
|
|
|
@retval EFI_INVALID_PARAMETER DispatchHandle does not refer to a valid handle.
|
|
|
|
|
|
|
|
**/
|
|
|
|
EFI_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SmiHandlerUnRegister (
|
|
|
|
IN EFI_HANDLE DispatchHandle
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SMI_HANDLER *SmiHandler;
|
|
|
|
SMI_ENTRY *SmiEntry;
|
2018-02-01 11:14:24 +01:00
|
|
|
LIST_ENTRY *EntryLink;
|
|
|
|
LIST_ENTRY *HandlerLink;
|
2010-02-26 00:41:19 +01:00
|
|
|
|
2018-02-01 11:14:24 +01:00
|
|
|
if (DispatchHandle == NULL) {
|
2010-02-26 00:41:19 +01:00
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2018-02-01 11:14:24 +01:00
|
|
|
//
|
|
|
|
// Look for it in root SMI handlers
|
|
|
|
//
|
|
|
|
SmiHandler = NULL;
|
|
|
|
for ( HandlerLink = GetFirstNode (&mRootSmiEntry.SmiHandlers)
|
2019-09-13 00:29:43 +02:00
|
|
|
; !IsNull (&mRootSmiEntry.SmiHandlers, HandlerLink) && ((EFI_HANDLE)SmiHandler != DispatchHandle)
|
2018-02-01 11:14:24 +01:00
|
|
|
; HandlerLink = GetNextNode (&mRootSmiEntry.SmiHandlers, HandlerLink)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SmiHandler = CR (HandlerLink, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Look for it in non-root SMI handlers
|
|
|
|
//
|
|
|
|
for ( EntryLink = GetFirstNode (&mSmiEntryList)
|
2019-09-13 00:29:43 +02:00
|
|
|
; !IsNull (&mSmiEntryList, EntryLink) && ((EFI_HANDLE)SmiHandler != DispatchHandle)
|
2018-02-01 11:14:24 +01:00
|
|
|
; EntryLink = GetNextNode (&mSmiEntryList, EntryLink)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SmiEntry = CR (EntryLink, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);
|
|
|
|
for ( HandlerLink = GetFirstNode (&SmiEntry->SmiHandlers)
|
2019-09-13 00:29:43 +02:00
|
|
|
; !IsNull (&SmiEntry->SmiHandlers, HandlerLink) && ((EFI_HANDLE)SmiHandler != DispatchHandle)
|
2018-02-01 11:14:24 +01:00
|
|
|
; HandlerLink = GetNextNode (&SmiEntry->SmiHandlers, HandlerLink)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
SmiHandler = CR (HandlerLink, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
if (SmiHandler == NULL) {
|
2010-02-26 00:41:19 +01:00
|
|
|
return EFI_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
ASSERT ((EFI_HANDLE)SmiHandler == DispatchHandle);
|
|
|
|
SmiHandler->ToRemove = TRUE;
|
2010-02-26 00:41:19 +01:00
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
if (mSmiManageCallingDepth > 0) {
|
2010-02-26 00:41:19 +01:00
|
|
|
//
|
2024-03-11 08:32:19 +01:00
|
|
|
// This function is called from SmiManage()
|
|
|
|
// Do not delete or remove SmiHandler or SmiEntry now.
|
|
|
|
// SmiManage will handle it later
|
2010-02-26 00:41:19 +01:00
|
|
|
//
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
SmiEntry = SmiHandler->SmiEntry;
|
2010-02-26 00:41:19 +01:00
|
|
|
|
2024-03-11 08:32:19 +01:00
|
|
|
//
|
|
|
|
// For root SMI handler, use NULL for SmiEntry
|
|
|
|
//
|
|
|
|
RemoveSmiHandler (SmiHandler, (SmiEntry == &mRootSmiEntry) ? NULL : SmiEntry);
|
2010-02-26 00:41:19 +01:00
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|