]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Update DXE Core to be compatible with PI 1.2 SMM Drivers.
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 13 Feb 2010 01:57:22 +0000 (01:57 +0000)
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Sat, 13 Feb 2010 01:57:22 +0000 (01:57 +0000)
PI 1.2 SMM Drivers are allowed to call UEFI/DXE services and Protocols from the entry point of the PI 1.2 SMM Driver.  These UEFI/DXE services and Protocols may directly or indirectly calls the UEFI Boot Services RaiseTPL() and RestoreTPL().  These UEFI Boot Services use the CPU Architectural Protocol to enable interrupts if the TPL level is below TPL_HIGH_LEVEL and enable interrupts of the TPL is at TPL_HIGH_LEVEL.  Interrupts should be masked while executing SMM drivers, so if a direct or indirect call to the UEFI Boot Service RestoreTPL() would enable interrupts, then an interrupt could be incorrectly delivered in SMM context.

The solution is for the DXE Core to register for the PI 1.2 SMM Base2 Protocol.  If that protocol is present in the platform, then the DXE Core can use the SMM Base 2 Protocol's InSmm() function to determine if the platform is currently executing in SMM content.  If the current context is in SMM, then do not allow any requests to be forwarded to the CPU Architecture Protocol to enable interrupts.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9997 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Core/Dxe/DxeMain.h
MdeModulePkg/Core/Dxe/DxeMain.inf
MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
MdeModulePkg/Core/Dxe/Event/Tpl.c

index 2f7f8b5ea0a6395caf0585f1045049d1d631ce2c..6a005be8d12d7e9fed94985a46dc1744adc389f8 100644 (file)
@@ -2,7 +2,7 @@
   The internal header file includes the common header files, defines\r
   internal structure and functions used by DxeCore module.\r
 \r
-Copyright (c) 2006 - 2009, Intel Corporation. <BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -50,6 +50,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/BusSpecificDriverOverride.h>\r
 #include <Protocol/TcgService.h>\r
 #include <Protocol/HiiPackageList.h>\r
+#include <Protocol/SmmBase2.h>\r
 #include <Guid/MemoryTypeInformation.h>\r
 #include <Guid/FirmwareFileSystem2.h>\r
 #include <Guid/HobList.h>\r
@@ -116,6 +117,7 @@ typedef struct {
   EFI_EVENT                   Event;\r
   VOID                        *Registration;\r
   BOOLEAN                     Present;\r
+  BOOLEAN                     ArchitecturalProtocol;\r
 } ARCHITECTURAL_PROTOCOL_ENTRY;\r
 \r
 //\r
@@ -194,6 +196,7 @@ extern EFI_METRONOME_ARCH_PROTOCOL              *gMetronome;
 extern EFI_TIMER_ARCH_PROTOCOL                  *gTimer;\r
 extern EFI_SECURITY_ARCH_PROTOCOL               *gSecurity;\r
 extern EFI_BDS_ARCH_PROTOCOL                    *gBds;\r
+extern EFI_SMM_BASE2_PROTOCOL                   *gSmmBase2;\r
 \r
 extern EFI_TPL                                  gEfiCurrentTpl;\r
 \r
index 5da6f148d98f2ab061fe9316332740f20f251f72..379cd8dafd12e02e34611d5a83985d0a59fb87d8 100644 (file)
   gEfiHiiPackageListProtocolGuid                ## SOMETIMES_PRODUCES\r
   gEfiEbcProtocolGuid                           ## SOMETIMES_CONSUMES\r
   gEfiLoadedImageDevicePathProtocolGuid         ## PRODUCES\r
+  gEfiSmmBase2ProtocolGuid                      ## SOMETIMES_CONSUMES\r
 \r
 [FeaturePcd.common]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport         ## CONSUMES\r
index cd2368e570a758e666bec22bfd584016782b57b7..36a7ec6be6ba8b80cb4c93027ff7d6f4308efefe 100644 (file)
@@ -29,6 +29,11 @@ EFI_TIMER_ARCH_PROTOCOL           *gTimer         = NULL;
 EFI_BDS_ARCH_PROTOCOL             *gBds           = NULL;\r
 EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *gWatchdogTimer = NULL;\r
 \r
+//\r
+// DXE Core globals for optional protocol dependencies\r
+//\r
+EFI_SMM_BASE2_PROTOCOL            *gSmmBase2      = NULL;\r
+\r
 //\r
 // DXE Core Global used to update core loaded image protocol handle\r
 //\r
index f67f03a835b8e68521d73534129cccb8e993a5fc..3b805a9f9d5573bc3c0250e1a5b3fafa8e7731f5 100644 (file)
@@ -3,7 +3,7 @@
   the Dxe Core. The mArchProtocols[] array represents a list of\r
   events that represent the Architectural Protocols.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -27,19 +27,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 \r
 ARCHITECTURAL_PROTOCOL_ENTRY  mArchProtocols[] = {\r
-  { &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE },\r
-  { &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE },\r
-  { &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE },\r
-  { &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE },\r
-  { &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE },\r
-  { &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },\r
-  { &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE },\r
-  { &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE },\r
-  { &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },\r
-  { &gEfiCapsuleArchProtocolGuid,          (VOID **)NULL,            NULL, NULL, FALSE },\r
-  { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE },\r
-  { &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE },\r
-  { &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE }\r
+  { &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiCapsuleArchProtocolGuid,          (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE, TRUE  },\r
+  { &gEfiSmmBase2ProtocolGuid,             (VOID **)&gSmmBase2,      NULL, NULL, FALSE, FALSE }\r
 };\r
 \r
 //\r
@@ -81,7 +82,7 @@ CoreAllEfiServicesAvailable (
   UINTN        Index;\r
 \r
   for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {\r
-    if (!mArchProtocols[Index].Present) {\r
+    if (mArchProtocols[Index].ArchitecturalProtocol && !mArchProtocols[Index].Present) {\r
       return EFI_NOT_FOUND;\r
     }\r
   }\r
index dd9c57e1d3d139779a6220de30b55a4945aeda45..265204f3160d591e4860ab8ba747f6c6c16ad27b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Task priority (TPL) functions.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -26,12 +26,23 @@ CoreSetInterruptState (
   IN BOOLEAN      Enable\r
   )\r
 {\r
-  if (gCpu != NULL) {\r
-    if (Enable) {\r
-      gCpu->EnableInterrupt(gCpu);\r
-    } else {\r
-      gCpu->DisableInterrupt(gCpu);\r
-    }\r
+  EFI_STATUS  Status;\r
+  BOOLEAN     InSmm;\r
+  \r
+  if (gCpu == NULL) {\r
+    return;\r
+  }\r
+  if (!Enable) {\r
+    gCpu->DisableInterrupt (gCpu);\r
+    return;\r
+  }\r
+  if (gSmmBase2 == NULL) {\r
+    gCpu->EnableInterrupt (gCpu);\r
+    return;\r
+  }\r
+  Status = gSmmBase2->InSmm (gSmmBase2, &InSmm);\r
+  if (!EFI_ERROR (Status) && !InSmm) {\r
+    gCpu->EnableInterrupt(gCpu);\r
   }\r
 }\r
 \r