]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/PeilessStartupLib/DxeLoad.c
OvmfPkg/PeilessStartupLib: Find NCCFV in non-td guest
[mirror_edk2.git] / OvmfPkg / Library / PeilessStartupLib / DxeLoad.c
index 6e79c30846725c7a8a13139693f5e92ade2e0e1b..4b1fefd452dc05fc30197c6ad25ab3e2ae416a59 100644 (file)
@@ -22,6 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/ReportStatusCodeLib.h>\r
 \r
 #define STACK_SIZE  0x20000\r
+extern EFI_GUID  gEfiNonCcFvGuid;\r
 \r
 /**\r
    Transfers control to DxeCore.\r
@@ -136,6 +137,133 @@ FindDxeCore (
   return Status;\r
 }\r
 \r
+/**\r
+ * This is a FFS_CHECK_SECTION_HOOK which is defined by caller to check\r
+ * if the section is an EFI_SECTION_FIRMWARE_VOLUME_IMAGE and if it is\r
+ * a NonCc FV.\r
+ *\r
+ * @param Section       The section in which we're checking for the NonCc FV.\r
+ * @return EFI_STATUS   The section is the NonCc FV.\r
+ */\r
+EFI_STATUS\r
+EFIAPI\r
+CheckSectionHookForDxeNonCc (\r
+  IN EFI_COMMON_SECTION_HEADER  *Section\r
+  )\r
+{\r
+  VOID         *Buffer;\r
+  EFI_STATUS   Status;\r
+  EFI_FV_INFO  FvImageInfo;\r
+\r
+  if (Section->Type != EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (IS_SECTION2 (Section)) {\r
+    Buffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER2));\r
+  } else {\r
+    Buffer = (VOID *)((UINT8 *)Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
+  }\r
+\r
+  ZeroMem (&FvImageInfo, sizeof (FvImageInfo));\r
+  Status = FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE)(UINTN)Buffer, &FvImageInfo);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO, "Cannot get volume info! %r\n", Status));\r
+    return Status;\r
+  }\r
+\r
+  return CompareGuid (&FvImageInfo.FvName, &gEfiNonCcFvGuid) ? EFI_SUCCESS : EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ * Find the NonCc FV.\r
+ *\r
+ * @param FvInstance    The FvInstance number.\r
+ * @return EFI_STATUS   Successfuly find the NonCc FV.\r
+ */\r
+EFI_STATUS\r
+EFIAPI\r
+FindDxeNonCc (\r
+  IN INTN  FvInstance\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+  EFI_PEI_FV_HANDLE    VolumeHandle;\r
+  EFI_PEI_FILE_HANDLE  FileHandle;\r
+  EFI_PEI_FV_HANDLE    FvImageHandle;\r
+  EFI_FV_INFO          FvImageInfo;\r
+  UINT32               FvAlignment;\r
+  VOID                 *FvBuffer;\r
+\r
+  FileHandle = NULL;\r
+\r
+  //\r
+  // Caller passed in a specific FV to try, so only try that one\r
+  //\r
+  Status = FfsFindNextVolume (FvInstance, &VolumeHandle);\r
+  ASSERT (Status == EFI_SUCCESS);\r
+\r
+  Status = FfsFindNextFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, VolumeHandle, &FileHandle);\r
+  ASSERT (FileHandle != NULL);\r
+\r
+  //\r
+  // Find FvImage in FvFile\r
+  //\r
+  Status = FfsFindSectionData (EFI_SECTION_FIRMWARE_VOLUME_IMAGE, CheckSectionHookForDxeNonCc, FileHandle, (VOID **)&FvImageHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Collect FvImage Info.\r
+  //\r
+  ZeroMem (&FvImageInfo, sizeof (FvImageInfo));\r
+  Status = FfsGetVolumeInfo (FvImageHandle, &FvImageInfo);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // FvAlignment must be more than 8 bytes required by FvHeader structure.\r
+  //\r
+  FvAlignment = 1 << ((FvImageInfo.FvAttributes & EFI_FVB2_ALIGNMENT) >> 16);\r
+  if (FvAlignment < 8) {\r
+    FvAlignment = 8;\r
+  }\r
+\r
+  //\r
+  // Check FvImage\r
+  //\r
+  if ((UINTN)FvImageInfo.FvStart % FvAlignment != 0) {\r
+    FvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32)FvImageInfo.FvSize), FvAlignment);\r
+    if (FvBuffer == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    CopyMem (FvBuffer, FvImageInfo.FvStart, (UINTN)FvImageInfo.FvSize);\r
+    //\r
+    // Update FvImageInfo after reload FvImage to new aligned memory\r
+    //\r
+    FfsGetVolumeInfo ((EFI_PEI_FV_HANDLE)FvBuffer, &FvImageInfo);\r
+  }\r
+\r
+  //\r
+  // Inform HOB consumer phase, i.e. DXE core, the existence of this FV\r
+  //\r
+  BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)FvImageInfo.FvStart, FvImageInfo.FvSize);\r
+\r
+  //\r
+  // Makes the encapsulated volume show up in DXE phase to skip processing of\r
+  // encapsulated file again.\r
+  //\r
+  BuildFv2Hob (\r
+    (EFI_PHYSICAL_ADDRESS)(UINTN)FvImageInfo.FvStart,\r
+    FvImageInfo.FvSize,\r
+    &FvImageInfo.FvName,\r
+    &(((EFI_FFS_FILE_HEADER *)FileHandle)->Name)\r
+    );\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
    This function finds DXE Core in the firmware volume and transfer the control to\r
    DXE core.\r
@@ -168,10 +296,14 @@ DxeLoadCore (
     return Status;\r
   }\r
 \r
+  if (!TdIsEnabled ()) {\r
+    FindDxeNonCc (FvInstance);\r
+  }\r
+\r
   //\r
   // Load the DXE Core from a Firmware Volume.\r
   //\r
-  Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);\r
+  Status = FfsFindSectionData (EFI_SECTION_PE32, NULL, FileHandle, &PeCoffImage);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r