Fix the bug that SMM Base Protocol.Communicate() does not work.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10067 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
rsun3 2010-02-25 09:23:44 +00:00
parent d555d90ff7
commit bade9bf5b2
3 changed files with 68 additions and 30 deletions

View File

@ -2,7 +2,7 @@
GUID and data structures for communication between SMM Base on SMM Base2 Thunk driver GUID and data structures for communication between SMM Base on SMM Base2 Thunk driver
and SmmBaseHelper driver. and SmmBaseHelper driver.
Copyright (c) 2009, Intel Corporation Copyright (c) 2009 - 2010, 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
@ -49,12 +49,19 @@ typedef struct {
VOID *Buffer; VOID *Buffer;
} SMMBASE_FREE_POOL_ARG; } SMMBASE_FREE_POOL_ARG;
typedef struct {
EFI_HANDLE ImageHandle;
VOID *CommunicationBuffer;
UINTN *SourceSize;
} SMMBASE_COMMUNICATE_ARG;
typedef union { typedef union {
SMMBASE_REGISTER_ARG Register; SMMBASE_REGISTER_ARG Register;
SMMBASE_UNREGISTER_ARG UnRegister; SMMBASE_UNREGISTER_ARG UnRegister;
SMMBASE_REGISTER_CALLBACK_ARG RegisterCallback; SMMBASE_REGISTER_CALLBACK_ARG RegisterCallback;
SMMBASE_ALLOCATE_POOL_ARG AllocatePool; SMMBASE_ALLOCATE_POOL_ARG AllocatePool;
SMMBASE_FREE_POOL_ARG FreePool; SMMBASE_FREE_POOL_ARG FreePool;
SMMBASE_COMMUNICATE_ARG Communicate;
} SMMBASE_FUNCTION_ARGS; } SMMBASE_FUNCTION_ARGS;
typedef enum { typedef enum {
@ -63,6 +70,7 @@ typedef enum {
SMMBASE_REGISTER_CALLBACK, SMMBASE_REGISTER_CALLBACK,
SMMBASE_ALLOCATE_POOL, SMMBASE_ALLOCATE_POOL,
SMMBASE_FREE_POOL, SMMBASE_FREE_POOL,
SMMBASE_COMMUNICATE,
} SMMBASE_FUNCTION; } SMMBASE_FUNCTION;
typedef struct { typedef struct {

View File

@ -602,6 +602,49 @@ HelperFreePool (
FunctionData->Status = EFI_SUCCESS; FunctionData->Status = EFI_SUCCESS;
} }
/**
Thunk service of EFI_SMM_BASE_PROTOCOL.Communicate().
@param[in, out] FunctionData Pointer to SMMBASE_FUNCTION_DATA.
**/
VOID
HelperCommunicate (
IN OUT SMMBASE_FUNCTION_DATA *FunctionData
)
{
LIST_ENTRY *Node;
CALLBACK_INFO *CallbackInfo;
if (FunctionData->Args.Communicate.CommunicationBuffer == NULL) {
FunctionData->Status = EFI_INVALID_PARAMETER;
return;
}
Node = GetFirstNode (&mCallbackInfoListHead);
while (!IsNull (&mCallbackInfoListHead, Node)) {
CallbackInfo = (CALLBACK_INFO *)Node;
if (FunctionData->Args.Communicate.ImageHandle == CallbackInfo->SmmImageHandle) {
///
/// Thunk into original Framwork SMI handler
///
(CallbackInfo->CallbackAddress) (
CallbackInfo->SmmImageHandle,
FunctionData->Args.Communicate.CommunicationBuffer,
FunctionData->Args.Communicate.SourceSize
);
///
/// The message was successfully posted.
///
FunctionData->Status = EFI_SUCCESS;
return;
}
Node = GetNextNode (&mCallbackInfoListHead, Node);
}
FunctionData->Status = EFI_INVALID_PARAMETER;
}
/** /**
Communication service SMI Handler entry. Communication service SMI Handler entry.
@ -654,6 +697,9 @@ SmmHandlerEntry (
case SMMBASE_FREE_POOL: case SMMBASE_FREE_POOL:
HelperFreePool (FunctionData); HelperFreePool (FunctionData);
break; break;
case SMMBASE_COMMUNICATE:
HelperCommunicate (FunctionData);
break;
default: default:
ASSERT (FALSE); ASSERT (FALSE);
FunctionData->Status = EFI_UNSUPPORTED; FunctionData->Status = EFI_UNSUPPORTED;

View File

@ -160,15 +160,10 @@ SmmBaseHelperService (
mCommunicationData.FunctionData.Status = EFI_UNSUPPORTED; mCommunicationData.FunctionData.Status = EFI_UNSUPPORTED;
if (IsInSmm()) { if ((mCommunicationData.FunctionData.Function != SMMBASE_COMMUNICATE) && IsInSmm()) {
/// ///
/// If in SMM mode, directly call services in SMM Base Helper. /// If in SMM mode, directly call services in SMM Base Helper.
/// ///
if (mSmmBaseHelperReady == NULL) {
ASSERT (FALSE);
return;
}
DataSize = (UINTN)(sizeof (SMMBASE_FUNCTION_DATA)); DataSize = (UINTN)(sizeof (SMMBASE_FUNCTION_DATA));
mSmmBaseHelperReady->ServiceEntry ( mSmmBaseHelperReady->ServiceEntry (
NULL, NULL,
@ -178,13 +173,8 @@ SmmBaseHelperService (
); );
} else { } else {
/// ///
/// If in non-SMM mode, call services in SMM Base Helper via SMM Communication Protocol. /// Call services in SMM Base Helper via SMM Communication Protocol.
/// ///
if (mSmmCommunication == NULL) {
ASSERT (FALSE);
return;
}
DataSize = (UINTN)(sizeof (mCommunicationData)); DataSize = (UINTN)(sizeof (mCommunicationData));
mSmmCommunication->Communicate ( mSmmCommunication->Communicate (
mSmmCommunication, mSmmCommunication,
@ -291,16 +281,17 @@ SmmBaseCommunicate (
IN OUT UINTN *BufferSize IN OUT UINTN *BufferSize
) )
{ {
if (mSmmCommunication == NULL) { ///
ASSERT (FALSE); /// Note this is a runtime interface
return EFI_UNSUPPORTED; ///
}
return mSmmCommunication->Communicate ( mCommunicationData.FunctionData.Function = SMMBASE_COMMUNICATE;
mSmmCommunication, mCommunicationData.FunctionData.Args.Communicate.ImageHandle = ImageHandle;
CommunicationBuffer, mCommunicationData.FunctionData.Args.Communicate.CommunicationBuffer = CommunicationBuffer;
BufferSize mCommunicationData.FunctionData.Args.Communicate.SourceSize = BufferSize;
);
SmmBaseHelperService ();
return mCommunicationData.FunctionData.Status;
} }
/** /**
@ -451,11 +442,6 @@ SmmBaseGetSmstLocation (
OUT EFI_SMM_SYSTEM_TABLE **Smst OUT EFI_SMM_SYSTEM_TABLE **Smst
) )
{ {
if (mSmmBaseHelperReady == NULL) {
ASSERT (FALSE);
return EFI_UNSUPPORTED;
}
if (!IsInSmm ()) { if (!IsInSmm ()) {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@ -484,10 +470,8 @@ SmmBaseAddressChangeEvent (
IN VOID *Context IN VOID *Context
) )
{ {
if (mSmmCommunication != NULL) {
EfiConvertPointer (0x0, (VOID **) &mSmmCommunication); EfiConvertPointer (0x0, (VOID **) &mSmmCommunication);
} }
}
/** /**
Entry Point for SMM Base Protocol on SMM Base2 Protocol Thunk driver. Entry Point for SMM Base Protocol on SMM Base2 Protocol Thunk driver.