]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / DxeLoad.c
index aa0507686b27f3ce7afaab1fc606ee2c87fd7c83..c6e5b8330927ed093cac6222b1591160cbf0b989 100644 (file)
@@ -2,14 +2,9 @@
   Last PEIM.\r
   Responsibility of this module is to load the DXE Core from a Firmware Volume.\r
 \r
-Copyright (c) 2006 - 2012, 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
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2016 HP Development Company, L.P.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -24,6 +19,12 @@ CONST EFI_DXE_IPL_PPI mDxeIplPpi = {
   DxeLoadCore\r
 };\r
 \r
+CONST EFI_PEI_PPI_DESCRIPTOR mDxeIplPpiList = {\r
+  EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gEfiDxeIplPpiGuid,\r
+  (VOID *) &mDxeIplPpi\r
+};\r
+\r
 CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {\r
   CustomGuidedSectionExtract\r
 };\r
@@ -32,17 +33,10 @@ CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {
   Decompress\r
 };\r
 \r
-CONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
-  {\r
-    EFI_PEI_PPI_DESCRIPTOR_PPI,\r
-    &gEfiDxeIplPpiGuid,\r
-    (VOID *) &mDxeIplPpi\r
-  },\r
-  {\r
-    (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
-    &gEfiPeiDecompressPpiGuid,\r
-    (VOID *) &mDecompressPpi\r
-  }\r
+CONST EFI_PEI_PPI_DESCRIPTOR mDecompressPpiList = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPeiDecompressPpiGuid,\r
+  (VOID *) &mDecompressPpi\r
 };\r
 \r
 CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {\r
@@ -51,17 +45,23 @@ CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
   NULL\r
 };\r
 \r
