Skip to content

Commit

Permalink
StandaloneMmPkg/Core: Support to dispatch multiple standalone MM FVs
Browse files Browse the repository at this point in the history
Add support to dispatch multiple standalone MM FVs for StandaloneMmCore.
Set the maximum supported FV count to 2.

Signed-off-by: Wei6 Xu <[email protected]>
  • Loading branch information
xuweiintel committed Dec 20, 2024
1 parent 816a02c commit 96aee6f
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 39 deletions.
6 changes: 2 additions & 4 deletions StandaloneMmPkg/Core/Dispatcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,11 +767,9 @@ MmDriverDispatchHandler (
MmiHandlerUnRegister (DispatchHandle);

//
// Free shadowed standalone BFV
// Free shadowed MM Fvs
//
if (mBfv != NULL) {
FreePool (mBfv);
}
MmFreeShadowedFvs ();

return EFI_SUCCESS;
}
Expand Down
80 changes: 80 additions & 0 deletions StandaloneMmPkg/Core/FwVol.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -233,3 +237,79 @@ MmCoreFfsFindMmDriver (

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]);
}
}
}
39 changes: 8 additions & 31 deletions StandaloneMmPkg/Core/StandaloneMmCore.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@

#include "StandaloneMmCore.h"

EFI_STATUS
MmDispatcher (
VOID
);

//
// Globals used to initialize the protocol
//
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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 ();
}

//
Expand Down
48 changes: 44 additions & 4 deletions StandaloneMmPkg/Core/StandaloneMmCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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

0 comments on commit 96aee6f

Please sign in to comment.