]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1) Fix IPF ICC 11.1 issue when /Ox is used related to the use of local variables...
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 11 May 2010 22:11:31 +0000 (22:11 +0000)
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 11 May 2010 22:11:31 +0000 (22:11 +0000)
2) Update the logic that computes the offset of the heap and stack from TEMP RAM to Permanent RAM to handle all possible offsets values.
3) Minor cleanups to the PEI_CORE_INSTANCE structure
4) Simplify the logic that manages the TEMP RAM to PERM RAM transition and clean up the related DEBUG() messages.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10481 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
MdeModulePkg/Core/Pei/PeiMain.h
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
MdeModulePkg/Core/Pei/Ppi/Ppi.c

index d0b7bb072dfbf4a3cb175553c24711e25369d5ee..6198114bb1a6a59477311f8db24765a0c4af70b7 100644 (file)
@@ -183,56 +183,6 @@ DiscoverPeimsAndOrderWithApriori (
 \r
 }\r
 \r
-/**\r
-  Shadow PeiCore module from flash to installed memory.\r
-  \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
-  @return PeiCore function address after shadowing.\r
-**/\r
-VOID*\r
-ShadowPeiCore(\r
-  IN CONST EFI_PEI_SERVICES     **PeiServices,\r
-  IN       PEI_CORE_INSTANCE    *PrivateInMem\r
-  )\r
-{\r
-  EFI_PEI_FILE_HANDLE  PeiCoreFileHandle;\r
-  EFI_PHYSICAL_ADDRESS EntryPoint;\r
-  EFI_STATUS           Status;\r
-  UINT32               AuthenticationState;\r
-\r
-  PeiCoreFileHandle = NULL;\r
-\r
-  //\r
-  // Find the PEI Core in the BFV\r
-  //\r
-  Status = PrivateInMem->Fv[0].FvPpi->FindFileByType (\r
-                                        PrivateInMem->Fv[0].FvPpi,\r
-                                        EFI_FV_FILETYPE_PEI_CORE,\r
-                                        PrivateInMem->Fv[0].FvHandle,\r
-                                        &PeiCoreFileHandle\r
-                                        );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Shadow PEI Core into memory so it will run faster\r
-  //\r
-  Status = PeiLoadImage (\r
-              PeiServices,\r
-              *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle),\r
-              PEIM_STATE_REGISITER_FOR_SHADOW,\r
-              &EntryPoint,\r
-              &AuthenticationState\r
-              );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Compute the PeiCore's function address after shaowed PeiCore.\r
-  // _ModuleEntryPoint is PeiCore main function entry\r
-  //\r
-  return (VOID*) ((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint);\r
-}\r
 //\r
 // This is the minimum memory required by DxeCore initialization. When LMFA feature enabled,\r
 // This part of memory still need reserved on the very top of memory so that the DXE Core could  \r
