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
This commit is contained in:
rsun3 2009-12-31 08:42:28 +00:00
parent a77e0eb17a
commit 9e62071910
17 changed files with 2392 additions and 38 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 } }

View File

@ -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

View File

@ -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
@ -313,21 +313,16 @@ _ModuleEntryPoint (
EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
EFI_HANDLE Handle;
//
// Call constructor for all libraries
//
ProcessLibraryConstructorList (ImageHandle, SystemTable);
//
// Cache a pointer to the Boot Services Table
//
mBS = SystemTable->BootServices;
//
// Retrieve the Loaded Image Protocol
//
Status = mBS->HandleProtocol (
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID*)&LoadedImage
);
ASSERT_EFI_ERROR (Status);
//
// 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,34 +384,18 @@ _ModuleEntryPoint (
//
Status = SmmBase->Register (SmmBase, CompleteFilePath, NULL, 0, &Handle, FALSE);
ASSERT_EFI_ERROR (Status);
return Status;
} 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 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;
//
// 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);
}