]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
MdeModulePkg: Allow DxeIpl to load without permanent memory
[mirror_edk2.git] / MdeModulePkg / Core / Pei / PeiMain / PeiMain.c
index bf000229aaccbe4b7326a3814c80ada2ce72d866..10db496140ad0d6f5820f72c08fedb63572d6019 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Pei Core Main Entry Point\r
   \r
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -63,7 +63,8 @@ EFI_PEI_SERVICES  gPs = {
   PeiFfsGetVolumeInfo,\r
   PeiRegisterForShadow,\r
   PeiFfsFindSectionData3,\r
-  PeiFfsGetFileInfo2\r
+  PeiFfsGetFileInfo2,\r
+  PeiResetSystem2\r
 };\r
 \r
 /**\r
@@ -120,7 +121,7 @@ ShadowPeiCore (
   from SEC to PEI. After switching stack in the PEI core, it will restart\r
   with the old core data.\r
 \r
-  @param SecCoreData     Points to a data structure containing information about the PEI core's operating\r
+  @param SecCoreDataPtr  Points to a data structure containing information about the PEI core's operating\r
                          environment, such as the size and location of temporary RAM, the stack location and\r
                          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
@@ -137,23 +138,28 @@ ShadowPeiCore (
 VOID\r
 EFIAPI\r
 PeiCore (\r
-  IN CONST EFI_SEC_PEI_HAND_OFF        *SecCoreData,\r
+  IN CONST EFI_SEC_PEI_HAND_OFF        *SecCoreDataPtr,\r
   IN CONST EFI_PEI_PPI_DESCRIPTOR      *PpiList,\r
   IN VOID                              *Data\r
   )\r
 {\r
   PEI_CORE_INSTANCE           PrivateData;\r
+  EFI_SEC_PEI_HAND_OFF        *SecCoreData;\r
+  EFI_SEC_PEI_HAND_OFF        NewSecCoreData;\r
   EFI_STATUS                  Status;\r
   PEI_CORE_TEMP_POINTERS      TempPtr;\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
+  EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi;\r
+  UINTN                       Index;\r
+  \r
   //\r
   // Retrieve context passed into PEI Core\r
   //\r
-  OldCoreData = (PEI_CORE_INSTANCE *)Data;\r
+  OldCoreData = (PEI_CORE_INSTANCE *) Data;\r
+  SecCoreData = (EFI_SEC_PEI_HAND_OFF *) SecCoreDataPtr;\r
 \r
   //\r
   // Perform PEI Core phase specific actions.\r
@@ -177,8 +183,28 @@ PeiCore (
       OldCoreData->CpuIo = &OldCoreData->ServiceTableShadow.CpuIo;\r
       if (OldCoreData->HeapOffsetPositive) {\r
         OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw + OldCoreData->HeapOffset);\r
+        OldCoreData->UnknownFvInfo        = (PEI_CORE_UNKNOW_FORMAT_FV_INFO *) ((UINT8 *) OldCoreData->UnknownFvInfo + OldCoreData->HeapOffset);\r
+        OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->CurrentFvFileHandles + OldCoreData->HeapOffset);\r
+        OldCoreData->PpiData.PpiListPtrs  = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiListPtrs + OldCoreData->HeapOffset);\r
+        OldCoreData->Fv                   = (PEI_CORE_FV_HANDLE *) ((UINT8 *) OldCoreData->Fv + OldCoreData->HeapOffset);\r
+        for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r
+          OldCoreData->Fv[Index].PeimState     = (UINT8 *) OldCoreData->Fv[Index].PeimState + OldCoreData->HeapOffset;\r
+          OldCoreData->Fv[Index].FvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->Fv[Index].FvFileHandles + OldCoreData->HeapOffset);\r
+        }\r
+        OldCoreData->FileGuid             = (EFI_GUID *) ((UINT8 *) OldCoreData->FileGuid + OldCoreData->HeapOffset);\r
+        OldCoreData->FileHandles          = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->FileHandles + OldCoreData->HeapOffset);\r
       } else {\r
         OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw - OldCoreData->HeapOffset);\r
+        OldCoreData->UnknownFvInfo        = (PEI_CORE_UNKNOW_FORMAT_FV_INFO *) ((UINT8 *) OldCoreData->UnknownFvInfo - OldCoreData->HeapOffset);\r
+        OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->CurrentFvFileHandles - OldCoreData->HeapOffset);\r
+        OldCoreData->PpiData.PpiListPtrs  = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiListPtrs - OldCoreData->HeapOffset);\r
+        OldCoreData->Fv                   = (PEI_CORE_FV_HANDLE *) ((UINT8 *) OldCoreData->Fv - OldCoreData->HeapOffset);\r
+        for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r
+          OldCoreData->Fv[Index].PeimState     = (UINT8 *) OldCoreData->Fv[Index].PeimState - OldCoreData->HeapOffset;\r
+          OldCoreData->Fv[Index].FvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->Fv[Index].FvFileHandles - OldCoreData->HeapOffset);\r
+        }\r
+        OldCoreData->FileGuid             = (EFI_GUID *) ((UINT8 *) OldCoreData->FileGuid - OldCoreData->HeapOffset);\r
+        OldCoreData->FileHandles          = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->FileHandles - OldCoreData->HeapOffset);\r
       }\r
 \r
       //\r
@@ -233,7 +259,11 @@ PeiCore (
       // 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
+      OldCoreData->ShadowedPeiCore = (PEICORE_FUNCTION_POINTER) (UINTN) PeiCore;\r
+      if ((HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME && PcdGetBool (PcdShadowPeimOnS3Boot))\r
+          || (HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME && PcdGetBool (PcdShadowPeimOnBoot))) {\r
+        OldCoreData->ShadowedPeiCore = ShadowPeiCore (OldCoreData);\r
+      }\r
       \r
       //\r
       // PEI Core has now been shadowed to memory.  Restart PEI Core in memory.\r
@@ -250,9 +280,11 @@ PeiCore (
     //\r
     // Memory is available to the PEI Core and the PEI Core has been shadowed to memory.\r
     //\r
-    \r
+    CopyMem (&NewSecCoreData, SecCoreDataPtr, sizeof (NewSecCoreData));\r
+    SecCoreData = &NewSecCoreData;\r
+\r
     CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData));\r
-    \r
+\r
     CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;\r
     PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;\r
     \r
@@ -279,8 +311,33 @@ PeiCore (
 \r
   //\r
   // Initialize PEI Core Services\r
-  //  \r
+  //\r
   InitializeMemoryServices   (&PrivateData,    SecCoreData, OldCoreData);\r
+  if (OldCoreData == NULL) {\r
+    //\r
+    // Initialize PEI Core Private Data Buffer\r
+    //\r
+    PrivateData.PpiData.PpiListPtrs  = AllocateZeroPool (sizeof (PEI_PPI_LIST_POINTERS) * PcdGet32 (PcdPeiCoreMaxPpiSupported));\r
+    ASSERT (PrivateData.PpiData.PpiListPtrs != NULL);\r
+    PrivateData.Fv                   = AllocateZeroPool (sizeof (PEI_CORE_FV_HANDLE) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+    ASSERT (PrivateData.Fv != NULL);\r
+    PrivateData.Fv[0].PeimState      = AllocateZeroPool (sizeof (UINT8) * PcdGet32 (PcdPeiCoreMaxPeimPerFv) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+    ASSERT (PrivateData.Fv[0].PeimState != NULL);\r
+    PrivateData.Fv[0].FvFileHandles  = AllocateZeroPool (sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+    ASSERT (PrivateData.Fv[0].FvFileHandles != NULL);\r
+    for (Index = 1; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r
+      PrivateData.Fv[Index].PeimState     = PrivateData.Fv[Index - 1].PeimState + PcdGet32 (PcdPeiCoreMaxPeimPerFv);\r
+      PrivateData.Fv[Index].FvFileHandles = PrivateData.Fv[Index - 1].FvFileHandles + PcdGet32 (PcdPeiCoreMaxPeimPerFv);\r
+    }\r
+    PrivateData.UnknownFvInfo        = AllocateZeroPool (sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO) * PcdGet32 (PcdPeiCoreMaxFvSupported));\r
+    ASSERT (PrivateData.UnknownFvInfo != NULL);\r
+    PrivateData.CurrentFvFileHandles = AllocateZeroPool (sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv));\r
+    ASSERT (PrivateData.CurrentFvFileHandles != NULL);\r
+    PrivateData.FileGuid             = AllocatePool (sizeof (EFI_GUID) * PcdGet32 (PcdPeiCoreMaxPeimPerFv));\r
+    ASSERT (PrivateData.FileGuid != NULL);\r
+    PrivateData.FileHandles          = AllocatePool (sizeof (EFI_PEI_FILE_HANDLE) * (PcdGet32 (PcdPeiCoreMaxPeimPerFv) + 1));\r
+    ASSERT (PrivateData.FileHandles != NULL);\r
+  }\r
   InitializePpiServices      (&PrivateData,    OldCoreData);\r
   \r
   //\r
@@ -328,6 +385,22 @@ PeiCore (
       ASSERT_EFI_ERROR (Status);\r
     }\r
   } else {\r
+    //\r
+    // Try to locate Temporary RAM Done Ppi.\r
+    //\r
+    Status = PeiServicesLocatePpi (\r
+               &gEfiTemporaryRamDonePpiGuid,\r
+               0,\r
+               NULL,\r
+               (VOID**)&TemporaryRamDonePpi\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Disable the use of Temporary RAM after the transition from Temporary RAM to Permanent RAM is complete.\r
+      //\r
+      TemporaryRamDonePpi->TemporaryRamDone ();\r
+    }\r
+\r
     //\r
     // Alert any listeners that there is permanent memory available\r
     //\r
@@ -347,10 +420,12 @@ PeiCore (
   //\r
   PeiDispatcher (SecCoreData, &PrivateData);\r
 \r
-  //\r
-  // Check if InstallPeiMemory service was called.\r
-  //\r
-  ASSERT(PrivateData.PeiMemoryInstalled == TRUE);\r
+  if (PrivateData.HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) {\r
+    //\r
+    // Check if InstallPeiMemory service was called on non-S3 resume boot path.\r
+    //\r
+    ASSERT(PrivateData.PeiMemoryInstalled == TRUE);\r
+  }\r
 \r
   //\r
   // Measure PEI Core execution time.\r
@@ -368,6 +443,17 @@ PeiCore (
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Report status code to indicate DXE IPL PPI could not be found.\r
+    //\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
+      (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND)\r
+      );\r
+    CpuDeadLoop ();\r
+  }\r
+\r
   //\r
   // Enter DxeIpl to load Dxe core.\r
   //\r