@@ -685,19 +635,16 @@ PeiDispatcher (
   UINTN                               SaveCurrentFvCount;\r
   EFI_PEI_FILE_HANDLE                 SaveCurrentFileHandle;\r
   PEIM_FILE_HANDLE_EXTENDED_DATA      ExtendedData;\r
-  EFI_PHYSICAL_ADDRESS                NewPermenentMemoryBase;\r
   TEMPORARY_RAM_SUPPORT_PPI           *TemporaryRamSupportPpi;\r
-  EFI_HOB_HANDOFF_INFO_TABLE          *OldHandOffTable;\r
-  EFI_HOB_HANDOFF_INFO_TABLE          *NewHandOffTable;\r
-  INTN                                StackOffset;\r
-  INTN                                HeapOffset;\r
-  PEI_CORE_INSTANCE                   *PrivateInMem;\r
-  UINT64                              NewPeiStackSize;\r
-  UINT64                              OldPeiStackSize;\r
-  UINT64                              StackGap;\r
+  UINT64                              NewStackSize;\r
+  EFI_PHYSICAL_ADDRESS                TopOfNewStack;\r
+  EFI_PHYSICAL_ADDRESS                TopOfOldStack;\r
+  EFI_PHYSICAL_ADDRESS                TemporaryRamBase;\r
+  UINTN                               TemporaryRamSize;\r
+  EFI_PHYSICAL_ADDRESS                TemporaryStackSize;\r
+  UINTN                               StackOffset;\r
+  BOOLEAN                             StackOffsetPositive;\r
   EFI_FV_FILE_INFO                    FvFileInfo;\r
-  UINTN                               OldCheckingTop;\r
-  UINTN                               OldCheckingBottom;\r
   PEI_CORE_FV_HANDLE                  *CoreFvHandle;\r
   VOID                                *LoadFixPeiCodeBegin;\r
 \r
@@ -889,13 +836,14 @@ PeiDispatcher (
                      && (*StackPointer == INIT_CAR_VALUE);\r
                      StackPointer ++);\r
                      \r
+                DEBUG ((EFI_D_INFO, "Temp Stack : BaseAddress=0x%p Length=0x%X\n", SecCoreData->StackBase, (UINT32)SecCoreData->StackSize));\r
+                DEBUG ((EFI_D_INFO, "Temp Heap  : BaseAddress=0x%p Length=0x%X\n", Private->HobList.Raw, (UINT32)((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN) Private->HobList.Raw)));\r
                 DEBUG ((EFI_D_INFO, "Total temporary memory:    %d bytes.\n", (UINT32)SecCoreData->TemporaryRamSize));\r
                 DEBUG ((EFI_D_INFO, "  temporary memory stack ever used: %d bytes.\n",\r
-                       (SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase))\r
+                       (UINT32)(SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase))\r
                       ));\r
                 DEBUG ((EFI_D_INFO, "  temporary memory heap used:       %d bytes.\n",\r
-                       ((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom -\r
-                       (UINTN) Private->HobList.Raw)\r
+                       (UINT32)((UINTN)Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw)\r
                       ));\r
               DEBUG_CODE_END ();\r
               \r
@@ -903,9 +851,10 @@ PeiDispatcher (
                 //\r
                 // Loading Module at Fixed Address is enabled\r
                 //\r
-                PeiLoadFixAddressHook(Private);\r
+                PeiLoadFixAddressHook (Private);\r
+\r
                 //\r
-                // if Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.\r
+                // If Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.\r
                 //\r
                 LoadFixPeiCodeBegin = AllocatePages((UINTN)PcdGet32(PcdLoadFixAddressPeiCodePageNumber));\r
                 DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64)(UINTN)LoadFixPeiCodeBegin, (UINT64)((UINTN)LoadFixPeiCodeBegin + PcdGet32(PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE)));\r
@@ -914,170 +863,104 @@ PeiDispatcher (
               //\r
               // Reserve the size of new stack at bottom of physical memory\r
               //\r
-              OldPeiStackSize = (UINT64) SecCoreData->StackSize;\r
-              NewPeiStackSize = (RShiftU64 (Private->PhysicalMemoryLength, 1) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;\r
-              if (PcdGet32(PcdPeiCoreMaxPeiStackSize) > (UINT32) NewPeiStackSize) {\r
-                Private->StackSize = NewPeiStackSize;\r
-              } else {\r
-                Private->StackSize = PcdGet32(PcdPeiCoreMaxPeiStackSize);\r
-              }\r
-\r
-              //\r
-              // In theory, the size of new stack in permenent memory should large than\r
-              // size of old stack in temporary memory.\r
+              // The size of new stack in permenent memory must be the same size \r
+              // or larger than the size of old stack in temporary memory.\r
               // But if new stack is smaller than the size of old stack, we also reserve\r
               // the size of old stack at bottom of permenent memory.\r
               //\r
-              DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (INT32) OldPeiStackSize, (INT32) Private->StackSize));\r
-              ASSERT (Private->StackSize >= OldPeiStackSize);\r
-              StackGap = Private->StackSize - OldPeiStackSize;\r
+              NewStackSize = RShiftU64 (Private->PhysicalMemoryLength, 1);\r
+              NewStackSize = ALIGN_VALUE (NewStackSize, EFI_PAGE_SIZE);\r
+              NewStackSize = MIN (PcdGet32(PcdPeiCoreMaxPeiStackSize), NewStackSize);\r
+              DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (UINT32)SecCoreData->StackSize, (UINT32)NewStackSize));\r
+              ASSERT (NewStackSize >= SecCoreData->StackSize);\r
 \r
               //\r
