#include <Library/ReportStatusCodeLib.h>\r
\r
#define STACK_SIZE 0x20000\r
+extern EFI_GUID gEfiNonCcFvGuid;\r
\r
/**\r
Transfers control to DxeCore.\r
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
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