From 27cb64fffc8669ce1992c6dd24909e14bc24ee16 Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Thu, 10 Jun 2021 15:08:13 +0800 Subject: UefiPayloadPkg: Fix up UPL Pcd database MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Edk2 bootloader will pass the pei 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 patch will manually fix up the UPL PCD database to meet that assumption. Cc: Maurice Ma Cc: Guo Dong Cc: Benjamin You Reviewed-by: Guo Dong Signed-off-by: Zhiguang Liu --- UefiPayloadPkg/UefiPayloadEntry/LoadDxeCore.c | 19 +++++--- UefiPayloadPkg/UefiPayloadEntry/UefiPayloadEntry.h | 45 +++++++++++++++++ .../UefiPayloadEntry/UniversalPayloadEntry.c | 57 ++++++++++++++++++++++ .../UefiPayloadEntry/UniversalPayloadEntry.inf | 2 + UefiPayloadPkg/UefiPayloadPkg.dec | 2 + UefiPayloadPkg/UefiPayloadPkg.dsc | 1 + 6 files changed, 119 insertions(+), 7 deletions(-) (limited to 'UefiPayloadPkg') 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 -- cgit v1.2.3