]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/Dispatcher.c
Update SMM Core to use SMM Mode as soon as SMM Mode is available
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / Dispatcher.c
index 78c29ffe2255670927cd4251dbce074d317ff4be..53eedbbf61055ffad18e58f1a45629cc803e89ac 100644 (file)
@@ -743,13 +743,15 @@ SmmGetDepexSectionAndPreProccess (
   drivers to run. Drain the mScheduledQueue and load and start a PE\r
   image for each driver. Search the mDiscoveredList to see if any driver can\r
   be placed on the mScheduledQueue. If no drivers are placed on the\r
-  mScheduledQueue exit the function. On exit it is assumed the Bds()\r
-  will be called, and when the Bds() exits the Dispatcher will be called\r
-  again.\r
-\r
+  mScheduledQueue exit the function. \r
+\r
+  @retval EFI_SUCCESS           All of the SMM Drivers that could be dispatched\r
+                                have been run and the SMM Entry Point has been\r
+                                registered.\r
+  @retval EFI_NOT_READY         The SMM Driver that registered the SMM Entry Point\r
+                                was just dispatched.\r
+  @retval EFI_NOT_FOUND         There are no SMM Drivers available to be dispatched.\r
   @retval EFI_ALREADY_STARTED   The SMM Dispatcher is already running\r
-  @retval EFI_NOT_FOUND         No SMM Drivers were dispatched\r
-  @retval EFI_SUCCESS           One or more SMM Drivers were dispatched\r
 \r
 **/\r
 EFI_STATUS\r
@@ -758,10 +760,10 @@ SmmDispatcher (
   )\r
 {\r
   EFI_STATUS            Status;\r
-  EFI_STATUS            ReturnStatus;\r
   LIST_ENTRY            *Link;\r
   EFI_SMM_DRIVER_ENTRY  *DriverEntry;\r
   BOOLEAN               ReadyToRun;\r
+  BOOLEAN               PreviousSmmEntryPointRegistered;\r
 \r
   if (!gRequestDispatch) {\r
     return EFI_NOT_FOUND;\r
@@ -776,7 +778,6 @@ SmmDispatcher (
 \r
   gDispatcherRunning = TRUE;\r
 \r
-  ReturnStatus = EFI_NOT_FOUND;\r
   do {\r
     //\r
     // Drain the Scheduled Queue\r
@@ -827,6 +828,11 @@ SmmDispatcher (
         sizeof (DriverEntry->ImageHandle)\r
         );\r
 \r
+      //\r
+      // Cache state of SmmEntryPointRegistered before calling entry point\r
+      //\r
+      PreviousSmmEntryPointRegistered = gSmmCorePrivate->SmmEntryPointRegistered;\r
+\r
       //\r
       // For each SMM driver, pass NULL as ImageHandle\r
       //\r
@@ -842,7 +848,19 @@ SmmDispatcher (
         sizeof (DriverEntry->ImageHandle)\r
         );\r
 \r
-      ReturnStatus = EFI_SUCCESS;\r
+      if (!PreviousSmmEntryPointRegistered && gSmmCorePrivate->SmmEntryPointRegistered) {\r
+        //\r
+        // Return immediately if the SMM Entry Point was registered by the SMM \r
+        // Driver that was just dispatched.  The SMM IPL will reinvoke the SMM\r
+        // Core Dispatcher.  This is required so SMM Mode may be enabled as soon \r
+        // as all the dependent SMM Drivers for SMM Mode have been dispatched.  \r
+        // Once the SMM Entry Point has been registered, then SMM Mode will be \r
+        // used.\r
+        //\r
+        gRequestDispatch = TRUE;\r
+        gDispatcherRunning = FALSE;\r
+        return EFI_NOT_READY;\r
+      }\r
     }\r
 \r
     //\r
@@ -886,7 +904,7 @@ SmmDispatcher (
 \r
   gDispatcherRunning = FALSE;\r
 \r
-  return ReturnStatus;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -1309,7 +1327,34 @@ SmmDriverDispatchHandler (
   // Execute the SMM Dispatcher on any newly discovered FVs and previously \r
   // discovered SMM drivers that have been discovered but not dispatched.\r
   //\r
-  return SmmDispatcher ();\r
+  Status = SmmDispatcher ();\r
+\r
+  //\r
+  // Check to see if CommBuffer and CommBufferSize are valid\r
+  //\r
+  if (CommBuffer != NULL && CommBufferSize != NULL) {\r
+    if (*CommBufferSize > 0) {\r
+      if (Status == EFI_NOT_READY) {\r
+        //\r
+        // If a the SMM Core Entry Point was just registered, then set flag to \r
+        // request the SMM Dispatcher to be restarted.\r
+        //\r
+        *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_RESTART;\r
+      } else if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Set the flag to show that the SMM Dispatcher executed without errors\r
+        //\r
+        *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_SUCCESS;\r
+      } else {\r
+        //\r
+        // Set the flag to show that the SMM Dispatcher encountered an error\r
+        //\r
+        *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_ERROR;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r