mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-26 15:14:02 +02:00
StandaloneMmPkg/Core: Introduce MM Communication Buffer
Get the MM Communication context from the MM Communication Buffer, instead of the pointer inside gMmCorePrivate. In the MmEntryPoint, check IsCommBufferValid from MM_COMM_BUFFER to decide whether the MMI is Synchronous MMI or Asynchronous MMI. If it is a Synchronous MMI, MM Core shadows the communication buffer into a internal copy, then invokes the MMI handlers, lastly copies data back to the MM Communication Buffer and set the return status. Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Sami Mujawar <sami.mujawar@arm.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
This commit is contained in:
parent
68487b4736
commit
24e41d1fa3
@ -88,6 +88,8 @@ MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = {
|
|||||||
|
|
||||||
UINTN mMmramRangeCount;
|
UINTN mMmramRangeCount;
|
||||||
EFI_MMRAM_DESCRIPTOR *mMmramRanges;
|
EFI_MMRAM_DESCRIPTOR *mMmramRanges;
|
||||||
|
MM_COMM_BUFFER *mMmCommunicationBuffer;
|
||||||
|
VOID *mInternalCommBufferCopy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Place holder function until all the MM System Table Service are available.
|
Place holder function until all the MM System Table Service are available.
|
||||||
@ -397,6 +399,62 @@ MmCoreInstallLoadedImage (
|
|||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Prepare communication buffer for MMI.
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
MmCorePrepareCommunicationBuffer (
|
||||||
|
VOID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_HOB_GUID_TYPE *GuidHob;
|
||||||
|
EFI_PHYSICAL_ADDRESS Buffer;
|
||||||
|
|
||||||
|
mMmCommunicationBuffer = NULL;
|
||||||
|
mInternalCommBufferCopy = NULL;
|
||||||
|
|
||||||
|
GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
|
||||||
|
ASSERT (GuidHob != NULL);
|
||||||
|
if (GuidHob == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mMmCommunicationBuffer = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob);
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
"MM Communication Buffer is at %x, number of pages is %x\n",
|
||||||
|
mMmCommunicationBuffer->PhysicalStart,
|
||||||
|
mMmCommunicationBuffer->NumberOfPages
|
||||||
|
));
|
||||||
|
ASSERT (mMmCommunicationBuffer->PhysicalStart != 0 && mMmCommunicationBuffer->NumberOfPages != 0);
|
||||||
|
|
||||||
|
if (!MmIsBufferOutsideMmValid (
|
||||||
|
mMmCommunicationBuffer->PhysicalStart,
|
||||||
|
EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)
|
||||||
|
))
|
||||||
|
{
|
||||||
|
mMmCommunicationBuffer = NULL;
|
||||||
|
DEBUG ((DEBUG_ERROR, "MM Communication Buffer is invalid!\n"));
|
||||||
|
ASSERT (FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmAllocatePages (
|
||||||
|
AllocateAnyPages,
|
||||||
|
EfiRuntimeServicesData,
|
||||||
|
mMmCommunicationBuffer->NumberOfPages,
|
||||||
|
&Buffer
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInternalCommBufferCopy = (VOID *)(UINTN)Buffer;
|
||||||
|
DEBUG ((DEBUG_INFO, "Internal Communication Buffer Copy is at %p\n", mInternalCommBufferCopy));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The main entry point to MM Foundation.
|
The main entry point to MM Foundation.
|
||||||
|
|
||||||
@ -414,6 +472,8 @@ MmEntryPoint (
|
|||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
|
EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
|
||||||
|
MM_COMM_BUFFER_STATUS *CommunicationStatus;
|
||||||
|
UINTN BufferSize;
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));
|
DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));
|
||||||
|
|
||||||
@ -440,33 +500,65 @@ MmEntryPoint (
|
|||||||
// Check to see if this is a Synchronous MMI sent through the MM Communication
|
// Check to see if this is a Synchronous MMI sent through the MM Communication
|
||||||
// Protocol or an Asynchronous MMI
|
// Protocol or an Asynchronous MMI
|
||||||
//
|
//
|
||||||
if (gMmCorePrivate->CommunicationBuffer != 0) {
|
if ((mMmCommunicationBuffer != NULL) && (mInternalCommBufferCopy != NULL)) {
|
||||||
//
|
CommunicationStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommunicationBuffer->Status;
|
||||||
// Synchronous MMI for MM Core or request from Communicate protocol
|
if (CommunicationStatus->IsCommBufferValid) {
|
||||||
//
|
|
||||||
if (!MmIsBufferOutsideMmValid ((UINTN)gMmCorePrivate->CommunicationBuffer, gMmCorePrivate->BufferSize)) {
|
|
||||||
//
|
//
|
||||||
// If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER
|
// Synchronous MMI for MM Core or request from Communicate protocol
|
||||||
//
|
//
|
||||||
gMmCorePrivate->CommunicationBuffer = 0;
|
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommunicationBuffer->PhysicalStart;
|
||||||
gMmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;
|
BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
|
||||||
} else {
|
if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
|
||||||
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)gMmCorePrivate->CommunicationBuffer;
|
//
|
||||||
gMmCorePrivate->BufferSize -= OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
|
// Shadow the data from MM Communication Buffer to internal buffer
|
||||||
Status = MmiManage (
|
//
|
||||||
&CommunicateHeader->HeaderGuid,
|
CopyMem (
|
||||||
NULL,
|
mInternalCommBufferCopy,
|
||||||
CommunicateHeader->Data,
|
(VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
|
||||||
(UINTN *)&gMmCorePrivate->BufferSize
|
BufferSize
|
||||||
);
|
);
|
||||||
//
|
ZeroMem (
|
||||||
// Update CommunicationBuffer, BufferSize and ReturnStatus
|
(UINT8 *)mInternalCommBufferCopy + BufferSize,
|
||||||
// Communicate service finished, reset the pointer to CommBuffer to NULL
|
EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages) - BufferSize
|
||||||
//
|
);
|
||||||
gMmCorePrivate->BufferSize += OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
|
|
||||||
gMmCorePrivate->CommunicationBuffer = 0;
|
CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mInternalCommBufferCopy;
|
||||||
gMmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
|
BufferSize = CommunicateHeader->MessageLength;
|
||||||
|
Status = MmiManage (
|
||||||
|
&CommunicateHeader->HeaderGuid,
|
||||||
|
NULL,
|
||||||
|
CommunicateHeader->Data,
|
||||||
|
&BufferSize
|
||||||
|
);
|
||||||
|
|
||||||
|
BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
|
||||||
|
if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
|
||||||
|
//
|
||||||
|
// Copy the data back to MM Communication Buffer
|
||||||
|
//
|
||||||
|
CopyMem (
|
||||||
|
(VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
|
||||||
|
mInternalCommBufferCopy,
|
||||||
|
BufferSize
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Returned buffer size is larger than the size of MM Communication Buffer\n"));
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update CommunicationBuffer, BufferSize and ReturnStatus
|
||||||
|
// Communicate service finished, reset the pointer to CommBuffer to NULL
|
||||||
|
//
|
||||||
|
CommunicationStatus->ReturnBufferSize = BufferSize;
|
||||||
|
CommunicationStatus->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Input buffer size is larger than the size of MM Communication Buffer\n"));
|
||||||
|
ASSERT (FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG ((DEBUG_ERROR, "No valid communication buffer, no Synchronous MMI will be processed\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -738,6 +830,8 @@ StandaloneMmMain (
|
|||||||
DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status));
|
DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MmCorePrepareCommunicationBuffer ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Install Loaded Image Protocol form MM Core
|
// Install Loaded Image Protocol form MM Core
|
||||||
//
|
//
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <Guid/HobList.h>
|
#include <Guid/HobList.h>
|
||||||
#include <Guid/MmFvDispatch.h>
|
#include <Guid/MmFvDispatch.h>
|
||||||
#include <Guid/MmramMemoryReserve.h>
|
#include <Guid/MmramMemoryReserve.h>
|
||||||
|
#include <Guid/MmCommBuffer.h>
|
||||||
|
|
||||||
#include <Library/StandaloneMmCoreEntryPoint.h>
|
#include <Library/StandaloneMmCoreEntryPoint.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
gEfiEventLegacyBootGuid
|
gEfiEventLegacyBootGuid
|
||||||
gEfiEventExitBootServicesGuid
|
gEfiEventExitBootServicesGuid
|
||||||
gEfiEventReadyToBootGuid
|
gEfiEventReadyToBootGuid
|
||||||
|
gMmCommBufferHobGuid
|
||||||
|
|
||||||
[Pcd]
|
[Pcd]
|
||||||
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES
|
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES
|
||||||
|
Loading…
x
Reference in New Issue
Block a user