+CONST EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList = {\r
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+  &gEfiPeiMemoryDiscoveredPpiGuid,\r
+  InstallIplPermanentMemoryPpis\r
+};\r
+\r
 /**\r
   Entry point of DXE IPL PEIM.\r
-  \r
-  This function installs DXE IPL PPI and Decompress PPI.  It also reloads\r
+\r
+  This function installs DXE IPL PPI.  It also reloads\r
   itself to memory on non-S3 resume boot path.\r
 \r
   @param  FileHandle  Handle of the file being invoked.\r
   @param  PeiServices Describes the list of possible PEI Services.\r
 \r
   @retval EFI_SUCESS  The entry point of DXE IPL PEIM executes successfully.\r
-  @retval Others      Some error occurs during the execution of this function. \r
+  @retval Others      Some error occurs during the execution of this function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -73,34 +73,93 @@ PeimInitializeDxeIpl (
 {\r
   EFI_STATUS                                Status;\r
   EFI_BOOT_MODE                             BootMode;\r
-  EFI_GUID                                  *ExtractHandlerGuidTable;\r
-  UINTN                                     ExtractHandlerNumber;\r
-  EFI_PEI_PPI_DESCRIPTOR                    *GuidPpi;\r
-  \r
+  VOID                                      *Dummy;\r
+\r
   BootMode = GetBootModeHob ();\r
 \r
   if (BootMode != BOOT_ON_S3_RESUME) {\r
     Status = PeiServicesRegisterForShadow (FileHandle);\r
     if (Status == EFI_SUCCESS) {\r
       //\r
-      // EFI_SUCESS means it is the first time to call register for shadow. \r
-      // \r
+      // EFI_SUCESS means it is the first time to call register for shadow.\r
+      //\r
       return Status;\r
     }\r
-    \r
+\r
     //\r
     // Ensure that DXE IPL is shadowed to permanent memory.\r
     //\r
     ASSERT (Status == EFI_ALREADY_STARTED);\r
+\r
+    //\r
+    // DXE core load requires permanent memory.\r
+    //\r
+    Status = PeiServicesLocatePpi (\r
+               &gEfiPeiMemoryDiscoveredPpiGuid,\r
+               0,\r
+               NULL,\r
+               (VOID **) &Dummy\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Now the permanent memory exists, install the PPIs for decompression\r
+    // and section extraction.\r
+    //\r
+    Status = InstallIplPermanentMemoryPpis (NULL, NULL, NULL);\r
+    ASSERT_EFI_ERROR (Status);\r
+  } else {\r
+    //\r
+    // Install memory discovered PPI notification to install PPIs for\r
+    // decompression and section extraction.\r
+    //\r
+    Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList);\r
+    ASSERT_EFI_ERROR (Status);\r
   }\r
-     \r
+\r
+  //\r
+  // Install DxeIpl PPI.\r
+  //\r
+  Status = PeiServicesInstallPpi (&mDxeIplPpiList);\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+   This function installs the PPIs that require permanent memory.\r
+\r
+   @param  PeiServices      Indirect reference to the PEI Services Table.\r
+   @param  NotifyDescriptor Address of the notification descriptor data structure.\r
+   @param  Ppi              Address of the PPI that was installed.\r
+\r
+   @return EFI_SUCCESS      The PPIs were installed successfully.\r
+   @return Others           Some error occurs during the execution of this function.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InstallIplPermanentMemoryPpis (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_GUID                      *ExtractHandlerGuidTable;\r
+  UINTN                         ExtractHandlerNumber;\r
+  EFI_PEI_PPI_DESCRIPTOR        *GuidPpi;\r
+\r
   //\r
-  // Get custom extract guided section method guid list \r
+  // Get custom extract guided section method guid list\r
   //\r
   ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
-  \r
+\r
   //\r
-  // Install custom extraction guid PPI\r
+  // Install custom guided section extraction PPI\r
   //\r
   if (ExtractHandlerNumber > 0) {\r
     GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
@@ -113,18 +172,18 @@ PeimInitializeDxeIpl (
       ASSERT_EFI_ERROR(Status);\r
     }\r
   }\r
-  \r
+\r
   //\r
-  // Install DxeIpl and Decompress PPIs.\r
+  // Install Decompress PPI.\r
   //\r
-  Status = PeiServicesInstallPpi (mPpiList);\r
+  Status = PeiServicesInstallPpi (&mDecompressPpiList);\r
   ASSERT_EFI_ERROR(Status);\r
 \r
   return Status;\r
 }\r
 \r
 /**\r
-   Validate variable data for the MemoryTypeInformation. \r
+   Validate variable data for the MemoryTypeInformation.\r
 \r
    @param MemoryData       Variable data.\r
    @param MemoryDataSize   Variable data length.\r
@@ -171,16 +230,16 @@ ValidateMemoryTypeInfoVariable (
 }\r
 \r
 /**\r
-   Main entry point to last PEIM. \r
+   Main entry point to last PEIM.\r
 \r
    This function finds DXE Core in the firmware volume and transfer the control to\r
    DXE core.\r
-    \r
+\r
    @param This          Entry point for DXE IPL PPI.\r
    @param PeiServices   General purpose services available to every PEIM.\r
    @param HobList       Address to the Pei HOB list.\r
-   \r
-   @return EFI_SUCCESS              DXE core was successfully loaded. \r
+\r
+   @return EFI_SUCCESS              DXE core was successfully loaded.\r
    @return EFI_OUT_OF_RESOURCES     There are not enough resources to load DXE core.\r
 \r
 **/\r
@@ -230,7 +289,7 @@ DxeLoadCore (
         );\r
     }\r
     ASSERT_EFI_ERROR (Status);\r
-    \r
+\r
     Status = S3Resume->S3RestoreConfig2 (S3Resume);\r
     ASSERT_EFI_ERROR (Status);\r
   } else if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
@@ -245,7 +304,7 @@ DxeLoadCore (
     if (EFI_ERROR (Status)) {\r
       DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status));\r
       //\r
