diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index 8e6b85caeece..a00c48cd9f20 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -767,11 +767,9 @@ MmDriverDispatchHandler ( MmiHandlerUnRegister (DispatchHandle); // - // Free shadowed standalone BFV + // Free shadowed MM Fvs // - if (mBfv != NULL) { - FreePool (mBfv); - } + MmFreeShadowedFvs (); return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Core/FwVol.c b/StandaloneMmPkg/Core/FwVol.c index 9c5ee9c41227..9559581e74a5 100644 --- a/StandaloneMmPkg/Core/FwVol.c +++ b/StandaloneMmPkg/Core/FwVol.c @@ -11,6 +11,10 @@ #include #include +#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 @@ 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]); + } + } +} diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c b/StandaloneMmPkg/Core/StandaloneMmCore.c index 292e556b372b..12d36fe35d84 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.c +++ b/StandaloneMmPkg/Core/StandaloneMmCore.c @@ -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 (); } // diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 7bff1cde1433..24574b254cda 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -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