-              // Update HandOffHob for new installed permenent memory\r
+              // Caculate stack offset and heap offset between temporary memory and new permement \r
+              // memory seperately.\r
               //\r
-              OldHandOffTable   = Private->HobList.HandoffInformationTable;\r
-              OldCheckingBottom = (UINTN)(SecCoreData->TemporaryRamBase);\r
-              OldCheckingTop    = (UINTN)(OldCheckingBottom + SecCoreData->TemporaryRamSize);\r
+              TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;\r
+              TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;\r
+              if (TopOfNewStack >= (UINTN)SecCoreData->PeiTemporaryRamBase) {\r
+                Private->HeapOffsetPositive = TRUE;\r
+                Private->HeapOffset = (UINTN)(TopOfNewStack - (UINTN)SecCoreData->PeiTemporaryRamBase);\r
+              } else {\r
+                Private->HeapOffsetPositive = FALSE;\r
+                Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - TopOfNewStack);\r
+              }\r
+              if (TopOfNewStack >= TopOfOldStack) {\r
+                StackOffsetPositive = TRUE;\r
+                StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack);\r
+              } else {\r
+                StackOffsetPositive = FALSE;\r
+                StackOffset = (UINTN)(TopOfOldStack - TopOfNewStack);\r
+              }\r
+\r
+              DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64)Private->HeapOffset, (UINT64)(StackOffset)));\r
 \r
               //\r
-              // The whole temporary memory will be migrated to physical memory.\r
-              // CAUTION: The new base is computed accounding to gap of new stack.\r
+              // Build Stack HOB that describes the permanent memory stack\r
               //\r
-              NewPermenentMemoryBase = Private->PhysicalMemoryBegin + StackGap;\r
-              \r
+              DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", TopOfNewStack - NewStackSize, NewStackSize));\r
+              BuildStackHob (TopOfNewStack - NewStackSize, NewStackSize);\r
+\r
               //\r
-              // Caculate stack offset and heap offset between temporary memory and new permement \r
-              // memory seperately.\r
+              // Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address\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%lX Stack Offset = 0x%lX\n", (INT64)HeapOffset, (INT64)StackOffset));\r
-              \r
+              TemporaryRamBase   = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;\r
+              TemporaryRamSize   = SecCoreData->TemporaryRamSize;\r
+              TemporaryStackSize = SecCoreData->StackSize;\r
+\r
               //\r
-              // Caculate new HandOffTable and PrivateData address in permenet memory's stack\r
+              // Caculate new HandOffTable and PrivateData address in permanent memory's stack\r
               //\r
-              NewHandOffTable        = (EFI_HOB_HANDOFF_INFO_TABLE *)((UINTN)OldHandOffTable + HeapOffset);\r
-              PrivateInMem           = (PEI_CORE_INSTANCE *)((UINTN) (VOID*) Private + StackOffset);\r
+              if (StackOffsetPositive) {\r
+                SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);\r
+                Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);\r
+              } else {\r
+                SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);\r
+                Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);\r
+              }\r
 \r
               //\r
               // TemporaryRamSupportPpi is produced by platform's SEC\r
               //\r
