/** @file\r
SMI management.\r
\r
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials are licensed and made available \r
- under the terms and conditions of the BSD License which accompanies this \r
- distribution. The full text of the license may be found at \r
- http://opensource.org/licenses/bsd-license.php \r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "PiSmmCore.h"\r
\r
-//\r
-// SMM_HANDLER - used for each SMM handler\r
-//\r
-\r
-#define SMI_ENTRY_SIGNATURE SIGNATURE_32('s','m','i','e')\r
-\r
- typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY AllEntries; // All entries\r
-\r
- EFI_GUID HandlerType; // Type of interrupt\r
- LIST_ENTRY SmiHandlers; // All handlers\r
-} SMI_ENTRY;\r
-\r
-#define SMI_HANDLER_SIGNATURE SIGNATURE_32('s','m','i','h')\r
-\r
- typedef struct {\r
- UINTN Signature;\r
- LIST_ENTRY Link; // Link on SMI_ENTRY.SmiHandlers\r
- EFI_SMM_HANDLER_ENTRY_POINT2 Handler; // The smm handler's entry point\r
- SMI_ENTRY *SmiEntry;\r
-} SMI_HANDLER;\r
-\r
-LIST_ENTRY mRootSmiHandlerList = INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiHandlerList);\r
LIST_ENTRY mSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mSmiEntryList);\r
\r
+SMI_ENTRY mRootSmiEntry = {\r
+ SMI_ENTRY_SIGNATURE,\r
+ INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntry.AllEntries),\r
+ {0},\r
+ INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntry.SmiHandlers),\r
+};\r
+\r
/**\r
Finds the SMI entry for the requested handler type.\r
\r
LIST_ENTRY *Head;\r
SMI_ENTRY *SmiEntry;\r
SMI_HANDLER *SmiHandler;\r
- BOOLEAN InterruptQuiesced;\r
+ BOOLEAN SuccessReturn;\r
EFI_STATUS Status;\r
- \r
+\r
Status = EFI_NOT_FOUND;\r
- InterruptQuiesced = FALSE;\r
+ SuccessReturn = FALSE;\r
if (HandlerType == NULL) {\r
//\r
// Root SMI handler\r
//\r
-\r
- Head = &mRootSmiHandlerList;\r
+ SmiEntry = &mRootSmiEntry;\r
} else {\r
//\r
// Non-root SMI handler\r
//\r
return Status;\r
}\r
-\r
- Head = &SmiEntry->SmiHandlers;\r
}\r
+ Head = &SmiEntry->SmiHandlers;\r
\r
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {\r
SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
switch (Status) {\r
case EFI_INTERRUPT_PENDING:\r
//\r
- // If a handler returns EFI_INTERRUPT_PENDING then no additional handlers \r
- // will be processed and EFI_INTERRUPT_PENDING will be returned.\r
+ // If a handler returns EFI_INTERRUPT_PENDING and HandlerType is not NULL then\r
+ // no additional handlers will be processed and EFI_INTERRUPT_PENDING will be returned.\r
//\r
- return EFI_INTERRUPT_PENDING;\r
+ if (HandlerType != NULL) {\r
+ return EFI_INTERRUPT_PENDING;\r
+ }\r
+ break;\r
\r
case EFI_SUCCESS:\r
//\r
- // If a handler returns EFI_SUCCESS then no additional handlers will be processed.\r
- // then the function will return EFI_SUCCESS.\r
+ // If at least one of the handlers returns EFI_SUCCESS then the function will return\r
+ // EFI_SUCCESS. If a handler returns EFI_SUCCESS and HandlerType is not NULL then no\r
+ // additional handlers will be processed.\r
//\r
- return EFI_SUCCESS;\r
+ if (HandlerType != NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ SuccessReturn = TRUE;\r
+ break;\r
\r
case EFI_WARN_INTERRUPT_SOURCE_QUIESCED:\r
//\r
// If at least one of the handlers returns EFI_WARN_INTERRUPT_SOURCE_QUIESCED\r
- // then the function will return EFI_SUCCESS. \r
+ // then the function will return EFI_SUCCESS.\r
//\r
- InterruptQuiesced = TRUE;\r
+ SuccessReturn = TRUE;\r
break;\r
\r
case EFI_WARN_INTERRUPT_SOURCE_PENDING:\r
}\r
}\r
\r
- if (InterruptQuiesced) {\r
+ if (SuccessReturn) {\r
Status = EFI_SUCCESS;\r
}\r
\r
\r
SmiHandler->Signature = SMI_HANDLER_SIGNATURE;\r
SmiHandler->Handler = Handler;\r
+ SmiHandler->CallerAddr = (UINTN)RETURN_ADDRESS (0);\r
\r
if (HandlerType == NULL) {\r
//\r
// This is root SMI handler\r
//\r
- SmiEntry = NULL;\r
- List = &mRootSmiHandlerList;\r
+ SmiEntry = &mRootSmiEntry;\r
} else {\r
//\r
// None root SMI handler\r
if (SmiEntry == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
-\r
- List = &SmiEntry->SmiHandlers;\r
}\r
+ List = &SmiEntry->SmiHandlers;\r
\r
SmiHandler->SmiEntry = SmiEntry;\r
InsertTailList (List, &SmiHandler->Link);\r
{\r
SMI_HANDLER *SmiHandler;\r
SMI_ENTRY *SmiEntry;\r
+ LIST_ENTRY *EntryLink;\r
+ LIST_ENTRY *HandlerLink;\r
\r
- SmiHandler = (SMI_HANDLER *) DispatchHandle;\r
-\r
- if (SmiHandler == NULL) {\r
+ if (DispatchHandle == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (SmiHandler->Signature != SMI_HANDLER_SIGNATURE) {\r
+ //\r
+ // Look for it in root SMI handlers\r
+ //\r
+ SmiHandler = NULL;\r
+ for ( HandlerLink = GetFirstNode (&mRootSmiEntry.SmiHandlers)\r
+ ; !IsNull (&mRootSmiEntry.SmiHandlers, HandlerLink) && (SmiHandler != DispatchHandle)\r
+ ; HandlerLink = GetNextNode (&mRootSmiEntry.SmiHandlers, HandlerLink)\r
+ ) {\r
+ SmiHandler = CR (HandlerLink, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
+ }\r
+\r
+ //\r
+ // Look for it in non-root SMI handlers\r
+ //\r
+ for ( EntryLink = GetFirstNode (&mSmiEntryList)\r
+ ; !IsNull (&mSmiEntryList, EntryLink) && (SmiHandler != DispatchHandle)\r
+ ; EntryLink = GetNextNode (&mSmiEntryList, EntryLink)\r
+ ) {\r
+ SmiEntry = CR (EntryLink, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);\r
+ for ( HandlerLink = GetFirstNode (&SmiEntry->SmiHandlers)\r
+ ; !IsNull (&SmiEntry->SmiHandlers, HandlerLink) && (SmiHandler != DispatchHandle)\r
+ ; HandlerLink = GetNextNode (&SmiEntry->SmiHandlers, HandlerLink)\r
+ ) {\r
+ SmiHandler = CR (HandlerLink, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE);\r
+ }\r
+ }\r
+\r
+ if (SmiHandler != DispatchHandle) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r