Guomin, See my 16 comments embedded below.
About PcdMigrateTemporaryRamFirmwareVolumes, I think we need more discussions on its use scenario along with PcdShadowPeimOnBoot and PcdShadowPeimOnS3Boot. Currently it need all of them enabled to make this solution work, which is a bit complex and confusion to me. > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Guomin > Jiang > Sent: Thursday, July 09, 2020 9:57 AM > To: devel@edk2.groups.io > Cc: Michael Kubacki <michael.a.kuba...@intel.com>; Wang, Jian J > <jian.j.w...@intel.com>; Wu, Hao A <hao.a...@intel.com>; Bi, Dandan > <dandan...@intel.com>; Gao, Liming <liming....@intel.com>; De, Debkumar > <debkumar...@intel.com>; Han, Harry <harry....@intel.com>; West, > Catharine <catharine.w...@intel.com> > Subject: [edk2-devel] [PATCH v5 2/9] MdeModulePkg/PeiCore: Enable T-RAM > evacuation in PeiCore (CVE-2019-11098) > > From: Michael Kubacki <michael.a.kuba...@intel.com> > > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=1614 > > Introduces new changes to PeiCore to move the contents of temporary > RAM visible to the PeiCore to permanent memory. This expands on > pre-existing shadowing support in the PeiCore to perform the following > additional actions: > > 1. Migrate pointers in PPIs installed in PeiCore to the permanent > memory copy of PeiCore. > > 2. Copy all installed firmware volumes to permanent memory. > > 3. Relocate and fix up the PEIMs within the firmware volumes. > > 4. Convert all PPIs into the migrated firmware volume to the corresponding > PPI address in the permanent memory location. > > This applies to PPIs and PEI notifications. > > 5. Convert all status code callbacks in the migrated firmware volume to > the corresponding address in the permanent memory location. > > 6. Update the FV HOB to the corresponding firmware volume in permanent > memory. > > 7. Add PcdMigrateTemporaryRamFirmwareVolumes to control if enable the > feature or not. when the PCD disable, the EvacuateTempRam() will > never be called. > > The function control flow as below: > PeiCore() > DumpPpiList() > EvacuateTempRam() > ConvertPeiCorePpiPointers() > ConvertPpiPointersFv() > MigratePeimsInFv() > MigratePeim() > PeiGetPe32Data() > LoadAndRelocatePeCoffImageInPlace() > MigrateSecModulesInFv() > ConvertPpiPointersFv() > ConvertStatusCodeCallbacks() > ConvertFvHob() > RemoveFvHobsInTemporaryMemory() > DumpPpiList() > > Cc: Jian J Wang <jian.j.w...@intel.com> > Cc: Hao A Wu <hao.a...@intel.com> > Cc: Dandan Bi <dandan...@intel.com> > Cc: Liming Gao <liming....@intel.com> > Cc: Debkumar De <debkumar...@intel.com> > Cc: Harry Han <harry....@intel.com> > Cc: Catharine West <catharine.w...@intel.com> > Signed-off-by: Michael Kubacki <michael.a.kuba...@intel.com> > --- > MdeModulePkg/Core/Pei/PeiMain.inf | 2 + > MdeModulePkg/Core/Pei/PeiMain.h | 168 ++++++++ > MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 402 ++++++++++++++++++ > MdeModulePkg/Core/Pei/Image/Image.c | 115 +++++ > MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 82 ++++ > MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 24 ++ > MdeModulePkg/Core/Pei/Ppi/Ppi.c | 287 +++++++++++++ > 7 files changed, 1080 insertions(+) > > diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf > b/MdeModulePkg/Core/Pei/PeiMain.inf > index 6e25cc40232a..5b36d516b3fa 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain.inf > +++ b/MdeModulePkg/Core/Pei/PeiMain.inf > @@ -76,6 +76,7 @@ [Guids] > ## CONSUMES ## UNDEFINED # Locate PPI > ## CONSUMES ## GUID # Used to compare with FV's file system GUID and > get the FV's file system format > gEfiFirmwareFileSystem3Guid > + gStatusCodeCallbackGuid > > [Ppis] > gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES # > PeiReportStatusService is not ready if this PPI doesn't exist > @@ -109,6 +110,7 @@ [Pcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot > ## > CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot > ## > CONSUMES > gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack > ## > CONSUMES > + > gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolum > es ## CONSUMES > > # [BootMode] > # S3_RESUME ## SOMETIMES_CONSUMES > diff --git a/MdeModulePkg/Core/Pei/PeiMain.h > b/MdeModulePkg/Core/Pei/PeiMain.h > index 56b3bd85793d..b0101dba5e30 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain.h > +++ b/MdeModulePkg/Core/Pei/PeiMain.h > @@ -394,6 +394,41 @@ PeimDispatchReadiness ( > IN VOID *DependencyExpression > ); > > +/** > + Migrate a PEIM from Temporary RAM to permanent memory. 1) 'Temporary' -> 'temporary' > + > + @param PeimFileHandle Pointer to the FFS file header of the image. > + @param MigratedFileHandle Pointer to the FFS file header of the migrated > image. > + > + @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent > memory. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigratePeim ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + IN EFI_PEI_FILE_HANDLE MigratedFileHandle > + ); > + > +/** > + Migrate FVs out of Temporary RAM before the cache is flushed. 2) 'Temporary' -> 'temporary' > + > + @param Private PeiCore's private data structure > + @param SecCoreData Points to a data structure containing information > about the PEI core's operating > + environment, such as the size and location of > temporary RAM, > the stack location and > + the BFV location. > + > + @retval EFI_SUCCESS Succesfully migrated installed FVs from > Temporary > RAM to permanent memory. 3) 'Temporary' -> 'temporary' > + @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate > needed pages. > + > +**/ > +EFI_STATUS > +EFIAPI > +EvacuateTempRam ( > + IN PEI_CORE_INSTANCE *Private, > + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData > + ); > + > /** > Conduct PEIM dispatch. > > @@ -477,6 +512,50 @@ ConvertPpiPointers ( > IN PEI_CORE_INSTANCE *PrivateData > ); > > +/** > + > + Migrate Notify Pointers inside an FV from temporary memory to permanent > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param OrgFvHandle Address of FV Handle in temporary memory. > + @param FvHandle Address of FV Handle in permanent memory. > + @param FvSize Size of the FV. > + > +**/ > +VOID > +ConvertPpiPointersFv ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle, > + IN UINTN FvSize > + ); > + > +/** > + > + Migrate PPI Pointers of PEI_CORE from temporary memory to permanent > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param CoreFvHandle Address of PEI_CORE FV Handle in temporary > memory. > + > +**/ > +VOID > +ConvertPeiCorePpiPointers ( > + IN PEI_CORE_INSTANCE *PrivateData, > + PEI_CORE_FV_HANDLE CoreFvHandle > + ); > + > +/** > + > + Dumps the PPI lists to debug output. > + > + @param PrivateData Points to PeiCore's private instance data. > + > +**/ > +VOID > +DumpPpiList ( > + IN PEI_CORE_INSTANCE *PrivateData > + ); > + > /** > > Install PPI services. It is implementation of EFI_PEI_SERVICE.InstallPpi. > @@ -808,6 +887,37 @@ PeiFfsFindNextFile ( > IN OUT EFI_PEI_FILE_HANDLE *FileHandle > ); > > +/** > + Go through the file to search SectionType section. > + Search within encapsulation sections (compression and GUIDed) recursively, > + until the match section is found. > + > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > + @param SectionType Filter to find only section of this type. > + @param SectionInstance Pointer to the filter to find the specific > instance of > section. > + @param Section From where to search. > + @param SectionSize The file size to search. > + @param OutputBuffer A pointer to the discovered section, if > successful. > + NULL if section not found 4) Missing '.' at the end > + @param AuthenticationStatus Updated upon return to point to the > authentication status for this section. 5) Please align the start of parameter description > + @param IsFfs3Fv Indicates the FV format. > + > + @return EFI_NOT_FOUND The match section is not found. > + @return EFI_SUCCESS The match section is found. > + > +**/ > +EFI_STATUS > +ProcessSection ( > + IN CONST EFI_PEI_SERVICES **PeiServices, > + IN EFI_SECTION_TYPE SectionType, > + IN OUT UINTN *SectionInstance, > + IN EFI_COMMON_SECTION_HEADER *Section, > + IN UINTN SectionSize, > + OUT VOID **OutputBuffer, > + OUT UINT32 *AuthenticationStatus, > + IN BOOLEAN IsFfs3Fv > + ); > + > /** > Searches for the next matching section within the specified file. > > @@ -931,6 +1041,33 @@ MigrateMemoryPages ( > IN BOOLEAN TemporaryRamMigrated > ); > > +/** > + Removes any FV HOBs whose base address is not in PEI installed memory. > + > + @param[in] Private Pointer to PeiCore's private data structure. > + > +**/ > +VOID > +RemoveFvHobsInTemporaryMemory ( > + IN PEI_CORE_INSTANCE *Private > + ); > + > +/** > + Migrate the base address in firmware volume allocation HOBs > + from temporary memory to PEI installed memory. > + > + @param[in] PrivateData Pointer to PeiCore's private data structure. > + @param[in] OrgFvHandle Address of FV Handle in temporary memory. > + @param[in] FvHandle Address of FV Handle in permanent memory. > + > +**/ > +VOID > +ConvertFvHob ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle > + ); > + > /** > Migrate MemoryBaseAddress in memory allocation HOBs > from the temporary memory to PEI installed memory. > @@ -1249,6 +1386,37 @@ InitializeImageServices ( > IN PEI_CORE_INSTANCE *OldCoreData > ); > > +/** > + Loads and relocates a PE/COFF image in place. > + > + @param Pe32Data The base address of the PE/COFF file that is to be > loaded and relocated > + @param ImageAddress The base address of the relocated PE/COFF image > + > + @retval EFI_SUCCESS The file was loaded and relocated > + > +**/ > +EFI_STATUS > +LoadAndRelocatePeCoffImageInPlace ( > + IN VOID *Pe32Data, > + IN VOID *ImageAddress > + ); > + > +/** > + Find the PE32 Data for an FFS file. > + > + @param FileHandle Pointer to the FFS file header of the image. > + @param Pe32Data Pointer to a (VOID *) PE32 Data pointer. > + > + @retval EFI_SUCCESS Image is successfully loaded. > + @retval EFI_NOT_FOUND Fail to locate PE32 Data. > + > +**/ > +EFI_STATUS > +PeiGetPe32Data ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + OUT VOID **Pe32Data > + ); > + > /** > The wrapper function of PeiLoadImageLoadImage(). > > diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > index 4c2eac1384e8..ef88b3423376 100644 > --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > @@ -952,6 +952,408 @@ PeiCheckAndSwitchStack ( > } > } > > +/** > + Migrate a PEIM from Temporary RAM to permanent memory. 6) 'Temporary' -> 'temporary' > + > + @param PeimFileHandle Pointer to the FFS file header of the image. > + @param MigratedFileHandle Pointer to the FFS file header of the migrated > image. > + > + @retval EFI_SUCCESS Sucessfully migrated the PEIM to permanent > memory. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigratePeim ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + IN EFI_PEI_FILE_HANDLE MigratedFileHandle > + ) > +{ > + EFI_STATUS Status; > + EFI_FFS_FILE_HEADER *FileHeader; > + VOID *Pe32Data; > + VOID *ImageAddress; > + CHAR8 *AsciiString; > + UINTN Index; > + > + Status = EFI_SUCCESS; > + > + FileHeader = (EFI_FFS_FILE_HEADER *) FileHandle; > + ASSERT (!IS_FFS_FILE2 (FileHeader)); > + > + ImageAddress = NULL; > + PeiGetPe32Data (MigratedFileHandle, &ImageAddress); > + if (ImageAddress != NULL) { > + AsciiString = PeCoffLoaderGetPdbPointer (ImageAddress); > + for (Index = 0; AsciiString[Index] != 0; Index++) { > + if (AsciiString[Index] == '\\' || AsciiString[Index] == '/') { > + AsciiString = AsciiString + Index + 1; > + Index = 0; > + } else if (AsciiString[Index] == '.') { > + AsciiString[Index] = 0; > + } > + } > + DEBUG ((DEBUG_INFO, "%a", AsciiString)); 7) Above code (from the line below 'if' to 'DEBUG') are used for debug only. Suggest to put them into DEBUG_CODE(); > + > + Pe32Data = (VOID *) ((UINTN) ImageAddress - (UINTN) MigratedFileHandle + > (UINTN) FileHandle); > + Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress); > + ASSERT_EFI_ERROR (Status); > + } > + > + return Status; > +} > + > +/** > + Migrate Status Code Callback function pointers inside an FV from temporary > memory to permanent memory. > + > + @param OrgFvHandle Address of FV Handle in temporary memory. 8) 'Handle' -> 'handle' > + @param FvHandle Address of FV Handle in permanent memory. 9) 'Handle' -> 'handle' > + @param FvSize Size of the FV. > + > +**/ > +VOID > +ConvertStatusCodeCallbacks ( > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle, > + IN UINTN FvSize > + ) > +{ > + EFI_PEI_HOB_POINTERS Hob; > + UINTN *NumberOfEntries; > + UINTN *CallbackEntry; > + UINTN Index; > + > + Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid); > + while (Hob.Raw != NULL) { > + NumberOfEntries = GET_GUID_HOB_DATA (Hob); > + CallbackEntry = NumberOfEntries + 1; > + for (Index = 0; Index < *NumberOfEntries; Index++) { > + if (((VOID *) CallbackEntry[Index]) != NULL) { > + if ((CallbackEntry[Index] >= OrgFvHandle) && (CallbackEntry[Index] < > (OrgFvHandle + FvSize))) { > + DEBUG ((DEBUG_INFO, "Migrating CallbackEntry[%d] from 0x%08X to ", > Index, CallbackEntry[Index])); CallbackEntry is defined as pointer to UINTN, which is 4-byte with 32-bit PEI. Using %08X might be not a good idea. Suggest to use %p instead. > + if (OrgFvHandle > FvHandle) { > + CallbackEntry[Index] = CallbackEntry[Index] - (OrgFvHandle - > FvHandle); > + } else { > + CallbackEntry[Index] = CallbackEntry[Index] + (FvHandle - > OrgFvHandle); > + } > + DEBUG ((DEBUG_INFO, "0x%08X\n", CallbackEntry[Index])); 10) The same as above. > + } > + } > + } > + Hob.Raw = GET_NEXT_HOB (Hob); > + Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw); > + } > +} > + > +/** > + Migrates SEC modules in the given firmware volume. > + > + Migrating SECURITY_CORE files requires special treatment since they are not > tracked for PEI dispatch. > + > + This functioun should be called after the FV has been copied to its post- > memory location and the PEI Core FV list has > + been updated. > + > + @param Private Pointer to the PeiCore's private data structure. > + @param FvIndex The firmware volume index to migrate. > + @param OrgFvHandle The handle to the firmware volume in temporary > memory. > + > + @retval EFI_SUCCESS SEC modules were migrated successfully > + @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is 11) There's EFI_NOT_FOUND returned in the function body. > invalid. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigrateSecModulesInFv ( > + IN PEI_CORE_INSTANCE *Private, > + IN UINTN FvIndex, > + IN UINTN OrgFvHandle > + ) > +{ > + EFI_STATUS Status; > + EFI_STATUS FindFileStatus; > + EFI_PEI_FILE_HANDLE MigratedFileHandle; > + EFI_PEI_FILE_HANDLE FileHandle; > + UINT32 SectionAuthenticationStatus; > + UINT32 FileSize; > + VOID *OrgPe32SectionData; > + VOID *Pe32SectionData; > + EFI_FFS_FILE_HEADER *FfsFileHeader; > + EFI_COMMON_SECTION_HEADER *Section; > + BOOLEAN IsFfs3Fv; > + UINTN SectionInstance; > + > + if (Private == NULL || FvIndex >= Private->FvCount) { > + return EFI_INVALID_PARAMETER; > + } > + > + do { > + FindFileStatus = PeiFfsFindNextFile ( > + GetPeiServicesTablePointer (), > + EFI_FV_FILETYPE_SECURITY_CORE, > + Private->Fv[FvIndex].FvHandle, > + &MigratedFileHandle > + ); > + if (!EFI_ERROR (FindFileStatus ) && MigratedFileHandle != NULL) { > + FileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) MigratedFileHandle - > (UINTN) > Private->Fv[FvIndex].FvHandle + OrgFvHandle); > + FfsFileHeader = (EFI_FFS_FILE_HEADER *) MigratedFileHandle; > + > + DEBUG ((DEBUG_VERBOSE, " Migrating SEC_CORE MigratedFileHandle at > 0x%x.\n", (UINTN) MigratedFileHandle)); > + DEBUG ((DEBUG_VERBOSE, " FileHandle at 0x%x.\n", > (UINTN) > FileHandle)); > + > + IsFfs3Fv = CompareGuid (&Private->Fv[FvIndex].FvHeader->FileSystemGuid, > &gEfiFirmwareFileSystem3Guid); > + if (IS_FFS_FILE2 (FfsFileHeader)) { > + ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF); > + if (!IsFfs3Fv) { > + DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 > formatted FV.\n", &FfsFileHeader->Name)); > + return EFI_NOT_FOUND; > + } > + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + > sizeof (EFI_FFS_FILE_HEADER2)); > + FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof > (EFI_FFS_FILE_HEADER2); > + } else { > + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + > sizeof (EFI_FFS_FILE_HEADER)); > + FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof > (EFI_FFS_FILE_HEADER); > + } > + > + SectionInstance = 1; > + SectionAuthenticationStatus = 0; > + Status = ProcessSection ( > + GetPeiServicesTablePointer (), > + EFI_SECTION_PE32, > + &SectionInstance, > + Section, > + FileSize, > + &Pe32SectionData, > + &SectionAuthenticationStatus, > + IsFfs3Fv > + ); > + > + if (!EFI_ERROR (Status)) { > + OrgPe32SectionData = (VOID *) ((UINTN) Pe32SectionData - (UINTN) > MigratedFileHandle + (UINTN) FileHandle); > + DEBUG ((DEBUG_VERBOSE, " PE32 section in migrated file at > 0x%x.\n", > (UINTN) Pe32SectionData)); > + DEBUG ((DEBUG_VERBOSE, " PE32 section in original file at > 0x%x.\n", > (UINTN) OrgPe32SectionData)); > + Status = LoadAndRelocatePeCoffImageInPlace (OrgPe32SectionData, > Pe32SectionData); > + ASSERT_EFI_ERROR (Status); > + } > + } > + } while (!EFI_ERROR (FindFileStatus)); > + > + return EFI_SUCCESS; > +} > + > +/** > + Migrates PEIMs in the given firmware volume. > + > + @param Private Pointer to the PeiCore's private data structure. > + @param FvIndex The firmware volume index to migrate. > + @param OrgFvHandle The handle to the firmware volume in temporary > memory. > + @param FvHandle The handle to the firmware volume in permanent > memory. > + > + @retval EFI_SUCCESS The PEIMs in the FV were migrated > successfully > + @retval EFI_INVALID_PARAMETER The Private pointer is NULL or FvCount is > invalid. > + > +**/ > +EFI_STATUS > +EFIAPI > +MigratePeimsInFv ( > + IN PEI_CORE_INSTANCE *Private, > + IN UINTN FvIndex, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle > + ) > +{ > + EFI_STATUS Status; > + volatile UINTN FileIndex; > + EFI_PEI_FILE_HANDLE MigratedFileHandle; > + EFI_PEI_FILE_HANDLE FileHandle; > + > + if (Private == NULL || FvIndex >= Private->FvCount) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (Private->Fv[FvIndex].ScanFv) { > + for (FileIndex = 0; FileIndex < Private->Fv[FvIndex].PeimCount; > FileIndex++) { > + if (Private->Fv[FvIndex].FvFileHandles[FileIndex] != NULL) { > + FileHandle = Private->Fv[FvIndex].FvFileHandles[FileIndex]; > + > + MigratedFileHandle = (EFI_PEI_FILE_HANDLE) ((UINTN) FileHandle - > OrgFvHandle + FvHandle); > + > + DEBUG ((DEBUG_VERBOSE, " Migrating FileHandle %2d ", FileIndex)); > + Status = MigratePeim (FileHandle, MigratedFileHandle); > + DEBUG ((DEBUG_INFO, "\n")); DEBUG_VERBOSE is used line above but DEBUG_INFO here. > + ASSERT_EFI_ERROR (Status); > + > + if (!EFI_ERROR (Status)) { > + // if (Private->Fv[FvIndex].PeimState[FileIndex] == > PEIM_STATE_REGISTER_FOR_SHADOW) { > + // Private->Fv[FvIndex].PeimState[FileIndex]++; > + // } 12) Remove the code which have been commented out. > + Private->Fv[FvIndex].FvFileHandles[FileIndex] = MigratedFileHandle; > + if (FvIndex == Private->CurrentPeimFvCount) { > + Private->CurrentFvFileHandles[FileIndex] = MigratedFileHandle; > + } > + } > + } > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Migrate FVs out of temporary RAM before the cache is flushed. > + > + @param Private PeiCore's private data structure > + @param SecCoreData Points to a data structure containing information > about the PEI core's operating > + environment, such as the size and location of > temporary RAM, > the stack location and > + the BFV location. > + > + @retval EFI_SUCCESS Succesfully migrated installed FVs from > temporary > RAM to permanent memory. > + @retval EFI_OUT_OF_RESOURCES Insufficient memory exists to allocate > needed pages. > + > +**/ > +EFI_STATUS > +EFIAPI > +EvacuateTempRam ( > + IN PEI_CORE_INSTANCE *Private, > + IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData > + ) > +{ > + EFI_STATUS Status; > + volatile UINTN FvIndex; > + volatile UINTN FvChildIndex; > + UINTN ChildFvOffset; > + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; > + EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader; > + EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader; > + EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader; > + > + PEI_CORE_FV_HANDLE PeiCoreFvHandle; > + EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi; > + > + ASSERT (Private->PeiMemoryInstalled); > + > + DEBUG ((DEBUG_VERBOSE, "Beginning evacuation of content in temporary > RAM.\n")); > + > + // > + // Migrate PPI Pointers of PEI_CORE from temporary memory to newly loaded > PEI_CORE in permanent memory. > + // > + Status = PeiLocatePpi ((CONST EFI_PEI_SERVICES **) &Private->Ps, > &gEfiPeiCoreFvLocationPpiGuid, 0, NULL, (VOID **) &PeiCoreFvLocationPpi); > + if (!EFI_ERROR (Status) && (PeiCoreFvLocationPpi->PeiCoreFvLocation != > NULL)) { > + PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) PeiCoreFvLocationPpi- > >PeiCoreFvLocation; > + } else { > + PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE) SecCoreData- > >BootFirmwareVolumeBase; > + } > + for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) { > + if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) { > + PeiCoreFvHandle = Private->Fv[FvIndex]; > + break; > + } > + } > + Status = EFI_SUCCESS; > + > + ConvertPeiCorePpiPointers (Private, PeiCoreFvHandle); > + > + for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) { > + FvHeader = Private->Fv[FvIndex].FvHeader; > + ASSERT (FvHeader != NULL); > + ASSERT (FvIndex < Private->FvCount); > + > + DEBUG ((DEBUG_VERBOSE, "FV[%02d] at 0x%x.\n", FvIndex, (UINTN) > FvHeader)); > + if ( > + !( > + ((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader >= Private- > >PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS)(UINTN) FvHeader + (FvHeader->FvLength - 1)) > < Private->FreePhysicalMemoryTop) > + ) > + ) { > + Status = PeiServicesAllocatePages ( > + EfiBootServicesCode, > + EFI_SIZE_TO_PAGES ((UINTN) FvHeader->FvLength), > + (EFI_PHYSICAL_ADDRESS *) &MigratedFvHeader > + ); > + ASSERT_EFI_ERROR (Status); > + > + DEBUG (( > + DEBUG_VERBOSE, > + " Migrating FV[%d] from 0x%08X to 0x%08X\n", > + FvIndex, > + (UINTN) FvHeader, > + (UINTN) MigratedFvHeader > + )); > + > + CopyMem (MigratedFvHeader, FvHeader, (UINTN) FvHeader->FvLength); > + > + // > + // Migrate any children for this FV now > + // > + for (FvChildIndex = FvIndex; FvChildIndex < Private->FvCount; > FvChildIndex++) { > + ChildFvHeader = Private->Fv[FvChildIndex].FvHeader; > + if ( > + ((UINTN) ChildFvHeader > (UINTN) FvHeader) && > + (((UINTN) ChildFvHeader + ChildFvHeader->FvLength) < ((UINTN) > FvHeader) + FvHeader->FvLength) > + ) { > + DEBUG ((DEBUG_VERBOSE, " Child FV[%02d] is being migrated.\n", > FvChildIndex)); > + ChildFvOffset = (UINTN) ChildFvHeader - (UINTN) FvHeader; > + DEBUG ((DEBUG_VERBOSE, " Child FV offset = 0x%x.\n", > ChildFvOffset)); > + MigratedChildFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) > MigratedFvHeader + ChildFvOffset); > + Private->Fv[FvChildIndex].FvHeader = MigratedChildFvHeader; > + Private->Fv[FvChildIndex].FvHandle = (EFI_PEI_FV_HANDLE) > MigratedChildFvHeader; > + DEBUG ((DEBUG_VERBOSE, " Child migrated FV header at 0x%x.\n", > (UINTN) MigratedChildFvHeader)); > + > + // @todo: find issue with file and section alignment in SEC PE32 > images > for migration > + // (alignment in P32 is given as 32-bit when actual > alignment is 16-bit) > + // SEC PPIs are currently re-installed with a dedicated PEIM > + // Status = MigrateSecModulesInFv (Private, FvChildIndex, (UINTN) > ChildFvHeader); > + // ASSERT_EFI_ERROR (Status); 13) Remove the code which have been commented out. > + Status = MigratePeimsInFv (Private, FvChildIndex, (UINTN) > ChildFvHeader, > (UINTN) MigratedChildFvHeader); > + ASSERT_EFI_ERROR (Status); > + > + ConvertPpiPointersFv ( > + Private, > + (UINTN) ChildFvHeader, > + (UINTN) MigratedChildFvHeader, > + (UINTN) ChildFvHeader->FvLength - 1 > + ); > + > + ConvertStatusCodeCallbacks ( > + (UINTN) ChildFvHeader, > + (UINTN) MigratedChildFvHeader, > + (UINTN) ChildFvHeader->FvLength - 1 > + ); > + > + ConvertFvHob (Private, (UINTN) ChildFvHeader, (UINTN) > MigratedChildFvHeader); > + } > + } > + Private->Fv[FvIndex].FvHeader = MigratedFvHeader; > + Private->Fv[FvIndex].FvHandle = (EFI_PEI_FV_HANDLE) MigratedFvHeader; > + > + // @todo: find issue with file and section alignment in SEC PE32 > images for > migration > + // (alignment in P32 is given as 32-bit when actual alignment > is 16-bit) > + // SEC PPIs are currently re-installed with a dedicated PEIM > + // Status = MigrateSecModulesInFv (Private, FvIndex, (UINTN) FvHeader); > + // ASSERT_EFI_ERROR (Status); 14) Remove the code which have been commented out. > + Status = MigratePeimsInFv (Private, FvIndex, (UINTN) FvHeader, (UINTN) > MigratedFvHeader); > + ASSERT_EFI_ERROR (Status); > + > + ConvertPpiPointersFv ( > + Private, > + (UINTN) FvHeader, > + (UINTN) MigratedFvHeader, > + (UINTN) FvHeader->FvLength - 1 > + ); > + > + ConvertStatusCodeCallbacks ( > + (UINTN) FvHeader, > + (UINTN) MigratedFvHeader, > + (UINTN) FvHeader->FvLength - 1 > + ); > + > + ConvertFvHob (Private, (UINTN) FvHeader, (UINTN) MigratedFvHeader); > + } > + } > + > + RemoveFvHobsInTemporaryMemory (Private); > + > + return Status; > +} > + > /** > Conduct PEIM dispatch. > > diff --git a/MdeModulePkg/Core/Pei/Image/Image.c > b/MdeModulePkg/Core/Pei/Image/Image.c > index e3ee3699337f..612797722a3e 100644 > --- a/MdeModulePkg/Core/Pei/Image/Image.c > +++ b/MdeModulePkg/Core/Pei/Image/Image.c > @@ -444,6 +444,121 @@ LoadAndRelocatePeCoffImage ( > return ReturnStatus; > } > > +/** > + Loads and relocates a PE/COFF image in place. > + > + @param Pe32Data The base address of the PE/COFF file that is to be > loaded and relocated > + @param ImageAddress The base address of the relocated PE/COFF image > + > + @retval EFI_SUCCESS The file was loaded and relocated 15) There're other return values from PeCoffLoaderLoadImage() and PeCoffLoaderRelocateImage(). > + > +**/ > +EFI_STATUS > +LoadAndRelocatePeCoffImageInPlace ( > + IN VOID *Pe32Data, > + IN VOID *ImageAddress > + ) > +{ > + EFI_STATUS Status; > + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; > + > + ZeroMem (&ImageContext, sizeof (ImageContext)); > + ImageContext.Handle = Pe32Data; > + ImageContext.ImageRead = PeiImageRead; > + > + Status = PeCoffLoaderGetImageInfo (&ImageContext); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN) ImageAddress; > + > + // > + // Load the image in place > + // > + Status = PeCoffLoaderLoadImage (&ImageContext); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // Relocate the image in place > + // > + Status = PeCoffLoaderRelocateImage (&ImageContext); > + if (EFI_ERROR (Status)) { > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // Flush the instruction cache so the image data is written before we > execute > it > + // > + if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN) > Pe32Data) { > + InvalidateInstructionCacheRange ((VOID > *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); > + } > + > + return Status; > +} > + > +/** > + Find the PE32 Data for an FFS file. > + > + @param FileHandle Pointer to the FFS file header of the image. > + @param Pe32Data Pointer to a (VOID *) PE32 Data pointer. > + > + @retval EFI_SUCCESS Image is successfully loaded. > + @retval EFI_NOT_FOUND Fail to locate PE32 Data. > + > +**/ > +EFI_STATUS > +PeiGetPe32Data ( > + IN EFI_PEI_FILE_HANDLE FileHandle, > + OUT VOID **Pe32Data > + ) > +{ > + EFI_STATUS Status; > + EFI_SECTION_TYPE SearchType1; > + EFI_SECTION_TYPE SearchType2; > + UINT32 AuthenticationState; > + > + *Pe32Data = NULL; > + > + if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) { > + SearchType1 = EFI_SECTION_TE; > + SearchType2 = EFI_SECTION_PE32; > + } else { > + SearchType1 = EFI_SECTION_PE32; > + SearchType2 = EFI_SECTION_TE; > + } > + > + // > + // Try to find a first exe section (if > PcdPeiCoreImageLoaderSearchTeSectionFirst > + // is true, TE will be searched first). > + // > + Status = PeiServicesFfsFindSectionData3 ( > + SearchType1, > + 0, > + FileHandle, > + Pe32Data, > + &AuthenticationState > + ); > + // > + // If we didn't find a first exe section, try to find the second exe > section. > + // > + if (EFI_ERROR (Status)) { > + Status = PeiServicesFfsFindSectionData3 ( > + SearchType2, > + 0, > + FileHandle, > + Pe32Data, > + &AuthenticationState > + ); > + } > + return Status; > +} > + > /** > Loads a PEIM into memory for subsequent execution. If there are compressed > images or images that need to be relocated into memory for performance > reasons, > diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > index 6b3a64a811cd..9d933f0393a8 100644 > --- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > +++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c > @@ -166,6 +166,88 @@ MigrateMemoryPages ( > Private->FreePhysicalMemoryTop = NewMemPagesBase; > } > > +/** > + Removes any FV HOBs whose base address is not in PEI installed memory. > + > + @param[in] Private Pointer to PeiCore's private data structure. > + > +**/ > +VOID > +RemoveFvHobsInTemporaryMemory ( > + IN PEI_CORE_INSTANCE *Private > + ) > +{ > + EFI_PEI_HOB_POINTERS Hob; > + EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob; > + > + DEBUG ((DEBUG_INFO, "Removing FVs in FV HOB not already migrated to > permanent memory.\n")); > + > + for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = > GET_NEXT_HOB (Hob)) { > + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV || GET_HOB_TYPE (Hob) == > EFI_HOB_TYPE_FV2 || GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) { > + FirmwareVolumeHob = Hob.FirmwareVolume; > + DEBUG ((DEBUG_INFO, " Found FV HOB.\n")); > + DEBUG (( > + DEBUG_INFO, > + " BA=%016lx L=%016lx\n", > + FirmwareVolumeHob->BaseAddress, > + FirmwareVolumeHob->Length > + )); > + if ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob- > >BaseAddress >= Private->PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS) (UINTN) FirmwareVolumeHob->BaseAddress > + (FirmwareVolumeHob->Length - 1)) < Private->FreePhysicalMemoryTop) > + ) > + ) { > + DEBUG ((DEBUG_INFO, " Removing FV HOB to an FV in T-RAM (was not > migrated).\n")); > + Hob.Header->HobType = EFI_HOB_TYPE_UNUSED; > + } > + } > + } > +} > + > +/** > + Migrate the base address in firmware volume allocation HOBs > + from temporary memory to PEI installed memory. > + > + @param[in] PrivateData Pointer to PeiCore's private data structure. > + @param[in] OrgFvHandle Address of FV Handle in temporary memory. > + @param[in] FvHandle Address of FV Handle in permanent memory. > + > +**/ > +VOID > +ConvertFvHob ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle > + ) > +{ > + EFI_PEI_HOB_POINTERS Hob; > + EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob; > + EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2Hob; > + EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3Hob; > + > + DEBUG ((DEBUG_INFO, "Converting FVs in FV HOB.\n")); > + > + for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = > GET_NEXT_HOB (Hob)) { > + if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) { > + FirmwareVolumeHob = Hob.FirmwareVolume; > + if (FirmwareVolumeHob->BaseAddress == OrgFvHandle) { > + FirmwareVolumeHob->BaseAddress = FvHandle; > + } > + } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) { > + FirmwareVolume2Hob = Hob.FirmwareVolume2; > + if (FirmwareVolume2Hob->BaseAddress == OrgFvHandle) { > + FirmwareVolume2Hob->BaseAddress = FvHandle; > + } > + } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) { > + FirmwareVolume3Hob = Hob.FirmwareVolume3; > + if (FirmwareVolume3Hob->BaseAddress == OrgFvHandle) { > + FirmwareVolume3Hob->BaseAddress = FvHandle; > + } > + } > + } > +} > + > /** > Migrate MemoryBaseAddress in memory allocation HOBs > from the temporary memory to PEI installed memory. > diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > index cca57c4c0686..4a0671f87604 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > @@ -176,6 +176,9 @@ PeiCore ( > EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable; > EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi; > UINTN Index; > + BOOLEAN Shadow; 16) Suggest to use different name other than Shadow. It's mainly for migrate temporary ram, not exactly the same as PcdShadowPeimOnBoot. Regards, Jian > + > + Shadow = FALSE; > > // > // Retrieve context passed into PEI Core > @@ -418,6 +421,27 @@ PeiCore ( > ProcessPpiListFromSec ((CONST EFI_PEI_SERVICES **) &PrivateData.Ps, > PpiList); > } > } else { > + if (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes)) { > + if (PrivateData.HobList.HandoffInformationTable->BootMode == > BOOT_ON_S3_RESUME) { > + Shadow = PcdGetBool (PcdShadowPeimOnS3Boot); > + } else { > + Shadow = PcdGetBool (PcdShadowPeimOnBoot); > + } > + } > + > + if (Shadow) { > + DEBUG ((DEBUG_VERBOSE, "PPI lists before temporary RAM > evacuation:\n")); > + DumpPpiList (&PrivateData); > + > + // > + // Migrate installed content from Temporary RAM to Permanent RAM > + // > + EvacuateTempRam (&PrivateData, SecCoreData); > + > + DEBUG ((DEBUG_VERBOSE, "PPI lists after temporary RAM evacuation:\n")); > + DumpPpiList (&PrivateData); > + } > + > // > // Try to locate Temporary RAM Done Ppi. > // > diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c > b/MdeModulePkg/Core/Pei/Ppi/Ppi.c > index 1ffe718c4702..018b25f86470 100644 > --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c > +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c > @@ -198,6 +198,227 @@ ConvertPpiPointers ( > } > } > > +/** > + > + Migrate Notify Pointers inside an FV from temporary memory to permanent > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param OrgFvHandle Address of FV Handle in temporary memory. > + @param FvHandle Address of FV Handle in permanent memory. > + @param FvSize Size of the FV. > + > +**/ > +VOID > +ConvertPpiPointersFv ( > + IN PEI_CORE_INSTANCE *PrivateData, > + IN UINTN OrgFvHandle, > + IN UINTN FvHandle, > + IN UINTN FvSize > + ) > +{ > + UINT8 Index; > + UINTN Offset; > + BOOLEAN OffsetPositive; > + EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi; > + UINT8 GuidIndex; > + EFI_GUID *Guid; > + EFI_GUID *GuidCheckList[2]; > + > + GuidCheckList[0] = &gEfiPeiFirmwareVolumeInfoPpiGuid; > + GuidCheckList[1] = &gEfiPeiFirmwareVolumeInfo2PpiGuid; > + > + if (FvHandle > OrgFvHandle) { > + OffsetPositive = TRUE; > + Offset = FvHandle - OrgFvHandle; > + } else { > + OffsetPositive = FALSE; > + Offset = OrgFvHandle - FvHandle; > + } > + > + DEBUG ((DEBUG_VERBOSE, "Converting PPI pointers in FV.\n")); > + DEBUG (( > + DEBUG_VERBOSE, > + " OrgFvHandle at 0x%08x. FvHandle at 0x%08x. FvSize = 0x%x\n", > + (UINTN) OrgFvHandle, > + (UINTN) FvHandle, > + FvSize > + )); > + DEBUG (( > + DEBUG_VERBOSE, > + " OrgFvHandle range: 0x%08x - 0x%08x\n", > + OrgFvHandle, > + OrgFvHandle + FvSize > + )); > + > + for (Index = 0; Index < > PrivateData->PpiData.CallbackNotifyList.CurrentCount; > Index++) { > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Notify, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + } > + > + for (Index = 0; Index < > PrivateData->PpiData.DispatchNotifyList.CurrentCount; > Index++) { > + ConvertPointer ( > + (VOID **) > &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Notify, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + } > + > + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; > Index++) { > + ConvertPointer ( > + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + ConvertPointer ( > + (VOID **) &PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + > + Guid = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid; > + for (GuidIndex = 0; GuidIndex < ARRAY_SIZE (GuidCheckList); ++GuidIndex) > { > + // > + // Don't use CompareGuid function here for performance reasons. > + // Instead we compare the GUID as INT32 at a time and branch > + // on the first failed comparison. > + // > + if ((((INT32 *)Guid)[0] == ((INT32 *)GuidCheckList[GuidIndex])[0]) && > + (((INT32 *)Guid)[1] == ((INT32 *)GuidCheckList[GuidIndex])[1]) && > + (((INT32 *)Guid)[2] == ((INT32 *)GuidCheckList[GuidIndex])[2]) && > + (((INT32 *)Guid)[3] == ((INT32 *)GuidCheckList[GuidIndex])[3])) { > + FvInfoPpi = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Ppi; > + DEBUG ((DEBUG_VERBOSE, " FvInfo: %p -> ", FvInfoPpi->FvInfo)); > + if ((UINTN)FvInfoPpi->FvInfo == OrgFvHandle) { > + ConvertPointer ( > + (VOID **)&FvInfoPpi->FvInfo, > + OrgFvHandle, > + OrgFvHandle + FvSize, > + Offset, > + OffsetPositive > + ); > + DEBUG ((DEBUG_VERBOSE, "%p", FvInfoPpi->FvInfo)); > + } > + DEBUG ((DEBUG_VERBOSE, "\n")); > + break; > + } > + } > + } > +} > + > +/** > + > + Dumps the PPI lists to debug output. > + > + @param PrivateData Points to PeiCore's private instance data. > + > +**/ > +VOID > +DumpPpiList ( > + IN PEI_CORE_INSTANCE *PrivateData > + ) > +{ > + DEBUG_CODE_BEGIN (); > + UINTN Index; > + > + if (PrivateData == NULL) { > + return; > + } > + > + for (Index = 0; Index < > PrivateData->PpiData.CallbackNotifyList.CurrentCount; > Index++) { > + DEBUG (( > + DEBUG_VERBOSE, > + "CallbackNotify[%2d] {%g} at 0x%x (%a)\n", > + Index, > + PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Notify->Guid, > + (UINTN) PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw, > + ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw >= PrivateData- > >PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index].Raw) + sizeof > (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop) > + ) > + ? "CAR" : "Post-Memory" > + ) > + )); > + } > + for (Index = 0; Index < > PrivateData->PpiData.DispatchNotifyList.CurrentCount; > Index++) { > + DEBUG ((DEBUG_VERBOSE, > + "DispatchNotify[%2d] {%g} at 0x%x (%a)\n", > + Index, > + PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Notify->Guid, > + (UINTN) PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw, > + ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw >=PrivateData- > >PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index].Raw) + sizeof > (EFI_PEI_NOTIFY_DESCRIPTOR)) < PrivateData->FreePhysicalMemoryTop) > + ) > + ? "CAR" : "Post-Memory" > + ) > + )); > + } > + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; > Index++) { > + DEBUG ((DEBUG_VERBOSE, > + "PPI[%2d] {%g} at 0x%x (%a)\n", > + Index, > + PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi->Guid, > + (UINTN) PrivateData->PpiData.PpiList.PpiPtrs[Index].Raw, > + ( > + !( > + ((EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData- > >PpiData.PpiList.PpiPtrs[Index].Raw >= PrivateData->PhysicalMemoryBegin) && > + (((EFI_PHYSICAL_ADDRESS) ((UINTN) PrivateData- > >PpiData.PpiList.PpiPtrs[Index].Raw) + sizeof (EFI_PEI_PPI_DESCRIPTOR)) < > PrivateData->FreePhysicalMemoryTop) > + ) > + ? "CAR" : "Post-Memory" > + ) > + )); > + } > + DEBUG_CODE_END (); > +} > + > /** > > This function installs an interface in the PEI PPI database by GUID. > @@ -830,3 +1051,69 @@ ProcessPpiListFromSec ( > } > } > > +/** > + > + Migrate PPI Pointers of PEI_CORE from temporary memory to permanent > memory. > + > + @param PrivateData Pointer to PeiCore's private data structure. > + @param CoreFvHandle Address of PEI_CORE FV Handle in temporary > memory. > + > +**/ > + > +VOID > +ConvertPeiCorePpiPointers ( > + IN PEI_CORE_INSTANCE *PrivateData, > + PEI_CORE_FV_HANDLE CoreFvHandle > + ) > +{ > + EFI_FV_FILE_INFO FileInfo; > + EFI_PHYSICAL_ADDRESS OrgImageBase; > + EFI_PHYSICAL_ADDRESS MigratedImageBase; > + UINTN PeiCoreModuleSize; > + EFI_PEI_FILE_HANDLE PeiCoreFileHandle; > + VOID *PeiCoreImageBase; > + VOID *PeiCoreEntryPoint; > + EFI_STATUS Status; > + > + PeiCoreFileHandle = NULL; > + > + // > + // Find the PEI Core in the BFV in temporary memory. > + // > + Status = CoreFvHandle.FvPpi->FindFileByType ( > + CoreFvHandle.FvPpi, > + EFI_FV_FILETYPE_PEI_CORE, > + CoreFvHandle.FvHandle, > + &PeiCoreFileHandle > + ); > + ASSERT_EFI_ERROR (Status); > + > + if (!EFI_ERROR (Status)) { > + Status = CoreFvHandle.FvPpi->GetFileInfo (CoreFvHandle.FvPpi, > PeiCoreFileHandle, &FileInfo); > + ASSERT_EFI_ERROR (Status); > + > + Status = PeiGetPe32Data (PeiCoreFileHandle, &PeiCoreImageBase); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Find PEI Core EntryPoint in the BFV in temporary memory. > + // > + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, > &PeiCoreEntryPoint); > + ASSERT_EFI_ERROR (Status); > + > + OrgImageBase = (UINTN) PeiCoreImageBase; > + MigratedImageBase = (UINTN) _ModuleEntryPoint - ((UINTN) > PeiCoreEntryPoint - (UINTN) PeiCoreImageBase); > + > + // > + // Size of loaded PEI_CORE in permanent memory. > + // > + PeiCoreModuleSize = (UINTN)FileInfo.BufferSize - ((UINTN) OrgImageBase - > (UINTN) FileInfo.Buffer); > + > + // > + // Migrate PEI_CORE PPI pointers from temporary memory to newly > + // installed PEI_CORE in permanent memory. > + // > + ConvertPpiPointersFv (PrivateData, (UINTN) OrgImageBase, (UINTN) > MigratedImageBase, PeiCoreModuleSize); > + } > +} > + > -- > 2.25.1.windows.1 > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#62392): https://edk2.groups.io/g/devel/message/62392 Mute This Topic: https://groups.io/mt/75390174/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-