-              Status = PeiLocatePpi (\r
-                         (CONST EFI_PEI_SERVICES **) PeiServices,\r
+              Status = PeiServicesLocatePpi (\r
                          &gEfiTemporaryRamSupportPpiGuid,\r
                          0,\r
                          NULL,\r
                          (VOID**)&TemporaryRamSupportPpi\r
                          );\r
-\r
-\r
               if (!EFI_ERROR (Status)) {\r
                 //\r
-                // Temporary Ram support Ppi is provided by platform, it will copy \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 temporary memory.\r
+                // After invoking Temporary Ram Support PPI, the following code's \r
+                // stack is in permanent memory.\r
                 //\r
                 TemporaryRamSupportPpi->TemporaryRamMigration (\r
-                                          (CONST EFI_PEI_SERVICES **) PeiServices,\r
-                                          (EFI_PHYSICAL_ADDRESS)(UINTN) SecCoreData->TemporaryRamBase,\r
-                                          (EFI_PHYSICAL_ADDRESS)(UINTN) NewPermenentMemoryBase,\r
-                                          SecCoreData->TemporaryRamSize\r
+                                          PeiServices,\r
+                                          TemporaryRamBase,\r
+                                          (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize),\r
+                                          TemporaryRamSize\r
                                           );\r
 \r
               } else {\r
                 //\r
                 // In IA32/x64/Itanium architecture, we need platform provide\r
-                // TEMPORAY_RAM_MIGRATION_PPI.\r
+                // TEMPORARY_RAM_MIGRATION_PPI.\r
                 //\r
                 ASSERT (FALSE);\r
               }\r
 \r
-\r
-              //\r
-              //\r
-              // Fixup the PeiCore's private data\r
-              //\r
-              PrivateInMem->Ps          = &PrivateInMem->ServiceTableShadow;\r
-              PrivateInMem->CpuIo       = &PrivateInMem->ServiceTableShadow.CpuIo;\r
-              PrivateInMem->HobList.Raw = (VOID*) ((UINTN) PrivateInMem->HobList.Raw + HeapOffset);\r
-              PrivateInMem->StackBase   = (EFI_PHYSICAL_ADDRESS)(((UINTN)PrivateInMem->PhysicalMemoryBegin + EFI_PAGE_MASK) & ~EFI_PAGE_MASK);\r
-\r
-              PeiServices = (CONST EFI_PEI_SERVICES **) &PrivateInMem->Ps;\r
-\r
-              //\r
-              // Fixup for PeiService's address\r
-              //\r
-              SetPeiServicesTablePointer(PeiServices);\r
-\r
-              //\r
-              // Update HandOffHob for new installed permenent memory\r
-              //\r
-              NewHandOffTable->EfiEndOfHobList =\r
-                (EFI_PHYSICAL_ADDRESS)((UINTN) NewHandOffTable->EfiEndOfHobList + HeapOffset);\r
-              NewHandOffTable->EfiMemoryTop        = PrivateInMem->PhysicalMemoryBegin +\r
-                                                     PrivateInMem->PhysicalMemoryLength;\r
-              NewHandOffTable->EfiMemoryBottom     = PrivateInMem->PhysicalMemoryBegin;\r
-              NewHandOffTable->EfiFreeMemoryTop    = PrivateInMem->FreePhysicalMemoryTop;\r
-              NewHandOffTable->EfiFreeMemoryBottom = NewHandOffTable->EfiEndOfHobList +\r
-                                                     sizeof (EFI_HOB_GENERIC_HEADER);\r
-\r
-              //\r
-              // We need convert the PPI desciptor's pointer\r
-              //\r
-              ConvertPpiPointers (PrivateInMem, \r
-                                  OldCheckingBottom, \r
-                                  OldCheckingTop, \r
-                                  HeapOffset\r
-                                  );\r
-\r
-              DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n",\r
-                                  PrivateInMem->StackBase,\r
-                                  PrivateInMem->StackSize));\r
-              BuildStackHob (PrivateInMem->StackBase, PrivateInMem->StackSize);\r
-\r
-              //\r
-              // After the whole temporary memory is migrated, then we can allocate page in\r
-              // permenent memory.\r
-              //\r
-              PrivateInMem->PeiMemoryInstalled     = TRUE;\r
-\r
-              //\r
-              // Indicate that PeiCore reenter\r
-              //\r
-              PrivateInMem->PeimDispatcherReenter  = TRUE;\r
-              \r
-              if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (PrivateInMem->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
-                //\r
-                // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array.\r
-                // Every bit in the array indicate the status of the corresponding memory page available or not\r
-                //\r
-                PrivateInMem->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64));\r
-              }\r
-              //\r
-              // Shadow PEI Core. When permanent memory is avaiable, shadow\r
-              // PEI Core and PEIMs to get high performance.\r
-              //\r
-              PrivateInMem->ShadowedPeiCore = ShadowPeiCore (\r
-                                                PeiServices,\r
-                                                PrivateInMem\r
-                                                );\r
-              //\r
-              // Process the Notify list and dispatch any notifies for\r
-              // newly installed PPIs.\r
-              //\r
-              ProcessNotifyList (PrivateInMem);\r
-\r
               //\r
               // Entry PEI Phase 2\r
               //\r
