StandaloneMmPkg/Core: Support to dispatch multiple standalone MM FVs

Add support to dispatch multiple standalone MM FVs for StandaloneMmCore.
Set the maximum supported FV count to 2.

Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
This commit is contained in:
Wei6 Xu 2024-12-18 15:23:36 +08:00 committed by mergify[bot]
parent 40df344b54
commit 79a64e73f7
4 changed files with 134 additions and 39 deletions

View File

@ -767,11 +767,9 @@ MmDriverDispatchHandler (
MmiHandlerUnRegister (DispatchHandle);
//
// Free shadowed standalone BFV
// Free shadowed MM Fvs
//
if (mBfv != NULL) {
FreePool (mBfv);
}
MmFreeShadowedFvs ();
return EFI_SUCCESS;
}

View File

@ -11,6 +11,10 @@
#include <Library/FvLib.h>
#include <Library/ExtractGuidedSectionLib.h>
#define MAX_MM_FV_COUNT 2
EFI_FIRMWARE_VOLUME_HEADER *mMmFv[MAX_MM_FV_COUNT];
EFI_STATUS
MmAddToDriverList (
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
@ -233,3 +237,79 @@ FreeDstBuffer:
return Status;
}
/**
Dispatch Standalone MM FVs.
The FVs will be shadowed into MMRAM, caller is responsible for calling
MmFreeShadowedFvs() to free the shadowed MM FVs.
**/
VOID
MmDispatchFvs (
VOID
)
{
UINTN Index;
EFI_PEI_HOB_POINTERS FvHob;
EFI_FIRMWARE_VOLUME_HEADER *Fv;
ZeroMem (mMmFv, sizeof (mMmFv));
Index = 0;
FvHob.Raw = GetHobList ();
while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {
if (Index == ARRAY_SIZE (mMmFv)) {
DEBUG ((
DEBUG_INFO,
"%a: The number of FV Hobs exceed the max supported FVs (%d) in StandaloneMmCore\n",
__func__,
ARRAY_SIZE (mMmFv)
));
return;
}
DEBUG ((DEBUG_INFO, "%a: FV[%d] address - 0x%x\n", __func__, Index, FvHob.FirmwareVolume->BaseAddress));
DEBUG ((DEBUG_INFO, "%a: FV[%d] size - 0x%x\n", __func__, Index, FvHob.FirmwareVolume->Length));
Fv = AllocatePool (FvHob.FirmwareVolume->Length);
if (Fv == NULL) {
DEBUG ((DEBUG_ERROR, "Fail to allocate memory for Fv\n"));
CpuDeadLoop ();
return;
}
CopyMem (
(VOID *)Fv,
(VOID *)(UINTN)FvHob.FirmwareVolume->BaseAddress,
FvHob.FirmwareVolume->Length
);
MmCoreFfsFindMmDriver (Fv, 0);
mMmFv[Index++] = Fv;
FvHob.Raw = GET_NEXT_HOB (FvHob);
}
if (Index == 0) {
DEBUG ((DEBUG_ERROR, "No FV hob is found\n"));
return;
}
MmDispatcher ();
}
/**
Free the shadowed MM FVs.
**/
VOID
MmFreeShadowedFvs (
VOID
)
{
UINTN Index;
for (Index = 0; Index < ARRAY_SIZE (mMmFv); Index++) {
if (mMmFv[Index] != NULL) {
FreePool (mMmFv[Index]);
}
}
}

View File

@ -9,11 +9,6 @@
#include "StandaloneMmCore.h"
EFI_STATUS
MmDispatcher (
VOID
);
//
// Globals used to initialize the protocol
//
@ -83,10 +78,9 @@ MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = {
{ NULL, NULL, NULL, FALSE },
};
BOOLEAN mMmEntryPointRegistered = FALSE;
MM_COMM_BUFFER *mMmCommunicationBuffer;
VOID *mInternalCommBufferCopy;
EFI_FIRMWARE_VOLUME_HEADER *mBfv = NULL;
BOOLEAN mMmEntryPointRegistered = FALSE;
MM_COMM_BUFFER *mMmCommunicationBuffer;
VOID *mInternalCommBufferCopy;
/**
Place holder function until all the MM System Table Service are available.
@ -802,7 +796,6 @@ StandaloneMmMain (
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
EFI_MMRAM_DESCRIPTOR *MmramRanges;
UINTN MmramRangeCount;
EFI_HOB_FIRMWARE_VOLUME *BfvHob;
ProcessLibraryConstructorList (HobStart, &gMmCoreMmst);
@ -868,30 +861,14 @@ StandaloneMmMain (
ASSERT_EFI_ERROR (Status);
//
// Get Boot Firmware Volume address from the BFV Hob
// Dispatch Standalone FVs
//
BfvHob = GetFirstHob (EFI_HOB_TYPE_FV);
if (BfvHob != NULL) {
DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress));
DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length));
MmDispatchFvs ();
if (!FeaturePcdGet (PcdRestartMmDispatcherOnceMmEntryRegistered)) {
//
// Dispatch standalone BFV
// Free shadowed standalone FVs
//
if (BfvHob->BaseAddress != 0) {
//
// Shadow standalone BFV into MMRAM
//
mBfv = AllocatePool (BfvHob->Length);
if (mBfv != NULL) {
CopyMem ((VOID *)mBfv, (VOID *)(UINTN)BfvHob->BaseAddress, BfvHob->Length);
DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", mBfv));
MmCoreFfsFindMmDriver (mBfv, 0);
MmDispatcher ();
if (!FeaturePcdGet (PcdRestartMmDispatcherOnceMmEntryRegistered)) {
FreePool (mBfv);
}
}
}
MmFreeShadowedFvs ();
}
//

View File

@ -178,10 +178,9 @@ typedef struct {
//
// MM Core Global Variables
//
extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
extern LIST_ENTRY gHandleList;
extern BOOLEAN mMmEntryPointRegistered;
extern EFI_FIRMWARE_VOLUME_HEADER *mBfv;
extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
extern LIST_ENTRY gHandleList;
extern BOOLEAN mMmEntryPointRegistered;
/**
Called to initialize the memory service.
@ -983,4 +982,45 @@ MmCoreGetMemoryMap (
OUT UINT32 *DescriptorVersion
);
/**
This is the main Dispatcher for MM and it exits when there are no more
drivers to run. Drain the mScheduledQueue and load and start a PE
image for each driver. Search the mDiscoveredList to see if any driver can
be placed on the mScheduledQueue. If no drivers are placed on the
mScheduledQueue exit the function.
@retval EFI_SUCCESS All of the MM Drivers that could be dispatched
have been run and the MM Entry Point has been
registered.
@retval EFI_NOT_READY The MM Driver that registered the MM Entry Point
was just dispatched.
@retval EFI_NOT_FOUND There are no MM Drivers available to be dispatched.
@retval EFI_ALREADY_STARTED The MM Dispatcher is already running
**/
EFI_STATUS
MmDispatcher (
VOID
);
/**
Dispatch Standalone MM FVs.
The FVs will be shadowed into MMRAM, caller is responsible for calling
MmFreeShadowedFvs() to free the shadowed MM FVs.
**/
VOID
MmDispatchFvs (
VOID
);
/**
Free the shadowed MM FVs.
**/
VOID
MmFreeShadowedFvs (
VOID
);
#endif