Hi, Michael Thanks for the comments. Yes, I am following the similar pattern of UnitTestUefiBootServicesTableLib. I agree we can explain these types in the readme in the future patch.
In the newer version of patch, I remove the debug code markers as you suggested. Because this is the only change, I will keep your Reviewed-by. Thanks Zhiguang > -----Original Message----- > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael > Kubacki > Sent: Tuesday, June 6, 2023 11:28 PM > To: devel@edk2.groups.io; Liu, Zhiguang <zhiguang....@intel.com> > Cc: Kinney, Michael D <michael.d.kin...@intel.com>; Sean Brogan > <sean.bro...@microsoft.com> > Subject: Re: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add > UnitTestPeiServicesTablePointerLib > > It looks like you're following a similar pattern to a library instance > already in UnitTestFrameworkPkg/Library like > UnitTestUefiBootServicesTableLib. I can't find where these types of > libraries are explicitly called out in the > UnitTestFrameworkPkg/ReadMe.md file [1]. You don't need to add it in > this patch, but we might want to explain these in the readme (unless I > just missed it). > > They are not really a pure mock since they have a self-contained > functional implementation of some structures typically in core modules > like the PPI and HOB lists. They might also have more code outside the > unit being tested than is ideal in a unit test, but they are useful for > code that has dependencies in global databases. > > [1] - > https://github.com/tianocore/edk2/blob/master/UnitTestFrameworkPkg/R > eadMe.md#unit-test-locationlayout-rules > > There's some code I think is unnecessary in a unit test implementation > like surrounding this NULL pointer check with debug code markers in > UnitTestGetHobList(): > > DEBUG_CODE_BEGIN (); > if (HobList == NULL) { > return EFI_INVALID_PARAMETER; > } > > DEBUG_CODE_END (); > > Can you please simply check if the pointer is NULL? > > Reviewed-by: Michael Kubacki <michael.kuba...@microsoft.com> > > On 6/6/2023 1:40 AM, Zhiguang Liu wrote: > > This library supports a PeiServicesTablePointerLib implementation > > that allows code dependent upon PeiServicesTable to operate in an > > isolated execution environment such as within the context of a > > host-based unit test framework. > > > > The unit test should initialize the PeiServicesTable database with > > any required elements (e.g. PPIs, Hob etc.) prior to the services > > being invoked by code under test. > > > > It is strongly recommended to clean any global databases by using > > EFI_PEI_SERVICES.ResetSystem2 after every unit test so the tests > > execute in a predictable manner from a clean state. > > > > Cc: Michael D Kinney <michael.d.kin...@intel.com> > > Cc: Michael Kubacki <mikub...@linux.microsoft.com> > > Cc: Sean Brogan <sean.bro...@microsoft.com> > > Signed-off-by: Zhiguang Liu <zhiguang....@intel.com> > > --- > > .../UnitTestPeiServicesTablePointerLib.c | 187 +++++ > > .../UnitTestPeiServicesTablePointerLib.h | 653 ++++++++++++++++++ > > .../UnitTestPeiServicesTablePointerLib.inf | 37 + > > .../UnitTestPeiServicesTablePointerLib.uni | 12 + > > .../UnitTestPeiServicesTablePointerLibHob.c | 162 +++++ > > .../UnitTestPeiServicesTablePointerLibMisc.c | 430 ++++++++++++ > > .../UnitTestPeiServicesTablePointerLibPpi.c | 485 +++++++++++++ > > UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc | 1 + > > .../UnitTestFrameworkPkgHost.dsc.inc | 1 + > > 9 files changed, 1968 insertions(+) > > create mode 100644 > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLib.c > > create mode 100644 > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLib.h > > create mode 100644 > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLib.inf > > create mode 100644 > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLib.uni > > create mode 100644 > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLibHob.c > > create mode 100644 > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLibMisc.c > > create mode 100644 > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLibPpi.c > > > > diff --git > a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.c > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.c > > new file mode 100644 > > index 0000000000..a1b982fbae > > --- /dev/null > > +++ > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.c > > @@ -0,0 +1,187 @@ > > +/** @file > > + This library supports a PEI Service table Pointer library implementation > that > > + allows code dependent upon PEI Service to operate in an isolated > execution environment > > + such as within the context of a host-based unit test framework. > > + > > + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include "UnitTestPeiServicesTablePointerLib.h" > > + > > +/// > > +/// Pei service instance > > +/// > > +EFI_PEI_SERVICES mPeiServices = { > > + { > > + PEI_SERVICES_SIGNATURE, > > + PEI_SERVICES_REVISION, > > + sizeof (EFI_PEI_SERVICES), > > + 0, > > + 0 > > + }, > > + UnitTestInstallPpi, // InstallPpi > > + UnitTestReInstallPpi, // ReInstallPpi > > + UnitTestLocatePpi, // LocatePpi > > + UnitTestNotifyPpi, // NotifyPpi > > + > > + UnitTestGetBootMode, // GetBootMode > > + UnitTestSetBootMode, // SetBootMode > > + > > + UnitTestGetHobList, // GetHobList > > + UnitTestCreateHob, // CreateHob > > + > > + UnitTestFfsFindNextVolume, // FfsFindNextVolume > > + UnitTestFfsFindNextFile, // FfsFindNextFile > > + UnitTestFfsFindSectionData, // FfsFindSectionData > > + > > + UnitTestInstallPeiMemory, // InstallPeiMemory > > + UnitTestAllocatePages, // AllocatePages > > + UnitTestAllocatePool, // AllocatePool > > + (EFI_PEI_COPY_MEM)CopyMem, > > + (EFI_PEI_SET_MEM)SetMem, > > + > > + UnitTestReportStatusCode, // ReportStatusCode > > + UnitTestResetSystem, // ResetSystem > > + > > + NULL, // CpuIo > > + NULL, // PciCfg > > + > > + UnitTestFfsFindFileByName, // FfsFindFileByName > > + UnitTestFfsGetFileInfo, // FfsGetFileInfo > > + UnitTestFfsGetVolumeInfo, // FfsGetVolumeInfo > > + UnitTestRegisterForShadow, // RegisterForShadow > > + UnitTestFfsFindSectionData3, // FfsFindSectionData3 > > + UnitTestFfsGetFileInfo2, // FfsGetFileInfo2 > > + UnitTestResetSystem2, // ResetSystem2 > > + UnitTestFreePages, // FreePages > > +}; > > + > > +PEI_CORE_INSTANCE mPrivateData; > > +UINT8 mHobBuffer[MAX_HOB_SIZE]; > > +VOID *mPeiServicesPointer; > > + > > +/** > > + Clear Buffer For Global Data. > > +**/ > > +VOID > > +ClearGlobalData ( > > + VOID > > + ) > > +{ > > + ZeroMem (&mPrivateData, sizeof (mPrivateData)); > > + mPrivateData.PpiData.PpiList.MaxCount = MAX_PPI_COUNT; > > + mPrivateData.PpiData.CallbackNotifyList.MaxCount = MAX_PPI_COUNT; > > + mPrivateData.PpiData.DispatchNotifyList.MaxCount = MAX_PPI_COUNT; > > + > > + ZeroMem (mHobBuffer, MAX_HOB_SIZE); > > + mPrivateData.HobList.Raw = mHobBuffer; > > + UnitTestCoreBuildHobHandoffInfoTable (0, > (EFI_PHYSICAL_ADDRESS)(UINTN)mHobBuffer, MAX_HOB_SIZE); > > +} > > + > > +/** > > + Resets the entire platform. > > + > > + @param[in] ResetType The type of reset to perform. > > + @param[in] ResetStatus The status code for the reset. > > + @param[in] DataSize The size, in bytes, of ResetData. > > + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, > or EfiResetShutdown > > + the data buffer starts with a Null-terminated > > string, > optionally > > + followed by additional binary data. The string > > is a description > > + that the caller may use to further indicate > > the reason for the > > + system reset. > > + > > +**/ > > +VOID > > +EFIAPI > > +UnitTestResetSystem2 ( > > + IN EFI_RESET_TYPE ResetType, > > + IN EFI_STATUS ResetStatus, > > + IN UINTN DataSize, > > + IN VOID *ResetData OPTIONAL > > + ) > > +{ > > + ClearGlobalData (); > > +} > > + > > +/** > > + Retrieves the cached value of the PEI Services Table pointer. > > + > > + Returns the cached value of the PEI Services Table pointer in a CPU > specific manner > > + as specified in the CPU binding section of the Platform Initialization > > Pre- > EFI > > + Initialization Core Interface Specification. > > + > > + If the cached PEI Services Table pointer is NULL, then ASSERT(). > > + > > + @return The pointer to PeiServices. > > + > > +**/ > > +CONST EFI_PEI_SERVICES ** > > +EFIAPI > > +GetPeiServicesTablePointer ( > > + VOID > > + ) > > +{ > > + mPeiServicesPointer = &mPeiServices; > > + return (CONST EFI_PEI_SERVICES **)&mPeiServicesPointer; > > +} > > + > > +/** > > + Caches a pointer PEI Services Table. > > + > > + Caches the pointer to the PEI Services Table specified by > PeiServicesTablePointer > > + in a CPU specific manner as specified in the CPU binding section of the > Platform Initialization > > + Pre-EFI Initialization Core Interface Specification. > > + > > + If PeiServicesTablePointer is NULL, then ASSERT(). > > + > > + @param PeiServicesTablePointer The address of PeiServices pointer. > > +**/ > > +VOID > > +EFIAPI > > +SetPeiServicesTablePointer ( > > + IN CONST EFI_PEI_SERVICES **PeiServicesTablePointer > > + ) > > +{ > > + ASSERT (FALSE); > > +} > > + > > +/** > > + Perform CPU specific actions required to migrate the PEI Services Table > > + pointer from temporary RAM to permanent RAM. > > + > > + For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes > > + immediately preceding the Interrupt Descriptor Table (IDT) in memory. > > + For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes > > + immediately preceding the Interrupt Descriptor Table (IDT) in memory. > > + For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in > > + a dedicated CPU register. This means that there is no memory storage > > + associated with storing the PEI Services Table pointer, so no additional > > + migration actions are required for Itanium or ARM CPUs. > > + > > +**/ > > +VOID > > +EFIAPI > > +MigratePeiServicesTablePointer ( > > + VOID > > + ) > > +{ > > + ASSERT (FALSE); > > +} > > + > > +/** > > + The constructor function init PeiServicesTable with clean buffer. > > + > > + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestPeiServicesTablePointerLibConstructor ( > > + VOID > > + ) > > +{ > > + ClearGlobalData (); > > + return EFI_SUCCESS; > > +} > > diff --git > a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.h > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.h > > new file mode 100644 > > index 0000000000..e411d08a86 > > --- /dev/null > > +++ > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.h > > @@ -0,0 +1,653 @@ > > +/** @file > > + An internal header file for the Unit Test instance of the PEI services > > Table > Pointer Library. > > + > > + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#ifndef PEI_SERVICES_TABLE_POINTER_LIB_UNIT_TEST_H_ > > +#define PEI_SERVICES_TABLE_POINTER_LIB_UNIT_TEST_H_ > > + > > +#include <Base.h> > > +#include <PiPei.h> > > +#include <Pi/PiMultiPhase.h> > > +#include <Library/BaseLib.h> > > +#include <Library/BaseMemoryLib.h> > > +#include <Library/DebugLib.h> > > +#include <Library/UnitTestLib.h> > > +#include <Library/PeiServicesTablePointerLib.h> > > +#include <Uefi.h> > > + > > +#define MAX_PPI_COUNT 100 > > +#define MAX_HOB_SIZE SIZE_32MB > > + > > +/// > > +/// Forward declaration for PEI_CORE_INSTANCE > > +/// > > +typedef struct _PEI_CORE_INSTANCE PEI_CORE_INSTANCE; > > + > > +/// > > +/// Pei Core private data structures > > +/// > > +typedef union { > > + EFI_PEI_PPI_DESCRIPTOR *Ppi; > > + EFI_PEI_NOTIFY_DESCRIPTOR *Notify; > > + VOID *Raw; > > +} PEI_PPI_LIST_POINTERS; > > + > > +typedef struct { > > + UINTN CurrentCount; > > + UINTN MaxCount; > > + UINTN LastDispatchedCount; > > + /// > > + /// MaxCount number of entries. > > + /// > > + PEI_PPI_LIST_POINTERS PpiPtrs[MAX_PPI_COUNT]; > > +} PEI_PPI_LIST; > > + > > +typedef struct { > > + UINTN CurrentCount; > > + UINTN MaxCount; > > + /// > > + /// MaxCount number of entries. > > + /// > > + PEI_PPI_LIST_POINTERS NotifyPtrs[MAX_PPI_COUNT]; > > +} PEI_CALLBACK_NOTIFY_LIST; > > + > > +typedef struct { > > + UINTN CurrentCount; > > + UINTN MaxCount; > > + UINTN LastDispatchedCount; > > + /// > > + /// MaxCount number of entries. > > + /// > > + PEI_PPI_LIST_POINTERS NotifyPtrs[MAX_PPI_COUNT]; > > +} PEI_DISPATCH_NOTIFY_LIST; > > + > > +/// > > +/// PPI database structure which contains three links: > > +/// PpiList, CallbackNotifyList and DispatchNotifyList. > > +/// > > +typedef struct { > > + /// > > + /// PPI List. > > + /// > > + PEI_PPI_LIST PpiList; > > + /// > > + /// Notify List at dispatch level. > > + /// > > + PEI_CALLBACK_NOTIFY_LIST CallbackNotifyList; > > + /// > > + /// Notify List at callback level. > > + /// > > + PEI_DISPATCH_NOTIFY_LIST DispatchNotifyList; > > +} PEI_PPI_DATABASE; > > + > > +/// > > +/// Pei Core private data structure instance > > +/// > > +struct _PEI_CORE_INSTANCE { > > + PEI_PPI_DATABASE PpiData; > > + EFI_PEI_HOB_POINTERS HobList; > > +}; > > + > > +extern PEI_CORE_INSTANCE mPrivateData; > > +#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) &mPrivateData > > + > > +VOID > > +ProcessNotify ( > > + IN PEI_CORE_INSTANCE *PrivateData, > > + IN UINTN NotifyType, > > + IN INTN InstallStartIndex, > > + IN INTN InstallStopIndex, > > + IN INTN NotifyStartIndex, > > + IN INTN NotifyStopIndex > > + ); > > + > > +/** > > + > > + This function installs an interface in the PEI PPI database by GUID. > > + The purpose of the service is to publish an interface that other parties > > + can use to call additional PEIMs. > > + > > + @param PeiServices An indirect pointer to the > > EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param PpiList Pointer to a list of PEI PPI > > Descriptors. > > + > > + @retval EFI_SUCCESS if all PPIs in PpiList are successfully > > installed. > > + @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer > > + if any PPI in PpiList is not valid > > + @retval EFI_OUT_OF_RESOURCES if there is no more memory > resource to install PPI > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestInstallPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList > > + ); > > + > > +/** > > + > > + This function reinstalls an interface in the PEI PPI database by GUID. > > + The purpose of the service is to publish an interface that other parties > can > > + use to replace an interface of the same name in the protocol database > with a > > + different interface. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param OldPpi Pointer to the old PEI PPI Descriptors. > > + @param NewPpi Pointer to the new PEI PPI Descriptors. > > + > > + @retval EFI_SUCCESS if the operation was successful > > + @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL > > + @retval EFI_INVALID_PARAMETER if NewPpi is not valid > > + @retval EFI_NOT_FOUND if the PPI was not in the database > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestReInstallPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, > > + IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi > > + ); > > + > > +/** > > + > > + Locate a given named PPI. > > + > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param Guid Pointer to GUID of the PPI. > > + @param Instance Instance Number to discover. > > + @param PpiDescriptor Pointer to reference the found descriptor. If > not NULL, > > + returns a pointer to the descriptor (includes > > flags, etc) > > + @param Ppi Pointer to reference the found PPI > > + > > + @retval EFI_SUCCESS if the PPI is in the database > > + @retval EFI_NOT_FOUND if the PPI is not in the database > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestLocatePpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_GUID *Guid, > > + IN UINTN Instance, > > + IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, > > + IN OUT VOID **Ppi > > + ); > > + > > +/** > > + > > + This function installs a notification service to be called back when a > > given > > + interface is installed or reinstalled. The purpose of the service is to > publish > > + an interface that other parties can use to call additional PPIs that may > materialize later. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param NotifyList Pointer to list of Descriptors to notify upon. > > + > > + @retval EFI_SUCCESS if successful > > + @retval EFI_OUT_OF_RESOURCES if no space in the database > > + @retval EFI_INVALID_PARAMETER if not a good descriptor > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestNotifyPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList > > + ); > > + > > +/** > > + Gets the pointer to the HOB List. > > + > > + @param PeiServices An indirect pointer to the > EFI_PEI_SERVICES table published by the PEI Foundation. > > + @param HobList Pointer to the HOB List. > > + > > + @retval EFI_SUCCESS Get the pointer of HOB List > > + @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published > > + @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode) > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestGetHobList ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN OUT VOID **HobList > > + ); > > + > > +/** > > + Add a new HOB to the HOB List. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param Type Type of the new HOB. > > + @param Length Length of the new HOB to allocate. > > + @param Hob Pointer to the new HOB. > > + > > + @return EFI_SUCCESS Success to create HOB. > > + @retval EFI_INVALID_PARAMETER if Hob is NULL > > + @retval EFI_NOT_AVAILABLE_YET if HobList is still not available. > > + @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow > the Hoblist. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestCreateHob ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINT16 Type, > > + IN UINT16 Length, > > + IN OUT VOID **Hob > > + ); > > + > > +/** > > + > > + Builds a Handoff Information Table HOB > > + > > + @param BootMode - Current Bootmode > > + @param MemoryBegin - Start Memory Address. > > + @param MemoryLength - Length of Memory. > > + > > + @return EFI_SUCCESS Always success to initialize HOB. > > + > > +**/ > > +EFI_STATUS > > +UnitTestCoreBuildHobHandoffInfoTable ( > > + IN EFI_BOOT_MODE BootMode, > > + IN EFI_PHYSICAL_ADDRESS MemoryBegin, > > + IN UINT64 MemoryLength > > + ); > > + > > +/** > > + Resets the entire platform. > > + > > + @param[in] ResetType The type of reset to perform. > > + @param[in] ResetStatus The status code for the reset. > > + @param[in] DataSize The size, in bytes, of ResetData. > > + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, > or EfiResetShutdown > > + the data buffer starts with a Null-terminated > > string, > optionally > > + followed by additional binary data. The string > > is a description > > + that the caller may use to further indicate > > the reason for the > > + system reset. > > + > > +**/ > > +VOID > > +EFIAPI > > +UnitTestResetSystem2 ( > > + IN EFI_RESET_TYPE ResetType, > > + IN EFI_STATUS ResetStatus, > > + IN UINTN DataSize, > > + IN VOID *ResetData OPTIONAL > > + ); > > + > > +/** > > + This service enables PEIMs to ascertain the present value of the boot > mode. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param BootMode A pointer to contain the value of the boot > mode. > > + > > + @retval EFI_SUCCESS The boot mode was returned successfully. > > + @retval EFI_INVALID_PARAMETER BootMode is NULL. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestGetBootMode ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN OUT EFI_BOOT_MODE *BootMode > > + ); > > + > > +/** > > + This service enables PEIMs to update the boot mode variable. > > + > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param BootMode The value of the boot mode to set. > > + > > + @return EFI_SUCCESS The value was successfully updated > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestSetBootMode ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_BOOT_MODE BootMode > > + ); > > + > > +/** > > + Search the firmware volumes by index > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation > > + @param Instance This instance of the firmware volume to find. The > value 0 is the Boot Firmware > > + Volume (BFV). > > + @param VolumeHandle On exit, points to the next volume handle or > NULL if it does not exist. > > + > > + @retval EFI_INVALID_PARAMETER VolumeHandle is NULL > > + @retval EFI_NOT_FOUND The volume was not found. > > + @retval EFI_SUCCESS The volume was found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindNextVolume ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINTN Instance, > > + IN OUT EFI_PEI_FV_HANDLE *VolumeHandle > > + ); > > + > > +/** > > + Searches for the next matching file in the firmware volume. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param SearchType Filter to find only files of this type. > > + Type EFI_FV_FILETYPE_ALL causes no filtering to > > be done. > > + @param FvHandle Handle of firmware volume in which to search. > > + @param FileHandle On entry, points to the current handle from which > to begin searching or NULL to start > > + at the beginning of the firmware volume. On exit, > > points the > file handle of the next file > > + in the volume or NULL if there are no more files. > > + > > + @retval EFI_NOT_FOUND The file was not found. > > + @retval EFI_NOT_FOUND The header checksum was not zero. > > + @retval EFI_SUCCESS The file was found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindNextFile ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINT8 SearchType, > > + IN EFI_PEI_FV_HANDLE FvHandle, > > + IN OUT EFI_PEI_FILE_HANDLE *FileHandle > > + ); > > + > > +/** > > + Searches for the next matching section within the specified file. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation > > + @param SectionType Filter to find only sections of this type. > > + @param FileHandle Pointer to the current file to search. > > + @param SectionData A pointer to the discovered section, if > > successful. > > + NULL if section not found > > + > > + @retval EFI_NOT_FOUND The section was not found. > > + @retval EFI_SUCCESS The section was found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindSectionData ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_SECTION_TYPE SectionType, > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT VOID **SectionData > > + ); > > + > > +/** > > + > > + This function registers the found memory configuration with the PEI > Foundation. > > + > > + The usage model is that the PEIM that discovers the permanent memory > shall invoke this service. > > + This routine will hold discoveried memory information into PeiCore's > private data, > > + and set SwitchStackSignal flag. After PEIM who discovery memory is > dispatched, > > + PeiDispatcher will migrate temporary memory to permanent memory. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param MemoryBegin Start of memory address. > > + @param MemoryLength Length of memory. > > + > > + @return EFI_SUCCESS Always success. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestInstallPeiMemory ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_PHYSICAL_ADDRESS MemoryBegin, > > + IN UINT64 MemoryLength > > + ); > > + > > +/** > > + The purpose of the service is to publish an interface that allows > > + PEIMs to allocate memory ranges that are managed by the PEI > Foundation. > > + > > + Prior to InstallPeiMemory() being called, PEI will allocate pages from > > the > heap. > > + After InstallPeiMemory() is called, PEI will allocate pages within the > region > > + of memory provided by InstallPeiMemory() service in a best-effort > fashion. > > + Location-specific allocations are not managed by the PEI foundation code. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param MemoryType The type of memory to allocate. > > + @param Pages The number of contiguous 4 KB pages to allocate. > > + @param Memory Pointer to a physical address. On output, the > address is set to the base > > + of the page range that was allocated. > > + > > + @retval EFI_SUCCESS The memory range was successfully > > allocated. > > + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. > > + @retval EFI_INVALID_PARAMETER Type is not equal to EfiLoaderCode, > EfiLoaderData, EfiRuntimeServicesCode, > > + EfiRuntimeServicesData, > > EfiBootServicesCode, > EfiBootServicesData, > > + EfiACPIReclaimMemory, > > EfiReservedMemoryType, or > EfiACPIMemoryNVS. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestAllocatePages ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_MEMORY_TYPE MemoryType, > > + IN UINTN Pages, > > + OUT EFI_PHYSICAL_ADDRESS *Memory > > + ); > > + > > +/** > > + > > + Pool allocation service. Before permanent memory is discovered, the > pool will > > + be allocated in the heap in temporary memory. Generally, the size of the > heap in temporary > > + memory does not exceed 64K, so the biggest pool size could be allocated > is > > + 64K. > > + > > + @param PeiServices An indirect pointer to the > > EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param Size Amount of memory required > > + @param Buffer Address of pointer to the buffer > > + > > + @retval EFI_SUCCESS The allocation was successful > > + @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy > the requirement > > + to allocate the requested size. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestAllocatePool ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINTN Size, > > + OUT VOID **Buffer > > + ); > > + > > +/** > > + > > + Core version of the Status Code reporter > > + > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param CodeType Type of Status Code. > > + @param Value Value to output for Status Code. > > + @param Instance Instance Number of this status code. > > + @param CallerId ID of the caller of this status code. > > + @param Data Optional data associated with this status code. > > + > > + @retval EFI_SUCCESS if status code is successfully reported > > + @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been > installed > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestReportStatusCode ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_STATUS_CODE_TYPE CodeType, > > + IN EFI_STATUS_CODE_VALUE Value, > > + IN UINT32 Instance, > > + IN CONST EFI_GUID *CallerId, > > + IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL > > + ); > > + > > +/** > > + > > +Core version of the Reset System > > + > > + > > +@param PeiServices An indirect pointer to the > > EFI_PEI_SERVICES > table published by the PEI Foundation. > > + > > +@retval EFI_NOT_AVAILABLE_YET PPI not available yet. > > +@retval EFI_DEVICE_ERROR Did not reset system. > > + Otherwise, resets the system. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestResetSystem ( > > + IN CONST EFI_PEI_SERVICES **PeiServices > > + ); > > + > > +/** > > + Find a file within a volume by its name. > > + > > + @param FileName A pointer to the name of the file to find within > > the > firmware volume. > > + @param VolumeHandle The firmware volume to search > > + @param FileHandle Upon exit, points to the found file's handle > > + or NULL if it could not be found. > > + > > + @retval EFI_SUCCESS File was found. > > + @retval EFI_NOT_FOUND File was not found. > > + @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or > FileName was NULL. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindFileByName ( > > + IN CONST EFI_GUID *FileName, > > + IN EFI_PEI_FV_HANDLE VolumeHandle, > > + OUT EFI_PEI_FILE_HANDLE *FileHandle > > + ); > > + > > +/** > > + Returns information about a specific file. > > + > > + @param FileHandle Handle of the file. > > + @param FileInfo Upon exit, points to the file's information. > > + > > + @retval EFI_INVALID_PARAMETER If FileInfo is NULL. > > + @retval EFI_INVALID_PARAMETER If FileHandle does not represent a > valid file. > > + @retval EFI_SUCCESS File information returned. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsGetFileInfo ( > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT EFI_FV_FILE_INFO *FileInfo > > + ); > > + > > +/** > > + Returns information about the specified volume. > > + > > + This function returns information about a specific firmware > > + volume, including its name, type, attributes, starting address > > + and size. > > + > > + @param VolumeHandle Handle of the volume. > > + @param VolumeInfo Upon exit, points to the volume's information. > > + > > + @retval EFI_SUCCESS Volume information returned. > > + @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent > a valid volume. > > + @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL. > > + @retval EFI_SUCCESS Information successfully returned. > > + @retval EFI_INVALID_PARAMETER The volume designated by the > VolumeHandle is not available. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsGetVolumeInfo ( > > + IN EFI_PEI_FV_HANDLE VolumeHandle, > > + OUT EFI_FV_INFO *VolumeInfo > > + ); > > + > > +/** > > +This routine enables a PEIM to register itself for shadow when the PEI > Foundation > > +discovers permanent memory. > > + > > +@param FileHandle File handle of a PEIM. > > + > > +@retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself. > > +@retval EFI_ALREADY_STARTED Indicate that the PEIM has been > registered itself. > > +@retval EFI_SUCCESS Successfully to register itself. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestRegisterForShadow ( > > + IN EFI_PEI_FILE_HANDLE FileHandle > > + ); > > + > > +/** > > +Searches for the next matching section within the specified file. > > + > > +@param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > +@param SectionType The value of the section type to find. > > +@param SectionInstance Section instance to find. > > +@param FileHandle Handle of the firmware file to search. > > +@param SectionData A pointer to the discovered section, if > successful. > > +@param AuthenticationStatus A pointer to the authentication status for > this section. > > + > > +@retval EFI_SUCCESS The section was found. > > +@retval EFI_NOT_FOUND The section was not found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindSectionData3 ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_SECTION_TYPE SectionType, > > + IN UINTN SectionInstance, > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT VOID **SectionData, > > + OUT UINT32 *AuthenticationStatus > > + ); > > + > > +/** > > +Returns information about a specific file. > > + > > +@param FileHandle Handle of the file. > > +@param FileInfo Upon exit, points to the file's information. > > + > > +@retval EFI_INVALID_PARAMETER If FileInfo is NULL. > > +@retval EFI_INVALID_PARAMETER If FileHandle does not represent a > valid file. > > +@retval EFI_SUCCESS File information returned. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsGetFileInfo2 ( > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT EFI_FV_FILE_INFO2 *FileInfo > > + ); > > + > > +/** > > +Frees memory pages. > > + > > +@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > +@param[in] Memory The base physical address of the pages to be > freed. > > +@param[in] Pages The number of contiguous 4 KB pages to free. > > + > > +@retval EFI_SUCCESS The requested pages were freed. > > +@retval EFI_INVALID_PARAMETER Memory is not a page-aligned address > or Pages is invalid. > > +@retval EFI_NOT_FOUND The requested memory pages were not > allocated with > > + AllocatePages(). > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFreePages ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_PHYSICAL_ADDRESS Memory, > > + IN UINTN Pages > > + ); > > + > > +#endif > > diff --git > a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.inf > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.inf > > new file mode 100644 > > index 0000000000..59d86c9db8 > > --- /dev/null > > +++ > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.inf > > @@ -0,0 +1,37 @@ > > +## @file > > +# Pei Services Table Pointer Lib for unit tests implementation. > > +# > > +# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > +[Defines] > > + INF_VERSION = 0x00010005 > > + BASE_NAME = UnitTestPeiServicesTablePointerLib > > + MODULE_UNI_FILE = UnitTestPeiServicesTablePointerLib.uni > > + FILE_GUID = 55F23CD2-9BB1-41EE-AB10-550B638210E1 > > + MODULE_TYPE = BASE > > + VERSION_STRING = 1.0 > > + LIBRARY_CLASS = PeiServicesTablePointerLib > > + > > + CONSTRUCTOR = > UnitTestPeiServicesTablePointerLibConstructor > > +# > > +# VALID_ARCHITECTURES = IA32 X64 EBC > > +# > > + > > +[Sources] > > + UnitTestPeiServicesTablePointerLib.h > > + UnitTestPeiServicesTablePointerLib.c > > + UnitTestPeiServicesTablePointerLibMisc.c > > + UnitTestPeiServicesTablePointerLibPpi.c > > + UnitTestPeiServicesTablePointerLibHob.c > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + BaseMemoryLib > > + DebugLib > > + UnitTestLib > > diff --git > a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.uni > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.uni > > new file mode 100644 > > index 0000000000..ca2118533a > > --- /dev/null > > +++ > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLib.uni > > @@ -0,0 +1,12 @@ > > +// /** @file > > +// Pei Services Table Pointer Lib for unit tests implementation. > > +// > > +// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > > +// > > +// SPDX-License-Identifier: BSD-2-Clause-Patent > > +// > > +// **/ > > + > > +#string STR_MODULE_ABSTRACT #language en-US "Pei Services > Table Pointer Lib for unit tests." > > + > > +#string STR_MODULE_DESCRIPTION #language en-US "Pei Services > Table Pointer Lib for unit tests." > > diff --git > a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibHob.c > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibHob.c > > new file mode 100644 > > index 0000000000..2d4ffe8c59 > > --- /dev/null > > +++ > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibHob.c > > @@ -0,0 +1,162 @@ > > +/** @file > > + This file implements some PEI services about Hob. > > + > > + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include "UnitTestPeiServicesTablePointerLib.h" > > + > > +/** > > + > > + Gets the pointer to the HOB List. > > + > > + @param PeiServices An indirect pointer to the > EFI_PEI_SERVICES table published by the PEI Foundation. > > + @param HobList Pointer to the HOB List. > > + > > + @retval EFI_SUCCESS Get the pointer of HOB List > > + @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published > > + @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode) > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestGetHobList ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN OUT VOID **HobList > > + ) > > +{ > > + PEI_CORE_INSTANCE *PrivateData; > > + > > + // > > + // Only check this parameter in debug mode > > + // > > + > > + DEBUG_CODE_BEGIN (); > > + if (HobList == NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + DEBUG_CODE_END (); > > + > > + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); > > + > > + *HobList = PrivateData->HobList.Raw; > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + Add a new HOB to the HOB List. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param Type Type of the new HOB. > > + @param Length Length of the new HOB to allocate. > > + @param Hob Pointer to the new HOB. > > + > > + @return EFI_SUCCESS Success to create HOB. > > + @retval EFI_INVALID_PARAMETER if Hob is NULL > > + @retval EFI_NOT_AVAILABLE_YET if HobList is still not available. > > + @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow > the Hoblist. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestCreateHob ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINT16 Type, > > + IN UINT16 Length, > > + IN OUT VOID **Hob > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; > > + EFI_HOB_GENERIC_HEADER *HobEnd; > > + EFI_PHYSICAL_ADDRESS FreeMemory; > > + > > + Status = UnitTestGetHobList (PeiServices, Hob); > > + if (EFI_ERROR (Status)) { > > + return Status; > > + } > > + > > + HandOffHob = *Hob; > > + > > + // > > + // Check Length to avoid data overflow. > > + // > > + if (0x10000 - Length <= 0x7) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + Length = (UINT16)((Length + 0x7) & (~0x7)); > > + > > + FreeMemory = HandOffHob->EfiFreeMemoryTop - > > + HandOffHob->EfiFreeMemoryBottom; > > + > > + if (FreeMemory < Length) { > > + DEBUG ((DEBUG_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", > (UINTN)Length)); > > + DEBUG ((DEBUG_ERROR, " FreeMemoryTop - 0x%08x\n", > (UINTN)HandOffHob->EfiFreeMemoryTop)); > > + DEBUG ((DEBUG_ERROR, " FreeMemoryBottom - 0x%08x\n", > (UINTN)HandOffHob->EfiFreeMemoryBottom)); > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + *Hob = (VOID *)(UINTN)HandOffHob- > >EfiEndOfHobList; > > + ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobType = Type; > > + ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobLength = Length; > > + ((EFI_HOB_GENERIC_HEADER *)*Hob)->Reserved = 0; > > + > > + HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)*Hob + > Length); > > + HandOffHob->EfiEndOfHobList = > (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; > > + > > + HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; > > + HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER); > > + HobEnd->Reserved = 0; > > + HobEnd++; > > + HandOffHob->EfiFreeMemoryBottom = > (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + > > + Builds a Handoff Information Table HOB > > + > > + @param BootMode - Current Bootmode > > + @param MemoryBegin - Start Memory Address. > > + @param MemoryLength - Length of Memory. > > + > > + @return EFI_SUCCESS Always success to initialize HOB. > > + > > +**/ > > +EFI_STATUS > > +UnitTestCoreBuildHobHandoffInfoTable ( > > + IN EFI_BOOT_MODE BootMode, > > + IN EFI_PHYSICAL_ADDRESS MemoryBegin, > > + IN UINT64 MemoryLength > > + ) > > +{ > > + EFI_HOB_HANDOFF_INFO_TABLE *Hob; > > + EFI_HOB_GENERIC_HEADER *HobEnd; > > + > > + Hob = (VOID *)(UINTN)MemoryBegin; > > + HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1); > > + Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF; > > + Hob->Header.HobLength = (UINT16)sizeof > (EFI_HOB_HANDOFF_INFO_TABLE); > > + Hob->Header.Reserved = 0; > > + > > + HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; > > + HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER); > > + HobEnd->Reserved = 0; > > + > > + Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION; > > + Hob->BootMode = BootMode; > > + > > + Hob->EfiMemoryTop = MemoryBegin + MemoryLength; > > + Hob->EfiMemoryBottom = MemoryBegin; > > + Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength; > > + Hob->EfiFreeMemoryBottom = > (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd + 1); > > + Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; > > + > > + return EFI_SUCCESS; > > +} > > diff --git > a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibMisc.c > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibMisc.c > > new file mode 100644 > > index 0000000000..90955bf482 > > --- /dev/null > > +++ > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibMisc.c > > @@ -0,0 +1,430 @@ > > +/** @file > > + This file implements some PEI services. > > + > > + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include "UnitTestPeiServicesTablePointerLib.h" > > + > > +/** > > + This service enables PEIMs to ascertain the present value of the boot > mode. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param BootMode A pointer to contain the value of the boot > mode. > > + > > + @retval EFI_SUCCESS The boot mode was returned successfully. > > + @retval EFI_INVALID_PARAMETER BootMode is NULL. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestGetBootMode ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN OUT EFI_BOOT_MODE *BootMode > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + This service enables PEIMs to update the boot mode variable. > > + > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param BootMode The value of the boot mode to set. > > + > > + @return EFI_SUCCESS The value was successfully updated > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestSetBootMode ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_BOOT_MODE BootMode > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + Search the firmware volumes by index > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation > > + @param Instance This instance of the firmware volume to find. The > value 0 is the Boot Firmware > > + Volume (BFV). > > + @param VolumeHandle On exit, points to the next volume handle or > NULL if it does not exist. > > + > > + @retval EFI_INVALID_PARAMETER VolumeHandle is NULL > > + @retval EFI_NOT_FOUND The volume was not found. > > + @retval EFI_SUCCESS The volume was found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindNextVolume ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINTN Instance, > > + IN OUT EFI_PEI_FV_HANDLE *VolumeHandle > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + Searches for the next matching file in the firmware volume. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param SearchType Filter to find only files of this type. > > + Type EFI_FV_FILETYPE_ALL causes no filtering to > > be done. > > + @param FvHandle Handle of firmware volume in which to search. > > + @param FileHandle On entry, points to the current handle from which > to begin searching or NULL to start > > + at the beginning of the firmware volume. On exit, > > points the > file handle of the next file > > + in the volume or NULL if there are no more files. > > + > > + @retval EFI_NOT_FOUND The file was not found. > > + @retval EFI_NOT_FOUND The header checksum was not zero. > > + @retval EFI_SUCCESS The file was found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindNextFile ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINT8 SearchType, > > + IN EFI_PEI_FV_HANDLE FvHandle, > > + IN OUT EFI_PEI_FILE_HANDLE *FileHandle > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + Searches for the next matching section within the specified file. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation > > + @param SectionType Filter to find only sections of this type. > > + @param FileHandle Pointer to the current file to search. > > + @param SectionData A pointer to the discovered section, if > > successful. > > + NULL if section not found > > + > > + @retval EFI_NOT_FOUND The section was not found. > > + @retval EFI_SUCCESS The section was found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindSectionData ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_SECTION_TYPE SectionType, > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT VOID **SectionData > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + > > + This function registers the found memory configuration with the PEI > Foundation. > > + > > + The usage model is that the PEIM that discovers the permanent memory > shall invoke this service. > > + This routine will hold discoveried memory information into PeiCore's > private data, > > + and set SwitchStackSignal flag. After PEIM who discovery memory is > dispatched, > > + PeiDispatcher will migrate temporary memory to permanent memory. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param MemoryBegin Start of memory address. > > + @param MemoryLength Length of memory. > > + > > + @return EFI_SUCCESS Always success. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestInstallPeiMemory ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_PHYSICAL_ADDRESS MemoryBegin, > > + IN UINT64 MemoryLength > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + The purpose of the service is to publish an interface that allows > > + PEIMs to allocate memory ranges that are managed by the PEI > Foundation. > > + > > + Prior to InstallPeiMemory() being called, PEI will allocate pages from > > the > heap. > > + After InstallPeiMemory() is called, PEI will allocate pages within the > region > > + of memory provided by InstallPeiMemory() service in a best-effort > fashion. > > + Location-specific allocations are not managed by the PEI foundation code. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param MemoryType The type of memory to allocate. > > + @param Pages The number of contiguous 4 KB pages to allocate. > > + @param Memory Pointer to a physical address. On output, the > address is set to the base > > + of the page range that was allocated. > > + > > + @retval EFI_SUCCESS The memory range was successfully > > allocated. > > + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. > > + @retval EFI_INVALID_PARAMETER Type is not equal to EfiLoaderCode, > EfiLoaderData, EfiRuntimeServicesCode, > > + EfiRuntimeServicesData, > > EfiBootServicesCode, > EfiBootServicesData, > > + EfiACPIReclaimMemory, > > EfiReservedMemoryType, or > EfiACPIMemoryNVS. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestAllocatePages ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_MEMORY_TYPE MemoryType, > > + IN UINTN Pages, > > + OUT EFI_PHYSICAL_ADDRESS *Memory > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + > > + Pool allocation service. Before permanent memory is discovered, the > pool will > > + be allocated in the heap in temporary memory. Generally, the size of the > heap in temporary > > + memory does not exceed 64K, so the biggest pool size could be allocated > is > > + 64K. > > + > > + @param PeiServices An indirect pointer to the > > EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param Size Amount of memory required > > + @param Buffer Address of pointer to the buffer > > + > > + @retval EFI_SUCCESS The allocation was successful > > + @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy > the requirement > > + to allocate the requested size. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestAllocatePool ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN UINTN Size, > > + OUT VOID **Buffer > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + > > + Core version of the Status Code reporter > > + > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table > published by the PEI Foundation. > > + @param CodeType Type of Status Code. > > + @param Value Value to output for Status Code. > > + @param Instance Instance Number of this status code. > > + @param CallerId ID of the caller of this status code. > > + @param Data Optional data associated with this status code. > > + > > + @retval EFI_SUCCESS if status code is successfully reported > > + @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been > installed > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestReportStatusCode ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_STATUS_CODE_TYPE CodeType, > > + IN EFI_STATUS_CODE_VALUE Value, > > + IN UINT32 Instance, > > + IN CONST EFI_GUID *CallerId, > > + IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + > > +Core version of the Reset System > > + > > + > > +@param PeiServices An indirect pointer to the > > EFI_PEI_SERVICES > table published by the PEI Foundation. > > + > > +@retval EFI_NOT_AVAILABLE_YET PPI not available yet. > > +@retval EFI_DEVICE_ERROR Did not reset system. > > + Otherwise, resets the system. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestResetSystem ( > > + IN CONST EFI_PEI_SERVICES **PeiServices > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + Find a file within a volume by its name. > > + > > + @param FileName A pointer to the name of the file to find within > > the > firmware volume. > > + @param VolumeHandle The firmware volume to search > > + @param FileHandle Upon exit, points to the found file's handle > > + or NULL if it could not be found. > > + > > + @retval EFI_SUCCESS File was found. > > + @retval EFI_NOT_FOUND File was not found. > > + @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or > FileName was NULL. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindFileByName ( > > + IN CONST EFI_GUID *FileName, > > + IN EFI_PEI_FV_HANDLE VolumeHandle, > > + OUT EFI_PEI_FILE_HANDLE *FileHandle > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + Returns information about a specific file. > > + > > + @param FileHandle Handle of the file. > > + @param FileInfo Upon exit, points to the file's information. > > + > > + @retval EFI_INVALID_PARAMETER If FileInfo is NULL. > > + @retval EFI_INVALID_PARAMETER If FileHandle does not represent a > valid file. > > + @retval EFI_SUCCESS File information returned. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsGetFileInfo ( > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT EFI_FV_FILE_INFO *FileInfo > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > + Returns information about the specified volume. > > + > > + This function returns information about a specific firmware > > + volume, including its name, type, attributes, starting address > > + and size. > > + > > + @param VolumeHandle Handle of the volume. > > + @param VolumeInfo Upon exit, points to the volume's information. > > + > > + @retval EFI_SUCCESS Volume information returned. > > + @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent > a valid volume. > > + @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL. > > + @retval EFI_SUCCESS Information successfully returned. > > + @retval EFI_INVALID_PARAMETER The volume designated by the > VolumeHandle is not available. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsGetVolumeInfo ( > > + IN EFI_PEI_FV_HANDLE VolumeHandle, > > + OUT EFI_FV_INFO *VolumeInfo > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > +This routine enables a PEIM to register itself for shadow when the PEI > Foundation > > +discovers permanent memory. > > + > > +@param FileHandle File handle of a PEIM. > > + > > +@retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself. > > +@retval EFI_ALREADY_STARTED Indicate that the PEIM has been > registered itself. > > +@retval EFI_SUCCESS Successfully to register itself. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestRegisterForShadow ( > > + IN EFI_PEI_FILE_HANDLE FileHandle > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > +Searches for the next matching section within the specified file. > > + > > +@param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > +@param SectionType The value of the section type to find. > > +@param SectionInstance Section instance to find. > > +@param FileHandle Handle of the firmware file to search. > > +@param SectionData A pointer to the discovered section, if > successful. > > +@param AuthenticationStatus A pointer to the authentication status for > this section. > > + > > +@retval EFI_SUCCESS The section was found. > > +@retval EFI_NOT_FOUND The section was not found. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsFindSectionData3 ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_SECTION_TYPE SectionType, > > + IN UINTN SectionInstance, > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT VOID **SectionData, > > + OUT UINT32 *AuthenticationStatus > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > +Returns information about a specific file. > > + > > +@param FileHandle Handle of the file. > > +@param FileInfo Upon exit, points to the file's information. > > + > > +@retval EFI_INVALID_PARAMETER If FileInfo is NULL. > > +@retval EFI_INVALID_PARAMETER If FileHandle does not represent a > valid file. > > +@retval EFI_SUCCESS File information returned. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFfsGetFileInfo2 ( > > + IN EFI_PEI_FILE_HANDLE FileHandle, > > + OUT EFI_FV_FILE_INFO2 *FileInfo > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > + > > +/** > > +Frees memory pages. > > + > > +@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > +@param[in] Memory The base physical address of the pages to be > freed. > > +@param[in] Pages The number of contiguous 4 KB pages to free. > > + > > +@retval EFI_SUCCESS The requested pages were freed. > > +@retval EFI_INVALID_PARAMETER Memory is not a page-aligned address > or Pages is invalid. > > +@retval EFI_NOT_FOUND The requested memory pages were not > allocated with > > + AllocatePages(). > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestFreePages ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN EFI_PHYSICAL_ADDRESS Memory, > > + IN UINTN Pages > > + ) > > +{ > > + return EFI_NOT_AVAILABLE_YET; > > +} > > diff --git > a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibPpi.c > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibPpi.c > > new file mode 100644 > > index 0000000000..09f4094dad > > --- /dev/null > > +++ > b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitT > estPeiServicesTablePointerLibPpi.c > > @@ -0,0 +1,485 @@ > > +/** @file > > + This file implements some PEI services about PPI. > > + > > + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > + > > +#include "UnitTestPeiServicesTablePointerLib.h" > > + > > +/** > > + > > + This function installs an interface in the PEI PPI database by GUID. > > + The purpose of the service is to publish an interface that other parties > > + can use to call additional PEIMs. > > + > > + @param PeiServices An indirect pointer to the > > EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param PpiList Pointer to a list of PEI PPI > > Descriptors. > > + @param Single TRUE if only single entry in the > > PpiList. > > + FALSE if the PpiList is ended with an > > entry which has the > > + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST > > flag set in > its Flags field. > > + > > + @retval EFI_SUCCESS if all PPIs in PpiList are successfully > > installed. > > + @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer > > + if any PPI in PpiList is not valid > > + @retval EFI_OUT_OF_RESOURCES if there is no more memory > resource to install PPI > > + > > +**/ > > +EFI_STATUS > > +InternalPeiInstallPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, > > + IN BOOLEAN Single > > + ) > > +{ > > + PEI_CORE_INSTANCE *PrivateData; > > + PEI_PPI_LIST *PpiListPointer; > > + UINTN Index; > > + UINTN LastCount; > > + > > + if (PpiList == NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); > > + > > + PpiListPointer = &PrivateData->PpiData.PpiList; > > + Index = PpiListPointer->CurrentCount; > > + LastCount = Index; > > + > > + // > > + // This is loop installs all PPI descriptors in the PpiList. It is > > terminated > > + // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the > last > > + // EFI_PEI_PPI_DESCRIPTOR in the list. > > + // > > + > > + for ( ; ;) { > > + // > > + // Check if it is a valid PPI. > > + // If not, rollback list to exclude all in this list. > > + // Try to indicate which item failed. > > + // > > + if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) { > > + PpiListPointer->CurrentCount = LastCount; > > + DEBUG ((DEBUG_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, > PpiList->Ppi)); > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + if (Index >= PpiListPointer->MaxCount) { > > + // > > + // Run out of room, assert. > > + // > > + ASSERT (Index < PpiListPointer->MaxCount); > > + } > > + > > + DEBUG ((DEBUG_INFO, "Install PPI: %g\n", PpiList->Guid)); > > + PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)PpiList; > > + Index++; > > + PpiListPointer->CurrentCount++; > > + > > + if (Single) { > > + // > > + // Only single entry in the PpiList. > > + // > > + break; > > + } else if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) > == > > + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) > > + { > > + // > > + // Continue until the end of the PPI List. > > + // > > + break; > > + } > > + > > + // > > + // Go to the next descriptor. > > + // > > + PpiList++; > > + } > > + > > + // > > + // Process any callback level notifies for newly installed PPIs. > > + // > > + ProcessNotify ( > > + PrivateData, > > + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, > > + LastCount, > > + PpiListPointer->CurrentCount, > > + 0, > > + PrivateData->PpiData.CallbackNotifyList.CurrentCount > > + ); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + > > + This function installs an interface in the PEI PPI database by GUID. > > + The purpose of the service is to publish an interface that other parties > > + can use to call additional PEIMs. > > + > > + @param PeiServices An indirect pointer to the > > EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param PpiList Pointer to a list of PEI PPI > > Descriptors. > > + > > + @retval EFI_SUCCESS if all PPIs in PpiList are successfully > > installed. > > + @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer > > + if any PPI in PpiList is not valid > > + @retval EFI_OUT_OF_RESOURCES if there is no more memory > resource to install PPI > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestInstallPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList > > + ) > > +{ > > + return InternalPeiInstallPpi (PeiServices, PpiList, FALSE); > > +} > > + > > +/** > > + > > + This function reinstalls an interface in the PEI PPI database by GUID. > > + The purpose of the service is to publish an interface that other parties > can > > + use to replace an interface of the same name in the protocol database > with a > > + different interface. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param OldPpi Pointer to the old PEI PPI Descriptors. > > + @param NewPpi Pointer to the new PEI PPI Descriptors. > > + > > + @retval EFI_SUCCESS if the operation was successful > > + @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL > > + @retval EFI_INVALID_PARAMETER if NewPpi is not valid > > + @retval EFI_NOT_FOUND if the PPI was not in the database > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestReInstallPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, > > + IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi > > + ) > > +{ > > + PEI_CORE_INSTANCE *PrivateData; > > + UINTN Index; > > + > > + if ((OldPpi == NULL) || (NewPpi == NULL)) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); > > + > > + // > > + // Find the old PPI instance in the database. If we can not find it, > > + // return the EFI_NOT_FOUND error. > > + // > > + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; > Index++) { > > + if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) { > > + break; > > + } > > + } > > + > > + if (Index == PrivateData->PpiData.PpiList.CurrentCount) { > > + return EFI_NOT_FOUND; > > + } > > + > > + // > > + // Replace the old PPI with the new one. > > + // > > + DEBUG ((DEBUG_INFO, "Reinstall PPI: %g\n", NewPpi->Guid)); > > + PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = > (EFI_PEI_PPI_DESCRIPTOR *)NewPpi; > > + > > + // > > + // Process any callback level notifies for the newly installed PPI. > > + // > > + ProcessNotify ( > > + PrivateData, > > + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, > > + Index, > > + Index+1, > > + 0, > > + PrivateData->PpiData.CallbackNotifyList.CurrentCount > > + ); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + > > + Locate a given named PPI. > > + > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param Guid Pointer to GUID of the PPI. > > + @param Instance Instance Number to discover. > > + @param PpiDescriptor Pointer to reference the found descriptor. If > not NULL, > > + returns a pointer to the descriptor (includes > > flags, etc) > > + @param Ppi Pointer to reference the found PPI > > + > > + @retval EFI_SUCCESS if the PPI is in the database > > + @retval EFI_NOT_FOUND if the PPI is not in the database > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestLocatePpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_GUID *Guid, > > + IN UINTN Instance, > > + IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, > > + IN OUT VOID **Ppi > > + ) > > +{ > > + PEI_CORE_INSTANCE *PrivateData; > > + UINTN Index; > > + EFI_GUID *CheckGuid; > > + EFI_PEI_PPI_DESCRIPTOR *TempPtr; > > + > > + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); > > + > > + // > > + // Search the data base for the matching instance of the GUIDed PPI. > > + // > > + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; > Index++) { > > + TempPtr = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi; > > + CheckGuid = TempPtr->Guid; > > + > > + // > > + // 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 *)CheckGuid)[0]) && > > + (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) && > > + (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) && > > + (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) > > + { > > + if (Instance == 0) { > > + if (PpiDescriptor != NULL) { > > + *PpiDescriptor = TempPtr; > > + } > > + > > + if (Ppi != NULL) { > > + *Ppi = TempPtr->Ppi; > > + } > > + > > + return EFI_SUCCESS; > > + } > > + > > + Instance--; > > + } > > + } > > + > > + return EFI_NOT_FOUND; > > +} > > + > > +/** > > + > > + This function installs a notification service to be called back when a > > given > > + interface is installed or reinstalled. The purpose of the service is to > publish > > + an interface that other parties can use to call additional PPIs that may > materialize later. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param NotifyList Pointer to list of Descriptors to notify upon. > > + @param Single TRUE if only single entry in the NotifyList. > > + FALSE if the NotifyList is ended with an entry > > which has the > > + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set > > in its > Flags field. > > + > > + @retval EFI_SUCCESS if successful > > + @retval EFI_OUT_OF_RESOURCES if no space in the database > > + @retval EFI_INVALID_PARAMETER if not a good descriptor > > + > > +**/ > > +EFI_STATUS > > +InternalPeiNotifyPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList, > > + IN BOOLEAN Single > > + ) > > +{ > > + PEI_CORE_INSTANCE *PrivateData; > > + PEI_CALLBACK_NOTIFY_LIST *CallbackNotifyListPointer; > > + UINTN CallbackNotifyIndex; > > + UINTN LastCallbackNotifyCount; > > + PEI_DISPATCH_NOTIFY_LIST *DispatchNotifyListPointer; > > + UINTN DispatchNotifyIndex; > > + UINTN LastDispatchNotifyCount; > > + > > + if (NotifyList == NULL) { > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); > > + > > + CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList; > > + CallbackNotifyIndex = CallbackNotifyListPointer->CurrentCount; > > + LastCallbackNotifyCount = CallbackNotifyIndex; > > + > > + DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList; > > + DispatchNotifyIndex = DispatchNotifyListPointer->CurrentCount; > > + LastDispatchNotifyCount = DispatchNotifyIndex; > > + > > + // > > + // This is loop installs all Notify descriptors in the NotifyList. It is > > + // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being > set in the last > > + // EFI_PEI_NOTIFY_DESCRIPTOR in the list. > > + // > > + > > + for ( ; ;) { > > + // > > + // If some of the PPI data is invalid restore original Notify PPI > > database > value > > + // > > + if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) { > > + CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount; > > + DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount; > > + DEBUG ((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList- > >Guid, NotifyList->Notify)); > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != > 0) { > > + if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) { > > + // > > + // Run out of room, assert. > > + // > > + ASSERT (CallbackNotifyIndex < CallbackNotifyListPointer->MaxCount); > > + } > > + > > + CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = > (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList; > > + CallbackNotifyIndex++; > > + CallbackNotifyListPointer->CurrentCount++; > > + } else { > > + ASSERT ((NotifyList->Flags & > EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0); > > + } > > + > > + DEBUG ((DEBUG_INFO, "Register PPI Notify: %g\n", NotifyList->Guid)); > > + > > + if (Single) { > > + // > > + // Only single entry in the NotifyList. > > + // > > + break; > > + } else if ((NotifyList->Flags & > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == > > + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) > > + { > > + // > > + // Continue until the end of the Notify List. > > + // > > + break; > > + } > > + > > + // > > + // Go to the next descriptor. > > + // > > + NotifyList++; > > + } > > + > > + // > > + // Process any callback level notifies for all previously installed PPIs. > > + // > > + ProcessNotify ( > > + PrivateData, > > + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, > > + 0, > > + PrivateData->PpiData.PpiList.CurrentCount, > > + LastCallbackNotifyCount, > > + CallbackNotifyListPointer->CurrentCount > > + ); > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + > > + This function installs a notification service to be called back when a > > given > > + interface is installed or reinstalled. The purpose of the service is to > publish > > + an interface that other parties can use to call additional PPIs that may > materialize later. > > + > > + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES > table published by the PEI Foundation. > > + @param NotifyList Pointer to list of Descriptors to notify upon. > > + > > + @retval EFI_SUCCESS if successful > > + @retval EFI_OUT_OF_RESOURCES if no space in the database > > + @retval EFI_INVALID_PARAMETER if not a good descriptor > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +UnitTestNotifyPpi ( > > + IN CONST EFI_PEI_SERVICES **PeiServices, > > + IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList > > + ) > > +{ > > + return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE); > > +} > > + > > +/** > > + > > + Process notifications. > > + > > + @param PrivateData PeiCore's private data structure > > + @param NotifyType Type of notify to fire. > > + @param InstallStartIndex Install Beginning index. > > + @param InstallStopIndex Install Ending index. > > + @param NotifyStartIndex Notify Beginning index. > > + @param NotifyStopIndex Notify Ending index. > > + > > +**/ > > +VOID > > +ProcessNotify ( > > + IN PEI_CORE_INSTANCE *PrivateData, > > + IN UINTN NotifyType, > > + IN INTN InstallStartIndex, > > + IN INTN InstallStopIndex, > > + IN INTN NotifyStartIndex, > > + IN INTN NotifyStopIndex > > + ) > > +{ > > + INTN Index1; > > + INTN Index2; > > + EFI_GUID *SearchGuid; > > + EFI_GUID *CheckGuid; > > + EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor; > > + > > + for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) { > > + if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) { > > + NotifyDescriptor = PrivateData- > >PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify; > > + } else { > > + NotifyDescriptor = PrivateData- > >PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify; > > + } > > + > > + CheckGuid = NotifyDescriptor->Guid; > > + > > + for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) { > > + SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid; > > + // > > + // 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 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) && > > + (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) && > > + (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) && > > + (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) > > + { > > + DEBUG (( > > + DEBUG_INFO, > > + "Notify: PPI Guid: %g, Peim notify entry point: %p\n", > > + SearchGuid, > > + NotifyDescriptor->Notify > > + )); > > + NotifyDescriptor->Notify ( > > + (EFI_PEI_SERVICES > > **)GetPeiServicesTablePointer (), > > + NotifyDescriptor, > > + > > (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi > > + ); > > + } > > + } > > + } > > +} > > diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc > b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc > > index a76e31d97d..872d9c0d8c 100644 > > --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc > > +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkg.dsc > > @@ -35,6 +35,7 @@ > > > UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/Un > itTestPersistenceLibSimpleFileSystem.inf > > > UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAss > ertLib.inf > > > UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTest > UefiBootServicesTableLib.inf > > + > UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTes > tPeiServicesTablePointerLib.inf > > > > > UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnit > TestDxe.inf > > > UnitTestFrameworkPkg/Test/UnitTest/Sample/SampleUnitTest/SampleUnit > TestPei.inf > > diff --git a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc > b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc > > index 7866c36e66..5217de31e4 100644 > > --- a/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc > > +++ b/UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc > > @@ -21,6 +21,7 @@ > > > DebugLib|UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPo > six.inf > > > MemoryAllocationLib|UnitTestFrameworkPkg/Library/Posix/MemoryAllocati > onLibPosix/MemoryAllocationLibPosix.inf > > > UefiBootServicesTableLib|UnitTestFrameworkPkg/Library/UnitTestUefiBoot > ServicesTableLib/UnitTestUefiBootServicesTableLib.inf > > + > PeiServicesTablePointerLib|UnitTestFrameworkPkg/Library/UnitTestPeiServi > cesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf > > > > [BuildOptions] > > GCC:*_*_*_CC_FLAGS = -fno-pie > > > > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#105994): https://edk2.groups.io/g/devel/message/105994 Mute This Topic: https://groups.io/mt/99357915/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-