Defer the dispatch of the remaining MM drivers once the CPU driver has
been dispatched.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4599

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+tianoc...@kernel.org>
Cc: Sami Mujawar <sami.muja...@arm.com>
Cc: Ray Ni <ray...@intel.com>
Signed-off-by: Wei6 Xu <wei6...@intel.com>
---
 StandaloneMmPkg/Core/Dispatcher.c         | 76 +++++++++++++++++++++++
 StandaloneMmPkg/Core/StandaloneMmCore.c   |  1 +
 StandaloneMmPkg/Core/StandaloneMmCore.inf |  3 +
 StandaloneMmPkg/StandaloneMmPkg.dec       |  6 ++
 4 files changed, 86 insertions(+)

diff --git a/StandaloneMmPkg/Core/Dispatcher.c 
b/StandaloneMmPkg/Core/Dispatcher.c
index b1ccba15b060..a3983785070b 100644
--- a/StandaloneMmPkg/Core/Dispatcher.c
+++ b/StandaloneMmPkg/Core/Dispatcher.c
@@ -586,6 +586,7 @@ MmDispatcher (
   LIST_ENTRY           *Link;
   EFI_MM_DRIVER_ENTRY  *DriverEntry;
   BOOLEAN              ReadyToRun;
+  BOOLEAN              PreviousMmEntryPointRegistered;
 
   DEBUG ((DEBUG_INFO, "MmDispatcher\n"));
 
@@ -649,6 +650,11 @@ MmDispatcher (
       DriverEntry->Initialized = TRUE;
       RemoveEntryList (&DriverEntry->ScheduledLink);
 
+      //
+      // Cache state of MmEntryPointRegistered before calling entry point
+      //
+      PreviousMmEntryPointRegistered = gMmCorePrivate->MmEntryPointRegistered;
+
       //
       // For each MM driver, pass NULL as ImageHandle
       //
@@ -667,6 +673,22 @@ MmDispatcher (
         DEBUG ((DEBUG_INFO, "StartImage Status - %r\n", Status));
         MmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
       }
+
+      if (!PreviousMmEntryPointRegistered && 
gMmCorePrivate->MmEntryPointRegistered) {
+        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;
+        }
+      }
     }
 
     //
@@ -897,6 +919,60 @@ 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 > 0) {
+      if (!EFI_ERROR (Status)) {
+        //
+        // Set the flag to show that the MM Dispatcher executed without errors
+        //
+        *(UINT8 *)CommBuffer = COMM_BUFFER_MM_DISPATCH_SUCCESS;
+      } else {
+        //
+        // Set the flag to show that the MM Dispatcher encountered an error
+        //
+        *(UINT8 *)CommBuffer = COMM_BUFFER_MM_DISPATCH_ERROR;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
 /**
   Traverse the discovered list for any drivers that were discovered but not 
loaded
   because the dependency expressions evaluated to false.
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.c 
b/StandaloneMmPkg/Core/StandaloneMmCore.c
index d221f1d1115d..e65edee6d8c2 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCore.c
+++ b/StandaloneMmPkg/Core/StandaloneMmCore.c
@@ -84,6 +84,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,  &gEfiEventDxeDispatchGuid,         NULL, TRUE  },
   { MmReadyToLockHandler,     &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE  },
   { MmEndOfDxeHandler,        &gEfiEndOfDxeEventGroupGuid,       NULL, FALSE },
   { MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid,    NULL, FALSE },
diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf 
b/StandaloneMmPkg/Core/StandaloneMmCore.inf
index c44b9ff33303..845fed831c47 100644
--- a/StandaloneMmPkg/Core/StandaloneMmCore.inf
+++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf
@@ -76,6 +76,9 @@ [Guids]
   gEfiEventExitBootServicesGuid
   gEfiEventReadyToBootGuid
 
+[Pcd]
+  gStandaloneMmPkgTokenSpaceGuid.PcdRestartMmDispatcherOnceMmEntryRegistered
+
 #
 # This configuration fails for CLANGPDB, which does not support PIE in the GCC
 # sense. Such however is required for ARM family StandaloneMmCore
diff --git a/StandaloneMmPkg/StandaloneMmPkg.dec 
b/StandaloneMmPkg/StandaloneMmPkg.dec
index 46784d94e421..bb4d1520f7d9 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.dec
+++ b/StandaloneMmPkg/StandaloneMmPkg.dec
@@ -48,3 +48,9 @@ [Guids]
   gEfiStandaloneMmNonSecureBufferGuid      = { 0xf00497e3, 0xbfa2, 0x41a1, { 
0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 }}
   gEfiArmTfCpuDriverEpDescriptorGuid       = { 0x6ecbd5a1, 0xc0f8, 0x4702, { 
0x83, 0x01, 0x4f, 0xc2, 0xc5, 0x47, 0x0a, 0x51 }}
 
+[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|0x00000001
-- 
2.29.2.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#111464): https://edk2.groups.io/g/devel/message/111464
Mute This Topic: https://groups.io/mt/102703852/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to