mirror of https://github.com/acidanthera/audk.git
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:
parent
a77e0eb17a
commit
9e62071910
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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 } }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue