summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Compatibility
diff options
context:
space:
mode:
authorrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>2009-12-31 08:42:28 +0000
committerrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>2009-12-31 08:42:28 +0000
commit9e620719100f80892adfa8e2f810a485bce32fb9 (patch)
tree23f2cf4fd9ab14e563539569e7b143e7986c4f1d /EdkCompatibilityPkg/Compatibility
parenta77e0eb17aecf3c4504e526063771eb8b4cc0968 (diff)
downloadedk2-platforms-9e620719100f80892adfa8e2f810a485bce32fb9.tar.xz
Add 4 Framework/PI SMM thunk drivers. Combined use of these drivers can support usage model of PI SMM infrastructure + Framework Chipset SMM code + Framework platform SMM code in ECP platforms.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9657 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkCompatibilityPkg/Compatibility')
-rw-r--r--EdkCompatibilityPkg/Compatibility/Include/Guid/SmmBaseThunkCommunication.h85
-rw-r--r--EdkCompatibilityPkg/Compatibility/Include/Protocol/SmmBaseHelperReady.h44
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.c208
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.h99
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.inf50
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c698
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.h57
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf62
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.c512
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.h219
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.inf53
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.c128
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.h73
-rw-r--r--EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf51
14 files changed, 2339 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Compatibility/Include/Guid/SmmBaseThunkCommunication.h b/EdkCompatibilityPkg/Compatibility/Include/Guid/SmmBaseThunkCommunication.h
new file mode 100644
index 0000000000..f8507e5946
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/Include/Guid/SmmBaseThunkCommunication.h
@@ -0,0 +1,85 @@
+/** @file
+ GUID and data structures for communication between SMM Base on SMM Base2 Thunk driver
+ and SmmBaseHelper driver.
+
+ Copyright (c) 2009, Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#ifndef _SMM_BASE_THUNK_COMMUNICATION_H_
+#define _SMM_BASE_THUNK_COMMUNICATION_H_
+
+#include <Protocol/SmmBase.h>
+
+#define EFI_SMM_BASE_THUNK_COMMUNICATION_GUID \
+ { 0x6568a3d6, 0x15f, 0x4b4a, { 0x9c, 0x89, 0x1d, 0x14, 0x63, 0x14, 0x13, 0xa } }
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ VOID *SourceBuffer;
+ UINTN SourceSize;
+ EFI_HANDLE *ImageHandle;
+ BOOLEAN LegacyIA32Binary;
+} SMMBASE_REGISTER_ARG;
+
+typedef struct {
+ EFI_HANDLE ImageHandle;
+} SMMBASE_UNREGISTER_ARG;
+
+typedef struct {
+ EFI_HANDLE SmmImageHandle;
+ EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress;
+ BOOLEAN MakeLast;
+ BOOLEAN FloatingPointSave;
+} SMMBASE_REGISTER_CALLBACK_ARG;
+
+typedef struct {
+ EFI_MEMORY_TYPE PoolType;
+ UINTN Size;
+ VOID **Buffer;
+} SMMBASE_ALLOCATE_POOL_ARG;
+
+typedef struct {
+ VOID *Buffer;
+} SMMBASE_FREE_POOL_ARG;
+
+typedef union {
+ SMMBASE_REGISTER_ARG Register;
+ SMMBASE_UNREGISTER_ARG UnRegister;
+ SMMBASE_REGISTER_CALLBACK_ARG RegisterCallback;
+ SMMBASE_ALLOCATE_POOL_ARG AllocatePool;
+ SMMBASE_FREE_POOL_ARG FreePool;
+} SMMBASE_FUNCTION_ARGS;
+
+typedef enum {
+ SMMBASE_REGISTER,
+ SMMBASE_UNREGISTER,
+ SMMBASE_REGISTER_CALLBACK,
+ SMMBASE_ALLOCATE_POOL,
+ SMMBASE_FREE_POOL,
+} SMMBASE_FUNCTION;
+
+typedef struct {
+ SMMBASE_FUNCTION Function;
+ EFI_STATUS Status;
+ SMMBASE_FUNCTION_ARGS Args;
+} SMMBASE_FUNCTION_DATA;
+
+#pragma pack(1)
+typedef struct {
+ EFI_GUID HeaderGuid;
+ UINTN MessageLength;
+ SMMBASE_FUNCTION_DATA FunctionData;
+} SMMBASETHUNK_COMMUNICATION_DATA;
+#pragma pack()
+
+extern EFI_GUID gEfiSmmBaseThunkCommunicationGuid;
+
+#endif
+
diff --git a/EdkCompatibilityPkg/Compatibility/Include/Protocol/SmmBaseHelperReady.h b/EdkCompatibilityPkg/Compatibility/Include/Protocol/SmmBaseHelperReady.h
new file mode 100644
index 0000000000..45d645bad7
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/Include/Protocol/SmmBaseHelperReady.h
@@ -0,0 +1,44 @@
+/** @file
+ EFI SMM Base Helper Ready Protocol.
+
+ This UEFI protocol is produced by the SMM Base Helper SMM driver to provide
+ a Framework SMST to the SMM Base Thunk driver. This protocol is also an indicator
+ that the SMM Base Helper SMM driver is ready in SMRAM for communication with
+ the SMM Base Thunk driver.
+
+ Copyright (c) 2009, Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_SMM_BASE_HELPER_READY_H__
+#define __EFI_SMM_BASE_HELPER_READY_H__
+
+#include <FrameworkSmm.h>
+#include <PiSmm.h>
+
+#define EFI_SMM_BASE_HELPER_READY_PROTOCOL_GUID \
+ { \
+ 0x910dca07, 0x1f94, 0x4ee7, { 0xaf, 0x2f, 0xff, 0x72, 0xf3, 0x15, 0x43, 0x53 } \
+ }
+
+typedef struct {
+ ///
+ /// Pointer to the Framework SMST built from PI SMST by SMM Base Helper SMM driver.
+ ///
+ EFI_SMM_SYSTEM_TABLE *FrameworkSmst;
+ ///
+ /// Services function directly called by SMM Base Thunk when in SMM
+ ///
+ EFI_SMM_HANDLER_ENTRY_POINT2 ServiceEntry;
+} EFI_SMM_BASE_HELPER_READY_PROTOCOL;
+
+extern EFI_GUID gEfiSmmBaseHelperReadyProtocolGuid;
+
+#endif
diff --git a/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.c b/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.c
new file mode 100644
index 0000000000..97df22c24a
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.c
@@ -0,0 +1,208 @@
+/** @file
+ SMM Access2 Protocol on SMM Access Protocol Thunk driver.
+
+ Copyright (c) 2009 Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "SmmAccess2OnSmmAccessThunk.h"
+
+EFI_SMM_ACCESS2_PROTOCOL gSmmAccess2 = {
+ SmmAccess2Open,
+ SmmAccess2Close,
+ SmmAccess2Lock,
+ SmmAccess2GetCapabilities,
+ FALSE,
+ FALSE
+};
+
+EFI_SMM_ACCESS_PROTOCOL *mSmmAccess;
+UINTN mSmramRegionNumber;
+
+/**
+ Opens the SMRAM area to be accessible by a boot-service driver.
+
+ This function "opens" SMRAM so that it is visible while not inside of SMM. The function should
+ return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM. The function
+ should return EFI_DEVICE_ERROR if the SMRAM configuration is locked.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be opened, perhaps because it is locked.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2Open (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ UINTN DescriptorIndex;
+
+ ///
+ /// Open all SMRAM regions via SMM Access Protocol
+ ///
+
+ Status = EFI_SUCCESS;
+ for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) {
+ Status = mSmmAccess->Open (mSmmAccess, DescriptorIndex);
+ }
+ if (!EFI_ERROR (Status)) {
+ gSmmAccess2.OpenState = TRUE;
+ }
+ return Status;
+}
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function "closes" SMRAM so that it is not visible while outside of SMM. The function should
+ return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be closed.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2Close (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ UINTN DescriptorIndex;
+
+ ///
+ /// Close all SMRAM regions via SMM Access Protocol
+ ///
+
+ Status = EFI_SUCCESS;
+ for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) {
+ Status = mSmmAccess->Close (mSmmAccess, DescriptorIndex);
+ }
+ if (!EFI_ERROR (Status)) {
+ gSmmAccess2.OpenState = FALSE;
+ }
+ return Status;
+}
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function prohibits access to the SMRAM region. This function is usually implemented such
+ that it is a write-once operation.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The device was successfully locked.
+ @retval EFI_UNSUPPORTED The system does not support locking of SMRAM.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2Lock (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ UINTN DescriptorIndex;
+
+ ///
+ /// Lock all SMRAM regions via SMM Access Protocol
+ ///
+
+ Status = EFI_SUCCESS;
+ for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) {
+ Status = mSmmAccess->Lock (mSmmAccess, DescriptorIndex);
+ }
+ if (!EFI_ERROR (Status)) {
+ gSmmAccess2.LockState = TRUE;
+ }
+ return Status;
+}
+
+/**
+ Queries the memory controller for the possible regions that will support SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+ @param[in,out] SmramMapSize A pointer to the size, in bytes, of the SmramMemoryMap buffer.
+ @param[in,out] SmramMap A pointer to the buffer in which firmware places the current memory map.
+
+ @retval EFI_SUCCESS The chipset supported the given resource.
+ @retval EFI_BUFFER_TOO_SMALL The SmramMap parameter was too small. The current buffer size
+ needed to hold the memory map is returned in SmramMapSize.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2GetCapabilities (
+ IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ )
+{
+ return mSmmAccess->GetCapabilities (mSmmAccess, SmramMapSize, SmramMap);
+}
+
+/**
+ Entry Point for SMM Access2 On SMM Access Thunk driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable A Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurred when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2ThunkMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN SmramMapSize;
+
+ ///
+ /// Locate SMM Access Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmAccessProtocolGuid, NULL, (VOID **)&mSmmAccess);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Calculate number of SMRAM regions
+ ///
+ SmramMapSize = 0;
+ Status = mSmmAccess->GetCapabilities (mSmmAccess, &SmramMapSize, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ mSmramRegionNumber = SmramMapSize/sizeof (EFI_SMRAM_DESCRIPTOR);
+ ASSERT (mSmramRegionNumber > 0);
+
+ ///
+ /// Assume all SMRAM regions have consistent OPEN and LOCK states
+ ///
+ gSmmAccess2.OpenState = mSmmAccess->OpenState;
+ gSmmAccess2.LockState = mSmmAccess->LockState;
+
+ ///
+ /// Publish PI SMM Access2 Protocol
+ ///
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEfiSmmAccess2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gSmmAccess2
+ );
+ return Status;
+}
+
diff --git a/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.h b/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.h
new file mode 100644
index 0000000000..bc3415903a
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.h
@@ -0,0 +1,99 @@
+/** @file
+ Include file for SMM Access2 Protocol on SMM Access Protocol Thunk driver.
+
+ Copyright (c) 2009, Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SMM_ACCESS2_ON_SMM_ACCESS_THUNK_H_
+#define _SMM_ACCESS2_ON_SMM_ACCESS_THUNK_H_
+
+#include <PiDxe.h>
+#include <FrameworkSmm.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Protocol/SmmAccess2.h>
+#include <Protocol/SmmAccess.h>
+
+/**
+ Opens the SMRAM area to be accessible by a boot-service driver.
+
+ This function "opens" SMRAM so that it is visible while not inside of SMM. The function should
+ return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM. The function
+ should return EFI_DEVICE_ERROR if the SMRAM configuration is locked.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be opened, perhaps because it is locked.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2Open (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function "closes" SMRAM so that it is not visible while outside of SMM. The function should
+ return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_UNSUPPORTED The system does not support opening and closing of SMRAM.
+ @retval EFI_DEVICE_ERROR SMRAM cannot be closed.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2Close (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+/**
+ Inhibits access to the SMRAM.
+
+ This function prohibits access to the SMRAM region. This function is usually implemented such
+ that it is a write-once operation.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The device was successfully locked.
+ @retval EFI_UNSUPPORTED The system does not support locking of SMRAM.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2Lock (
+ IN EFI_SMM_ACCESS2_PROTOCOL *This
+ );
+
+/**
+ Queries the memory controller for the possible regions that will support SMRAM.
+
+ @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance.
+ @param[in,out] SmramMapSize A pointer to the size, in bytes, of the SmramMemoryMap buffer.
+ @param[in,out] SmramMap A pointer to the buffer in which firmware places the current memory map.
+
+ @retval EFI_SUCCESS The chipset supported the given resource.
+ @retval EFI_BUFFER_TOO_SMALL The SmramMap parameter was too small. The current buffer size
+ needed to hold the memory map is returned in SmramMapSize.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccess2GetCapabilities (
+ IN CONST EFI_SMM_ACCESS2_PROTOCOL *This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap
+ );
+
+#endif
diff --git a/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.inf b/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.inf
new file mode 100644
index 0000000000..2262f4328e
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.inf
@@ -0,0 +1,50 @@
+## @file
+# Component description file for SMM Access2 Protocol on SMM Access Protocol Thunk driver.
+#
+# Copyright (c) 2009, Intel Corporation
+#
+# 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmAccess2OnSmmAccessThunk
+ FILE_GUID = 98BBCDA4-18B4-46d3-BD1F-6A3A52D44CF8
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmAccess2ThunkMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmAccess2OnSmmAccessThunk.c
+ SmmAccess2OnSmmAccessThunk.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ EdkCompatibilityPkg/EdkCompatibilityPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ DebugLib
+
+[Protocols]
+ gEfiSmmAccessProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiSmmAccess2ProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+
+[Depex]
+ gEfiSmmAccessProtocolGuid
+
diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
new file mode 100644
index 0000000000..381f6ae2ed
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
@@ -0,0 +1,698 @@
+/** @file
+ SMM Base Helper SMM driver.
+
+ This driver is the counterpart of the SMM Base On SMM Base2 Thunk driver. It
+ provides helping services in SMM to the SMM Base On SMM Base2 Thunk driver.
+
+ Copyright (c) 2009, Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "SmmBaseHelper.h"
+
+EFI_HANDLE mDispatchHandle;
+EFI_SMM_CPU_PROTOCOL *mSmmCpu;
+EFI_GUID mEfiSmmCpuIoGuid = EFI_SMM_CPU_IO_GUID;
+EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;
+EFI_SMM_SYSTEM_TABLE *mFrameworkSmst;
+
+LIST_ENTRY mCallbackInfoListHead = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackInfoListHead);
+
+CPU_SAVE_STATE_CONVERSION mCpuSaveStateConvTable[] = {
+ {EFI_SMM_SAVE_STATE_REGISTER_LDTBASE , CPU_SAVE_STATE_GET_OFFSET(LDTBase)},
+ {EFI_SMM_SAVE_STATE_REGISTER_ES , CPU_SAVE_STATE_GET_OFFSET(ES)},
+ {EFI_SMM_SAVE_STATE_REGISTER_CS , CPU_SAVE_STATE_GET_OFFSET(CS)},
+ {EFI_SMM_SAVE_STATE_REGISTER_SS , CPU_SAVE_STATE_GET_OFFSET(SS)},
+ {EFI_SMM_SAVE_STATE_REGISTER_DS , CPU_SAVE_STATE_GET_OFFSET(DS)},
+ {EFI_SMM_SAVE_STATE_REGISTER_FS , CPU_SAVE_STATE_GET_OFFSET(FS)},
+ {EFI_SMM_SAVE_STATE_REGISTER_GS , CPU_SAVE_STATE_GET_OFFSET(GS)},
+ {EFI_SMM_SAVE_STATE_REGISTER_TR_SEL , CPU_SAVE_STATE_GET_OFFSET(TR)},
+ {EFI_SMM_SAVE_STATE_REGISTER_DR7 , CPU_SAVE_STATE_GET_OFFSET(DR7)},
+ {EFI_SMM_SAVE_STATE_REGISTER_DR6 , CPU_SAVE_STATE_GET_OFFSET(DR6)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RAX , CPU_SAVE_STATE_GET_OFFSET(EAX)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RBX , CPU_SAVE_STATE_GET_OFFSET(EBX)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RCX , CPU_SAVE_STATE_GET_OFFSET(ECX)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RDX , CPU_SAVE_STATE_GET_OFFSET(EDX)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RSP , CPU_SAVE_STATE_GET_OFFSET(ESP)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RBP , CPU_SAVE_STATE_GET_OFFSET(EBP)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RSI , CPU_SAVE_STATE_GET_OFFSET(ESI)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RDI , CPU_SAVE_STATE_GET_OFFSET(EDI)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RIP , CPU_SAVE_STATE_GET_OFFSET(EIP)},
+ {EFI_SMM_SAVE_STATE_REGISTER_RFLAGS , CPU_SAVE_STATE_GET_OFFSET(EFLAGS)},
+ {EFI_SMM_SAVE_STATE_REGISTER_CR0 , CPU_SAVE_STATE_GET_OFFSET(CR0)},
+ {EFI_SMM_SAVE_STATE_REGISTER_CR3 , CPU_SAVE_STATE_GET_OFFSET(CR3)}
+};
+
+/**
+ Framework SMST SmmInstallConfigurationTable() Thunk.
+
+ This thunk calls the PI SMM SmmInstallConfigurationTable() and then update the configuration
+ table related fields in the Framework SMST because the PI SMM SmmInstallConfigurationTable()
+ function may modify these fields.
+
+ @param[in] SystemTable A pointer to the SMM System Table.
+ @param[in] Guid A pointer to the GUID for the entry to add, update, or remove.
+ @param[in] Table A pointer to the buffer of the table to add.
+ @param[in] TableSize The size of the table to install.
+
+ @retval EFI_SUCCESS The (Guid, Table) pair was added, updated, or removed.
+ @retval EFI_INVALID_PARAMETER Guid is not valid.
+ @retval EFI_NOT_FOUND An attempt was made to delete a non-existent entry.
+ @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation.
+**/
+EFI_STATUS
+EFIAPI
+SmmInstallConfigurationTable (
+ IN EFI_SMM_SYSTEM_TABLE *SystemTable,
+ IN EFI_GUID *Guid,
+ IN VOID *Table,
+ IN UINTN TableSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gSmst->SmmInstallConfigurationTable (gSmst, Guid, Table, TableSize);
+ if (!EFI_ERROR (Status)) {
+ mFrameworkSmst->NumberOfTableEntries = gSmst->NumberOfTableEntries;
+ mFrameworkSmst->SmmConfigurationTable = gSmst->SmmConfigurationTable;
+ }
+ return Status;
+}
+
+/**
+ Construct a Framework SMST based on the PI SMM SMST.
+
+ @return Pointer to the constructed Framework SMST.
+**/
+EFI_SMM_SYSTEM_TABLE *
+ConstructFrameworkSmst (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_SYSTEM_TABLE *FrameworkSmst;
+
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (EFI_SMM_SYSTEM_TABLE),
+ (VOID **)&FrameworkSmst
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Copy same things from PI SMST to Framework SMST
+ ///
+ CopyMem (FrameworkSmst, gSmst, (UINTN)(&((EFI_SMM_SYSTEM_TABLE *)0)->SmmIo));
+ CopyMem (
+ &FrameworkSmst->SmmIo,
+ &gSmst->SmmIo,
+ sizeof (EFI_SMM_SYSTEM_TABLE) - (UINTN)(&((EFI_SMM_SYSTEM_TABLE *)0)->SmmIo)
+ );
+
+ ///
+ /// Update Framework SMST
+ ///
+ FrameworkSmst->Hdr.Revision = EFI_SMM_SYSTEM_TABLE_REVISION;
+ CopyGuid (&FrameworkSmst->EfiSmmCpuIoGuid, &mEfiSmmCpuIoGuid);
+
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ gSmst->NumberOfCpus * sizeof (EFI_SMI_CPU_SAVE_STATE),
+ (VOID **)&FrameworkSmst->CpuSaveState
+ );
+ ASSERT_EFI_ERROR (Status);
+ ZeroMem (FrameworkSmst->CpuSaveState, gSmst->NumberOfCpus * sizeof (EFI_SMI_CPU_SAVE_STATE));
+
+ ///
+ /// Do not support floating point state now
+ ///
+ FrameworkSmst->CpuOptionalFloatingPointState = NULL;
+
+ FrameworkSmst->SmmInstallConfigurationTable = SmmInstallConfigurationTable;
+
+ return FrameworkSmst;
+}
+
+/**
+ Load a given Framework SMM driver into SMRAM and invoke its entry point.
+
+ @param[in] FilePath Location of the image to be installed as the handler.
+ @param[in] SourceBuffer Optional source buffer in case the image file
+ is in memory.
+ @param[in] SourceSize Size of the source image file, if in memory.
+ @param[out] ImageHandle The handle that the base driver uses to decode
+ the handler. Unique among SMM handlers only,
+ not unique across DXE/EFI.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_OUT_OF_RESOURCES There were no additional SMRAM resources to load the handler
+ @retval EFI_UNSUPPORTED Can not find its copy in normal memory.
+ @retval EFI_INVALID_PARAMETER The handlers was not the correct image type
+**/
+EFI_STATUS
+LoadImage (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN PageCount;
+ EFI_PHYSICAL_ADDRESS Buffer;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_HANDLE PesudoImageHandle;
+ UINTN NumHandles;
+ UINTN Index;
+ EFI_HANDLE *HandleBuffer;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH *LoadedImageDevicePath;
+ UINTN DevicePathSize;
+
+ if (FilePath == NULL || ImageHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ///
+ /// Assume Framework SMM driver has an image copy in memory before registering itself into SMRAM.
+ /// Currently only supports load Framework SMM driver from existing image copy in memory.
+ /// Load PE32 Image Protocol can be used to support loading Framework SMM driver directly from FV.
+ ///
+ if (SourceBuffer == NULL) {
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiLoadedImageDevicePathProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DevicePathSize = GetDevicePathSize (FilePath);
+
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiLoadedImageDevicePathProtocolGuid,
+ (VOID **)&LoadedImageDevicePath
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (GetDevicePathSize (LoadedImageDevicePath) == DevicePathSize &&
+ CompareMem (LoadedImageDevicePath, FilePath, DevicePathSize) == 0) {
+ break;
+ }
+ }
+
+ if (Index < NumHandles) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SourceBuffer = LoadedImage->ImageBase;
+ gBS->FreePool (HandleBuffer);
+ } else {
+ gBS->FreePool (HandleBuffer);
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ ImageContext.Handle = SourceBuffer;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ ///
+ /// Get information about the image being loaded
+ ///
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Allocate buffer for loading image into SMRAM
+ ///
+ PageCount = (UINTN)EFI_SIZE_TO_PAGES (ImageContext.ImageSize + ImageContext.SectionAlignment);
+ Status = gSmst->SmmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, PageCount, &Buffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ImageContext.ImageAddress = (PHYSICAL_ADDRESS)Buffer;
+
+ ///
+ /// Align buffer on section boundry
+ ///
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+ ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
+
+ ///
+ /// Load the image into SMRAM
+ ///
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ ///
+ /// Relocate the image in our new buffer
+ ///
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ ///
+ /// Flush the instruction cache so the image data are written before we execute it
+ ///
+ InvalidateInstructionCacheRange ((VOID *)(UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize);
+
+ ///
+ /// Update MP state in Framework SMST before transferring control to Framework SMM driver entry point
+ /// in case it may invoke AP
+ ///
+ mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;
+
+ ///
+ /// For Framework SMM, ImageHandle does not have to be a UEFI image handle. The only requirement is that the
+ /// ImageHandle is a unique value. Use image base address as the unique value.
+ ///
+ PesudoImageHandle = (EFI_HANDLE)(UINTN)ImageContext.ImageAddress;
+
+ Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)ImageContext.EntryPoint) (PesudoImageHandle, gST);
+ if (!EFI_ERROR (Status)) {
+ *ImageHandle = PesudoImageHandle;
+ return EFI_SUCCESS;
+ }
+
+Error:
+ gSmst->SmmFreePages (Buffer, PageCount);
+ return Status;
+}
+
+/**
+ Thunk service of EFI_SMM_BASE_PROTOCOL.Register().
+
+ @param[in] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
+*/
+VOID
+Register (
+ IN OUT SMMBASE_FUNCTION_DATA *FunctionData
+ )
+{
+ EFI_STATUS Status;
+
+ if (FunctionData->Args.Register.LegacyIA32Binary) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = LoadImage (
+ FunctionData->Args.Register.FilePath,
+ FunctionData->Args.Register.SourceBuffer,
+ FunctionData->Args.Register.SourceSize,
+ FunctionData->Args.Register.ImageHandle
+ );
+ }
+ FunctionData->Status = Status;
+}
+
+/**
+ Thunk service of EFI_SMM_BASE_PROTOCOL.UnRegister().
+
+ @param[in] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
+*/
+VOID
+UnRegister (
+ IN OUT SMMBASE_FUNCTION_DATA *FunctionData
+ )
+{
+ ///
+ /// Unregister not supported now
+ ///
+ FunctionData->Status = EFI_UNSUPPORTED;
+}
+
+/**
+ Search for Framework SMI handler information according to specific PI SMM dispatch handle.
+
+ @param[in] DispatchHandle The unique handle assigned by SmiHandlerRegister().
+
+ @return Pointer to CALLBACK_INFO.
+**/
+CALLBACK_INFO *
+GetCallbackInfo (
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ LIST_ENTRY *Node;
+
+ Node = GetFirstNode (&mCallbackInfoListHead);
+ while (!IsNull (&mCallbackInfoListHead, Node)) {
+ if (((CALLBACK_INFO *)Node)->DispatchHandle == DispatchHandle) {
+ return (CALLBACK_INFO *)Node;
+ }
+ Node = GetNextNode (&mCallbackInfoListHead, Node);
+ }
+ return NULL;
+}
+
+/**
+ Callback thunk for Framework SMI handler.
+
+ This thunk functions calls the Framework SMI handler and converts the return value
+ defined from Framework SMI handlers to a correpsonding return value defined by PI SMM.
+
+ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+ @param[in] Context Points to an optional handler context which was specified when the
+ handler was registered.
+ @param[in,out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param[in,out] CommBufferSize The size of the CommBuffer.
+
+ @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
+ should still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
+ still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
+ be called.
+ @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
+**/
+EFI_STATUS
+EFIAPI
+CallbackThunk (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ CALLBACK_INFO *CallbackInfo;
+ UINTN Index;
+ UINTN CpuIndex;
+ EFI_SMM_CPU_STATE *State;
+ EFI_SMI_CPU_SAVE_STATE *SaveState;
+
+ ///
+ /// Before transferring the control into the Framework SMI handler, update CPU Save States
+ /// and MP states in the Framework SMST.
+ ///
+
+ for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) {
+ State = (EFI_SMM_CPU_STATE *)gSmst->CpuSaveState[CpuIndex];
+ SaveState = &mFrameworkSmst->CpuSaveState[CpuIndex].Ia32SaveState;
+
+ if (State->x86.SMMRevId < EFI_SMM_MIN_REV_ID_x64) {
+ SaveState->SMBASE = State->x86.SMBASE;
+ SaveState->SMMRevId = State->x86.SMMRevId;
+ SaveState->IORestart = State->x86.IORestart;
+ SaveState->AutoHALTRestart = State->x86.AutoHALTRestart;
+ } else {
+ SaveState->SMBASE = State->x64.SMBASE;
+ SaveState->SMMRevId = State->x64.SMMRevId;
+ SaveState->IORestart = State->x64.IORestart;
+ SaveState->AutoHALTRestart = State->x64.AutoHALTRestart;
+ }
+
+ for (Index = 0; Index < sizeof (mCpuSaveStateConvTable) / sizeof (CPU_SAVE_STATE_CONVERSION); Index++) {
+ ///
+ /// Try to use SMM CPU Protocol to access CPU save states if possible
+ ///
+ Status = mSmmCpu->ReadSaveState (
+ mSmmCpu,
+ EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32,
+ mCpuSaveStateConvTable[Index].Register,
+ CpuIndex,
+ ((UINT8 *)SaveState) + mCpuSaveStateConvTable[Index].Offset
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;
+
+ ///
+ /// Search for Framework SMI handler information
+ ///
+ CallbackInfo = GetCallbackInfo (DispatchHandle);
+ ASSERT (CallbackInfo != NULL);
+
+ ///
+ /// Thunk into original Framwork SMI handler
+ ///
+ Status = (CallbackInfo->CallbackAddress) (
+ CallbackInfo->SmmImageHandle,
+ CommBuffer,
+ CommBufferSize
+ );
+ ///
+ /// Save CPU Save States in case any of them was modified
+ ///
+ for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) {
+ for (Index = 0; Index < sizeof (mCpuSaveStateConvTable) / sizeof (CPU_SAVE_STATE_CONVERSION); Index++) {
+ Status = mSmmCpu->WriteSaveState (
+ mSmmCpu,
+ EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32,
+ mCpuSaveStateConvTable[Index].Register,
+ CpuIndex,
+ ((UINT8 *)&mFrameworkSmst->CpuSaveState[CpuIndex].Ia32SaveState) +
+ mCpuSaveStateConvTable[Index].Offset
+ );
+ }
+ }
+
+ ///
+ /// Conversion of returned status code
+ ///
+ switch (Status) {
+ case EFI_HANDLER_SUCCESS:
+ Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ break;
+ case EFI_HANDLER_CRITICAL_EXIT:
+ case EFI_HANDLER_SOURCE_QUIESCED:
+ Status = EFI_SUCCESS;
+ break;
+ case EFI_HANDLER_SOURCE_PENDING:
+ Status = EFI_WARN_INTERRUPT_SOURCE_PENDING;
+ break;
+ }
+ return Status;
+}
+
+/**
+ Thunk service of EFI_SMM_BASE_PROTOCOL.RegisterCallback().
+
+ @param[in] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
+*/
+VOID
+RegisterCallback (
+ IN OUT SMMBASE_FUNCTION_DATA *FunctionData
+ )
+{
+ EFI_STATUS Status;
+ CALLBACK_INFO *Buffer;
+
+ ///
+ /// Note that MakeLast and FloatingPointSave options are not supported in PI SMM
+ ///
+
+ ///
+ /// Allocate buffer for callback thunk information
+ ///
+ Status = gSmst->SmmAllocatePool (
+ EfiRuntimeServicesCode,
+ sizeof (CALLBACK_INFO),
+ (VOID **)&Buffer
+ );
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Fill SmmImageHandle and CallbackAddress into the thunk
+ ///
+ Buffer->SmmImageHandle = FunctionData->Args.RegisterCallback.SmmImageHandle;
+ Buffer->CallbackAddress = FunctionData->Args.RegisterCallback.CallbackAddress;
+
+ ///
+ /// Register the thunk code as a root SMI handler
+ ///
+ Status = gSmst->SmiHandlerRegister (
+ CallbackThunk,
+ NULL,
+ &Buffer->DispatchHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Save this callback info
+ ///
+ InsertTailList (&mCallbackInfoListHead, &Buffer->Link);
+ } else {
+ gSmst->SmmFreePool (Buffer);
+ }
+ }
+ FunctionData->Status = Status;
+}
+
+
+/**
+ Thunk service of EFI_SMM_BASE_PROTOCOL.SmmAllocatePool().
+
+ @param[in] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
+*/
+VOID
+HelperAllocatePool (
+ IN OUT SMMBASE_FUNCTION_DATA *FunctionData
+ )
+{
+ FunctionData->Status = gSmst->SmmAllocatePool (
+ FunctionData->Args.AllocatePool.PoolType,
+ FunctionData->Args.AllocatePool.Size,
+ FunctionData->Args.AllocatePool.Buffer
+ );
+}
+
+/**
+ Thunk service of EFI_SMM_BASE_PROTOCOL.SmmFreePool().
+
+ @param[in] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
+*/
+VOID
+HelperFreePool (
+ IN OUT SMMBASE_FUNCTION_DATA *FunctionData
+ )
+{
+ FunctionData->Status = gSmst->SmmFreePool (
+ FunctionData->Args.FreePool.Buffer
+ );
+}
+
+/**
+ Communication service SMI Handler entry.
+
+ This SMI handler provides services for the SMM Base Thunk driver.
+
+ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+ @param[in] Context Points to an optional handler context which was specified when the
+ handler was registered.
+ @param[in,out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param[in,out] CommBufferSize The size of the CommBuffer.
+
+ @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
+ should still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
+ still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
+ be called.
+ @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
+**/
+EFI_STATUS
+EFIAPI
+SmmHandlerEntry (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *RegisterContext,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ )
+{
+ SMMBASE_FUNCTION_DATA *FunctionData;
+
+ ASSERT (CommBuffer != NULL);
+ ASSERT (*CommBufferSize == sizeof (SMMBASE_FUNCTION_DATA));
+
+ FunctionData = (SMMBASE_FUNCTION_DATA *)CommBuffer;
+
+ switch (FunctionData->Function) {
+ case SMMBASE_REGISTER:
+ Register (FunctionData);
+ break;
+ case SMMBASE_UNREGISTER:
+ UnRegister (FunctionData);
+ break;
+ case SMMBASE_REGISTER_CALLBACK:
+ RegisterCallback (FunctionData);
+ break;
+ case SMMBASE_ALLOCATE_POOL:
+ HelperAllocatePool (FunctionData);
+ break;
+ case SMMBASE_FREE_POOL:
+ HelperFreePool (FunctionData);
+ break;
+ default:
+ ASSERT (FALSE);
+ FunctionData->Status = EFI_UNSUPPORTED;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Entry point function of the SMM Base Helper SMM driver.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseHelperMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+
+ ///
+ /// Locate SMM CPU Protocol which is used later to update CPU Save States
+ ///
+ Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **) &mSmmCpu);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Interface structure of SMM BASE Helper Ready Protocol is allocated from UEFI pool
+ /// instead of SMM pool so that SMM Base Thunk driver can access it in Non-SMM mode.
+ ///
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_SMM_BASE_HELPER_READY_PROTOCOL),
+ (VOID **)&mSmmBaseHelperReady
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Construct Framework SMST from PI SMST
+ ///
+ mFrameworkSmst = ConstructFrameworkSmst ();
+ mSmmBaseHelperReady->FrameworkSmst = mFrameworkSmst;
+ mSmmBaseHelperReady->ServiceEntry = SmmHandlerEntry;
+
+ ///
+ /// Register SMM Base Helper services for SMM Base Thunk driver
+ ///
+ Status = gSmst->SmiHandlerRegister (SmmHandlerEntry, &gEfiSmmBaseThunkCommunicationGuid, &mDispatchHandle);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Install EFI SMM Base Helper Protocol in the UEFI handle database
+ ///
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiSmmBaseHelperReadyProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ mSmmBaseHelperReady
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.h b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.h
new file mode 100644
index 0000000000..b372f700fa
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.h
@@ -0,0 +1,57 @@
+/** @file
+ Include file for SMM Base Helper SMM driver.
+
+ Copyright (c) 2009, Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SMM_BASE_HELPER_H_
+#define _SMM_BASE_HELPER_H_
+
+#include <PiSmm.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Guid/SmmBaseThunkCommunication.h>
+#include <Protocol/SmmBaseHelperReady.h>
+#include <Protocol/SmmCpu.h>
+#include <Protocol/LoadedImage.h>
+#include <Common/CpuSaveState.h>
+
+///
+/// Structure for tracking paired information of registered Framework SMI handler
+/// and correpsonding dispatch handle for SMI handler thunk.
+///
+typedef struct {
+ LIST_ENTRY Link;
+ EFI_HANDLE DispatchHandle;
+ EFI_HANDLE SmmImageHandle;
+ EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress;
+} CALLBACK_INFO;
+
+typedef struct {
+ ///
+ /// PI SMM CPU Save State register index
+ ///
+ EFI_SMM_SAVE_STATE_REGISTER Register;
+ ///
+ /// Offset in Framework SMST
+ ///
+ UINTN Offset;
+} CPU_SAVE_STATE_CONVERSION;
+
+#define CPU_SAVE_STATE_GET_OFFSET(Field) (UINTN)(&(((EFI_SMM_CPU_SAVE_STATE *) 0)->Ia32SaveState.Field))
+
+#endif
diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf
new file mode 100644
index 0000000000..6a12600551
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf
@@ -0,0 +1,62 @@
+## @file
+# Component description file for SMM Base Helper SMM driver.
+#
+# Copyright (c) 2009, Intel Corporation.
+#
+# 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmBaseHelper
+ FILE_GUID = 8C87E0A0-B390-4be3-819C-7C6C83CAE4EB
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x0001000A
+
+ ENTRY_POINT = SmmBaseHelperMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmBaseHelper.c
+ SmmBaseHelper.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IA32FamilyCpuPkg/IA32FamilyCpuPkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ EdkCompatibilityPkg/EdkCompatibilityPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ SmmServicesTableLib
+ BaseMemoryLib
+ PeCoffLib
+ DevicePathLib
+ CacheMaintenanceLib
+
+[Guids]
+ gEfiSmmBaseThunkCommunicationGuid
+
+[Protocols]
+ gEfiSmmBaseHelperReadyProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiSmmCpuProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiLoadedImageDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Depex]
+ gEfiSmmCpuProtocolGuid
+
diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.c b/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.c
new file mode 100644
index 0000000000..fe6024af52
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.c
@@ -0,0 +1,512 @@
+/** @file
+ SMM Base Protocol on SMM Base2 Protocol Thunk driver.
+
+ This driver co-operates with SMM Base Helper SMM driver to provide SMM Base Protocol
+ based on SMM Base2 Protocol.
+
+ This thunk driver is expected to be loaded before PI SMM IPL driver so that
+ SMM BASE Protocol can be published immediately after SMM Base2 Protocol is installed to
+ make SMM Base Protocol.InSmm() as early as possible.
+
+ Copyright (c) 2009 Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "SmmBaseOnSmmBase2Thunk.h"
+
+EFI_SMM_BASE_PROTOCOL gSmmBase = {
+ SmmBaseRegister,
+ SmmBaseUnregister,
+ SmmBaseCommunicate,
+ SmmBaseRegisterCallback,
+ SmmBaseInSmm,
+ SmmBaseSmmAllocatePool,
+ SmmBaseSmmFreePool,
+ SmmBaseGetSmstLocation
+};
+
+SMMBASETHUNK_COMMUNICATION_DATA gCommunicationData = {
+ EFI_SMM_BASE_THUNK_COMMUNICATION_GUID,
+ sizeof (SMMBASE_FUNCTION_DATA)
+};
+
+EFI_HANDLE mImageHandle;
+EFI_SMM_BASE2_PROTOCOL *mSmmBase2 = NULL;
+EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
+EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady = NULL;
+
+BOOLEAN
+IsInSmm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN InSmm;
+
+ Status = mSmmBase2->InSmm (mSmmBase2, &InSmm);
+ ASSERT_EFI_ERROR (Status);
+ return InSmm;
+}
+
+/**
+ Invoke services provided by SMM Base Helper SMM driver.
+**/
+VOID
+SmmBaseHelperService (
+ VOID
+ )
+{
+ UINTN DataSize;
+
+ gCommunicationData.FunctionData.Status = EFI_UNSUPPORTED;
+
+ if (IsInSmm()) {
+ ///
+ /// If in SMM mode, directly call services in SMM Base Helper.
+ ///
+ if (mSmmBaseHelperReady == NULL) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ DataSize = (UINTN)(sizeof (SMMBASE_FUNCTION_DATA));
+ mSmmBaseHelperReady->ServiceEntry (
+ NULL,
+ NULL,
+ &gCommunicationData.FunctionData,
+ &DataSize
+ );
+ } else {
+ ///
+ /// If in non-SMM mode, call services in SMM Base Helper via SMM Communication Protocol.
+ ///
+ if (mSmmCommunication == NULL) {
+ ASSERT (FALSE);
+ return;
+ }
+
+ DataSize = (UINTN)(sizeof (gCommunicationData));
+ mSmmCommunication->Communicate (
+ mSmmCommunication,
+ &gCommunicationData,
+ &DataSize
+ );
+ }
+}
+
+/**
+ Register a given driver into SMRAM. This is the equivalent of performing
+ the LoadImage/StartImage into System Management Mode.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] FilePath Location of the image to be installed as the handler.
+ @param[in] SourceBuffer Optional source buffer in case the image file
+ is in memory.
+ @param[in] SourceSize Size of the source image file, if in memory.
+ @param[out] ImageHandle The handle that the base driver uses to decode
+ the handler. Unique among SMM handlers only,
+ not unique across DXE/EFI.
+ @param[in] LegacyIA32Binary An optional parameter specifying that the associated
+ file is a real-mode IA-32 binary.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_OUT_OF_RESOURCES There were no additional SMRAM resources to load the handler
+ @retval EFI_UNSUPPORTED This platform does not support 16-bit handlers.
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+ @retval EFI_INVALID_PARAMETER The handlers was not the correct image type
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseRegister (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle,
+ IN BOOLEAN LegacyIA32Binary
+ )
+{
+ if (LegacyIA32Binary) {
+ return EFI_UNSUPPORTED;
+ }
+
+ gCommunicationData.FunctionData.Function = SMMBASE_REGISTER;
+ gCommunicationData.FunctionData.Args.Register.FilePath = FilePath;
+ gCommunicationData.FunctionData.Args.Register.SourceBuffer = SourceBuffer;
+ gCommunicationData.FunctionData.Args.Register.SourceSize = SourceSize;
+ gCommunicationData.FunctionData.Args.Register.ImageHandle = ImageHandle;
+ gCommunicationData.FunctionData.Args.Register.LegacyIA32Binary = LegacyIA32Binary;
+
+ SmmBaseHelperService ();
+ return gCommunicationData.FunctionData.Status;
+}
+
+/**
+ Removes a handler from execution within SMRAM. This is the equivalent of performing
+ the UnloadImage in System Management Mode.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] ImageHandle The handler to be removed.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_INVALID_PARAMETER The handler did not exist
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseUnregister (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ gCommunicationData.FunctionData.Function = SMMBASE_UNREGISTER;
+ gCommunicationData.FunctionData.Args.UnRegister.ImageHandle = ImageHandle;
+
+ SmmBaseHelperService ();
+ return gCommunicationData.FunctionData.Status;
+}
+
+/**
+ The SMM Inter-module Communicate Service Communicate() function
+ provides a service to send/receive messages from a registered
+ EFI service. The BASE protocol driver is responsible for doing
+ any of the copies such that the data lives in boot-service-accessible RAM.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] ImageHandle The handle of the registered driver.
+ @param[in,out] CommunicationBuffer Pointer to the buffer to convey into SMRAM.
+ @param[in,out] BufferSize The size of the data buffer being passed in.
+ On exit, the size of data being returned.
+ Zero if the handler does not wish to reply with any data.
+
+ @retval EFI_SUCCESS The message was successfully posted
+ @retval EFI_INVALID_PARAMETER The buffer was NULL
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseCommunicate (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle,
+ IN OUT VOID *CommunicationBuffer,
+ IN OUT UINTN *BufferSize
+ )
+{
+ if (mSmmCommunication == NULL) {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ return mSmmCommunication->Communicate (
+ mSmmCommunication,
+ CommunicationBuffer,
+ BufferSize
+ );
+}
+
+/**
+ Register a callback to execute within SMM.
+ This allows receipt of messages created with EFI_SMM_BASE_PROTOCOL.Communicate().
+
+ @param[in] This Protocol instance pointer.
+ @param[in] SmmImageHandle Handle of the callback service.
+ @param[in] CallbackAddress Address of the callback service.
+ @param[in] MakeLast If present, will stipulate that the handler is posted to
+ be executed last in the dispatch table.
+ @param[in] FloatingPointSave An optional parameter that informs the
+ EFI_SMM_ACCESS_PROTOCOL Driver core if it needs to save
+ the floating point register state. If any handler
+ require this, the state will be saved for all handlers.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_OUT_OF_RESOURCES Not enough space in the dispatch queue
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+ @retval EFI_UNSUPPORTED The caller is not in SMM.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseRegisterCallback (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE SmmImageHandle,
+ IN EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress,
+ IN BOOLEAN MakeLast,
+ IN BOOLEAN FloatingPointSave
+ )
+{
+ if (!IsInSmm()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ gCommunicationData.FunctionData.Function = SMMBASE_REGISTER_CALLBACK;
+ gCommunicationData.FunctionData.Args.RegisterCallback.SmmImageHandle = SmmImageHandle;
+ gCommunicationData.FunctionData.Args.RegisterCallback.CallbackAddress = CallbackAddress;
+ gCommunicationData.FunctionData.Args.RegisterCallback.MakeLast = MakeLast;
+ gCommunicationData.FunctionData.Args.RegisterCallback.FloatingPointSave = FloatingPointSave;
+
+ SmmBaseHelperService();
+ return gCommunicationData.FunctionData.Status;
+}
+
+/**
+ This routine tells caller if execution context is SMM or not.
+
+ @param[in] This Protocol instance pointer.
+ @param[out] InSmm Whether the caller is inside SMM for IA-32
+ or servicing a PMI for the Itanium processor
+ family.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_INVALID_PARAMETER InSmm was NULL.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseInSmm (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ OUT BOOLEAN *InSmm
+ )
+{
+ return mSmmBase2->InSmm (mSmmBase2, InSmm);
+}
+
+/**
+ The SmmAllocatePool() function allocates a memory region of Size bytes from memory of
+ type PoolType and returns the address of the allocated memory in the location referenced
+ by Buffer. This function allocates pages from EFI SMRAM Memory as needed to grow the
+ requested pool type. All allocations are eight-byte aligned.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] PoolType The type of pool to allocate.
+ The only supported type is EfiRuntimeServicesData;
+ the interface will internally map this runtime request to
+ SMRAM for IA-32 and leave as this type for the Itanium
+ processor family. Other types can be ignored.
+ @param[in] Size The number of bytes to allocate from the pool.
+ @param[out] Buffer A pointer to a pointer to the allocated buffer if the call
+ succeeds; undefined otherwise.
+
+ @retval EFI_SUCCESS The requested number of bytes was allocated.
+ @retval EFI_OUT_OF_RESOURCES The pool requested could not be allocated.
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseSmmAllocatePool (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+{
+ gCommunicationData.FunctionData.Function = SMMBASE_ALLOCATE_POOL;
+ gCommunicationData.FunctionData.Args.AllocatePool.PoolType = PoolType;
+ gCommunicationData.FunctionData.Args.AllocatePool.Size = Size;
+ gCommunicationData.FunctionData.Args.AllocatePool.Buffer = Buffer;
+
+ SmmBaseHelperService ();
+ return gCommunicationData.FunctionData.Status;
+}
+
+/**
+ The SmmFreePool() function returns the memory specified by Buffer to the system.
+ On return, the memory's type is EFI SMRAM Memory. The Buffer that is freed must
+ have been allocated by SmmAllocatePool().
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Buffer Pointer to the buffer allocation.
+
+ @retval EFI_SUCCESS The memory was returned to the system.
+ @retval EFI_INVALID_PARAMETER Buffer was invalid.
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseSmmFreePool (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN VOID *Buffer
+ )
+{
+ gCommunicationData.FunctionData.Function = SMMBASE_FREE_POOL;
+ gCommunicationData.FunctionData.Args.FreePool.Buffer = Buffer;
+
+ SmmBaseHelperService ();
+ return gCommunicationData.FunctionData.Status;
+}
+
+/**
+ The GetSmstLocation() function returns the location of the System Management
+ Service Table. The use of the API is such that a driver can discover the
+ location of the SMST in its entry point and then cache it in some driver
+ global variable so that the SMST can be invoked in subsequent callbacks.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Smst Pointer to the SMST.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_INVALID_PARAMETER Smst was invalid.
+ @retval EFI_UNSUPPORTED Not in SMM.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseGetSmstLocation (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ OUT EFI_SMM_SYSTEM_TABLE **Smst
+ )
+{
+ if (mSmmBaseHelperReady == NULL) {
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ if (!IsInSmm ()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Smst == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Smst = mSmmBaseHelperReady->FrameworkSmst;
+ return EFI_SUCCESS;
+}
+
+/**
+ SMM Base Protocol notification event handler.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+SmmBaseProtocolNotification (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Assume only one instance of SMM Base2 Protocol in the system
+ /// Locate SMM Base2 Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **) &mSmmBase2);
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Publish Framework SMM BASE Protocol immediately after SMM Base2 Protocol is installed to
+ /// make SMM Base Protocol.InSmm() available as early as possible.
+ ///
+ Status = gBS->InstallProtocolInterface (
+ &mImageHandle,
+ &gEfiSmmBaseProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gSmmBase
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+/**
+ SMM Communication Protocol notification event handler.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+SmmCommunicationProtocolNotification (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ ///
+ /// Assume only one instance of SMM Communication Protocol in the system
+ /// Locate SMM Communication Protocol
+ ///
+ gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
+}
+
+/**
+ SMM Base Helper Ready Protocol notification event handler.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+SmmBaseHelperReadyProtocolNotification (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ ///
+ /// Assume only one instance of SMM Base Helper Ready Protocol in the system
+ /// Locate SMM Base Helper Ready Protocol
+ ///
+ gBS->LocateProtocol (&gEfiSmmBaseHelperReadyProtocolGuid, NULL, (VOID **) &mSmmBaseHelperReady);
+}
+
+/**
+ Entry Point for SMM Base Protocol on SMM Base2 Protocol Thunk driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable A Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseThunkMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ VOID *Registration;
+
+ mImageHandle = ImageHandle;
+
+ ///
+ /// Install notifications for required protocols
+ ///
+ /// Note we use protocol notifications here so as that this thunk driver can be
+ /// loaded before PI SMM IPL driver. Framework SMM BASE Protocol will be published
+ /// immediately after SMM Base2 Protocol is installed to make SMM Base Protocol.InSmm()
+ /// available as early as possible because some Framework code's behavior depends on
+ /// correct detection of SMM mode via SMM Base Protocol.InSmm().
+ ///
+ /// Also SMM Base Helper driver is expected to be dispatched
+ /// in the earliest round of SMM driver dispatch just after SMM IPL driver loads SMM Foundation.
+ /// So the full functionality of SMM Base Protocol is ready immediately after SMM IPL driver is
+ /// loaded. Since that point Framework SMM driver can be succesufully supported.
+ ///
+ EfiCreateProtocolNotifyEvent (
+ &gEfiSmmBase2ProtocolGuid,
+ TPL_CALLBACK,
+ SmmBaseProtocolNotification,
+ NULL,
+ &Registration
+ );
+
+ EfiCreateProtocolNotifyEvent (
+ &gEfiSmmCommunicationProtocolGuid,
+ TPL_CALLBACK,
+ SmmCommunicationProtocolNotification,
+ NULL,
+ &Registration
+ );
+
+ EfiCreateProtocolNotifyEvent (
+ &gEfiSmmBaseHelperReadyProtocolGuid,
+ TPL_CALLBACK,
+ SmmBaseHelperReadyProtocolNotification,
+ NULL,
+ &Registration
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.h b/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.h
new file mode 100644
index 0000000000..6fc3f192c5
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.h
@@ -0,0 +1,219 @@
+/** @file
+ Include file for SMM Base Protocol on SMM Base2 Protocol Thunk driver.
+
+ Copyright (c) 2009, Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SMM_BASE_ON_SMM_BASE2_THUNK_H_
+#define _SMM_BASE_ON_SMM_BASE2_THUNK_H_
+
+#include <PiDxe.h>
+#include <FrameworkSmm.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Guid/SmmBaseThunkCommunication.h>
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmCommunication.h>
+#include <Protocol/SmmBaseHelperReady.h>
+
+/**
+ Register a given driver into SMRAM. This is the equivalent of performing
+ the LoadImage/StartImage into System Management Mode.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] FilePath Location of the image to be installed as the handler.
+ @param[in] SourceBuffer Optional source buffer in case the image file
+ is in memory.
+ @param[in] SourceSize Size of the source image file, if in memory.
+ @param[out] ImageHandle The handle that the base driver uses to decode
+ the handler. Unique among SMM handlers only,
+ not unique across DXE/EFI.
+ @param[in] LegacyIA32Binary An optional parameter specifying that the associated
+ file is a real-mode IA-32 binary.
+
+ @retval EFI_SUCCESS The operation was successful.
+ @retval EFI_OUT_OF_RESOURCES There were no additional SMRAM resources to load the handler
+ @retval EFI_UNSUPPORTED This platform does not support 16-bit handlers.
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+ @retval EFI_INVALID_PARAMETER The handlers was not the correct image type
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseRegister (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle,
+ IN BOOLEAN LegacyIA32Binary
+ );
+
+/**
+ Removes a handler from execution within SMRAM. This is the equivalent of performing
+ the UnloadImage in System Management Mode.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] ImageHandle The handler to be removed.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_INVALID_PARAMETER The handler did not exist
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseUnregister (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ The SMM Inter-module Communicate Service Communicate() function
+ provides a service to send/receive messages from a registered
+ EFI service. The BASE protocol driver is responsible for doing
+ any of the copies such that the data lives in boot-service-accessible RAM.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] ImageHandle The handle of the registered driver.
+ @param[in,out] CommunicationBuffer Pointer to the buffer to convey into SMRAM.
+ @param[in,out] BufferSize The size of the data buffer being passed in.
+ On exit, the size of data being returned.
+ Zero if the handler does not wish to reply with any data.
+
+ @retval EFI_SUCCESS The message was successfully posted
+ @retval EFI_INVALID_PARAMETER The buffer was NULL
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseCommunicate (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle,
+ IN OUT VOID *CommunicationBuffer,
+ IN OUT UINTN *BufferSize
+ );
+
+/**
+ Register a callback to execute within SMM.
+ This allows receipt of messages created with EFI_SMM_BASE_PROTOCOL.Communicate().
+
+ @param[in] This Protocol instance pointer.
+ @param[in] SmmImageHandle Handle of the callback service.
+ @param[in] CallbackAddress Address of the callback service.
+ @param[in] MakeLast If present, will stipulate that the handler is posted to
+ be executed last in the dispatch table.
+ @param[in] FloatingPointSave An optional parameter that informs the
+ EFI_SMM_ACCESS_PROTOCOL Driver core if it needs to save
+ the floating point register state. If any handler
+ require this, the state will be saved for all handlers.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_OUT_OF_RESOURCES Not enough space in the dispatch queue
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+ @retval EFI_UNSUPPORTED The caller is not in SMM.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseRegisterCallback (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE SmmImageHandle,
+ IN EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress,
+ IN BOOLEAN MakeLast,
+ IN BOOLEAN FloatingPointSave
+ );
+
+/**
+ This routine tells caller if execution context is SMM or not.
+
+ @param[in] This Protocol instance pointer.
+ @param[out] InSmm Whether the caller is inside SMM for IA-32
+ or servicing a PMI for the Itanium processor
+ family.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_INVALID_PARAMETER InSmm was NULL.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseInSmm (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ OUT BOOLEAN *InSmm
+ );
+
+/**
+ The SmmAllocatePool() function allocates a memory region of Size bytes from memory of
+ type PoolType and returns the address of the allocated memory in the location referenced
+ by Buffer. This function allocates pages from EFI SMRAM Memory as needed to grow the
+ requested pool type. All allocations are eight-byte aligned.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] PoolType The type of pool to allocate.
+ The only supported type is EfiRuntimeServicesData;
+ the interface will internally map this runtime request to
+ SMRAM for IA-32 and leave as this type for the Itanium
+ processor family. Other types can be ignored.
+ @param[in] Size The number of bytes to allocate from the pool.
+ @param[out] Buffer A pointer to a pointer to the allocated buffer if the call
+ succeeds; undefined otherwise.
+
+ @retval EFI_SUCCESS The requested number of bytes was allocated.
+ @retval EFI_OUT_OF_RESOURCES The pool requested could not be allocated.
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseSmmAllocatePool (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ );
+
+/**
+ The SmmFreePool() function returns the memory specified by Buffer to the system.
+ On return, the memory's type is EFI SMRAM Memory. The Buffer that is freed must
+ have been allocated by SmmAllocatePool().
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Buffer Pointer to the buffer allocation.
+
+ @retval EFI_SUCCESS The memory was returned to the system.
+ @retval EFI_INVALID_PARAMETER Buffer was invalid.
+ @retval EFI_UNSUPPORTED Platform is in runtime.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseSmmFreePool (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN VOID *Buffer
+ );
+
+/**
+ The GetSmstLocation() function returns the location of the System Management
+ Service Table. The use of the API is such that a driver can discover the
+ location of the SMST in its entry point and then cache it in some driver
+ global variable so that the SMST can be invoked in subsequent callbacks.
+
+ @param[in] This Protocol instance pointer.
+ @param[in] Smst Pointer to the SMST.
+
+ @retval EFI_SUCCESS The operation was successful
+ @retval EFI_INVALID_PARAMETER Smst was invalid.
+ @retval EFI_UNSUPPORTED Not in SMM.
+**/
+EFI_STATUS
+EFIAPI
+SmmBaseGetSmstLocation (
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ OUT EFI_SMM_SYSTEM_TABLE **Smst
+ );
+
+#endif
diff --git a/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.inf b/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.inf
new file mode 100644
index 0000000000..cea74e8186
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.inf
@@ -0,0 +1,53 @@
+## @file
+# Component description file for SMM Base Protocol on SMM Base2 Protocol Thunk driver.
+#
+# Copyright (c) 2009, Intel Corporation
+#
+# 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmBaseOnSmmBase2Thunk
+ FILE_GUID = 21CCF0B7-246B-412c-A334-0B65A07B28DF
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmBaseThunkMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmBaseOnSmmBase2Thunk.c
+ SmmBaseOnSmmBase2Thunk.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ EdkCompatibilityPkg/EdkCompatibilityPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ DebugLib
+ UefiLib
+
+[Protocols]
+ gEfiSmmBase2ProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEfiSmmCommunicationProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEfiSmmBaseHelperReadyProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEfiSmmBaseProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+
+[Depex]
+ TRUE
+
diff --git a/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.c b/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.c
new file mode 100644
index 0000000000..1b8a40779b
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.c
@@ -0,0 +1,128 @@
+/** @file
+ SMM Control2 Protocol on SMM Control Protocol Thunk driver.
+
+ Copyright (c) 2009 Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "SmmControl2OnSmmControlThunk.h"
+
+EFI_SMM_CONTROL2_PROTOCOL gSmmControl2 = {
+ SmmControl2Trigger,
+ SmmControl2Clear,
+ 0
+};
+
+EFI_SMM_CONTROL_PROTOCOL *mSmmControl;
+UINT8 mDataPort;
+
+/**
+ Invokes SMI activation from either the preboot or runtime environment.
+
+ This function generates an SMI.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in,out] CommandPort The value written to the command port.
+ @param[in,out] DataPort The value written to the data port.
+ @param[in] Periodic Optional mechanism to engender a periodic stream.
+ @param[in] ActivationInterval Optional parameter to repeat at this period one
+ time or, if the Periodic Boolean is set, periodically.
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The timing is unsupported.
+ @retval EFI_INVALID_PARAMETER The activation period is unsupported.
+ @retval EFI_NOT_STARTED The SMM base service has not been initialized.
+**/
+EFI_STATUS
+EFIAPI
+SmmControl2Trigger (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN OUT UINT8 *CommandPort OPTIONAL,
+ IN OUT UINT8 *DataPort OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ UINTN ArgumentBufferSize = 0;
+
+ if (CommandPort != NULL) {
+ ArgumentBufferSize = 1;
+ }
+ if (DataPort != NULL) {
+ IoWrite8 (mDataPort, *DataPort);
+ }
+ return mSmmControl->Trigger (mSmmControl, (INT8 *)CommandPort, &ArgumentBufferSize, Periodic, ActivationInterval);
+}
+
+/**
+ Clears any system state that was created in response to the Trigger() call.
+
+ This function acknowledges and causes the deassertion of the SMI activation source.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in] Periodic Optional parameter to repeat at this period one time
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The source could not be cleared.
+ @retval EFI_INVALID_PARAMETER The service did not support the Periodic input argument.
+**/
+EFI_STATUS
+EFIAPI
+SmmControl2Clear (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ return mSmmControl->Clear (mSmmControl, Periodic);
+}
+
+/**
+ Entry Point for this thunk driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable A Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurred when executing this entry point.
+**/
+EFI_STATUS
+EFIAPI
+SmmControl2ThunkMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_CONTROL_REGISTER RegisterInfo;
+
+ ///
+ /// Locate Framework SMM Control Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmControlProtocolGuid, NULL, (VOID **)&mSmmControl);
+ ASSERT_EFI_ERROR (Status);
+
+ gSmmControl2.MinimumTriggerPeriod = mSmmControl->MinimumTriggerPeriod;
+
+ Status = mSmmControl->GetRegisterInfo (mSmmControl, &RegisterInfo);
+ ASSERT_EFI_ERROR (Status);
+ mDataPort = RegisterInfo.SmiDataRegister;
+
+ ///
+ /// Publish framework SMM Control Protocol
+ ///
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gEfiSmmControl2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gSmmControl2
+ );
+ return Status;
+}
+
diff --git a/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.h b/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.h
new file mode 100644
index 0000000000..ebee0086fe
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.h
@@ -0,0 +1,73 @@
+/** @file
+ Include file for SMM Control2 Protocol on SMM Control Protocol Thunk driver.
+
+ Copyright (c) 2009, Intel Corporation
+ 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
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SMM_CONTROL2_ON_SMM_CONTROL_THUNK_H_
+#define _SMM_CONTROL2_ON_SMM_CONTROL_THUNK_H_
+
+#include <PiDxe.h>
+#include <FrameworkSmm.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/IoLib.h>
+#include <Protocol/SmmControl2.h>
+#include <Protocol/SmmControl.h>
+
+/**
+ Invokes SMI activation from either the preboot or runtime environment.
+
+ This function generates an SMI.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in,out] CommandPort The value written to the command port.
+ @param[in,out] DataPort The value written to the data port.
+ @param[in] Periodic Optional mechanism to engender a periodic stream.
+ @param[in] ActivationInterval Optional parameter to repeat at this period one
+ time or, if the Periodic Boolean is set, periodically.
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The timing is unsupported.
+ @retval EFI_INVALID_PARAMETER The activation period is unsupported.
+ @retval EFI_NOT_STARTED The SMM base service has not been initialized.
+**/
+EFI_STATUS
+EFIAPI
+SmmControl2Trigger (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN OUT UINT8 *CommandPort OPTIONAL,
+ IN OUT UINT8 *DataPort OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ );
+
+/**
+ Clears any system state that was created in response to the Trigger() call.
+
+ This function acknowledges and causes the deassertion of the SMI activation source.
+
+ @param[in] This The EFI_SMM_CONTROL2_PROTOCOL instance.
+ @param[in] Periodic Optional parameter to repeat at this period one time
+
+ @retval EFI_SUCCESS The SMI/PMI has been engendered.
+ @retval EFI_DEVICE_ERROR The source could not be cleared.
+ @retval EFI_INVALID_PARAMETER The service did not support the Periodic input argument.
+**/
+EFI_STATUS
+EFIAPI
+SmmControl2Clear (
+ IN CONST EFI_SMM_CONTROL2_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+
+#endif
diff --git a/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf b/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf
new file mode 100644
index 0000000000..2c3996b1b7
--- /dev/null
+++ b/EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf
@@ -0,0 +1,51 @@
+## @file
+# Component description file for SMM Control2 Protocol on SMM Control Protocol Thunk driver.
+#
+# Copyright (c) 2009, Intel Corporation
+#
+# 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmControl2OnSmmControlThunk
+ FILE_GUID = B55A4515-5895-4ea8-845B-75B7480F6502
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmControl2ThunkMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmControl2OnSmmControlThunk.c
+ SmmControl2OnSmmControlThunk.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ EdkCompatibilityPkg/EdkCompatibilityPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ DebugLib
+ IoLib
+
+[Protocols]
+ gEfiSmmControlProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiSmmControl2ProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+
+[Depex]
+ gEfiSmmControlProtocolGuid
+