From 9e620719100f80892adfa8e2f810a485bce32fb9 Mon Sep 17 00:00:00 2001 From: rsun3 Date: Thu, 31 Dec 2009 08:42:28 +0000 Subject: [PATCH] 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 --- .../Include/Guid/SmmBaseThunkCommunication.h | 85 +++ .../Include/Protocol/SmmBaseHelperReady.h | 44 ++ .../SmmAccess2OnSmmAccessThunk.c | 208 ++++++ .../SmmAccess2OnSmmAccessThunk.h | 99 +++ .../SmmAccess2OnSmmAccessThunk.inf | 50 ++ .../SmmBaseHelper/SmmBaseHelper.c | 698 ++++++++++++++++++ .../SmmBaseHelper/SmmBaseHelper.h | 57 ++ .../SmmBaseHelper/SmmBaseHelper.inf | 62 ++ .../SmmBaseOnSmmBase2Thunk.c | 512 +++++++++++++ .../SmmBaseOnSmmBase2Thunk.h | 219 ++++++ .../SmmBaseOnSmmBase2Thunk.inf | 53 ++ .../SmmControl2OnSmmControlThunk.c | 128 ++++ .../SmmControl2OnSmmControlThunk.h | 73 ++ .../SmmControl2OnSmmControlThunk.inf | 51 ++ EdkCompatibilityPkg/EdkCompatibilityPkg.dec | 4 + EdkCompatibilityPkg/EdkCompatibilityPkg.dsc | 13 +- .../EdkIIGlueSmmDriverEntryPoint.c | 72 +- 17 files changed, 2391 insertions(+), 37 deletions(-) create mode 100644 EdkCompatibilityPkg/Compatibility/Include/Guid/SmmBaseThunkCommunication.h create mode 100644 EdkCompatibilityPkg/Compatibility/Include/Protocol/SmmBaseHelperReady.h create mode 100644 EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.c create mode 100644 EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.h create mode 100644 EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.inf create mode 100644 EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c create mode 100644 EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.h create mode 100644 EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf create mode 100644 EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.c create mode 100644 EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.h create mode 100644 EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.inf create mode 100644 EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.c create mode 100644 EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.h create mode 100644 EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf 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 + +#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 +#include + +#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 +#include +#include +#include +#include +#include +#include + +/** + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/// +/// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + 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 +#include +#include +#include +#include +#include +#include +#include + +/** + 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 + diff --git a/EdkCompatibilityPkg/EdkCompatibilityPkg.dec b/EdkCompatibilityPkg/EdkCompatibilityPkg.dec index 6472a48357..0aac9fb147 100644 --- a/EdkCompatibilityPkg/EdkCompatibilityPkg.dec +++ b/EdkCompatibilityPkg/EdkCompatibilityPkg.dec @@ -55,9 +55,13 @@ ## LanguageLib|Compatibility/Include/Library/LanguageLib.h +[Guids.common] + gEfiSmmBaseThunkCommunicationGuid = { 0x6568a3d6, 0x15f, 0x4b4a, { 0x9c, 0x89, 0x1d, 0x14, 0x63, 0x14, 0x13, 0xa } } + [Ppis.common] gEcpPeiPciCfgPpiGuid = { 0xb0ee53d4, 0xa049, 0x4a79, { 0xb2, 0xff, 0x19, 0xd9, 0xfa, 0xef, 0xaa, 0x94 }} [Protocols.common] gEfiPrintProtocolGuid = { 0xdf2d868e, 0x32fc, 0x4cf0, {0x8e, 0x6b, 0xff, 0xd9, 0x5d, 0x13, 0x43, 0xd0} } + gEfiSmmBaseHelperReadyProtocolGuid = { 0x910dca07, 0x1f94, 0x4ee7, { 0xaf, 0x2f, 0xff, 0x72, 0xf3, 0x15, 0x43, 0x53 } } diff --git a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc index 05201e5494..1d88d71062 100644 --- a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc +++ b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc @@ -63,14 +63,21 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf LanguageLib|EdkCompatibilityPkg/Compatibility/Library/UefiLanguageLib/UefiLanguageLib.inf DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf -[LibraryClasses.common.DXE_DRIVER] +[LibraryClasses.common.DXE_DRIVER,LibraryClasses.common.DXE_RUNTIME_DRIVER,LibraryClasses.common.DXE_SMM_DRIVER] MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +[LibraryClasses.IA32.DXE_SMM_DRIVER,LibraryClasses.X64.DXE_SMM_DRIVER] + SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf + [BuildOptions] GCC:*_*_IA32_CC_FLAGS = -DEFI32 $(GCC_MACRO) GCC:*_*_IA32_ASM_FLAGS = @@ -267,6 +274,10 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/DxePerformanceLib/DxePerformanceLib.inf # Use IA32/X64 specific AsmReadTsc (). EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/PeiPerformanceLib/PeiPerformanceLib.inf # Use IA32/X64 specific AsmReadTsc (). EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.inf + EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.inf + EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf + EdkCompatibilityPkg/Compatibility/SmmAccess2OnSmmAccessThunk/SmmAccess2OnSmmAccessThunk.inf + EdkCompatibilityPkg/Compatibility/SmmControl2OnSmmControlThunk/SmmControl2OnSmmControlThunk.inf [Components.IPF] EdkCompatibilityPkg/Foundation/Cpu/Itanium/CpuIa64Lib/CpuIA64Lib.inf diff --git a/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/EntryPoints/EdkIIGlueSmmDriverEntryPoint.c b/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/EntryPoints/EdkIIGlueSmmDriverEntryPoint.c index 9d5f467cfd..6dd128af8c 100644 --- a/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/EntryPoints/EdkIIGlueSmmDriverEntryPoint.c +++ b/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/EntryPoints/EdkIIGlueSmmDriverEntryPoint.c @@ -1,6 +1,6 @@ /*++ -Copyright (c) 2004 - 2006, Intel Corporation +Copyright (c) 2004 - 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 @@ -314,19 +314,14 @@ _ModuleEntryPoint ( EFI_HANDLE Handle; // - // Cache a pointer to the Boot Services Table + // Call constructor for all libraries // - mBS = SystemTable->BootServices; + ProcessLibraryConstructorList (ImageHandle, SystemTable); // - // Retrieve the Loaded Image Protocol + // Cache a pointer to the Boot Services Table // - Status = mBS->HandleProtocol ( - ImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID*)&LoadedImage - ); - ASSERT_EFI_ERROR (Status); + mBS = SystemTable->BootServices; // // Retrieve SMM Base Protocol @@ -347,6 +342,27 @@ _ModuleEntryPoint ( // // if (!InSmm) { + // + // Retrieve the Loaded Image Protocol + // + Status = mBS->HandleProtocol ( + ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID*)&LoadedImage + ); + ASSERT_EFI_ERROR (Status); + + // + // Install the unload handler + // + Status = mBS->HandleProtocol ( + ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + ASSERT_EFI_ERROR (Status); + LoadedImage->Unload = _DriverUnloadHandler; + // // Retrieve the Device Path Protocol from the DeviceHandle tha this driver was loaded from // @@ -368,33 +384,17 @@ _ModuleEntryPoint ( // Status = SmmBase->Register (SmmBase, CompleteFilePath, NULL, 0, &Handle, FALSE); ASSERT_EFI_ERROR (Status); - return Status; - } - - // - // Call constructor for all libraries - // - ProcessLibraryConstructorList (ImageHandle, SystemTable); - - // - // Install the unload handler - // - Status = mBS->HandleProtocol ( - ImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - ASSERT_EFI_ERROR (Status); - LoadedImage->Unload = _DriverUnloadHandler; + } else { - // - // Call the list of driver entry points - // - #ifdef __EDKII_GLUE_MODULE_ENTRY_POINT__ - Status = (__EDKII_GLUE_MODULE_ENTRY_POINT__ (ImageHandle, SystemTable)); - #else - Status = EFI_SUCCESS; - #endif + // + // Call the list of driver entry points + // + #ifdef __EDKII_GLUE_MODULE_ENTRY_POINT__ + Status = (__EDKII_GLUE_MODULE_ENTRY_POINT__ (ImageHandle, SystemTable)); + #else + Status = EFI_SUCCESS; + #endif + } if (EFI_ERROR (Status)) { ProcessLibraryDestructorList (ImageHandle, SystemTable); -- 2.39.2