diff --git a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c index f5d70c59f8..0b6cb47cd0 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c +++ b/UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c @@ -114,20 +114,23 @@ LoadPeCoffImage ( } /** - This function searchs a given file type within a valid FV. + This function searchs a given file type with a given Guid within a valid FV. + If input Guid is NULL, will locate the first section having the given file type @param FvHeader A pointer to firmware volume header that contains the set of files to be searched. @param FileType File type to be searched. + @param Guid Will ignore if it is NULL. @param FileHeader A pointer to the discovered file, if successful. @retval EFI_SUCCESS Successfully found FileType @retval EFI_NOT_FOUND File type can't be found. **/ EFI_STATUS -FvFindFile ( +FvFindFileByTypeGuid ( IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader, IN EFI_FV_FILETYPE FileType, + IN EFI_GUID *Guid OPTIONAL, OUT EFI_FFS_FILE_HEADER **FileHeader ) { @@ -171,8 +174,10 @@ FvFindFile ( // Look for file type // if (File->Type == FileType) { - *FileHeader = File; - return EFI_SUCCESS; + if (Guid == NULL || CompareGuid(&File->Name, Guid)) { + *FileHeader = File; + return EFI_SUCCESS; + } } } @@ -266,7 +271,7 @@ LoadDxeCore ( // // DXE FV is inside Payload FV. Here find DXE FV from Payload FV // - Status = FvFindFile (PayloadFv, EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &FileHeader); + Status = FvFindFileByTypeGuid (PayloadFv, EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, NULL, &FileHeader); if (EFI_ERROR (Status)) { return Status; } @@ -283,7 +288,7 @@ LoadDxeCore ( // // Find DXE core file from DXE FV // - Status = FvFindFile (DxeCoreFv, EFI_FV_FILETYPE_DXE_CORE, &FileHeader); + Status = FvFindFileByTypeGuid (DxeCoreFv, EFI_FV_FILETYPE_DXE_CORE, NULL, &FileHeader); if (EFI_ERROR (Status)) { return Status; } @@ -330,7 +335,7 @@ UniversalLoadDxeCore ( // // Find DXE core file from DXE FV // - Status = FvFindFile (DxeFv, EFI_FV_FILETYPE_DXE_CORE, &FileHeader); + Status = FvFindFileByTypeGuid (DxeFv, EFI_FV_FILETYPE_DXE_CORE, NULL, &FileHeader); if (EFI_ERROR (Status)) { return Status; } diff --git a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h index dff7b6b87f..331724c687 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h +++ b/UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h @@ -35,6 +35,7 @@ #include #include #include +#include #define LEGACY_8259_MASK_REGISTER_MASTER 0x21 #define LEGACY_8259_MASK_REGISTER_SLAVE 0xA1 @@ -159,4 +160,48 @@ HandOffToDxeCore ( IN EFI_PEI_HOB_POINTERS HobList ); +EFI_STATUS +FixUpPcdDatabase ( + IN EFI_FIRMWARE_VOLUME_HEADER *DxeFv + ); + +/** + This function searchs a given section type within a valid FFS file. + + @param FileHeader A pointer to the file header that contains the set of sections to + be searched. + @param SearchType The value of the section type to search. + @param SectionData A pointer to the discovered section, if successful. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +FileFindSection ( + IN EFI_FFS_FILE_HEADER *FileHeader, + IN EFI_SECTION_TYPE SectionType, + OUT VOID **SectionData + ); + +/** + This function searchs a given file type with a given Guid within a valid FV. + If input Guid is NULL, will locate the first section having the given file type + + @param FvHeader A pointer to firmware volume header that contains the set of files + to be searched. + @param FileType File type to be searched. + @param Guid Will ignore if it is NULL. + @param FileHeader A pointer to the discovered file, if successful. + + @retval EFI_SUCCESS Successfully found FileType + @retval EFI_NOT_FOUND File type can't be found. +**/ +EFI_STATUS +FvFindFileByTypeGuid ( + IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader, + IN EFI_FV_FILETYPE FileType, + IN EFI_GUID *Guid OPTIONAL, + OUT EFI_FFS_FILE_HEADER **FileHeader + ); #endif diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c index 13f4587cd9..a67653eb11 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.c @@ -25,6 +25,62 @@ extern VOID *mHobList; +/** + Some bootloader may pass a pcd database, and UPL also contain a PCD database. + Dxe PCD driver has the assumption that the two PCD database can be catenated and + the local token number should be successive。 + This function will fix up the UPL PCD database to meet that assumption. + + @param[in] DxeFv The FV where to find the Universal PCD database. + + @retval EFI_SUCCESS If it completed successfully. + @retval other Failed to fix up. +**/ +EFI_STATUS +FixUpPcdDatabase ( + IN EFI_FIRMWARE_VOLUME_HEADER *DxeFv + ) +{ + EFI_STATUS Status; + EFI_FFS_FILE_HEADER *FileHeader; + VOID *PcdRawData; + PEI_PCD_DATABASE *PeiDatabase; + PEI_PCD_DATABASE *UplDatabase; + EFI_HOB_GUID_TYPE *GuidHob; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + + GuidHob = GetFirstGuidHob (&gPcdDataBaseHobGuid); + if (GuidHob == NULL) { + // + // No fix-up is needed. + // + return EFI_SUCCESS; + } + PeiDatabase = (PEI_PCD_DATABASE *) GET_GUID_HOB_DATA (GuidHob); + DEBUG ((DEBUG_INFO, "Find the Pei PCD data base, the total local token number is %d\n", PeiDatabase->LocalTokenCount)); + + Status = FvFindFileByTypeGuid (DxeFv, EFI_FV_FILETYPE_DRIVER, PcdGetPtr (PcdPcdDriverFile), &FileHeader); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + Status = FileFindSection (FileHeader, EFI_SECTION_RAW, &PcdRawData); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return Status; + } + + UplDatabase = (PEI_PCD_DATABASE *) PcdRawData; + ExMapTable = (DYNAMICEX_MAPPING *) (UINTN) ((UINTN) PcdRawData + UplDatabase->ExMapTableOffset); + + for (Index = 0; Index < UplDatabase->ExTokenCount; Index++) { + ExMapTable[Index].TokenNumber += PeiDatabase->LocalTokenCount; + } + DEBUG ((DEBUG_INFO, "Fix up UPL PCD database successfully\n")); + return EFI_SUCCESS; +} + /** Add HOB into HOB list @@ -327,6 +383,7 @@ _ModuleEntryPoint ( Status = BuildHobs (BootloaderParameter, &DxeFv); ASSERT_EFI_ERROR (Status); + FixUpPcdDatabase (DxeFv); Status = UniversalLoadDxeCore (DxeFv, &DxeCoreEntryPoint); ASSERT_EFI_ERROR (Status); diff --git a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf index 77cd25aafd..76d7e4791c 100644 --- a/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf +++ b/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf @@ -63,6 +63,7 @@ gEfiAcpiTableGuid gUefiSerialPortInfoGuid gUniversalPayloadExtraDataGuid + gPcdDataBaseHobGuid [FeaturePcd.IA32] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES @@ -72,6 +73,7 @@ [Pcd.IA32,Pcd.X64] + gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask ## CONSUMES diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 105e1f5a1c..d84f560995 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -72,3 +72,5 @@ gUefiPayloadPkgTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|0x80|UINT32|0x # Size of the region used by UEFI in permanent memory gUefiPayloadPkgTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x02000000|UINT32|0x00000017 + +gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile|{ 0x57, 0x72, 0xcf, 0x80, 0xab, 0x87, 0xf9, 0x47, 0xa3, 0xfe, 0xD5, 0x0B, 0x76, 0xd8, 0x95, 0x41 }|VOID*|0x00000018 diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index d8277efccd..e3d669a6d6 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -298,6 +298,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + gUefiPayloadPkgTokenSpaceGuid.PcdPcdDriverFile|{ 0x57, 0x72, 0xcf, 0x80, 0xab, 0x87, 0xf9, 0x47, 0xa3, 0xfe, 0xD5, 0x0B, 0x76, 0xd8, 0x95, 0x41 } !if $(SOURCE_DEBUG_ENABLE) gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2