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
|
LanguageLib|Compatibility/Include/Library/LanguageLib.h
|
||||||
|
|
||||||
|
[Guids.common]
|
||||||
|
gEfiSmmBaseThunkCommunicationGuid = { 0x6568a3d6, 0x15f, 0x4b4a, { 0x9c, 0x89, 0x1d, 0x14, 0x63, 0x14, 0x13, 0xa } }
|
||||||
|
|
||||||
[Ppis.common]
|
[Ppis.common]
|
||||||
gEcpPeiPciCfgPpiGuid = { 0xb0ee53d4, 0xa049, 0x4a79, { 0xb2, 0xff, 0x19, 0xd9, 0xfa, 0xef, 0xaa, 0x94 }}
|
gEcpPeiPciCfgPpiGuid = { 0xb0ee53d4, 0xa049, 0x4a79, { 0xb2, 0xff, 0x19, 0xd9, 0xfa, 0xef, 0xaa, 0x94 }}
|
||||||
|
|
||||||
[Protocols.common]
|
[Protocols.common]
|
||||||
gEfiPrintProtocolGuid = { 0xdf2d868e, 0x32fc, 0x4cf0, {0x8e, 0x6b, 0xff, 0xd9, 0x5d, 0x13, 0x43, 0xd0} }
|
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
|
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
||||||
LanguageLib|EdkCompatibilityPkg/Compatibility/Library/UefiLanguageLib/UefiLanguageLib.inf
|
LanguageLib|EdkCompatibilityPkg/Compatibility/Library/UefiLanguageLib/UefiLanguageLib.inf
|
||||||
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.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]
|
[LibraryClasses.common.PEIM]
|
||||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||||
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.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
|
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]
|
[BuildOptions]
|
||||||
GCC:*_*_IA32_CC_FLAGS = -DEFI32 $(GCC_MACRO)
|
GCC:*_*_IA32_CC_FLAGS = -DEFI32 $(GCC_MACRO)
|
||||||
GCC:*_*_IA32_ASM_FLAGS =
|
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/DxePerformanceLib/DxePerformanceLib.inf # Use IA32/X64 specific AsmReadTsc ().
|
||||||
EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/PeiPerformanceLib/PeiPerformanceLib.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/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]
|
[Components.IPF]
|
||||||
EdkCompatibilityPkg/Foundation/Cpu/Itanium/CpuIa64Lib/CpuIA64Lib.inf
|
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
|
All rights reserved. This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
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_DEVICE_PATH_PROTOCOL *ImageDevicePath;
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call constructor for all libraries
|
||||||
|
//
|
||||||
|
ProcessLibraryConstructorList (ImageHandle, SystemTable);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Cache a pointer to the Boot Services Table
|
// Cache a pointer to the Boot Services Table
|
||||||
//
|
//
|
||||||
mBS = SystemTable->BootServices;
|
mBS = SystemTable->BootServices;
|
||||||
|
|
||||||
//
|
|
||||||
// Retrieve the Loaded Image Protocol
|
|
||||||
//
|
|
||||||
Status = mBS->HandleProtocol (
|
|
||||||
ImageHandle,
|
|
||||||
&gEfiLoadedImageProtocolGuid,
|
|
||||||
(VOID*)&LoadedImage
|
|
||||||
);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Retrieve SMM Base Protocol
|
// Retrieve SMM Base Protocol
|
||||||
//
|
//
|
||||||
|
@ -347,6 +342,27 @@ _ModuleEntryPoint (
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
if (!InSmm) {
|
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
|
// 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);
|
Status = SmmBase->Register (SmmBase, CompleteFilePath, NULL, 0, &Handle, FALSE);
|
||||||
ASSERT_EFI_ERROR (Status);
|
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)) {
|
if (EFI_ERROR (Status)) {
|
||||||
ProcessLibraryDestructorList (ImageHandle, SystemTable);
|
ProcessLibraryDestructorList (ImageHandle, SystemTable);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue