]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
Enhance PeiCore's dispatcher, move PeimDispatchOnThisPass and PeimNeedingDispatch...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Dispatcher / Dispatcher.c
index 481cf5d02e5c99da47fb0b26a5a2103bcb14523a..9e0160cc866ca440278ca50c96b6bfffda0a0b25 100644 (file)
@@ -175,7 +175,7 @@ DiscoverPeimsAndOrderWithApriori (
 /**\r
   Shadow PeiCore module from flash to installed memory.\r
   \r
-  @param PeiServices     Pointer to PeiService table\r
+  @param PeiServices     An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
   @param PrivateInMem    PeiCore's private data structure\r
 \r
 **/\r
@@ -247,8 +247,6 @@ PeiDispatcher (
   UINT32                              AuthenticationState;\r
   EFI_PHYSICAL_ADDRESS                EntryPoint;\r
   EFI_PEIM_ENTRY_POINT2               PeimEntryPoint;\r
-  BOOLEAN                             PeimNeedingDispatch;\r
-  BOOLEAN                             PeimDispatchOnThisPass;\r
   UINTN                               SaveCurrentPeimCount;\r
   UINTN                               SaveCurrentFvCount;\r
   EFI_PEI_FILE_HANDLE                 SaveCurrentFileHandle;\r
@@ -332,8 +330,6 @@ PeiDispatcher (
   // satisfied, this dipatcher should run only once.\r
   //\r
   do {\r
-    PeimNeedingDispatch = FALSE;\r
-    PeimDispatchOnThisPass = FALSE;\r
 \r
     for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {\r
       Private->CurrentPeimFvCount = FvCount;\r
@@ -359,7 +355,7 @@ PeiDispatcher (
 \r
         if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {\r
           if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {\r
-            PeimNeedingDispatch = TRUE;\r
+            Private->PeimNeedingDispatch = TRUE;\r
           } else {\r
             Status = PeiFfsGetFileInfo (PeimFileHandle, &FvFileInfo);\r
             ASSERT_EFI_ERROR (Status);\r
@@ -411,7 +407,7 @@ PeiDispatcher (
                   PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);\r
                 }\r
 \r
-                PeimDispatchOnThisPass = TRUE;\r
+                Private->PeimDispatchOnThisPass = TRUE;\r
               }\r
 \r
               REPORT_STATUS_CODE_WITH_EXTENDED_DATA (\r
@@ -473,7 +469,7 @@ PeiDispatcher (
               // Update HandOffHob for new installed permenent memory\r
               //\r
               OldHandOffTable   = Private->HobList.HandoffInformationTable;\r
-              OldCheckingBottom = (UINTN)OldHandOffTable;\r
+              OldCheckingBottom = (UINTN)(SecCoreData->TemporaryRamBase);\r
               OldCheckingTop    = (UINTN)(OldCheckingBottom + SecCoreData->TemporaryRamSize);\r
 \r
               //\r
@@ -481,11 +477,19 @@ PeiDispatcher (
               // CAUTION: The new base is computed accounding to gap of new stack.\r
               //\r
               NewPermenentMemoryBase = Private->PhysicalMemoryBegin + StackGap;\r
+              \r
+              //\r
+              // Caculate stack offset and heap offset between CAR and new permement \r
+              // memory seperately.\r
+              //\r
               StackOffset            = (UINTN) NewPermenentMemoryBase - (UINTN) SecCoreData->StackBase;\r
               HeapOffset             = (INTN) ((UINTN) Private->PhysicalMemoryBegin + Private->StackSize - \\r
                                                (UINTN) SecCoreData->PeiTemporaryRamBase);\r
               DEBUG ((EFI_D_INFO, "Heap Offset = 0x%X Stack Offset = 0x%X\n", HeapOffset, StackOffset));\r
               \r
+              //\r
+              // Caculate new HandOffTable and PrivateData address in permenet memory's stack\r
+              //\r
               NewHandOffTable        = (EFI_HOB_HANDOFF_INFO_TABLE *)((UINTN)OldHandOffTable + HeapOffset);\r
               PrivateInMem           = (PEI_CORE_INSTANCE *)((UINTN) (VOID*) Private + StackOffset);\r
 \r
@@ -502,6 +506,12 @@ PeiDispatcher (
 \r
 \r
               if (!EFI_ERROR (Status)) {\r
+                //\r
+                // Temporary Ram support Ppi is provided by platform, it will copy \r
+                // temporary memory to permenent memory and do stack switching.\r
+                // After invoken temporary Ram support, following code's stack is in \r
+                // memory but not in CAR.\r
+                //\r
                 TemporaryRamSupportPpi->TemporaryRamMigration (\r
                                           (CONST EFI_PEI_SERVICES **) PeiServices,\r
                                           (EFI_PHYSICAL_ADDRESS)(UINTN) SecCoreData->TemporaryRamBase,\r
@@ -549,10 +559,11 @@ PeiDispatcher (
               //\r
               // We need convert the PPI desciptor's pointer\r
               //\r
-              ConvertPpiPointers ((CONST EFI_PEI_SERVICES **)PeiServices\r
+              ConvertPpiPointers (PrivateInMem\r
                                   OldCheckingBottom, \r
                                   OldCheckingTop, \r
-                                  NewHandOffTable);\r
+                                  HeapOffset\r
+                                  );\r
 \r
               DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%X Length=0x%X\n",\r
                                   (UINTN)PrivateInMem->StackBase,\r
@@ -565,11 +576,6 @@ PeiDispatcher (
               //\r
               PrivateInMem->PeiMemoryInstalled     = TRUE;\r
 \r
-              //\r
-              // Restart scan of all PEIMs on next pass\r
-              //\r
-              PrivateInMem->CurrentPeimCount = 0;\r
-\r
               //\r
               // Shadow PEI Core. When permanent memory is avaiable, shadow\r
               // PEI Core and PEIMs to get high performance.\r
@@ -653,7 +659,7 @@ PeiDispatcher (
     //  pass. If we did not dispatch a PEIM there is no point in trying again\r
     //  as it will fail the next time too (nothing has changed).\r
     //\r
-  } while (PeimNeedingDispatch && PeimDispatchOnThisPass);\r
+  } while (Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass);\r
 \r
 }\r
 \r
@@ -678,6 +684,8 @@ InitializeDispatcherData (
   )\r
 {\r
   if (OldCoreData == NULL) {\r
+    PrivateData->PeimNeedingDispatch    = FALSE;\r
+    PrivateData->PeimDispatchOnThisPass = FALSE;\r
     PeiInitializeFv (PrivateData, SecCoreData);\r
   }\r
 \r
@@ -778,7 +786,7 @@ PeiRegisterForShadow (
 /**\r
   Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.\r
 \r
-  @param PeiServices          Pointer to the PEI Core Services Table.\r
+  @param PeiServices          An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
   @param FvFileHandle         File handle of a Fv type file.\r
   @param AuthenticationState  Pointer to attestation authentication state of image.\r
 \r
@@ -799,7 +807,7 @@ ProcessFvFile (
   EFI_FV_INFO           FvImageInfo;\r
   UINT32                FvAlignment;\r
   VOID                  *FvBuffer;\r
-  EFI_PEI_HOB_POINTERS  HobFv2;\r
+  EFI_PEI_HOB_POINTERS  HobPtr;\r
 \r
   FvBuffer             = NULL;\r
   *AuthenticationState = 0;\r
@@ -808,15 +816,15 @@ ProcessFvFile (
   // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already\r
   // been extracted.\r
   //\r
-  HobFv2.Raw = GetHobList ();\r
-  while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {\r
-    if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobFv2.FirmwareVolume2->FileName)) {\r
+  HobPtr.Raw = GetHobList ();\r
+  while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobPtr.Raw)) != NULL) {\r
+    if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name), &HobPtr.FirmwareVolume2->FileName)) {\r
       //\r
       // this FILE has been dispatched, it will not be dispatched again.\r
       //\r
       return EFI_SUCCESS;\r
     }\r
-    HobFv2.Raw = GET_NEXT_HOB (HobFv2);\r
+    HobPtr.Raw = GET_NEXT_HOB (HobPtr);\r
   }\r
 \r
   //\r
@@ -871,12 +879,24 @@ ProcessFvFile (
     );\r
 \r
   //\r
-  // Inform HOB consumer phase, i.e. DXE core, the existance of this FV\r
+  // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase\r
+  // based on its parent Fvimage is informed or not.\r
+  // If FvHob of its parent fvimage is built, the extracted FvImage will be built also. \r
+  // Or, the extracted FvImage will not be built.\r
   //\r
-  BuildFvHob (\r
-    (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,\r
-    FvImageInfo.FvSize\r
-  );\r
+  HobPtr.Raw = GetHobList ();\r
+  while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_FV, HobPtr.Raw)) != NULL) {\r
+    if (((EFI_PHYSICAL_ADDRESS) (UINTN)FvFileHandle > HobPtr.FirmwareVolume->BaseAddress) && \r
+        ((EFI_PHYSICAL_ADDRESS) (UINTN)FvFileHandle < HobPtr.FirmwareVolume->BaseAddress + HobPtr.FirmwareVolume->Length)) {\r
+      BuildFvHob (\r
+        (EFI_PHYSICAL_ADDRESS) (UINTN) FvImageInfo.FvStart,\r
+        FvImageInfo.FvSize\r
+      );\r
+      break;\r
+    }\r
+    HobPtr.Raw = GET_NEXT_HOB (HobPtr);\r
+  }\r
+\r
   //\r
   // Makes the encapsulated volume show up in DXE phase to skip processing of\r
   // encapsulated file again.\r