]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Smi.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Smi.c
index 1868bbf9e195be969ba07a220ea3b3bdd34ad6b0..f8bd9f49ee3c5d393e3e39b49c58f1e21d5940ff 100644 (file)
@@ -1,45 +1,22 @@
 /** @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
@@ -128,17 +105,16 @@ SmiManage (
   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
@@ -150,9 +126,8 @@ SmiManage (
       //\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
@@ -167,24 +142,32 @@ SmiManage (
     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
@@ -203,7 +186,7 @@ SmiManage (
     }\r
   }\r
 \r
-  if (InterruptQuiesced) {\r
+  if (SuccessReturn) {\r
     Status = EFI_SUCCESS;\r
   }\r
 \r
@@ -244,13 +227,13 @@ SmiHandlerRegister (
 \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
@@ -259,9 +242,8 @@ SmiHandlerRegister (
     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
@@ -288,14 +270,41 @@ SmiHandlerUnRegister (
 {\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