public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Zhiguang Liu" <zhiguang.liu@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
	"mikuback@linux.microsoft.com" <mikuback@linux.microsoft.com>
Cc: "Kinney, Michael D" <michael.d.kinney@intel.com>,
	Sean Brogan <sean.brogan@microsoft.com>
Subject: Re: [edk2-devel] [PATCH v2] UnitTestFrameworkPkg: Add UnitTestPeiServicesTablePointerLib
Date: Mon, 12 Jun 2023 05:07:12 +0000	[thread overview]
Message-ID: <PH0PR11MB504847A9DA301A30D1F70D7A9054A@PH0PR11MB5048.namprd11.prod.outlook.com> (raw)
In-Reply-To: <f9efec52-740e-938e-9fde-9c805cc046de@linux.microsoft.com>

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.liu@intel.com>
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Sean Brogan
> <sean.brogan@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.kubacki@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.kinney@intel.com>
> > Cc: Michael Kubacki <mikuback@linux.microsoft.com>
> > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > Signed-off-by: Zhiguang Liu <zhiguang.liu@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
> 
> 
> 
> 


      reply	other threads:[~2023-06-12  5:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-06  5:40 [PATCH v2] UnitTestFrameworkPkg: Add UnitTestPeiServicesTablePointerLib Zhiguang Liu
2023-06-06  5:47 ` [edk2-devel] " Ni, Ray
2023-06-06 15:28 ` Michael Kubacki
2023-06-12  5:07   ` Zhiguang Liu [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=PH0PR11MB504847A9DA301A30D1F70D7A9054A@PH0PR11MB5048.namprd11.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox