summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-13 01:57:22 +0000
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>2010-02-13 01:57:22 +0000
commit0803854bc1e211dded35c5c02d0428285a2da407 (patch)
treeeb61c7af73a057d64ca6a44a2157c880c6cd10ad
parent60428d0000da41bb55b41984f785761fcd6320be (diff)
downloadedk2-0803854bc1e211dded35c5c02d0428285a2da407.zip
edk2-0803854bc1e211dded35c5c02d0428285a2da407.tar.gz
edk2-0803854bc1e211dded35c5c02d0428285a2da407.tar.bz2
Update DXE Core to be compatible with PI 1.2 SMM Drivers.
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
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.h5
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.inf1
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c5
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c31
-rw-r--r--MdeModulePkg/Core/Dxe/Event/Tpl.c25
5 files changed, 44 insertions, 23 deletions
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h
index 2f7f8b5..6a005be 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.h
+++ b/MdeModulePkg/Core/Dxe/DxeMain.h
@@ -2,7 +2,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by DxeCore module.
-Copyright (c) 2006 - 2009, Intel Corporation. <BR>
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -50,6 +50,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/BusSpecificDriverOverride.h>
#include <Protocol/TcgService.h>
#include <Protocol/HiiPackageList.h>
+#include <Protocol/SmmBase2.h>
#include <Guid/MemoryTypeInformation.h>
#include <Guid/FirmwareFileSystem2.h>
#include <Guid/HobList.h>
@@ -116,6 +117,7 @@ typedef struct {
EFI_EVENT Event;
VOID *Registration;
BOOLEAN Present;
+ BOOLEAN ArchitecturalProtocol;
} ARCHITECTURAL_PROTOCOL_ENTRY;
//
@@ -194,6 +196,7 @@ extern EFI_METRONOME_ARCH_PROTOCOL *gMetronome;
extern EFI_TIMER_ARCH_PROTOCOL *gTimer;
extern EFI_SECURITY_ARCH_PROTOCOL *gSecurity;
extern EFI_BDS_ARCH_PROTOCOL *gBds;
+extern EFI_SMM_BASE2_PROTOCOL *gSmmBase2;
extern EFI_TPL gEfiCurrentTpl;
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf
index 5da6f14..379cd8d 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain.inf
+++ b/MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -136,6 +136,7 @@
gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES
gEfiEbcProtocolGuid ## SOMETIMES_CONSUMES
gEfiLoadedImageDevicePathProtocolGuid ## PRODUCES
+ gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES
[FeaturePcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index cd2368e..36a7ec6 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -30,6 +30,11 @@ EFI_BDS_ARCH_PROTOCOL *gBds = NULL;
EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL;
//
+// DXE Core globals for optional protocol dependencies
+//
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2 = NULL;
+
+//
// DXE Core Global used to update core loaded image protocol handle
//
EFI_GUID *gDxeCoreFileName;
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
index f67f03a..3b805a9 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c
@@ -3,7 +3,7 @@
the Dxe Core. The mArchProtocols[] array represents a list of
events that represent the Architectural Protocols.
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -27,19 +27,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
ARCHITECTURAL_PROTOCOL_ENTRY mArchProtocols[] = {
- { &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE },
- { &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE },
- { &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE },
- { &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL, NULL, FALSE },
- { &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL, NULL, FALSE },
- { &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },
- { &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL, NULL, FALSE },
- { &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE },
- { &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }
+ { &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE, TRUE },
+ { &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE, TRUE },
+ { &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE, TRUE },
+ { &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL, NULL, FALSE, TRUE },
+ { &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL, NULL, FALSE, TRUE },
+ { &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL, NULL, FALSE, TRUE },
+ { &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL, NULL, FALSE, TRUE },
+ { &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE, TRUE },
+ { &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE, TRUE },
+ { &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE, TRUE },
+ { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE, TRUE },
+ { &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE, TRUE },
+ { &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE, TRUE },
+ { &gEfiSmmBase2ProtocolGuid, (VOID **)&gSmmBase2, NULL, NULL, FALSE, FALSE }
};
//
@@ -81,7 +82,7 @@ CoreAllEfiServicesAvailable (
UINTN Index;
for (Index = 0; Index < sizeof (mArchProtocols) / sizeof (mArchProtocols[0]); Index++) {
- if (!mArchProtocols[Index].Present) {
+ if (mArchProtocols[Index].ArchitecturalProtocol && !mArchProtocols[Index].Present) {
return EFI_NOT_FOUND;
}
}
diff --git a/MdeModulePkg/Core/Dxe/Event/Tpl.c b/MdeModulePkg/Core/Dxe/Event/Tpl.c
index dd9c57e..265204f 100644
--- a/MdeModulePkg/Core/Dxe/Event/Tpl.c
+++ b/MdeModulePkg/Core/Dxe/Event/Tpl.c
@@ -1,7 +1,7 @@
/** @file
Task priority (TPL) functions.
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -26,12 +26,23 @@ CoreSetInterruptState (
IN BOOLEAN Enable
)
{
- if (gCpu != NULL) {
- if (Enable) {
- gCpu->EnableInterrupt(gCpu);
- } else {
- gCpu->DisableInterrupt(gCpu);
- }
+ EFI_STATUS Status;
+ BOOLEAN InSmm;
+
+ if (gCpu == NULL) {
+ return;
+ }
+ if (!Enable) {
+ gCpu->DisableInterrupt (gCpu);
+ return;
+ }
+ if (gSmmBase2 == NULL) {
+ gCpu->EnableInterrupt (gCpu);
+ return;
+ }
+ Status = gSmmBase2->InSmm (gSmmBase2, &InSmm);
+ if (!EFI_ERROR (Status) && !InSmm) {
+ gCpu->EnableInterrupt(gCpu);
}
}