-              PeiCore (SecCoreData, NULL, PrivateInMem);\r
+              PeiCore (SecCoreData, NULL, Private);\r
 \r
               //\r
               // Code should not come here\r
               //\r
-              ASSERT_EFI_ERROR(FALSE);\r
+              ASSERT (FALSE);\r
             }\r
 \r
             //\r
index 1bb1103b7382fcfc6135a748256ce3578996b7b9..fbfe4f59da9935f2e03305c796b359253e28c665 100644 (file)
@@ -128,13 +128,39 @@ typedef struct {
   UINTN                               SectionIndex;\r
 } CACHE_SECTION_DATA;\r
 \r
+///\r
+/// Forward declaration for PEI_CORE_INSTANCE\r
+///\r
+typedef struct _PEI_CORE_INSTANCE  PEI_CORE_INSTANCE;\r
+\r
+\r
+/**\r
+  Function Pointer type for PeiCore function.\r
+  @param SecCoreData     Points to a data structure containing SEC to PEI handoff data, such as the size \r
+                         and location of temporary RAM, the stack location and the BFV location.\r
+  @param PpiList         Points to a list of one or more PPI descriptors to be installed initially by the PEI core.\r
+                         An empty PPI list consists of a single descriptor with the end-tag\r
+                         EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization\r
+                         phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such\r
+                         that both the PEI Foundation and any modules can leverage the associated service\r
+                         calls and/or code in these early PPIs\r
+  @param OldCoreData     Pointer to old core data that is used to initialize the\r
+                         core's data areas.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PEICORE_FUNCTION_POINTER)(\r
+  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,\r
+  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,\r
+  IN PEI_CORE_INSTANCE              *OldCoreData\r
+  );\r
 \r
 #define PEI_CORE_HANDLE_SIGNATURE  SIGNATURE_32('P','e','i','C')\r
 \r
 ///\r
 /// Pei Core private data structure instance\r
 ///\r
-typedef struct{\r
+struct _PEI_CORE_INSTANCE {\r
   UINTN                              Signature;\r
   \r
   ///\r
@@ -166,8 +192,6 @@ typedef struct{
   EFI_PEI_HOB_POINTERS               HobList;\r
   BOOLEAN                            SwitchStackSignal;\r
   BOOLEAN                            PeiMemoryInstalled;\r
-  EFI_PHYSICAL_ADDRESS               StackBase;\r
-  UINT64                             StackSize;\r
   VOID                               *CpuIo;\r
   EFI_PEI_SECURITY2_PPI              *PrivateSecurityPpi;\r
   EFI_PEI_SERVICES                   ServiceTableShadow;\r
@@ -175,7 +199,9 @@ typedef struct{
   EFI_PHYSICAL_ADDRESS               PhysicalMemoryBegin;\r
   UINT64                             PhysicalMemoryLength;\r
   EFI_PHYSICAL_ADDRESS               FreePhysicalMemoryTop;\r
-  VOID*                              ShadowedPeiCore;\r
+  UINTN                              HeapOffset;\r
+  BOOLEAN                            HeapOffsetPositive;\r
+  PEICORE_FUNCTION_POINTER           ShadowedPeiCore;\r
   CACHE_SECTION_DATA                 CacheSection;\r
   //\r
   // For Loading modules at fixed address feature to cache the top address below which the \r
@@ -193,7 +219,7 @@ typedef struct{
   // This field points to the shadowed image read function\r
   //\r
   PE_COFF_LOADER_READ_FILE          ShadowedImageRead;\r
-} PEI_CORE_INSTANCE;\r
+};\r
 \r
 ///\r
 /// Pei Core Instance Data Macros\r
@@ -201,27 +227,6 @@ typedef struct{
 #define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \\r
   CR(a, PEI_CORE_INSTANCE, Ps, PEI_CORE_HANDLE_SIGNATURE)\r
 \r
-/**\r
-  Function Pointer type for PeiCore function.\r
-  @param SecCoreData     Points to a data structure containing SEC to PEI handoff data, such as the size \r
-                         and location of temporary RAM, the stack location and the BFV location.\r
-  @param PpiList         Points to a list of one or more PPI descriptors to be installed initially by the PEI core.\r
-                         An empty PPI list consists of a single descriptor with the end-tag\r
-                         EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization\r
-                         phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such\r
-                         that both the PEI Foundation and any modules can leverage the associated service\r
-                         calls and/or code in these early PPIs\r
-  @param OldCoreData     Pointer to old core data that is used to initialize the\r
-                         core's data areas.\r
-**/\r
-typedef\r
-EFI_STATUS\r
-(EFIAPI *PEICORE_FUNCTION_POINTER)(\r
-  IN CONST  EFI_SEC_PEI_HAND_OFF    *SecCoreData,\r
-  IN CONST  EFI_PEI_PPI_DESCRIPTOR  *PpiList,\r
-  IN PEI_CORE_INSTANCE              *OldCoreData\r
-  );\r
-\r
 ///\r
 /// Union of temporarily used function pointers (to save stack space)\r
 ///\r