-      // Report Status code the failure of locating Recovery PPI \r
+      // Report Status code the failure of locating Recovery PPI\r
       //\r
       REPORT_STATUS_CODE (\r
         EFI_ERROR_CODE | EFI_ERROR_MAJOR,\r
@@ -273,31 +332,36 @@ DxeLoadCore (
     //\r
   }\r
 \r
-  Status = PeiServicesLocatePpi (\r
-             &gEfiPeiReadOnlyVariable2PpiGuid,\r
-             0,\r
-             NULL,\r
-             (VOID **)&Variable\r
-             );\r
-  if (!EFI_ERROR (Status)) {\r
-    DataSize = sizeof (MemoryData);\r
-    Status = Variable->GetVariable ( \r
-                         Variable, \r
-                         EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
-                         &gEfiMemoryTypeInformationGuid,\r
-                         NULL,\r
-                         &DataSize,\r
-                         &MemoryData\r
-                         );\r
-    if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {\r
-      //\r
-      // Build the GUID'd HOB for DXE\r
-      //\r
-      BuildGuidDataHob (\r
-        &gEfiMemoryTypeInformationGuid,\r
-        MemoryData,\r
-        DataSize\r
-        );\r
+  if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) {\r
+    //\r
+    // Don't build GuidHob if GuidHob has been installed.\r
+    //\r
+    Status = PeiServicesLocatePpi (\r
+               &gEfiPeiReadOnlyVariable2PpiGuid,\r
+               0,\r
+               NULL,\r
+               (VOID **)&Variable\r
+               );\r
+    if (!EFI_ERROR (Status)) {\r
+      DataSize = sizeof (MemoryData);\r
+      Status = Variable->GetVariable (\r
+                           Variable,\r
+                           EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
+                           &gEfiMemoryTypeInformationGuid,\r
+                           NULL,\r
+                           &DataSize,\r
+                           &MemoryData\r
+                           );\r
+      if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) {\r
+        //\r
+        // Build the GUID'd HOB for DXE\r
+        //\r
+        BuildGuidDataHob (\r
+          &gEfiMemoryTypeInformationGuid,\r
+          MemoryData,\r
+          DataSize\r
+          );\r
+      }\r
     }\r
   }\r
 \r
@@ -371,7 +435,7 @@ DxeLoadCore (
    instance that contains DxeCore.\r
 \r
    @return FileHandle of DxeCore to load DxeCore.\r
-   \r
+\r
 **/\r
 EFI_PEI_FILE_HANDLE\r
 DxeIplFindDxeCore (\r
@@ -382,7 +446,7 @@ DxeIplFindDxeCore (
   UINTN                 Instance;\r
   EFI_PEI_FV_HANDLE     VolumeHandle;\r
   EFI_PEI_FILE_HANDLE   FileHandle;\r
-  \r
+\r
   Instance    = 0;\r
   while (TRUE) {\r
     //\r
@@ -397,7 +461,7 @@ DxeIplFindDxeCore (
       REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT));\r
     }\r
     ASSERT_EFI_ERROR (Status);\r
-    \r
+\r
     //\r
     // Find the DxeCore file type from the beginning in this firmware volume.\r
     //\r
@@ -450,7 +514,7 @@ DxeIplFindDxeCore (
                                 output buffer. If the input\r
                                 section's GuidedSectionHeader.\r
                                 Attributes field has the\r
-                                EFI_GUIDED_SECTION_AUTH_STATUS_VALID \r
+                                EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
                                 bit as clear,\r
                                 AuthenticationStatus must return\r
                                 zero. These bits reflect the\r
@@ -460,14 +524,14 @@ DxeIplFindDxeCore (
                                 EFI_SUCCESS, the value of\r
                                 AuthenticationStatus is\r
                                 undefined.\r
-  \r
+\r
   @retval EFI_SUCCESS           The InputSection was\r
                                 successfully processed and the\r
                                 section contents were returned.\r
-  \r
+\r
   @retval EFI_OUT_OF_RESOURCES  The system has insufficient\r
                                 resources to process the request.\r
-  \r
+\r
   @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
                                 not match this instance of the\r
                                 GUIDed Section Extraction PPI.\r
@@ -488,7 +552,7 @@ CustomGuidedSectionExtract (
   UINT32          ScratchBufferSize;\r
   UINT32          OutputBufferSize;\r
   UINT16          SectionAttribute;\r
-  \r
+\r
   //\r
   // Init local variable\r
   //\r
@@ -503,12 +567,12 @@ CustomGuidedSectionExtract (
              &ScratchBufferSize,\r
              &SectionAttribute\r
              );\r
-  \r
+\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
     return Status;\r
   }\r
-  \r
+\r
   if (ScratchBufferSize != 0) {\r
     //\r
     // Allocate scratch buffer\r
@@ -519,24 +583,19 @@ CustomGuidedSectionExtract (
     }\r
   }\r
 \r
-  if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {  \r
+  if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {\r
     //\r
     // Allocate output buffer\r
     //\r
-    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
+    *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize));\r
     if (*OutputBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
-    //\r
-    // *OutputBuffer still is one section. Adjust *OutputBuffer offset, \r
-    // skip EFI section header to make section data at page alignment.\r
-    //\r
-    *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
   }\r
-  \r
+\r
   Status = ExtractGuidedSectionDecode (\r
-             InputSection, \r
+             InputSection,\r
              OutputBuffer,\r
              ScratchBuffer,\r
              AuthenticationStatus\r
@@ -548,9 +607,9 @@ CustomGuidedSectionExtract (
     DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));\r
     return Status;\r
   }\r
-  \r
+\r
   *OutputSize = (UINTN) OutputBufferSize;\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -562,7 +621,7 @@ CustomGuidedSectionExtract (
    This function looks up the compression type field in the input section and\r
    applies the appropriate compression algorithm to compress the section to a\r
    callee allocated buffer.\r
-    \r
+\r
    @param  This                  Points to this instance of the\r
                                  EFI_PEI_DECOMPRESS_PEI PPI.\r
    @param  CompressionSection    Points to the compressed section.\r
@@ -570,14 +629,14 @@ CustomGuidedSectionExtract (
                                  sections.\r
    @param  OutputSize            Holds the returned size of the decompress\r
                                  section streams.\r
-   \r
+\r
    @retval EFI_SUCCESS           The section was decompressed successfully.\r
                                  OutputBuffer contains the resulting data and\r
                                  OutputSize contains the resulting size.\r
 \r
 **/\r
 EFI_STATUS\r
-EFIAPI \r
+EFIAPI\r
 Decompress (\r
   IN CONST  EFI_PEI_DECOMPRESS_PPI  *This,\r
   IN CONST  EFI_COMPRESSION_SECTION *CompressionSection,\r
@@ -611,7 +670,7 @@ Decompress (
     UncompressedLength = CompressionSection->UncompressedLength;\r
     CompressionType = CompressionSection->CompressionType;\r
   }\r
-  \r
+\r
   //\r
   // This is a compression set, expand it\r
   //\r
@@ -643,18 +702,13 @@ Decompress (
         return EFI_OUT_OF_RESOURCES;\r
       }\r
       //\r
-      // Allocate destination buffer, extra one page for adjustment \r
+      // Allocate destination buffer\r
       //\r
-      DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
+      DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
       if (DstBuffer == NULL) {\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
       //\r
-      // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
-      // to make section data at page alignment.\r
-      //\r
-      DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
-      //\r
       // Call decompress function\r
       //\r
       Status = UefiDecompress (\r
@@ -684,16 +738,11 @@ Decompress (
     // Allocate destination buffer\r
     //\r
     DstBufferSize = UncompressedLength;\r
-    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
+    DstBuffer     = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));\r
     if (DstBuffer == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
     //\r
-    // Adjust DstBuffer offset, skip EFI section header\r
-    // to make section data at page alignment.\r
-    //\r
-    DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
-    //\r
     // stream is not actually compressed, just encapsulated.  So just copy it.\r
     //\r
     CopyMem (DstBuffer, CompressionSource, DstBufferSize);\r
@@ -736,8 +785,8 @@ UpdateStackHob (
   while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
     if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
       //\r
-      // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to \r
-      // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some \r
+      // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to\r
+      // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some\r
       // PEIMs may also keep key information on stack\r
       //\r
       BuildMemoryAllocationHob (\r
@@ -755,3 +804,4 @@ UpdateStackHob (
     Hob.Raw = GET_NEXT_HOB (Hob);\r
   }\r
 }\r
+\r