mirror of https://github.com/acidanthera/audk.git
StandaloneMmPkg/Core: Restart dispatcher once MmEntryPoint is registered
Defer the dispatch of the remaining MM drivers once the CPU driver has been dispatched. In MmDispatcher, return immediately if the MM Entry Point was registered. Then the MM IPL will reinvoke the MM Core Dispatcher. This is required so MM Mode may be enabled as soon as all the dependent MM Drivers for MM Mode have been dispatched. Introduce a FeatureFlag PCD to control if MmDispatcher returns or not when MmEntryPointPoint is registered. Default value is FALSE. 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
003a4d4ef4
commit
487fa274c4
|
@ -384,6 +384,7 @@ MmDispatcher (
|
|||
LIST_ENTRY *Link;
|
||||
EFI_MM_DRIVER_ENTRY *DriverEntry;
|
||||
BOOLEAN ReadyToRun;
|
||||
BOOLEAN PreviousMmEntryPointRegistered;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "MmDispatcher\n"));
|
||||
|
||||
|
@ -447,6 +448,11 @@ MmDispatcher (
|
|||
DriverEntry->Initialized = TRUE;
|
||||
RemoveEntryList (&DriverEntry->ScheduledLink);
|
||||
|
||||
//
|
||||
// Cache state of MmEntryPointRegistered before calling entry point
|
||||
//
|
||||
PreviousMmEntryPointRegistered = mMmEntryPointRegistered;
|
||||
|
||||
//
|
||||
// For each MM driver, pass NULL as ImageHandle
|
||||
//
|
||||
|
@ -463,6 +469,22 @@ MmDispatcher (
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PreviousMmEntryPointRegistered && mMmEntryPointRegistered) {
|
||||
if (FeaturePcdGet (PcdRestartMmDispatcherOnceMmEntryRegistered)) {
|
||||
//
|
||||
// Return immediately if the MM Entry Point was registered by the MM
|
||||
// Driver that was just dispatched. The MM IPL will reinvoke the MM
|
||||
// Core Dispatcher. This is required so MM Mode may be enabled as soon
|
||||
// as all the dependent MM Drivers for MM Mode have been dispatched.
|
||||
// Once the MM Entry Point has been registered, then MM Mode will be
|
||||
// used.
|
||||
//
|
||||
gRequestDispatch = TRUE;
|
||||
gDispatcherRunning = FALSE;
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -693,6 +715,55 @@ MmAddToDriverList (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Event notification that is fired MM IPL to dispatch the previously discovered MM drivers.
|
||||
|
||||
@param[in] DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
|
||||
@param[in] Context Points to an optional handler context which was specified when the
|
||||
handler was registered.
|
||||
@param[in, out] CommBuffer A pointer to a collection of data in memory that will
|
||||
be conveyed from a non-MM environment into an MM environment.
|
||||
@param[in, out] CommBufferSize The size of the CommBuffer.
|
||||
|
||||
@return EFI_SUCCESS Dispatcher is executed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
MmDriverDispatchHandler (
|
||||
IN EFI_HANDLE DispatchHandle,
|
||||
IN CONST VOID *Context OPTIONAL,
|
||||
IN OUT VOID *CommBuffer OPTIONAL,
|
||||
IN OUT UINTN *CommBufferSize OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
DEBUG ((DEBUG_INFO, "MmDriverDispatchHandler\n"));
|
||||
|
||||
//
|
||||
// Execute the MM Dispatcher on MM drivers that have been discovered
|
||||
// previously but not dispatched.
|
||||
//
|
||||
Status = MmDispatcher ();
|
||||
|
||||
//
|
||||
// Check to see if CommBuffer and CommBufferSize are valid
|
||||
//
|
||||
if ((CommBuffer != NULL) && (CommBufferSize != NULL)) {
|
||||
if (*CommBufferSize > sizeof (EFI_STATUS)) {
|
||||
//
|
||||
// Set the status of MmDispatcher to CommBuffer
|
||||
//
|
||||
*(EFI_STATUS *)CommBuffer = Status;
|
||||
}
|
||||
}
|
||||
|
||||
MmiHandlerUnRegister (DispatchHandle);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Traverse the discovered list for any drivers that were discovered but not loaded
|
||||
because the dependency expressions evaluated to false.
|
||||
|
|
|
@ -74,6 +74,7 @@ EFI_MM_SYSTEM_TABLE gMmCoreMmst = {
|
|||
// Table of MMI Handlers that are registered by the MM Core when it is initialized
|
||||
//
|
||||
MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = {
|
||||
{ MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE },
|
||||
{ MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE },
|
||||
{ MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE },
|
||||
{ MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE },
|
||||
|
|
|
@ -177,6 +177,7 @@ typedef struct {
|
|||
//
|
||||
extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
|
||||
extern LIST_ENTRY gHandleList;
|
||||
extern BOOLEAN mMmEntryPointRegistered;
|
||||
|
||||
/**
|
||||
Called to initialize the memory service.
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
|
||||
[Guids]
|
||||
gAprioriGuid ## SOMETIMES_CONSUMES ## File
|
||||
gEfiEventDxeDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister
|
||||
gEventMmDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister
|
||||
gEfiEndOfDxeEventGroupGuid ## PRODUCES ## GUID # SmiHandlerRegister
|
||||
## SOMETIMES_CONSUMES ## GUID # Locate protocol
|
||||
## SOMETIMES_PRODUCES ## GUID # SmiHandlerRegister
|
||||
|
@ -79,6 +79,7 @@
|
|||
|
||||
[Pcd]
|
||||
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES
|
||||
gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered ##CONSUMES
|
||||
|
||||
#
|
||||
# This configuration fails for CLANGPDB, which does not support PIE in the GCC
|
||||
|
|
|
@ -56,3 +56,10 @@
|
|||
# in the MM phase. Minimum value is 1. Sections nested more deeply are rejected.
|
||||
# @Prompt Maximum permitted FwVol section nesting depth (exclusive) in MM.
|
||||
gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth|0x10|UINT32|0x00000001
|
||||
|
||||
[PcdsFeatureFlag]
|
||||
## Indicates if restart MM Dispatcher once MM Entry Point is registered.<BR><BR>
|
||||
# TRUE - Restart MM Dispatcher once MM Entry Point is registered.<BR>
|
||||
# FALSE - Do not restart MM Dispatcher once MM Entry Point is registered.<BR>
|
||||
# @Prompt Restart MM Dispatcher once MM Entry Point is registered.
|
||||
gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered|FALSE|BOOLEAN|0x00000002
|
||||
|
|
Loading…
Reference in New Issue