@@ -380,6 +385,8 @@ InitializePpiServices (
                              will be fixup for PpiData and PpiDescriptor.\r
   @param Fixup               The address difference between\r
                              the new Hob list and old Hob list.\r
+  @param FixupPositive       TRUE if new Hob list is above the old Hob list.  \r
+                             Otherwise FALSE.\r
 \r
 **/\r
 VOID\r
@@ -387,7 +394,8 @@ ConvertPpiPointers (
   IN PEI_CORE_INSTANCE       *PrivateData,\r
   IN UINTN                   OldCheckingBottom,\r
   IN UINTN                   OldCheckingTop,\r
-  IN INTN                    Fixup\r
+  IN UINTN                   Fixup,\r
+  IN BOOLEAN                 FixupPositive\r
   );\r
 \r
 /**\r
index ba665ee57bbdafe10d0a71bfeb1771a99cd623df..bf99e4bd4c2229e24b59e345a345e98a72cef003 100644 (file)
@@ -64,6 +64,55 @@ EFI_PEI_SERVICES  gPs = {
   PeiRegisterForShadow\r
 };\r
 \r
+/**\r
+  Shadow PeiCore module from flash to installed memory.\r
+  \r
+  @param PrivateData    PeiCore's private data structure\r
+\r
+  @return PeiCore function address after shadowing.\r
+**/\r
+PEICORE_FUNCTION_POINTER\r
+ShadowPeiCore (\r
+  IN PEI_CORE_INSTANCE  *PrivateData\r
+  )\r
+{\r
+  EFI_PEI_FILE_HANDLE  PeiCoreFileHandle;\r
+  EFI_PHYSICAL_ADDRESS EntryPoint;\r
+  EFI_STATUS           Status;\r
+  UINT32               AuthenticationState;\r
+\r
+  PeiCoreFileHandle = NULL;\r
+\r
+  //\r
+  // Find the PEI Core in the BFV\r
+  //\r
+  Status = PrivateData->Fv[0].FvPpi->FindFileByType (\r
+                                       PrivateData->Fv[0].FvPpi,\r
+                                       EFI_FV_FILETYPE_PEI_CORE,\r
+                                       PrivateData->Fv[0].FvHandle,\r
+                                       &PeiCoreFileHandle\r
+                                       );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Shadow PEI Core into memory so it will run faster\r
+  //\r
+  Status = PeiLoadImage (\r
+              GetPeiServicesTablePointer (),\r
+              *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle),\r
+              PEIM_STATE_REGISITER_FOR_SHADOW,\r
+              &EntryPoint,\r
+              &AuthenticationState\r
+              );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Compute the PeiCore's function address after shaowed PeiCore.\r
+  // _ModuleEntryPoint is PeiCore main function entry\r
+  //\r
+  return (PEICORE_FUNCTION_POINTER)((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint);\r
+}\r
+\r
 /**\r
   This routine is invoked by main entry of PeiMain module during transition\r
   from SEC to PEI. After switching stack in the PEI core, it will restart\r
@@ -91,17 +140,17 @@ PeiCore (
   IN VOID                              *Data\r
   )\r
 {\r
-  PEI_CORE_INSTANCE                                     PrivateData;\r
-  EFI_STATUS                                            Status;\r
-  PEI_CORE_TEMP_POINTERS                                TempPtr;\r
-  UINT64                                                Tick;\r
-  PEI_CORE_INSTANCE                                     *OldCoreData;\r
-  EFI_PEI_CPU_IO_PPI                                    *CpuIo;\r
-  EFI_PEI_PCI_CFG2_PPI                                  *PciCfg;\r
-  PEICORE_FUNCTION_POINTER                              ShadowedPeiCore;\r
+  PEI_CORE_INSTANCE           PrivateData;\r
+  EFI_STATUS                  Status;\r
+  PEI_CORE_TEMP_POINTERS      TempPtr;\r
+  UINT64                      Tick;\r
+  PEI_CORE_INSTANCE           *OldCoreData;\r
+  EFI_PEI_CPU_IO_PPI          *CpuIo;\r
+  EFI_PEI_PCI_CFG2_PPI        *PciCfg;\r
+  EFI_HOB_HANDOFF_INFO_TABLE  *HandoffInformationTable;\r
 \r
   Tick = 0;\r
-  OldCoreData = (PEI_CORE_INSTANCE *) Data;\r
+  OldCoreData = (PEI_CORE_INSTANCE *)Data;\r
 \r
   //\r
   // Record the system tick for first entering PeiCore.\r
@@ -114,22 +163,82 @@ PeiCore (
   }\r
 \r
   if (OldCoreData != NULL) {\r
-    ShadowedPeiCore = (PEICORE_FUNCTION_POINTER) (UINTN) OldCoreData->ShadowedPeiCore;\r
-    \r
-    //\r
-    // PeiCore has been shadowed to memory for first entering, so\r
-    // just jump to PeiCore in memory here.\r
-    //\r
-    if (ShadowedPeiCore != NULL) {\r
-      OldCoreData->ShadowedPeiCore = NULL;\r
-      ShadowedPeiCore (\r
-        SecCoreData,\r
-        PpiList,\r
-        OldCoreData\r
-        );\r
+    if (OldCoreData->ShadowedPeiCore == NULL) {\r
+      //\r
+      //\r
+      // Fixup the PeiCore's private data\r
+      //\r
+      OldCoreData->Ps          = &OldCoreData->ServiceTableShadow;\r
+      OldCoreData->CpuIo       = &OldCoreData->ServiceTableShadow.CpuIo;\r
+      if (OldCoreData->HeapOffsetPositive) {\r
+        OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw + OldCoreData->HeapOffset);\r
+      } else {\r
+        OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw - OldCoreData->HeapOffset);\r
+      }\r
+\r
+      //\r
+      // Fixup for PeiService's address\r
+      //\r
+      SetPeiServicesTablePointer ((CONST EFI_PEI_SERVICES **)&OldCoreData->Ps);\r
+\r
+      //\r
+      // Update HandOffHob for new installed permenent memory\r
+      //\r
+      HandoffInformationTable = OldCoreData->HobList.HandoffInformationTable;\r
+      if (OldCoreData->HeapOffsetPositive) {\r
+        HandoffInformationTable->EfiEndOfHobList   = HandoffInformationTable->EfiEndOfHobList + OldCoreData->HeapOffset;\r
+      } else {\r
+        HandoffInformationTable->EfiEndOfHobList   = HandoffInformationTable->EfiEndOfHobList - OldCoreData->HeapOffset;\r
+      }\r
+      HandoffInformationTable->EfiMemoryTop        = OldCoreData->PhysicalMemoryBegin + OldCoreData->PhysicalMemoryLength;\r
+      HandoffInformationTable->EfiMemoryBottom     = OldCoreData->PhysicalMemoryBegin;\r
+      HandoffInformationTable->EfiFreeMemoryTop    = OldCoreData->FreePhysicalMemoryTop;\r
+      HandoffInformationTable->EfiFreeMemoryBottom = HandoffInformationTable->EfiEndOfHobList + sizeof (EFI_HOB_GENERIC_HEADER);\r
+\r
+      //\r
+      // We need convert the PPI desciptor's pointer\r
+      //\r
+      ConvertPpiPointers (OldCoreData, (UINTN)SecCoreData->TemporaryRamBase, (UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize, OldCoreData->HeapOffset, OldCoreData->HeapOffsetPositive);\r
+\r
+      //\r
+      // After the whole temporary memory is migrated, then we can allocate page in\r
+      // permenent memory.\r
+      //\r
+      OldCoreData->PeiMemoryInstalled = TRUE;\r
+\r
+      //\r
+      // Indicate that PeiCore reenter\r
+      //\r
+      OldCoreData->PeimDispatcherReenter = TRUE;\r
+      \r
+      if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (OldCoreData->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {\r
+        //\r
+        // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array.\r
+        // Every bit in the array indicate the status of the corresponding memory page available or not\r
+        //\r
+        OldCoreData->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64));\r
+      }\r
+\r
+      //\r
+      // Process the Notify list and dispatch any notifies for\r
+      // newly installed PPIs.\r
+      //\r
+      ProcessNotifyList (OldCoreData);\r
+\r
+      //\r
+      // Shadow PEI Core. When permanent memory is avaiable, shadow\r
+      // PEI Core and PEIMs to get high performance.\r
+      //\r
+      OldCoreData->ShadowedPeiCore = ShadowPeiCore (OldCoreData);\r
+      \r
+      //\r
+      // PeiCore has been shadowed to memory for first entering, so\r
+      // just jump to PeiCore in memory here.\r
+      //\r
+      OldCoreData->ShadowedPeiCore (SecCoreData, PpiList, OldCoreData);\r
     }\r
 \r
-    CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));\r
+    CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData));\r
     \r
     CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;\r
     PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;\r
index 8089796d7b62ba400cf9bbb09c186a287818b987..65dc5be9fcd96ae5519c15b769f44dee5a117277 100644 (file)
@@ -47,6 +47,8 @@ InitializePpiServices (
                              will be fixup for PpiData and PpiDescriptor.\r
   @param Fixup               The address difference between\r
                              the new Hob list and old Hob list.\r
+  @param FixupPositive       TRUE if new Hob list is above the old Hob list.  \r
+                             Otherwise FALSE.\r
 \r
 **/\r
 VOID\r
@@ -54,7 +56,8 @@ ConvertPpiPointers (
   IN PEI_CORE_INSTANCE       *PrivateData,\r
   IN UINTN                   OldCheckingBottom,\r
   IN UINTN                   OldCheckingTop,\r
-  IN INTN                    Fixup\r
+  IN UINTN                   Fixup,\r
+  IN BOOLEAN                 FixupPositive\r
   )\r
 {\r
   UINT8                 Index;\r
@@ -71,7 +74,11 @@ ConvertPpiPointers (
         // Convert the pointer to the PEIM descriptor from the old HOB heap\r
         // to the relocated HOB heap.\r
         //\r
-        PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);\r
+        if (FixupPositive) {\r
+          PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);\r
+        } else {\r
+          PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - Fixup);\r
+        }\r
 \r
         //\r
         // Only when the PEIM descriptor is in the old HOB should it be necessary\r
@@ -84,7 +91,11 @@ ConvertPpiPointers (
           // Convert the pointer to the GUID in the PPI or NOTIFY descriptor\r
           // from the old HOB heap to the relocated HOB heap.\r
           //\r
-          PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);\r
+          if (FixupPositive) {\r
+            PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);\r
+          } else {\r
+            PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - Fixup);\r
+          }\r
         }\r
 \r
         //\r
@@ -98,7 +109,11 @@ ConvertPpiPointers (
             // Convert the pointer to the PPI interface structure in the PPI descriptor\r
             // from the old HOB heap to the relocated HOB heap.\r
             //\r
-            PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);\r
+            if (FixupPositive) {\r
+              PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + Fixup);\r
+            } else {\r
+              PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - Fixup);\r
+            }\r
         }\r
       }\r
     }\r