public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chang, Abner via groups.io" <abner.chang=amd.com@groups.io>
To: "Zhai, MingXin (Duke)" <duke.zhai@amd.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Xing, Eric" <Eric.Xing@amd.com>, "Fu, Igniculus" <Igniculus.Fu@amd.com>
Subject: Re: [edk2-devel] [PATCH V2 27/32] AMD/VanGoghBoard: Check in Fsp2WrapperPkg
Date: Fri, 26 Jan 2024 09:36:22 +0000	[thread overview]
Message-ID: <LV8PR12MB9452EB3798BBE5F1F89005F7EA792@LV8PR12MB9452.namprd12.prod.outlook.com> (raw)
In-Reply-To: <LV8PR12MB945204202B066E2D432908E8EA792@LV8PR12MB9452.namprd12.prod.outlook.com>

[AMD Official Use Only - General]

I didn't go through entire file. Please check it as several copyright are put in the wrong place.

Thanks
Abner

> -----Original Message-----
> From: Chang, Abner
> Sent: Friday, January 26, 2024 5:35 PM
> To: Zhai, MingXin (Duke) <duke.zhai@amd.com>; devel@edk2.groups.io
> Cc: Xing, Eric <Eric.Xing@amd.com>; Fu, Igniculus <Igniculus.Fu@amd.com>
> Subject: RE: [PATCH V2 27/32] AMD/VanGoghBoard: Check in
> Fsp2WrapperPkg
>
>
>
> > -----Original Message-----
> > From: Zhai, MingXin (Duke) <duke.zhai@amd.com>
> > Sent: Friday, January 26, 2024 2:01 PM
> > To: devel@edk2.groups.io
> > Cc: Xing, Eric <Eric.Xing@amd.com>; Zhai, MingXin (Duke)
> > <duke.zhai@amd.com>; Fu, Igniculus <Igniculus.Fu@amd.com>; Chang,
> > Abner <Abner.Chang@amd.com>
> > Subject: [PATCH V2 27/32] AMD/VanGoghBoard: Check in Fsp2WrapperPkg
> >
> > From: Duke Zhai <Duke.Zhai@amd.com>
> >
> > BZ #:4640
> > In V2: Improve coding style.
> >   1.Remove the leading underscore and use double underscore at trailing in C
> > header files.
> >   2.Remove old tianocore licenses and redundant license description.
> >   3.Improve coding style. For example: remove space between @param.
> >
> > In V1:
> >   Initial Fsp2WrapperPkg. It is based on BDK 0.0.7.3323 (USP3527X),
> >   For more information, Please reference FSP_Release_Notes.txt.
> >
> > Signed-off-by: Ken Yao <ken.yao@amd.com>
> > Cc: Eric Xing <eric.xing@amd.com>
> > Cc: Duke Zhai <duke.zhai@amd.com>
> > Cc: Igniculus Fu <igniculus.fu@amd.com>
> > Cc: Abner Chang <abner.chang@amd.com>
> > ---
> >  .../edk2/Fsp2WrapperPkg/FSP_Release_Notes.txt |    4 +
> >  .../edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec    |  167 ++
> >  .../FspWrapperNotifyDxe/FspWrapperNotifyDxe.c |  676 ++++++++
> >  .../FspWrapperNotifyDxe.inf                   |   82 +
> >  .../FspWrapperNotifyDxe/LoadBelow4G.c         |  147 ++
> >  .../FspmWrapperPeim/FspmWrapperPeim.c         |  478 ++++++
> >  .../FspmWrapperPeim/FspmWrapperPeim.inf       |   99 ++
> >  .../FspsMultiPhaseSiInitDxe.c                 |  206 +++
> >  .../FspsMultiPhaseSiInitDxe.inf               |   81 +
> >  .../FspsMultiPhaseSiInitDxe/LoadBelow4G.c     |  148 ++
> >  .../FspsWrapperPeim/FspsWrapperPeim.c         |  632 ++++++++
> >  .../FspsWrapperPeim/FspsWrapperPeim.inf       |   98 ++
> >  .../Include/FspExportedInterfaceHob.h         |  146 ++
> >  .../Include/FspMemoryRegionHob.h              |   15 +
> >  .../Include/FspSmmDataExchangeBuffer.h        |   24 +
> >  .../edk2/Fsp2WrapperPkg/Include/FspUpd.h      |   23 +
> >  .../edk2/Fsp2WrapperPkg/Include/FspmUpd.h     |   66 +
> >  .../edk2/Fsp2WrapperPkg/Include/FspsUpd.h     |   45 +
> >  .../edk2/Fsp2WrapperPkg/Include/FsptUpd.h     |   18 +
> >  .../Include/Library/FspMeasurementLib.h       |   41 +
> >  .../Include/Library/FspWrapperApiLib.h        |   82 +
> >  .../Include/Library/FspWrapperApiTestLib.h    |   56 +
> >  .../Include/Library/FspWrapperHobProcessLib.h |   39 +
> >  .../Library/FspWrapperMultiPhaseProcessLib.h  |   45 +
> >  .../Include/Library/FspWrapperPlatformLib.h   |   81 +
> >  .../Library/FspWrapperPlatformMultiPhaseLib.h |   31 +
> >  .../Include/MultiPhaseSiPhases.h              |   19 +
> >  .../Include/Ppi/FspSiliconInitDone.h          |   38 +
> >  .../Include/Ppi/TopOfTemporaryRam.h           |   15 +
> >  .../BaseFspMeasurementLib.inf                 |   54 +
> >  .../BaseFspMeasurementLib/FspMeasurementLib.c |  254 +++
> >  .../BaseFspWrapperApiLib.inf                  |   73 +
> >  .../BaseFspWrapperApiLib/FspWrapperApiLib.c   |  235 +++
> >  .../IA32/DispatchExecute.c                    |   71 +
> >  .../X64/DispatchExecute.c                     |  167 ++
> >  .../BaseFspWrapperApiLib/X64/Thunk64To32.nasm |  252 +++
> >  .../BaseFspWrapperApiTestLibNull.inf          |   56 +
> >  .../FspWrapperApiTestNull.c                   |   60 +
> >  .../BaseFspWrapperPlatformLibSample.inf       |   79 +
> >  .../FspWrapperPlatformLibSample.c             |  347 ++++
> >  ...aseFspWrapperPlatformMultiPhaseLibNull.inf |   45 +
> >  .../FspWrapperPlatformMultiPhaseLibNull.c     |   51 +
> >  .../DxeFspWrapperMultiPhaseProcessLib.c       |  531 ++++++
> >  .../DxeFspWrapperMultiPhaseProcessLib.inf     |   87 +
> >  .../FspWrapperMultiPhaseProcessLib.inf        |   56 +
> >  .../PeiFspWrapperMultiPhaseProcessLib.c       |  385 +++++
> >  .../FspWrapperApiTest.c                       |   85 +
> >  .../PeiFspWrapperApiTestLib.inf               |   59 +
> >  .../CommonHeader.h                            |   91 ++
> >  .../FspWrapperHobProcessLibSample.c           | 1439 +++++++++++++++++
> >  .../MemoryInstall.h                           |  171 ++
> >  .../PeiFspWrapperHobProcessLibSample.inf      |  128 ++
> >  .../SecFspWrapperPlatformSecLibSample/Fsp.h   |   45 +
> >  .../FspWrapperPlatformSecLibSample.c          |  129 ++
> >  .../Ia32/PeiCoreEntry.nasm                    |  130 ++
> >  .../Ia32/SecEntry.nasm                        |  335 ++++
> >  .../Ia32/Stack.nasm                           |   73 +
> >  .../PlatformInit.c                            |   38 +
> >  .../SecFspWrapperPlatformSecLibSample.inf     |   87 +
> >  .../SecGetPerformance.c                       |   84 +
> >  .../SecPlatformInformation.c                  |   78 +
> >  .../SecRamInitData.c                          |   63 +
> >  .../SecTempRamDone.c                          |   43 +
> >  .../X64/PeiCoreEntry.nasm                     |  149 ++
> >  .../X64/SecEntry.nasm                         |  173 ++
> >  .../X64/Stack.nasm                            |   73 +
> >  .../PrepareForFspSmmDxe/PrepareForFspSmmDxe.c |  152 ++
> >  .../PrepareForFspSmmDxe.inf                   |   57 +
> >  .../PrepareForFspSmmDxeFsp.c                  |   86 +
> >  .../PrepareForFspSmmDxeFsp.inf                |   49 +
> >  70 files changed, 10222 insertions(+)
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FSP_Release
> > _Notes.txt
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Fsp2Wrapp
> > erPkg.dec
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapper
> > NotifyDxe/FspWrapperNotifyDxe.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapper
> > NotifyDxe/FspWrapperNotifyDxe.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapper
> > NotifyDxe/LoadBelow4G.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapp
> > erPeim/FspmWrapperPeim.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapp
> > erPeim/FspmWrapperPeim.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiP
> > haseSiInitDxe/FspsMultiPhaseSiInitDxe.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiP
> > haseSiInitDxe/FspsMultiPhaseSiInitDxe.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiP
> > haseSiInitDxe/LoadBelow4G.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapp
> > erPeim/FspsWrapperPeim.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapp
> > erPeim/FspsWrapperPeim.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Fsp
> > ExportedInterfaceHob.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Fsp
> > MemoryRegionHob.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Fsp
> > SmmDataExchangeBuffer.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Fsp
> > Upd.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Fsp
> > mUpd.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Fsp
> > sUpd.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Fsp
> > tUpd.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Libr
> > ary/FspMeasurementLib.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Libr
> > ary/FspWrapperApiLib.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Libr
> > ary/FspWrapperApiTestLib.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Libr
> > ary/FspWrapperHobProcessLib.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Libr
> > ary/FspWrapperMultiPhaseProcessLib.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Libr
> > ary/FspWrapperPlatformLib.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Libr
> > ary/FspWrapperPlatformMultiPhaseLib.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Mul
> > tiPhaseSiPhases.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi
> > /FspSiliconInitDone.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi
> > /TopOfTemporaryRam.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspMeasurementLib/BaseFspMeasurementLib.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspMeasurementLib/FspMeasurementLib.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperApiLib/BaseFspWrapperApiLib.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperApiLib/FspWrapperApiLib.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperApiLib/IA32/DispatchExecute.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperApiLib/X64/DispatchExecute.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperApiLib/X64/Thunk64To32.nasm
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> > eFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> >
> eFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPhase
> > LibNull.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Bas
> >
> eFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLibN
> > ull.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Dxe
> > FspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Dxe
> > FspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fsp
> > WrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fsp
> > WrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiF
> > spWrapperApiTestLib/FspWrapperApiTest.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiF
> > spWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiF
> > spWrapperHobProcessLibSample/CommonHeader.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiF
> > spWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiF
> > spWrapperHobProcessLibSample/MemoryInstall.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiF
> > spWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/Fsp.h
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/Ia32/Stack.nasm
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/PlatformInit.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/SecGetPerformance.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/SecPlatformInformation.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/SecRamInitData.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/SecTempRamDone.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/X64/SecEntry.nasm
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecF
> > spWrapperPlatformSecLibSample/X64/Stack.nasm
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForF
> > spSmmDxe/PrepareForFspSmmDxe.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForF
> > spSmmDxe/PrepareForFspSmmDxe.inf
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForF
> > spSmmDxeFsp/PrepareForFspSmmDxeFsp.c
> >  create mode 100644
> >
> Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForF
> > spSmmDxeFsp/PrepareForFspSmmDxeFsp.inf
> >
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FSP_Relea
> > se_Notes.txt
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FSP_Rele
> > ase_Notes.txt
> > new file mode 100644
> > index 0000000000..92e8f7a43b
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FSP_Rele
> > ase_Notes.txt
> > @@ -0,0 +1,4 @@
> > +***************************************************
> > +Sephiroth FSP USP3527X     2023-05-27
> > +***************************************************
> > +Based on BDK 0.0.7.3323 (USP3527X)
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Fsp2Wra
> > pperPkg.dec
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Fsp2Wra
> > pperPkg.dec
> > new file mode 100644
> > index 0000000000..25327755e6
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Fsp2Wra
> > pperPkg.dec
> > @@ -0,0 +1,167 @@
> > +## @file
> > +# EDK II Fsp2WrapperPkg.dec file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +##
> > +
>
> Please put AMD copy right under Intel's.
>
> > +## @file
> > +# Provides drivers and definitions to support fsp in EDKII bios.
> > +#
> > +# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  DEC_SPECIFICATION              = 0x00010005
> > +  PACKAGE_NAME                   = Fsp2WrapperPkg
> > +  PACKAGE_GUID                   = FAFE06D4-7245-42D7-9FD2-E5D5E36AB0A0
> > +  PACKAGE_VERSION                = 0.1
> > +
> > +[Includes]
> > +  Include
> > +
> > +[LibraryClasses]
> > +  ##  @libraryclass  Provide FSP API related function.
> > +  FspWrapperApiLib|Include/Library/FspWrapperApiLib.h
> > +  FspWrapperApiTestLib|Include/Library/FspWrapperApiTestLib.h
> > +
> > +  ##  @libraryclass  Provide FSP hob process related function.
> > +  FspWrapperHobProcessLib|Include/Library/FspWrapperHobProcessLib.h
> > +
> > +  ##  @libraryclass  Provide FSP platform related function.
> > +  FspWrapperPlatformLib|Include/Library/FspWrapperPlatformLib.h
> > +
> > +  ##  @libraryclass  Provide FSP TPM measurement related function.
> > +  FspMeasurementLib|Include/Library/FspMeasurementLib.h
> > +
> > +  ##  @libraryclass  Provide MultiPhase handling related functions.
> > +
> >
> FspWrapperMultiPhaseProcessLib|Include/Library/FspWrapperMultiPhasePr
> > ocessLib.h
> > +
> > +  ##  @libraryclass  Provide MultiPhase platform actions related functions.
> > +
> >
> FspWrapperPlatformMultiPhaseLib|Include/Library/FspWrapperPlatformMul
> > tiPhaseLib.h
> > +
> > +
> > +[Guids]
> > +  #
> > +  # GUID defined in package
> > +  #
> > +  gIntelFsp2WrapperTokenSpaceGuid       = { 0xa34cf082, 0xf50, 0x4f0d,
> > { 0x89, 0x8a, 0x3d, 0x39, 0x30, 0x2b, 0xc5, 0x1e } }
> > +  gFspApiPerformanceGuid                = { 0xc9122295, 0x56ed, 0x4d4e, { 0x06,
> > 0xa6, 0x50, 0x8d, 0x89, 0x4d, 0x3e, 0x40 } }
> > +  gFspHobGuid                           = { 0x6d86fb36, 0xba90, 0x472c, { 0xb5, 0x83,
> > 0x3f, 0xbe, 0xd3, 0xfb, 0x20, 0x9a } }
> > +  gAmdFspMemoryUnder1MGuid              = { 0x1b551672, 0xe7cd, 0x4639,
> > { 0xae, 0xc0, 0x5f, 0x55, 0x9c, 0xd5, 0x51, 0x85 }}
> > +  gFspsUpdDataPointerAddressGuid        = { 0x8fdb4d5e, 0x5309, 0x4940,
> > { 0x9e, 0x4a, 0xa2, 0x9c, 0x8f, 0xac, 0x4d, 0x50 }}
> > +  gFsp2WrapperTokenSpaceGuid            = { 0x9db7c6aa, 0x8621, 0x43cf,
> > { 0xa1, 0x53, 0xfb, 0xac, 0x5, 0xd, 0x88, 0xcc   } }
> > +  gAmdFspPkgGuid                        = { 0x1b58cd9a, 0x878f, 0x481c, { 0x83,
> > 0x82, 0x4c, 0xf9, 0x6a, 0x83, 0xc8, 0xfe }}
> > +  gAmdFspUpdGuid                        = { 0x728d3b7c, 0xfaec, 0x4f77, { 0xb7,
> > 0x84, 0x6b, 0x2, 0x37, 0xf1, 0x1e, 0xa7 } }
> > +
> > +
> > +[Ppis]
> > +  gFspSiliconInitDonePpiGuid            = { 0x4eb6e09c, 0xd256, 0x4e1e, { 0xb5,
> > 0x0a, 0x87, 0x4b, 0xd2, 0x84, 0xb3, 0xde } }
> > +  gTopOfTemporaryRamPpiGuid             = { 0x2f3962b2, 0x57c5, 0x44ec,
> > { 0x9e, 0xfc, 0xa6, 0x9f, 0xd3, 0x02, 0x03, 0x2b } }
> > +
> > +[Protocols]
> > +  gAddPerfRecordProtocolGuid            = { 0xc4a58d6d, 0x3677, 0x49cb,
> > { 0xa0, 0x0a, 0x94, 0x70, 0x76, 0x5f, 0xb5, 0x5e } }
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# PCD Declarations section - list of all PCDs Declared by this Package
> > +#                            Only this package should be providing the
> > +#                            declaration, other packages should not.
> > +#
> >
> +##################################################################
> > ##############
> > +[PcdsFixedAtBuild, PcdsPatchableInModule]
> > +  ## Provides the memory mapped base address of the BIOS CodeCache
> Flash
> > Device.
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress|0xFFE00000
> > |UINT32|0x10000001
> > +  ## Provides the size of the BIOS Flash Device.
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize|0x00200000|UI
> > NT32|0x10000002
> > +
> > +  ## Indicate the PEI memory size platform want to report
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize|0x1800000|UINT32
> > |0x40000004
> > +  ## Indicate the PEI memory size platform want to report
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize|0x3000000
> > |UINT32|0x40000005
> > +
> > +  ## This is the base address of FSP-T
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress|0x00000000|UINT
> > 32|0x00000300
> > +
> > +  ## This PCD indicates if FSP APIs are skipped from FSP wrapper.<BR><BR>
> > +  #  If a bit is set, that means this FSP API is skipped.<BR>
> > +  #  If a bit is clear, that means this FSP API is NOT skipped.<BR>
> > +  #  NOTE: Only NotifyPhase Post PCI enumeration (BIT16) is
> > implemented.<BR>
> > +  #  BIT[15:0] is for function:<BR>
> > +  #    BIT0    - Skip TempRamInit<BR>
> > +  #    BIT1    - Skip MemoryInit<BR>
> > +  #    BIT2    - Skip TempRamExit<BR>
> > +  #    BIT3    - Skip SiliconInit<BR>
> > +  #    BIT4    - Skip NotifyPhase<BR>
> > +  #  BIT[32:16] is for sub-function:<BR>
> > +  #    BIT16   - Skip NotifyPhase (AfterPciEnumeration)<BR>
> > +  #    BIT17   - Skip NotifyPhase (ReadyToBoot)<BR>
> > +  #    BIT18   - Skip NotifyPhase (EndOfFirmware)<BR>
> > +  #  Any undefined BITs are reserved for future use.<BR>
> > +  # @Prompt Skip FSP API from FSP wrapper.
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdSkipFspApi|0x00000000|UINT32|0x
> > 40000009
> > +
> > +  ## This PCD decides how FSP is measured
> > +  # 1) The BootGuard ACM may already measured the FSP component, such
> > as FSPT/FSPM.
> > +  # We need a flag (PCD) to indicate if there is need to do such FSP
> > measurement or NOT.
> > +  # 2) The FSP binary includes FSP code and FSP UPD region. The UPD region
> is
> > considered
> > +  # as configuration block, and it may be updated by OEM by design.
> > +  # This flag (PCD) is to indicate if we need isolate the UPD region from the
> FSP
> > code region.
> > +  # BIT0: Need measure FSP. (for FSP1.x) - reserved in FSP2.
> > +  # BIT1: Need measure FSPT. (for FSP 2.x)
> > +  # BIT2: Need measure FSPM. (for FSP 2.x)
> > +  # BIT3: Need measure FSPS. (for FSP 2.x)
> > +  # BIT4~30: reserved.
> > +  # BIT31: Need isolate UPD region measurement.
> > +    #0: measure FSP[T|M|S] as one binary in one record (PCR0).
> > +    #1: measure FSP UPD region in one record (PCR1), the FSP code without
> > UPD in another record (PCR0).
> > +  #
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig|0x00000000
> > |UINT32|0x4000000B
> > +
> > +[PcdsFixedAtBuild, PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx]
> > +  ## This PCD decides how Wrapper code utilizes FSP
> > +  # 0: DISPATCH mode (FSP Wrapper will load PeiCore from FSP without
> calling
> > FSP API)
> > +  # 1: API mode (FSP Wrapper will call FSP API)
> > +  #
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection|0x00000001|UIN
> > T8|0x4000000A
> > +
> > +  #
> > +  ## These are the base address of FSP-M/S
> > +  #
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInFlash|0x00000000|U
> > INT32|0x00001000
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInFlash|0x00000000|UI
> > NT32|0x00001001
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspoPeiBaseAddressInFlash|0x00000000|
> > UINT32|0x00001002
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspoDxeBaseAddressInFlash|0x00000000
> > |UINT32|0x00001003
> > +
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInMemory|0x0000000
> > 0|UINT32|0x00002000
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInMemory|0x00000000
> > |UINT32|0x00002001
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspoPeiBaseAddressInMemory|0x000000
> > 00|UINT32|0x00002002
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspoDxeBaseAddressInMemory|0x00000
> > 000|UINT32|0x00002003
> > +
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspmRegionSize|0x00000000|UINT32|0x
> > 00003000
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspsRegionSize|0x00000000|UINT32|0x
> > 00003001
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspoPeiRegionSize|0x00000000|UINT32|
> > 0x00003002
> > +
> >
> gFsp2WrapperTokenSpaceGuid.PcdFspoDxeRegionSize|0x00000000|UINT32
> > |0x00003003
> > +
> > +
> >
> gFsp2WrapperTokenSpaceGuid.FspoPeiWorkaroundShadowCopyAddress|0x
> > 09E00000|UINT32|0x18000005
> > +
> > +  #
> > +  # To provide flexibility for platform to pre-allocate FSP UPD buffer
> > +  #
> > +  # The PCDs define the pre-allocated FSPM and FSPS UPD Data Buffer
> > Address.
> > +  # 0x00000000 - Platform will not pre-allocate UPD buffer before
> > FspWrapper module
> > +  # non-zero   - Platform will pre-allocate UPD buffer and patch this value to
> > +  #              buffer address before FspWrapper module executing.
> > +  #
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress|0x00000000|
> > UINT32|0x50000000
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress|0x00000000|
> > UINT32|0x50000001
> > +  #
> > +  # Non-0 means PcdFspmUpdDataAddress will be ignored, otherwise
> > PcdFspmUpdDataAddress will be used.
> > +  #
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress64|0x0000000
> > 0|UINT64|0x50000002
> > +  #
> > +  # Non-0 means PcdFspsUpdDataAddress will be ignored, otherwise
> > PcdFspsUpdDataAddress will be used.
> > +  #
> > +
> >
> gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress64|0x00000000
> > |UINT64|0x50000003
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/FspWrapperNotifyDxe.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/FspWrapperNotifyDxe.c
> > new file mode 100644
> > index 0000000000..0c997b40d0
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/FspWrapperNotifyDxe.c
> > @@ -0,0 +1,676 @@
> > +/** @file
> > +  This driver will register two callbacks to call fsp's notifies.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiDxe.h>
> > +
> > +#include <Protocol/PciEnumerationComplete.h>
> > +
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/FspWrapperPlatformLib.h>
> > +#include <Library/PerformanceLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/DxeServicesTableLib.h>
> > +#include <Protocol/AcpiSystemDescriptionTable.h>
> > +#include <Protocol/AcpiTable.h>
> > +#include <Protocol/Timer.h>
> > +#include <Protocol/PciIo.h>
> > +#include <FspsUpd.h>
> > +#include <FspMemoryRegionHob.h>
> > +#include <FspExportedInterfaceHob.h>
> > +#include <FspStatusCode.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +
> > +#define   FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION  BIT16
> > +extern EFI_GUID  gFspsUpdDataPointerAddressGuid;
> > +extern EFI_GUID  gFspReservedMemoryResourceHobGuid;
> > +extern EFI_GUID  gEfiEventExitBootServicesGuid;
> > +extern EFI_GUID  gEfiEventVirtualAddressChangeGuid;
> > +extern EFI_GUID  gEfiPciIoProtocolGuid;
> > +
> > +FSPS_UPD *volatile                   FspsUpd;
> > +FSPS_UPD *volatile                   FspsUpdInRt;
> > +volatile FSP_EXPORTED_INTERFACE_HOB  *ExportedInterfaceHob;
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *ADD_PERFORMANCE_RECORDS)(
> > +  IN CONST VOID *HobStart
> > +  );
> > +
> > +struct _ADD_PERFORMANCE_RECORD_PROTOCOL {
> > +  ADD_PERFORMANCE_RECORDS    AddPerformanceRecords;
> > +};
> > +
> > +typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL
> > ADD_PERFORMANCE_RECORD_PROTOCOL;
> > +
> > +extern EFI_GUID  gAddPerfRecordProtocolGuid;
> > +extern EFI_GUID  gFspHobGuid;
> > +extern EFI_GUID  gFspApiPerformanceGuid;
> > +
> > +static EFI_EVENT  mExitBootServicesEvent     = NULL;
> > +static EFI_EVENT  mVirtualAddressChangeEvent = NULL;
> > +
> > +/**
> > +  Relocate this image under 4G memory.
> > +
> > +  @param  ImageHandle  Handle of driver image.
> > +  @param  SystemTable  Pointer to system table.
> > +
> > +  @retval EFI_SUCCESS  Image successfully relocated.
> > +  @retval EFI_ABORTED  Failed to relocate image.
> > +
> > +**/
> > +EFI_STATUS
> > +RelocateImageUnder4GIfNeeded (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  );
> > +
> > +/**
> > + * For some reason, the FSP MAY enable the interrupt after processing
> SMM,
> > + * which is not ideal because this MAY cause timer interrupt being fired
> during
> > FSP.
> > + *
> > + * A workaround is to disable timer shortly, and re-enable it after FSP call.
> > +**/
> > +
> > +STATIC EFI_TIMER_ARCH_PROTOCOL  *gTimer        = NULL;
> > +STATIC UINT64                   mTimerInterval = 0;
> > +
> > +VOID
> > +EFIAPI
> > +DisableTimer (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS  Status = gTimer->GetTimerPeriod (gTimer, &mTimerInterval);
> > +
> > +  if (!EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "FSP TimerWorkaround begin: Timer interval val
> > %llx\n", mTimerInterval));
> > +  }
> > +
> > +  Status = gTimer->SetTimerPeriod (gTimer, 0);
> > +  ASSERT_EFI_ERROR (Status);
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +EnableTimer (
> > +  VOID
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "FSP TimerWorkaround end: Timer interval val
> > %llx\n", mTimerInterval));
> > +  EFI_STATUS  Status = EFI_SUCCESS;
> > +
> > +  if (mTimerInterval != 0) {
> > +    Status = gTimer->SetTimerPeriod (gTimer, mTimerInterval);
> > +  }
> > +
> > +  ASSERT_EFI_ERROR (Status);
> > +}
> > +
> > +/**
> > +  PciEnumerationComplete Protocol notification event handler.
> > +
> > +  @param[in] Event    Event whose notification function is being invoked.
> > +  @param[in] Context  Pointer to the notification function's context.
> > +**/
> > +VOID
> > +EFIAPI
> > +OnPciEnumerationComplete (
> > +  IN EFI_EVENT  Event,
> > +  IN VOID       *Context
> > +  )
> > +{
> > +  NOTIFY_PHASE_PARAMS  NotifyPhaseParams;
> > +  EFI_STATUS           Status;
> > +  VOID                 *Interface;
> > +
> > +  //
> > +  // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will
> > trigger it once when registration.
> > +  // Just return if it is not found.
> > +  //
> > +  Status = gBS->LocateProtocol (
> > +                  &gEfiPciEnumerationCompleteProtocolGuid,
> > +                  NULL,
> > +                  &Interface
> > +                  );
> > +  if (EFI_ERROR (Status)) {
> > +    return;
> > +  }
> > +
> > +  NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;
> > +  EFI_HANDLE  *Handles      = NULL;
> > +  VOID        *Protocol     = NULL;
> > +  UINTN       ProtocolCount = 0;
> > +
> > +  gBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid, NULL,
> > &ProtocolCount, &Handles);
> > +  EFI_PCI_IO_PROTOCOL  **Protocols = AllocateZeroPool (sizeof (VOID
> > *)*ProtocolCount);
> > +
> > +  for (UINT64 i = 0; i < ProtocolCount; i++) {
> > +    DEBUG ((DEBUG_INFO, "FSP-S Wrapper: Getting PCI Protocol %d/%d\n",
> i,
> > ProtocolCount));
> > +    gBS->HandleProtocol (Handles[i], &gEfiPciIoProtocolGuid, &Protocol);
> > +    Protocols[i] = Protocol;
> > +  }
> > +
> > +  DEBUG ((DEBUG_ERROR, " ExportedInterfaceHob:%011p\n",
> > ExportedInterfaceHob));
> > +  // gBS->LocateProtocol(&gEfiPciIoProtocolGuid,NULL,&Protocol);
> > +  ExportedInterfaceHob->EfiPciIoProtocol      = Protocols;
> > +  ExportedInterfaceHob->EfiPciIoProtocolCount = ProtocolCount;
> > +  PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION |
> > FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
> > +  DisableTimer ();
> > +  Status = CallFspNotifyPhase (&NotifyPhaseParams);
> > +  EnableTimer ();
> > +  PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION |
> > FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration requested
> > reset 0x%x\n", Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    DEBUG ((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed,
> > status: 0x%x\n", Status));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration
> > Success.\n"));
> > +  }
> > +}
> > +
> > +STATIC
> > +VOID
> > +ReportFspMemoryUsage (
> > +  VOID
> > +  )
> > +{
> > +  FSP_MEMORY_REGION_HOB  *MemoryRegionHob = NULL;
> > +  EFI_STATUS             Status;
> > +
> > +  DEBUG ((DEBUG_ERROR, " ExportedInterfaceHob:%011p\n",
> > ExportedInterfaceHob));
> > +  DEBUG ((
> > +    DEBUG_INFO,
> > +    "FSP Memory Map Size:%llx,Memory Descriptor Size:%llx:\n",
> > +    ExportedInterfaceHob->FinalMemoryMapSize,
> > +    ExportedInterfaceHob->FinalMemoryDescriptorSize
> > +    ));
> > +  DEBUG ((DEBUG_INFO, "FSP Memory usage:\n"));
> > +  UINTN  MemoryDescriptorEntries = ExportedInterfaceHob-
> > >FinalMemoryMapSize / \
> > +                                   ExportedInterfaceHob->FinalMemoryDescriptorSize;
> > +  EFI_MEMORY_DESCRIPTOR  *FspMemoryDescriptor =
> > ExportedInterfaceHob->FinalMemoryMap;
> > +  // Now we find the FSP memory HOB, "Free" it, and "Allocate" the
> memory
> > as its layout in FSP.
> > +  VOID  *FspHob = GetFirstGuidHob
> > (&gFspReservedMemoryResourceHobGuid);
> > +
> > +  if (FspHob != NULL) {
> > +    MemoryRegionHob = GET_GUID_HOB_DATA (FspHob);
> > +  }
> > +
> > +  if (!MemoryRegionHob) {
> > +    DEBUG ((DEBUG_ERROR, "Cannot find FSP HOB!\n"));
> > +    ASSERT ((FALSE));
> > +    return;
> > +  }
> > +
> > +  DEBUG ((
> > +    DEBUG_INFO,
> > +    "FSP memory region:0x%08p~0x%08p\n",
> > +    MemoryRegionHob->BeginAddress, \
> > +    MemoryRegionHob->BeginAddress+MemoryRegionHob->Length
> > +    ));
> > +  // Free previously reserved explicitly for EDK memory recycle.
> > +  EFI_PHYSICAL_ADDRESS  ReservedMemoryAddress = MemoryRegionHob-
> > >BeginAddress+MemoryRegionHob->Length-(10<<EFI_PAGE_SHIFT);
> > +
> > +  // Atomic code begins here
> > +  gBS->RaiseTPL (TPL_NOTIFY);
> > +  DEBUG ((DEBUG_INFO, "Address    Pages      Type\n"));
> > +  // Reverse iteration due to EDK's memory allocation method.
> > +  FspMemoryDescriptor = (EFI_MEMORY_DESCRIPTOR
> > *)((UINTN)FspMemoryDescriptor+ExportedInterfaceHob-
> > >FinalMemoryDescriptorSize*(MemoryDescriptorEntries-1));
> > +  for (UINTN i = 0; i < MemoryDescriptorEntries; i++) {
> > +    DEBUG ((
> > +      DEBUG_INFO,
> > +      "0x%08p 0x%08p %x\n",
> > +      FspMemoryDescriptor->PhysicalStart, \
> > +      FspMemoryDescriptor->NumberOfPages,
> > +      FspMemoryDescriptor->Type
> > +      ));
> > +    if (FspMemoryDescriptor->PhysicalStart == ReservedMemoryAddress) {
> > +      gBS->FreePages (ReservedMemoryAddress, FspMemoryDescriptor-
> > >NumberOfPages);
> > +      FspMemoryDescriptor = (EFI_MEMORY_DESCRIPTOR
> > *)((UINTN)FspMemoryDescriptor-ExportedInterfaceHob-
> > >FinalMemoryDescriptorSize);
> > +      continue;
> > +    }
> > +
> > +    if (FspMemoryDescriptor->Type == EfiMemoryMappedIO) {
> > +      EFI_GCD_MEMORY_SPACE_DESCRIPTOR  GcdMemorySpaceDescriptor;
> > +      Status = gDS->GetMemorySpaceDescriptor (FspMemoryDescriptor-
> > >PhysicalStart, &GcdMemorySpaceDescriptor);
> > +      if (!EFI_ERROR (Status)) {
> > +        if (GcdMemorySpaceDescriptor.GcdMemoryType ==
> > EfiGcdMemoryTypeNonExistent) {
> > +          Status = gDS->AddMemorySpace (
> > +                          EfiGcdMemoryTypeMemoryMappedIo,
> > +                          FspMemoryDescriptor->PhysicalStart,
> > +                          FspMemoryDescriptor->NumberOfPages<<EFI_PAGE_SHIFT,
> > +                          EFI_MEMORY_RUNTIME | EFI_MEMORY_UC
> > +                          );
> > +          if (!EFI_ERROR (Status)) {
> > +            Status = gDS->AllocateMemorySpace (
> > +                            EfiGcdAllocateAddress,
> > +                            EfiGcdMemoryTypeMemoryMappedIo,
> > +                            12,
> > +                            FspMemoryDescriptor->NumberOfPages<<EFI_PAGE_SHIFT,
> > +                            &FspMemoryDescriptor->PhysicalStart,
> > +                            gImageHandle,
> > +                            NULL
> > +                            );
> > +            if (!EFI_ERROR (Status)) {
> > +              Status = gDS->GetMemorySpaceDescriptor (FspMemoryDescriptor-
> > >PhysicalStart, &GcdMemorySpaceDescriptor);
> > +            }
> > +          }
> > +        }
> > +      }
> > +
> > +      // Attempt to set runtime attribute
> > +      if (!EFI_ERROR (Status)) {
> > +        if (GcdMemorySpaceDescriptor.GcdMemoryType ==
> > EfiGcdMemoryTypeMemoryMappedIo) {
> > +          UINT64  Attributes = GcdMemorySpaceDescriptor.Attributes |
> > EFI_MEMORY_RUNTIME | EFI_MEMORY_UC;
> > +          Status = gDS->SetMemorySpaceAttributes (
> > +                          FspMemoryDescriptor->PhysicalStart,
> > +                          FspMemoryDescriptor->NumberOfPages<<EFI_PAGE_SHIFT,
> > +                          Attributes
> > +                          );
> > +        }
> > +      }
> > +
> > +      if (EFI_ERROR (Status)) {
> > +        DEBUG ((
> > +          DEBUG_ERROR,
> > +          "MMIO Region 0x%08p~0x%08p cannot be reserved as RT.\n", \
> > +          FspMemoryDescriptor->PhysicalStart, \
> > +          (FspMemoryDescriptor->PhysicalStart+(FspMemoryDescriptor-
> > >NumberOfPages<<EFI_PAGE_SHIFT))
> > +          ));
> > +        ASSERT (FALSE);
> > +      }
> > +
> > +      DEBUG ((
> > +        DEBUG_ERROR,
> > +        "MMIO Region 0x%08p~0x%08p is reserved as RT.\n", \
> > +        FspMemoryDescriptor->PhysicalStart, \
> > +        (FspMemoryDescriptor->PhysicalStart+(FspMemoryDescriptor-
> > >NumberOfPages<<EFI_PAGE_SHIFT))
> > +        ));
> > +    } else {
> > +      if (  (FspMemoryDescriptor->PhysicalStart >= MemoryRegionHob-
> > >BeginAddress)
> > +         && ((FspMemoryDescriptor->PhysicalStart+(FspMemoryDescriptor-
> > >NumberOfPages<<EFI_PAGE_SHIFT)) <= (MemoryRegionHob-
> > >BeginAddress+MemoryRegionHob->Length)))
> > +      {
> > +        Status = gBS->FreePages (FspMemoryDescriptor->PhysicalStart,
> > FspMemoryDescriptor->NumberOfPages);
> > +        ASSERT (Status == EFI_SUCCESS);
> > +        if (FspMemoryDescriptor->Type != EfiConventionalMemory) {
> > +          Status = gBS->AllocatePages (AllocateAddress, FspMemoryDescriptor-
> > >Type, FspMemoryDescriptor->NumberOfPages, &FspMemoryDescriptor-
> > >PhysicalStart);
> > +          ASSERT (Status == EFI_SUCCESS);
> > +        } else {
> > +          DEBUG ((
> > +            DEBUG_ERROR,
> > +            "Address 0x%08p~0x%08p is free\n", \
> > +            FspMemoryDescriptor->PhysicalStart, \
> > +            (FspMemoryDescriptor->PhysicalStart+(FspMemoryDescriptor-
> > >NumberOfPages<<EFI_PAGE_SHIFT))
> > +            ));
> > +        }
> > +      } else {
> > +        DEBUG ((
> > +          DEBUG_ERROR,
> > +          "Address 0x%08p~0x%08p out of range\n", \
> > +          FspMemoryDescriptor->PhysicalStart, \
> > +          (FspMemoryDescriptor->PhysicalStart+(FspMemoryDescriptor-
> > >NumberOfPages<<EFI_PAGE_SHIFT))
> > +          ));
> > +      }
> > +    }
> > +
> > +    FspMemoryDescriptor = (EFI_MEMORY_DESCRIPTOR
> > *)((UINTN)FspMemoryDescriptor-ExportedInterfaceHob-
> > >FinalMemoryDescriptorSize);
> > +  }
> > +
> > +  // Atomic code ends here
> > +  gBS->RestoreTPL (TPL_CALLBACK);
> > +}
> > +
> > +/**
> > +  Notification function of EVT_GROUP_READY_TO_BOOT event group.
> > +
> > +  This is a notification function registered on EVT_GROUP_READY_TO_BOOT
> > event group.
> > +  When the Boot Manager is about to load and execute a boot option, it
> > reclaims variable
> > +  storage if free size is below the threshold.
> > +
> > +  @param[in] Event        Event whose notification function is being invoked.
> > +  @param[in] Context      Pointer to the notification function's context.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +OnReadyToBoot (
> > +  IN EFI_EVENT  Event,
> > +  IN VOID       *Context
> > +  )
> > +{
> > +  NOTIFY_PHASE_PARAMS  NotifyPhaseParams;
> > +  EFI_STATUS           Status;
> > +
> > +  NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;
> > +  PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION |
> > FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
> > +  DisableTimer ();
> > +  Status = CallFspNotifyPhase (&NotifyPhaseParams);
> > +  EnableTimer ();
> > +  PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION |
> > FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot requested reset
> > 0x%x\n", Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    DEBUG ((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status:
> > 0x%x\n", Status));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));
> > +    // Now we install ACPI Tables.
> > +    EFI_ACPI_TABLE_PROTOCOL  *AcpiTableProtocol = NULL;
> > +    VOID                     *FspsUpdHob        = GetFirstGuidHob
> > (&gFspsUpdDataPointerAddressGuid);
> > +    if ( FspsUpdHob != NULL ) {
> > +      FspsUpd = ((FSPS_UPD *)(UINTN)(*(UINT32 *)GET_GUID_HOB_DATA
> > (FspsUpdHob)));
> > +      Status  = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL,
> (VOID
> > **)&AcpiTableProtocol);
> > +      if (!EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_INFO, "%a:FSP-S UPD Ptr:%x\n", __FUNCTION__,
> > FspsUpd));
> > +        UINTN  TableKey = 0;
> > +        if (ExportedInterfaceHob->AcpiTpm2Table != 0) {
> > +          DEBUG ((DEBUG_INFO, "TPM2 Table: %x\n", ExportedInterfaceHob-
> > >AcpiTpm2Table));
> > +          Status |= AcpiTableProtocol->InstallAcpiTable (
> > +                                         AcpiTableProtocol,
> > +                                         (VOID *)(UINTN)(ExportedInterfaceHob-
> > >AcpiTpm2Table),
> > +                                         ((EFI_ACPI_SDT_HEADER
> > *)(UINTN)(ExportedInterfaceHob->AcpiTpm2Table))->Length,
> > +                                         &TableKey
> > +                                         );
> > +        }
> > +
> > +        if (ExportedInterfaceHob->AcpiCratTable != 0) {
> > +          DEBUG ((DEBUG_INFO, "CRAT Table: %x\n", ExportedInterfaceHob-
> > >AcpiCratTable));
> > +          Status |= AcpiTableProtocol->InstallAcpiTable (
> > +                                         AcpiTableProtocol,
> > +                                         (VOID *)(UINTN)(ExportedInterfaceHob-
> > >AcpiCratTable),
> > +                                         ((EFI_ACPI_SDT_HEADER
> > *)(UINTN)(ExportedInterfaceHob->AcpiCratTable))->Length,
> > +                                         &TableKey
> > +                                         );
> > +        }
> > +
> > +        if (ExportedInterfaceHob->AcpiCditTable != 0) {
> > +          DEBUG ((DEBUG_INFO, "CDIT Table: %x\n", ExportedInterfaceHob-
> > >AcpiCditTable));
> > +          Status |= AcpiTableProtocol->InstallAcpiTable (
> > +                                         AcpiTableProtocol,
> > +                                         (VOID *)(UINTN)(ExportedInterfaceHob-
> > >AcpiCditTable),
> > +                                         ((EFI_ACPI_SDT_HEADER
> > *)(UINTN)(ExportedInterfaceHob->AcpiCditTable))->Length,
> > +                                         &TableKey
> > +                                         );
> > +        }
> > +
> > +        if (ExportedInterfaceHob->AcpiIvrsTable != 0) {
> > +          DEBUG ((DEBUG_INFO, "IVRS Table: %x\n", ExportedInterfaceHob-
> > >AcpiIvrsTable));
> > +          Status |= AcpiTableProtocol->InstallAcpiTable (
> > +                                         AcpiTableProtocol,
> > +                                         (VOID *)(UINTN)(ExportedInterfaceHob-
> >AcpiIvrsTable),
> > +                                         ((EFI_ACPI_SDT_HEADER
> > *)(UINTN)(ExportedInterfaceHob->AcpiIvrsTable))->Length,
> > +                                         &TableKey
> > +                                         );
> > +        }
> > +
> > +        for (int i = 0; i < MAX_ACPI_SSDT_TABLE_COUNT; i++) {
> > +          if (ExportedInterfaceHob->AcpiSsdtTables[i] != 0) {
> > +            DEBUG ((DEBUG_INFO, "SSDT Table #%d: %x\n", i,
> > ExportedInterfaceHob->AcpiSsdtTables[i]));
> > +            Status |= AcpiTableProtocol->InstallAcpiTable (
> > +                                           AcpiTableProtocol,
> > +                                           (VOID *)(UINTN)(ExportedInterfaceHob-
> > >AcpiSsdtTables[i]),
> > +                                           ((EFI_ACPI_SDT_HEADER
> > *)(UINTN)(ExportedInterfaceHob->AcpiSsdtTables[i]))->Length,
> > +                                           &TableKey
> > +                                           );
> > +          }
> > +        }
> > +      }
> > +    }
> > +
> > +    ReportFspMemoryUsage ();
> > +  }
> > +
> > +  gBS->CloseEvent (Event);
> > +}
> > +
> > +VOID *
> > +EFIAPI
> > +ConvertPointer (
> > +  VOID  *In
> > +  )
> > +{
> > +  if (gRT->ConvertPointer (0, &In) == EFI_SUCCESS) {
> > +    return In;
> > +  }
> > +
> > +  return NULL;
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +OnVirtualAddressChange (
> > +  IN EFI_EVENT  Event,
> > +  IN VOID       *Context
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  typedef VOID (EFIAPI
> > *FSP_VIRTUAL_ADDRESS_CHANGE_CALLBACK)(FSPS_UPD
> > *NewUpdAddress);
> > +  FSP_VIRTUAL_ADDRESS_CHANGE_CALLBACK
> > VirtualAddressChangeCallback;
> > +
> > +  // VOID *VirtualAddressChangeCallbackAddress;
> > +  // First, we convert the FSP UPD Address.
> > +  Status = gRT->ConvertPointer (0, (VOID **)&FspsUpdInRt);
> > +  ASSERT (Status == EFI_SUCCESS);
> > +  FspsUpd                              = (FSPS_UPD *)FspsUpdInRt;
> > +  ExportedInterfaceHob->ConvertPointer = ConvertPointer;
> > +  VirtualAddressChangeCallback         = ExportedInterfaceHob-
> > >VirtualAddressChangeCallback;
> > +  VirtualAddressChangeCallback (FspsUpdInRt);
> > +  return;
> > +}
> > +
> > +/**
> > +  This stage is notified just before the firmware/Preboot environment
> > transfers
> > +  management of all system resources to the OS or next level execution
> > environment.
> > +
> > +  @param  Event         Event whose notification function is being invoked.
> > +  @param  Context       Pointer to the notification function's context, which
> is
> > +                        always zero in current implementation.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +OnEndOfFirmware (
> > +  IN EFI_EVENT  Event,
> > +  IN VOID       *Context
> > +  )
> > +{
> > +  NOTIFY_PHASE_PARAMS              NotifyPhaseParams;
> > +  EFI_STATUS                       Status;
> > +  ADD_PERFORMANCE_RECORD_PROTOCOL  *AddPerfRecordInterface;
> > +  EFI_PEI_HOB_POINTERS             Hob;
> > +  VOID                             **FspHobListPtr;
> > +
> > +  gBS->CloseEvent (Event);
> > +  // The FSP UPD is meant to be used in UEFI RT mode.
> > +  // For this reason, we MUST copy the UPD to RT Memory region.
> > +  DEBUG ((DEBUG_ERROR, "Copy :%p<->%p\n", FspsUpd, FspsUpdInRt));
> > +  CopyMem (FspsUpdInRt, FspsUpd, sizeof (FSPS_UPD));
> > +  NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;
> > +  PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION |
> > FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
> > +  DisableTimer ();
> > +  Status = CallFspNotifyPhase (&NotifyPhaseParams);
> > +  EnableTimer ();
> > +  PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION |
> > FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware requested
> reset
> > 0x%x\n", Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    DEBUG ((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status:
> > 0x%x\n", Status));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n"));
> > +  }
> > +
> > +  // Add the FSP interface here.
> > +  ExportedInterfaceHob->ConvertPointer = ConvertPointer;
> > +  Status                               = gBS->LocateProtocol (
> > +                                                &gAddPerfRecordProtocolGuid,
> > +                                                NULL,
> > +                                                (VOID **)&AddPerfRecordInterface
> > +                                                );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol
> > failed\n"));
> > +    return;
> > +  } else {
> > +    Hob.Raw = GetFirstGuidHob (&gFspHobGuid);
> > +    if (Hob.Raw != NULL) {
> > +      FspHobListPtr = GET_GUID_HOB_DATA (Hob.Raw);
> > +      AddPerfRecordInterface->AddPerformanceRecords ((VOID
> > *)(UINTN)(((UINT32)(UINTN)*FspHobListPtr) & 0xFFFFFFFF));
> > +    }
> > +  }
> > +}
> > +
> > +STATIC
> > +VOID *
> > +GetFspHobList (
> > +  VOID
> > +  )
> > +{
> > +  EFI_HOB_GUID_TYPE  *GuidHob;
> > +
> > +  GuidHob = GetFirstGuidHob (&gFspHobGuid);
> > +  if (GuidHob != NULL) {
> > +    return *(VOID **)GET_GUID_HOB_DATA (GuidHob);
> > +  } else {
> > +    return NULL;
> > +  }
> > +}
> > +
> > +/**
> > +  Main entry for the FSP DXE module.
> > +
> > +  This routine registers two callbacks to call fsp's notifies.
> > +
> > +  @param[in] ImageHandle    The firmware allocated handle for the EFI
> image.
> > +  @param[in] SystemTable    A pointer to the EFI System Table.
> > +
> > +  @retval EFI_SUCCESS       The entry point is executed successfully.
> > +  @retval other             Some error occurs when executing this entry point.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspWrapperNotifyDxeEntryPoint (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +  EFI_EVENT   ReadyToBootEvent;
> > +  VOID        *Registration;
> > +  EFI_EVENT   ProtocolNotifyEvent;
> > +  UINT32      FspApiMask;
> > +
> > +  if (!PcdGet8 (PcdFspModeSelection)) {
> > +    // Dispatch Mode
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // Load this driver's image to memory
> > +  //
> > +  Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);
> > +  if (EFI_ERROR (Status)) {
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  FspApiMask = PcdGet32 (PcdSkipFspApi);
> > +  if ((FspApiMask & FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION)
> ==
> > 0) {
> > +    ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
> > +                            &gEfiPciEnumerationCompleteProtocolGuid,
> > +                            TPL_CALLBACK,
> > +                            OnPciEnumerationComplete,
> > +                            NULL,
> > +                            &Registration
> > +                            );
> > +    ASSERT (ProtocolNotifyEvent != NULL);
> > +  }
> > +
> > +  Status = EfiCreateEventReadyToBootEx (
> > +             TPL_CALLBACK,
> > +             OnReadyToBoot,
> > +             NULL,
> > +             &ReadyToBootEvent
> > +             );
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  Status = gBS->CreateEventEx (
> > +                  EVT_NOTIFY_SIGNAL,
> > +                  TPL_CALLBACK,
> > +                  OnEndOfFirmware,
> > +                  NULL,
> > +                  &gEfiEventExitBootServicesGuid,
> > +                  &mExitBootServicesEvent
> > +                  );
> > +
> > +  gBS->CreateEventEx (
> > +         EVT_NOTIFY_SIGNAL,
> > +         TPL_NOTIFY,
> > +         OnVirtualAddressChange,
> > +         NULL,
> > +         &gEfiEventVirtualAddressChangeGuid,
> > +         &mVirtualAddressChangeEvent
> > +         );
> > +  ASSERT_EFI_ERROR (Status);
> > +  // The FSP UPD is meant to be used in UEFI RT mode.
> > +  // For this reason, we MUST copy the UPD to RT Memory region.
> > +  Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof (FSPS_UPD),
> > (VOID **)&FspsUpdInRt);
> > +  ASSERT ((Status == EFI_SUCCESS));
> > +  Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID
> > **)&gTimer);
> > +  ASSERT ((Status == EFI_SUCCESS));
> > +  VOID  *ExportedInterfaceRawHob = GetNextGuidHob
> > (&gFspExportedInterfaceHobGuid, (VOID *)((UINTN)GetFspHobList
> > ()&0xFFFFFFFF));
> > +
> > +  DEBUG ((DEBUG_ERROR, " ExportedInterfaceRawHob:%011p\n",
> > ExportedInterfaceRawHob));
> > +  if ( ExportedInterfaceRawHob != NULL) {
> > +    ExportedInterfaceHob = GET_GUID_HOB_DATA
> > (ExportedInterfaceRawHob);
> > +    DEBUG ((DEBUG_ERROR, " ExportedInterfaceHob:%011p\n",
> > ExportedInterfaceHob));
> > +    ExportedInterfaceHob = ExportedInterfaceHob-
> > >ExportedInterfaceHobAddressAfterNotifyPhase;
> > +    DEBUG ((DEBUG_ERROR, "New ExportedInterfaceHob:%011p\n",
> > ExportedInterfaceHob));
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +CallFspWrapperResetSystem (
> > +  IN EFI_STATUS  FspStatusResetType
> > +  )
> > +{
> > +  //
> > +  // Perform reset according to the type.
> > +  //
> > +
> > +  CpuDeadLoop ();
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/FspWrapperNotifyDxe.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/FspWrapperNotifyDxe.inf
> > new file mode 100644
> > index 0000000000..9ec6de6a13
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/FspWrapperNotifyDxe.inf
> > @@ -0,0 +1,82 @@
> > +## @file
> > +#  FSP-S wrapper Notify DXE Module INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
>
>
> Please put AMD copy right under Intel's.
>
>
>
> > +
> > +## @file
> > +# FSP DXE Module
> > +#
> > +# This driver will register two callbacks to call fsp's notifies.
> > +#
> > +#  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = FspWrapperNotifyDxe
> > +  FILE_GUID                      = AD61999A-507E-47E6-BA28-79CC609FA1A4
> > +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = FspWrapperNotifyDxeEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources]
> > +  FspWrapperNotifyDxe.c
> > +  LoadBelow4G.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  ChachaniBoardPkg/Project.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  AgesaPublic/AgesaPublic.dec
> > +
> > +[LibraryClasses]
> > +  UefiDriverEntryPoint
> > +  DxeServicesTableLib
> > +  UefiBootServicesTableLib
> > +  UefiRuntimeServicesTableLib
> > +  DebugLib
> > +  BaseMemoryLib
> > +  UefiLib
> > +  FspWrapperApiLib
> > +  PeCoffLib
> > +  CacheMaintenanceLib
> > +  DxeServicesLib
> > +  PerformanceLib
> > +  HobLib
> > +  UefiRuntimeLib
> > +
> > +[Protocols]
> > +  gEfiPciEnumerationCompleteProtocolGuid            ## CONSUMES
> > +  gAddPerfRecordProtocolGuid                        ## SOMETIMES_CONSUMES
> > +  gEfiAcpiTableProtocolGuid                         ## CONSUMES  FOR_ACPI
> > +  gEfiTimerArchProtocolGuid                         ## CONSUMES
> > FOR_INTERRUPT_WORKAROUND
> > +  gEfiPciIoProtocolGuid                             ## CONSUMES  FOR_FSP
> > +
> > +[Guids]
> > +  gFspApiPerformanceGuid                            ## SOMETIMES_CONSUMES ##
> > GUID
> > +  gEfiEventExitBootServicesGuid                     ## CONSUMES ## Event
> > +  gFspHobGuid                                       ## CONSUMES ## HOB
> > +  gFspsUpdDataPointerAddressGuid                    ## CONSUMES  FOR_HOB
> > +  gEfiEventVirtualAddressChangeGuid                 ## CONSUMES  FOR FSP_RT
> > +  gFspReservedMemoryResourceHobGuid                 ## CONSUMES  FOR
> > FSP_MEMORY_REPORT
> > +  gFspExportedInterfaceHobGuid                      ## CONSUMES  FOR
> > EXPORTED_INTERFACE
> > +
> > +[Pcd]
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdSkipFspApi       ## CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection
> > +[Depex]
> > +  gEfiTimerArchProtocolGuid AND gFspSmmDependencyReadyProtocolGuid
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/LoadBelow4G.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/LoadBelow4G.c
> > new file mode 100644
> > index 0000000000..9a49d3b492
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrap
> > perNotifyDxe/LoadBelow4G.c
> > @@ -0,0 +1,147 @@
> > +/** @file
> > +
> > +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PeCoffLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/DxeServicesLib.h>
> > +#include <Library/CacheMaintenanceLib.h>
> > +#include <Library/UefiLib.h>
> > +
> > +/**
> > +  Relocate this image under 4G memory.
> > +
> > +  @param  ImageHandle  Handle of driver image.
> > +  @param  SystemTable  Pointer to system table.
> > +
> > +  @retval EFI_SUCCESS  Image successfully relocated.
> > +  @retval EFI_ABORTED  Failed to relocate image.
> > +
> > +**/
> > +EFI_STATUS
> > +RelocateImageUnder4GIfNeeded (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  )
> > +{
> > +  EFI_STATUS                    Status;
> > +  UINT8                         *Buffer;
> > +  UINTN                         BufferSize;
> > +  EFI_HANDLE                    NewImageHandle;
> > +  UINTN                         Pages;
> > +  EFI_PHYSICAL_ADDRESS          FfsBuffer;
> > +  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
> > +  VOID                          *Interface;
> > +
> > +  //
> > +  // If it is already <4G, no need do relocate
> > +  //
> > +  if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // If locate gEfiCallerIdGuid success, it means 2nd entry.
> > +  //
> > +  Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);
> > +  if (!EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "FspNotifyDxe - 1st entry\n"));
> > +
> > +  //
> > +  // Here we install a dummy handle
> > +  //
> > +  NewImageHandle = NULL;
> > +  Status         = gBS->InstallProtocolInterface (
> > +                          &NewImageHandle,
> > +                          &gEfiCallerIdGuid,
> > +                          EFI_NATIVE_INTERFACE,
> > +                          NULL
> > +                          );
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Reload image itself to <4G mem
> > +  //
> > +  Status = GetSectionFromAnyFv (
> > +             &gEfiCallerIdGuid,
> > +             EFI_SECTION_PE32,
> > +             0,
> > +             (VOID **)&Buffer,
> > +             &BufferSize
> > +             );
> > +  ASSERT_EFI_ERROR (Status);
> > +  ImageContext.Handle    = Buffer;
> > +  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
> > +  //
> > +  // Get information about the image being loaded
> > +  //
> > +  Status = PeCoffLoaderGetImageInfo (&ImageContext);
> > +  ASSERT_EFI_ERROR (Status);
> > +  if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
> > +    Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize +
> > ImageContext.SectionAlignment));
> > +  } else {
> > +    Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);
> > +  }
> > +
> > +  FfsBuffer = 0xFFFFFFFF;
> > +  Status    = gBS->AllocatePages (
> > +                     AllocateMaxAddress,
> > +                     EfiBootServicesCode,
> > +                     Pages,
> > +                     &FfsBuffer
> > +                     );
> > +  ASSERT_EFI_ERROR (Status);
> > +  ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
> > +  //
> > +  // Align buffer on section boundary
> > +  //
> > +  ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
> > +  ImageContext.ImageAddress &=
> > ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
> > +  //
> > +  // Load the image to our new buffer
> > +  //
> > +  Status = PeCoffLoaderLoadImage (&ImageContext);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Relocate the image in our new buffer
> > +  //
> > +  Status = PeCoffLoaderRelocateImage (&ImageContext);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Free the buffer allocated by ReadSection since the image has been
> > relocated in the new buffer
> > +  //
> > +  gBS->FreePool (Buffer);
> > +
> > +  //
> > +  // Flush the instruction cache so the image data is written before we
> execute
> > it
> > +  //
> > +  InvalidateInstructionCacheRange ((VOID
> > *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
> > +
> > +  DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n",
> > (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));
> > +  Status =
> >
> ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImage
> > Handle, gST);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n",
> > ImageContext.ImageAddress, Status));
> > +    gBS->FreePages (FfsBuffer, Pages);
> > +  }
> > +
> > +  //
> > +  // return error to unload >4G copy, if we already relocate itself to <4G.
> > +  //
> > +  return EFI_ALREADY_STARTED;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWra
> > pperPeim/FspmWrapperPeim.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWra
> > pperPeim/FspmWrapperPeim.c
> > new file mode 100644
> > index 0000000000..fc5a339e8b
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWra
> > pperPeim/FspmWrapperPeim.c
> > @@ -0,0 +1,478 @@
> > +/** @file
> > +  This will be invoked only once. It will call FspMemoryInit API,
> > +  register TemporaryRamDonePpi to call TempRamExit API, and register
> > MemoryDiscoveredPpi
> > +  notify to call FspSiliconInit API.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Library/PeimEntryPoint.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/PeiServicesTablePointerLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/TimerLib.h>
> > +#include <Library/PerformanceLib.h>
> > +#include <Library/FspWrapperPlatformLib.h>
> > +#include <Library/FspWrapperHobProcessLib.h>
> > +#include <Library/FspWrapperMultiPhaseProcessLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Ppi/FspSiliconInitDone.h>
> > +#include <Ppi/EndOfPeiPhase.h>
> > +#include <Ppi/MemoryDiscovered.h>
> > +#include <Ppi/SecPlatformInformation.h>
> > +#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
> > +#include <Library/FspWrapperApiTestLib.h>
> > +#include <FspEas.h>
> > +#include <FspStatusCode.h>
> > +#include <FspGlobalData.h>
> > +#include <Library/FspCommonLib.h>
> > +#include <Library/PeiServicesTablePointerLib.h>
> > +#include <FspmUpd.h>
> > +
> > +extern EFI_GUID  gFspHobGuid;
> > +extern EFI_GUID  gEfiAmdAgesaPkgTokenSpaceGuid;
> > +extern EFI_GUID  gAmdCpmOemTablePpiGuid;
> > +
> > +// The EDK 202208 Doesn't hold these structs.
> > +typedef enum {
> > +  EnumMultiPhaseGetVariableRequestInfo  = 0x2,
> > +  EnumMultiPhaseCompleteVariableRequest = 0x3
> > +} FSP_MULTI_PHASE_ACTION_23;
> > +
> > +typedef enum {
> > +  FspMultiPhaseMemInitApiIndex = 8
> > +} FSP_API_INDEX_23;
> > +
> > +/**
> > +  Get the FSP M UPD Data address
> > +
> > +  @return FSP-M UPD Data Address
> > +**/
> > +volatile
> > +VOID
> > +MakePcdNotBeingDeleted (
> > +  VOID
> > +  );
> > +
> > +UINTN
> > +GetFspmUpdDataAddress (
> > +  VOID
> > +  )
> > +{
> > +  if (PcdGet64 (PcdFspmUpdDataAddress64) != 0) {
> > +    return (UINTN)PcdGet64 (PcdFspmUpdDataAddress64);
> > +  } else {
> > +    return (UINTN)PcdGet32 (PcdFspmUpdDataAddress);
> > +  }
> > +}
> > +
> > +#define ACPI_MMIO_BASE         0xFED80000ul
> > +#define SMI_BASE               0x200                     // DWORD
> > +#define FCH_PMIOA_REG60        0x60                      // AcpiPm1EvtBlk
> > +#define FCH_PMIOA_REG62        0x62                      // AcpiPm1CntBlk
> > +#define FCH_PMIOA_REG64        0x64                      // AcpiPmTmrBlk
> > +#define PMIO_BASE              0x300                     // DWORD
> > +#define FCH_SMI_REGA0          0xA0
> > +#define FCH_SMI_REGC4          0xC4
> > +#define R_FCH_ACPI_PM_CONTROL  0x04
> > +
> > +/**
> > + Clear all SMI enable bit in SmiControl0-SmiControl9 register
> > +
> > + @param [in]        None
> > +
> > + @retval            None
> > +*/
> > +VOID
> > +ClearAllSmiControlRegisters (
> > +  VOID
> > +  )
> > +{
> > +  UINTN  SmiControlOffset;
> > +
> > +  for (SmiControlOffset = FCH_SMI_REGA0; SmiControlOffset <=
> > FCH_SMI_REGC4; SmiControlOffset += 4) {
> > +    MmioWrite32 (ACPI_MMIO_BASE + SMI_BASE + SmiControlOffset,
> 0x00);
> > +  }
> > +}
> > +
> > +/**
> > +  Clear any SMI status or wake status left over from boot.
> > +
> > +  @param  none
> > +
> > +  @retval none
> > +**/
> > +VOID
> > +EFIAPI
> > +ClearSmiAndWake (
> > +  VOID
> > +  )
> > +{
> > +  UINT16  Pm1Status;
> > +  UINT16  PmControl;
> > +  UINT16  AcpiBaseAddr;
> > +
> > +  AcpiBaseAddr = MmioRead16 (ACPI_MMIO_BASE + PMIO_BASE +
> > FCH_PMIOA_REG60);
> > +
> > +  //
> > +  // Read the ACPI registers
> > +  //
> > +  Pm1Status = IoRead16 (AcpiBaseAddr);
> > +  PmControl = IoRead16 ((UINT16)(AcpiBaseAddr +
> > R_FCH_ACPI_PM_CONTROL));
> > +
> > +  //
> > +  // Clear any SMI or wake state from the boot
> > +  //
> > +  Pm1Status |= 0xFF;          // clear all events
> > +  PmControl &= 0xFFFE;        // clear Bit0(SciEn) in PmControl
> > +
> > +  //
> > +  // Write them back
> > +  //
> > +  IoWrite16 (AcpiBaseAddr, Pm1Status);
> > +  IoWrite16 ((UINT16)(AcpiBaseAddr + R_FCH_ACPI_PM_CONTROL),
> > PmControl);
> > +}
> > +
> > +/// AMD CPM OEM TABLE PPI Definition
> > +
> > +typedef struct _AMD_CPM_OEM_TABLE_PPI {
> > +  UINTN     Revision;                         ///< Revision Number
> > +  UINT16    PlatformId;                       ///< Current Platform Id
> > +  VOID      *TableList;                       ///< The Point of CPM Definition Table List
> > +} AMD_CPM_OEM_TABLE_PPI;
> > +
> > +// Report FSP-O PEI FV manually.
> > +EFI_STATUS
> > +EFIAPI
> > +GetFspoPeiFv (
> > +  OUT EFI_FIRMWARE_VOLUME_HEADER  **FspoPeiFvHeader
> > +  )
> > +{
> > + #ifdef COMPRESS_FSP_REGION
> > +  BuildMemoryAllocationHob (
> > +    (EFI_PHYSICAL_ADDRESS)PcdGet32 (PcdFspoPeiBaseAddressInMemory),
> > +    PcdGet32 (PcdFspoPeiRegionSize),
> > +    EfiACPIMemoryNVS
> > +    );
> > +  // Workaround for PSP FV sig check.
> > +  CopyMem (
> > +    (VOID *)PcdGet32 (FspoPeiWorkaroundShadowCopyAddress),
> > +    (VOID *)PcdGet32 (PcdFspoPeiBaseAddressInMemory),
> > +    PcdGet32 (PcdFspoPeiRegionSize)
> > +    );
> > + #else
> > +  CopyMem (
> > +    (VOID *)PcdGet32 (FspoPeiWorkaroundShadowCopyAddress),
> > +    (VOID *)PcdGet32 (PcdFspoPeiBaseAddressInFlash),
> > +    PcdGet32 (PcdFspoPeiRegionSize)
> > +    );
> > + #endif
> > +
> > +  BuildMemoryAllocationHob (
> > +    (EFI_PHYSICAL_ADDRESS)PcdGet32
> > (FspoPeiWorkaroundShadowCopyAddress),
> > +    PcdGet32 (PcdFspoPeiRegionSize),
> > +    EfiACPIMemoryNVS
> > +    );
> > +  *FspoPeiFvHeader = (EFI_FIRMWARE_VOLUME_HEADER
> > *)(UINTN)PcdGet32 (FspoPeiWorkaroundShadowCopyAddress);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Call FspMemoryInit API.
> > +
> > +  @return Status returned by FspMemoryInit API.
> > +**/
> > +EFI_STATUS
> > +PeiFspMemoryInit (
> > +  VOID
> > +  )
> > +{
> > +  FSP_INFO_HEADER  *FspmHeaderPtr;
> > +  EFI_STATUS       Status;
> > +  UINT64           TimeStampCounterStart;
> > +  VOID             *FspHobListPtr;
> > +  VOID             *HobData;
> > +  VOID             *FspmUpdDataPtr;
> > +  UINTN            *SourceData;
> > +  UINT32           FspmBaseAddress;
> > +
> > +  DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n"));
> > +
> > +  FspHobListPtr  = NULL;
> > +  FspmUpdDataPtr = NULL;
> > +  // Copied from PlatformInit.
> > +  ClearSmiAndWake ();
> > +  ClearAllSmiControlRegisters ();
> > +  FspmBaseAddress = (UINT32)(UINTN)PcdGet32
> > (PcdFspmBaseAddressInMemory);
> > + #ifndef COMPRESS_FSP_REGION
> > +  CopyMem ((VOID *)PcdGet32 (PcdFspmBaseAddressInMemory), (VOID
> > *)PcdGet32 (PcdFspmBaseAddressInFlash), (UINT32)PcdGet32
> > (PcdFspmRegionSize));
> > + #endif
> > +  FspmHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader
> > ((EFI_PHYSICAL_ADDRESS)(UINTN)FspmBaseAddress);
> > +  DEBUG ((DEBUG_INFO, "Fspm Base Address - 0x%x\n",
> > FspmBaseAddress));
> > +  DEBUG ((DEBUG_INFO, "FspmHeaderPtr - 0x%x\n", FspmHeaderPtr));
> > +  if (FspmHeaderPtr == NULL) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BuildMemoryAllocationHob (
> > +    (EFI_PHYSICAL_ADDRESS)FspmBaseAddress,
> > +    (UINT32)PcdGet32 (PcdFspmRegionSize),
> > +    EfiACPIMemoryNVS
> > +    );
> > +  FspmHeaderPtr->ImageBase = (UINTN)FspmBaseAddress;
> > +
> > +  if ((GetFspmUpdDataAddress () == 0) && (FspmHeaderPtr-
> > >CfgRegionSize != 0) && (FspmHeaderPtr->CfgRegionOffset != 0)) {
> > +    //
> > +    // Copy default FSP-M UPD data from Flash
> > +    //
> > +    FspmUpdDataPtr = AllocateZeroPool ((UINTN)FspmHeaderPtr-
> > >CfgRegionSize);
> > +    ASSERT (FspmUpdDataPtr != NULL);
> > +    SourceData = (UINTN *)((UINTN)FspmHeaderPtr->ImageBase +
> > (UINTN)FspmHeaderPtr->CfgRegionOffset);
> > +    CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr-
> > >CfgRegionSize);
> > +  } else {
> > +    //
> > +    // External UPD is ready, get the buffer from PCD pointer.
> > +    //
> > +    FspmUpdDataPtr = (VOID *)GetFspmUpdDataAddress ();
> > +    ASSERT (FspmUpdDataPtr != NULL);
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "UpdateFspmUpdData enter\n"));
> > +  UpdateFspmUpdData (FspmUpdDataPtr);
> > +  if (((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.Revision
> > >= 3) {
> > +    DEBUG ((DEBUG_INFO, "  StackBase           - 0x%lx\n",
> > ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)-
> > >FspmArchUpd.StackBase));
> > +    DEBUG ((DEBUG_INFO, "  StackSize           - 0x%lx\n",
> > ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)-
> > >FspmArchUpd.StackSize));
> > +    DEBUG ((DEBUG_INFO, "  BootLoaderTolumSize - 0x%x\n",
> > ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)-
> > >FspmArchUpd.BootLoaderTolumSize));
> > +    DEBUG ((DEBUG_INFO, "  BootMode            - 0x%x\n",
> > ((FSPM_UPD_COMMON_FSP24 *)FspmUpdDataPtr)-
> > >FspmArchUpd.BootMode));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "  NvsBufferPtr        - 0x%x\n",
> > ((FSPM_UPD_COMMON *)FspmUpdDataPtr)-
> >FspmArchUpd.NvsBufferPtr));
> > +    DEBUG ((DEBUG_INFO, "  StackBase           - 0x%x\n",
> > ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.StackBase));
> > +    DEBUG ((DEBUG_INFO, "  StackSize           - 0x%x\n",
> > ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.StackSize));
> > +    DEBUG ((DEBUG_INFO, "  BootLoaderTolumSize - 0x%x\n",
> > ((FSPM_UPD_COMMON *)FspmUpdDataPtr)-
> > >FspmArchUpd.BootLoaderTolumSize));
> > +    DEBUG ((DEBUG_INFO, "  BootMode            - 0x%x\n",
> > ((FSPM_UPD_COMMON *)FspmUpdDataPtr)->FspmArchUpd.BootMode));
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "  HobListPtr          - 0x%x\n", &FspHobListPtr));
> > +
> > +  // Report FSP-O PEI manually.
> > +  EFI_FIRMWARE_VOLUME_HEADER  *Header = NULL;
> > +  if (GetFspoPeiFv (&Header) == EFI_SUCCESS) {
> > +    ((FSPM_UPD *)FspmUpdDataPtr)-
> > >FspmConfig.fsp_o_pei_volume_address = (UINT32)(UINTN)Header;
> > +    DEBUG ((DEBUG_INFO, "  FSP-O Fv 0x%p\n", Header));
> > +  }
> > +
> > +  TimeStampCounterStart = AsmReadTsc ();
> > +  Status                = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr);
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FspMemoryInitApi requested reset %r\n",
> > Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  if ((Status != FSP_STATUS_VARIABLE_REQUEST) && EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(),
> > Status = %r\n", Status));
> > +    ASSERT_EFI_ERROR (Status);
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "FspMemoryInit status: %r\n", Status));
> > +  if (Status == FSP_STATUS_VARIABLE_REQUEST) {
> > +    //
> > +    // call to Variable request handler
> > +    //
> > +    FspWrapperVariableRequestHandler (&FspHobListPtr,
> > FspMultiPhaseMemInitApiIndex);
> > +  }
> > +
> > +  //
> > +  // See if MultiPhase process is required or not
> > +  //
> > +  FspWrapperMultiPhaseHandler (&FspHobListPtr,
> > FspMultiPhaseMemInitApiIndex);    // FspM MultiPhase
> > +
> > +  //
> > +  // Create hobs after memory initialization and not in temp RAM. Hence
> > passing the recorded timestamp here
> > +  //
> > +  PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL,
> > TimeStampCounterStart, FSP_STATUS_CODE_MEMORY_INIT |
> > FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
> > +  PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE
> |
> > FSP_STATUS_CODE_API_EXIT);
> > +  DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi:
> %d
> > millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () -
> > TimeStampCounterStart), 1000000)));
> > +
> > +  Status = TestFspMemoryInitApiOutput (FspmUpdDataPtr,
> &FspHobListPtr);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "ERROR - TestFspMemoryInitApiOutput () fail,
> > Status = %r\n", Status));
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "  FspHobListPtr (returned) - 0x%x\n",
> > FspHobListPtr));
> > +  ASSERT (FspHobListPtr != NULL);
> > +
> > +  PostFspmHobProcess (FspHobListPtr);
> > +
> > +  //
> > +  // FspHobList is not complete at this moment.
> > +  // Save FspHobList pointer to hob, so that it can be got later
> > +  //
> > +  HobData = BuildGuidHob (
> > +              &gFspHobGuid,
> > +              sizeof (VOID *)
> > +              );
> > +  ASSERT (HobData != NULL);
> > +  CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  BuildUpdHob
> > +
> > +  @return Status returned by FspMemoryInit API.
> > +**/
> > +VOID *
> > +BuildUpdHob (
> > +  VOID  *FspmBaseAddress
> > +  )
> > +{
> > +  VOID             *FspmUpdDataPtr;
> > +  FSP_INFO_HEADER  *FspmHeaderPtr;
> > +  UINTN            *SourceData;
> > +
> > +  FspmHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader
> > ((EFI_PHYSICAL_ADDRESS)(UINTN)FspmBaseAddress);
> > +  DEBUG ((DEBUG_INFO, "Fspm Base Address - 0x%x\n",
> > FspmBaseAddress));
> > +  DEBUG ((DEBUG_INFO, "FspmHeaderPtr - 0x%x\n", FspmHeaderPtr));
> > +  ASSERT (FspmHeaderPtr != NULL);
> > +
> > +  FspmHeaderPtr->ImageBase = (UINTN)FspmBaseAddress;
> > +
> > +  if ((GetFspmUpdDataAddress () == 0) && (FspmHeaderPtr-
> > >CfgRegionSize != 0) && (FspmHeaderPtr->CfgRegionOffset != 0)) {
> > +    //
> > +    // Copy default FSP-M UPD data from Flash
> > +    //
> > +    FspmUpdDataPtr = AllocateZeroPool ((UINTN)FspmHeaderPtr-
> > >CfgRegionSize);
> > +    ASSERT (FspmUpdDataPtr != NULL);
> > +    SourceData = (UINTN *)((UINTN)FspmHeaderPtr->ImageBase +
> > (UINTN)FspmHeaderPtr->CfgRegionOffset);
> > +    CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr-
> > >CfgRegionSize);
> > +  } else {
> > +    //
> > +    // External UPD is ready, get the buffer from PCD pointer.
> > +    //
> > +    FspmUpdDataPtr = (VOID *)GetFspmUpdDataAddress ();
> > +    ASSERT (FspmUpdDataPtr != NULL);
> > +  }
> > +
> > +  return BuildGuidDataHob (&gAmdFspUpdGuid, &FspmUpdDataPtr, sizeof
> > (VOID *));
> > +}
> > +
> > +/**
> > +  Do FSP initialization.
> > +
> > +  @return FSP initialization status.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspmWrapperInit (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS                                             Status;
> > +  EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
> > *MeasurementExcludedFvPpi;
> > +  EFI_PEI_PPI_DESCRIPTOR                                 *MeasurementExcludedPpiList;
> > +
> > +  MeasurementExcludedFvPpi = AllocatePool (sizeof
> > (*MeasurementExcludedFvPpi));
> > +  ASSERT (MeasurementExcludedFvPpi != NULL);
> > +  MeasurementExcludedFvPpi->Count          = 1;
> > +  MeasurementExcludedFvPpi->Fv[0].FvBase   = PcdGet32
> > (PcdFspmBaseAddressInMemory);
> > +  MeasurementExcludedFvPpi->Fv[0].FvLength = (UINT32)PcdGet32
> > (PcdFspmRegionSize);
> > +
> > +  MeasurementExcludedPpiList = AllocatePool (sizeof
> > (*MeasurementExcludedPpiList));
> > +  ASSERT (MeasurementExcludedPpiList != NULL);
> > +  MeasurementExcludedPpiList->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> > +  MeasurementExcludedPpiList->Guid  =
> > &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid;
> > +  MeasurementExcludedPpiList->Ppi   = MeasurementExcludedFvPpi;
> > +
> > +  Status = EFI_SUCCESS;
> > +
> > +  if (PcdGet8 (PcdFspModeSelection) == 1) {
> > +    Status = PeiFspMemoryInit ();
> > +    ASSERT_EFI_ERROR (Status);
> > +  } else {
> > +    Status = PeiServicesInstallPpi (MeasurementExcludedPpiList);
> > +    ASSERT_EFI_ERROR (Status);
> > +    VOID  *FspmBaseAddress = (VOID *)(UINTN)PcdGet32
> > (PcdFspmBaseAddressInMemory);
> > + #ifndef COMPRESS_FSP_REGION
> > +    CopyMem (FspmBaseAddress, (VOID *)PcdGet32
> > (PcdFspmBaseAddressInFlash), (UINT32)PcdGet32 (PcdFspmRegionSize));
> > + #endif
> > +    // Build a Upd address pointer guid hob for FSP.
> > +    VOID  **upd_guid_hob = BuildUpdHob (FspmBaseAddress);
> > +    DEBUG ((DEBUG_INFO, "upd_guid_hob: 0x%x\n", *upd_guid_hob));
> > +    ASSERT (upd_guid_hob != NULL);
> > +    // Update UPD variables according to OEM requirement
> > +    // Sample code
> > +    //  FSPM_UPD * volatile fsp_m_upd = *upd_guid_hob;
> > +    //  FSP_M_CONFIG * volatile fsp_m_cfg = &fsp_m_upd->FspmConfig;
> > +    //  fsp_m_cfg->DbgFchUsbUsb0DrdMode = xx;
> > +
> > +    BuildMemoryAllocationHob (
> > +      (UINTN)FspmBaseAddress,
> > +      PcdGet32 (PcdFspmRegionSize),
> > +      EfiACPIMemoryNVS
> > +      );
> > +    PeiServicesInstallFvInfoPpi (
> > +      NULL,
> > +      (VOID *)(UINTN)FspmBaseAddress,
> > +      PcdGet32 (PcdFspmRegionSize),
> > +      NULL,
> > +      NULL
> > +      );
> > +    BuildFvHob (
> > +      (EFI_PHYSICAL_ADDRESS)(UINTN)FspmBaseAddress,
> > +      PcdGet32 (PcdFspmRegionSize)
> > +      );
> > +
> > +    EFI_FIRMWARE_VOLUME_HEADER  *FspoBaseAddress = NULL;
> > +    Status = GetFspoPeiFv (&FspoBaseAddress);
> > +    PeiServicesInstallFvInfoPpi (
> > +      NULL,
> > +      FspoBaseAddress,
> > +      PcdGet32 (PcdFspoPeiRegionSize),
> > +      NULL,
> > +      NULL
> > +      );
> > +    BuildFvHob (
> > +      (EFI_PHYSICAL_ADDRESS)(UINTN)FspoBaseAddress,
> > +      PcdGet32 (PcdFspoPeiRegionSize)
> > +      );
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This is the entrypoint of PEIM
> > +
> > +  @param[in] FileHandle  Handle of the file being invoked.
> > +  @param[in] PeiServices Describes the list of possible PEI Services.
> > +
> > +  @retval EFI_SUCCESS if it completed successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspmWrapperPeimEntryPoint (
> > +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> > +  IN CONST EFI_PEI_SERVICES     **PeiServices
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "FspmWrapperPeimEntryPoint\n"));
> > +
> > +  FspmWrapperInit ();
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWra
> > pperPeim/FspmWrapperPeim.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWra
> > pperPeim/FspmWrapperPeim.inf
> > new file mode 100644
> > index 0000000000..ced1873a44
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWra
> > pperPeim/FspmWrapperPeim.inf
> > @@ -0,0 +1,99 @@
> > +## @file
> > +#  FSP-M wrapper PEI Module INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
>
> Please put AMD copy right under Intel's.
>
>
> > +
> > +## @file
> > +# FSP-M wrapper PEI Module
> > +#
> > +# This PEIM initialize FSP.
> > +# This will be invoked only once. It will call FspMemoryInit API,
> > +# register TemporaryRamDonePpi to call TempRamExit API, and register
> > MemoryDiscoveredPpi
> > +# notify to call FspSiliconInit API.
> > +#
> > +#  Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010017
> > +  BASE_NAME                      = FspmWrapperPeim
> > +  FILE_GUID                      = 9FAAD0FF-0E0C-4885-A738-BAB4E4FA1E66
> > +  VERSION_STRING                 = 1.0
> > +  MODULE_TYPE                    = PEIM
> > +  ENTRY_POINT                    = FspmWrapperPeimEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32
> > +#
> > +
> > +[LibraryClasses]
> > +  PeimEntryPoint
> > +  PeiServicesLib
> > +  PeiServicesTablePointerLib
> > +  BaseLib
> > +  BaseMemoryLib
> > +  MemoryAllocationLib
> > +  DebugLib
> > +  HobLib
> > +  FspWrapperPlatformLib
> > +  FspWrapperHobProcessLib
> > +  CpuLib
> > +  UefiCpuLib
> > +  PeCoffGetEntryPointLib
> > +  PeCoffExtraActionLib
> > +  PerformanceLib
> > +  TimerLib
> > +  FspWrapperApiLib
> > +  FspWrapperApiTestLib
> > +  IoLib
> > +#-  FspMeasurementLib
> > +  FspWrapperMultiPhaseProcessLib
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  UefiCpuPkg/UefiCpuPkg.dec
> > +  SecurityPkg/SecurityPkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  ChachaniBoardPkg/Project.dec
> > +
> > +[Pcd]
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress    ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection      ##
> CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress       ##
> CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig  ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmUpdDataAddress64  ##
> > CONSUMES
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInFlash
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInMemory
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspoPeiBaseAddressInFlash
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspoPeiBaseAddressInMemory
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspmRegionSize
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspoPeiRegionSize
> > +  gFsp2WrapperTokenSpaceGuid.FspoPeiWorkaroundShadowCopyAddress
> > +
> > +[Sources]
> > +  FspmWrapperPeim.c
> > +
> > +[Guids]
> > +  gFspHobGuid                           ## PRODUCES ## HOB
> > +  gFspApiPerformanceGuid                ## SOMETIMES_CONSUMES ## GUID
> > +  gPlatformPkgTokenSpaceGuid
> > +  gAmdFspUpdGuid
> > +
> > +[Ppis]
> > +#-  gEdkiiTcgPpiGuid                                       ## NOTIFY
> > +  gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid    ## PRODUCES
> > +
> > +
> > +[Depex]
> > +  gEfiPeiMasterBootModePpiGuid
> > +  AND gEfiPeiReadOnlyVariable2PpiGuid
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/FspsMultiPhaseSiInitDxe.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/FspsMultiPhaseSiInitDxe.c
> > new file mode 100644
> > index 0000000000..bb5e12cba9
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/FspsMultiPhaseSiInitDxe.c
> > @@ -0,0 +1,206 @@
> > +/** @file
> > +  This driver will register two callbacks to call fsp's notifies.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiDxe.h>
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/FspWrapperPlatformLib.h>
> > +#include <Library/HobLib.h>
> > +#include <FspStatusCode.h>
> > +#include "../Include/FspGlobalData.h"
> > +
> > +extern EFI_GUID  gFspHobGuid;
> > +extern EFI_GUID  gEfiResetArchProtocolGuid;
> > +extern EFI_GUID  gAmdFspSetupTableInitDoneGuid;
> > +
> > +EFI_EVENT  gAmdFspSetupTableInitDoneEvent;
> > +EFI_EVENT  gResetDoneEvent;
> > +
> > +/**
> > +  Relocate this image under 4G memory.
> > +
> > +  @param  ImageHandle  Handle of driver image.
> > +  @param  SystemTable  Pointer to system table.
> > +
> > +  @retval EFI_SUCCESS  Image successfully relocated.
> > +  @retval EFI_ABORTED  Failed to relocate image.
> > +
> > +**/
> > +EFI_STATUS
> > +RelocateImageUnder4GIfNeeded (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FspWrapperMultiPhaseHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  );
> > +
> > +STATIC
> > +VOID *
> > +GetFspHobList (
> > +  VOID
> > +  )
> > +{
> > +  EFI_HOB_GUID_TYPE  *GuidHob;
> > +
> > +  GuidHob = GetFirstGuidHob (&gFspHobGuid);
> > +  if (GuidHob != NULL) {
> > +    return *(VOID **)GET_GUID_HOB_DATA (GuidHob);
> > +  } else {
> > +    return NULL;
> > +  }
> > +}
> > +
> > +/**
> > +  Callback function after runtime reset being ready immediately.
> > +
> > +  @param[in] Event      Not used.
> > +  @param[in] Context    Not used.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +DoResetAfterRtImmediately (
> > +  IN  EFI_EVENT  Event,
> > +  IN  VOID       *Context
> > +  )
> > +{
> > +  gBS->CloseEvent (Event);
> > +  gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
> > +}
> > +
> > +/**
> > +  Callback function after FSP finished applying setup table in DXE phase.
> > +
> > +  The platform is considered to stop ANY critical services, and then do COLD
> > RESET.
> > +
> > +  @param[in] Event      Not used.
> > +  @param[in] Context    Not used.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +CheckAndRebootSystemAfterFspSetupTable (
> > +  IN  EFI_EVENT  Event,
> > +  IN  VOID       *Context
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  gBS->CloseEvent (Event);
> > +  VOID  *Registration;
> > +
> > +  DEBUG ((DEBUG_INFO, "FSP Setup table Done!\n"));
> > +  DEBUG ((DEBUG_INFO, "Reset?%s\n", PcdGetBool
> > (PcdAmdFspSetupTableInitNeedsReset) ? L"TRUE" : L"FALSE"));
> > +  if (!PcdGetBool (PcdAmdFspSetupTableInitNeedsReset)) {
> > +    return;
> > +  }
> > +
> > +  // DO RESET HERE!
> > +  Status = gBS->LocateProtocol (&gEfiResetArchProtocolGuid, NULL, (VOID
> > **)&Registration);
> > +  if ( !EFI_ERROR (Status)) {
> > +    gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
> > +    // Will not return here.
> > +  }
> > +
> > +  Status = gBS->CreateEvent (
> > +                  EVT_NOTIFY_SIGNAL,
> > +                  TPL_CALLBACK,
> > +                  DoResetAfterRtImmediately,
> > +                  NULL,
> > +                  &gResetDoneEvent
> > +                  );
> > +  if (!EFI_ERROR (Status)) {
> > +    Registration = NULL;
> > +    Status       = gBS->RegisterProtocolNotify (
> > +                          &gEfiResetArchProtocolGuid,
> > +                          gResetDoneEvent,
> > +                          &Registration
> > +                          );
> > +  }
> > +}
> > +
> > +/**
> > +  Main entry for the FSP DXE module.
> > +
> > +  This routine registers two callbacks to call fsp's notifies.
> > +
> > +  @param[in] ImageHandle    The firmware allocated handle for the EFI
> image.
> > +  @param[in] SystemTable    A pointer to the EFI System Table.
> > +
> > +  @retval EFI_SUCCESS       The entry point is executed successfully.
> > +  @retval other             Some error occurs when executing this entry point.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspsMultiPhaseSiInitDxeEntryPoint (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +  VOID        *Registration;
> > +
> > +  if (!PcdGet8 (PcdFspModeSelection)) {
> > +    // Dispatch Mode
> > +    DEBUG ((DEBUG_INFO, "Waiting for FSP Setup table...\n"));
> > +    Status = gBS->CreateEvent (
> > +                    EVT_NOTIFY_SIGNAL,
> > +                    TPL_CALLBACK,
> > +                    CheckAndRebootSystemAfterFspSetupTable,
> > +                    NULL,
> > +                    &gAmdFspSetupTableInitDoneEvent
> > +                    );
> > +    if (!EFI_ERROR (Status)) {
> > +      Registration = NULL;
> > +      Status       = gBS->RegisterProtocolNotify (
> > +                            &gAmdFspSetupTableInitDoneGuid,
> > +                            gAmdFspSetupTableInitDoneEvent,
> > +                            &Registration
> > +                            );
> > +    }
> > +
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // Load this driver's image to memory
> > +  //
> > +  Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "Cannot relocate into 4G- Mem!\n"));
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  VOID  *FspHobList = (VOID *)((UINTN)GetFspHobList ()&0xFFFFFFFF);
> > +
> > +  return FspWrapperMultiPhaseHandler (&FspHobList,
> > FspMultiPhaseSiInitApiIndex);
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +CallFspWrapperResetSystem (
> > +  IN EFI_STATUS  FspStatusResetType
> > +  )
> > +{
> > +  //
> > +  // Perform reset according to the type.
> > +  //
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/FspsMultiPhaseSiInitDxe.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/FspsMultiPhaseSiInitDxe.inf
> > new file mode 100644
> > index 0000000000..7eefe691cf
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/FspsMultiPhaseSiInitDxe.inf
> > @@ -0,0 +1,81 @@
> > +## @file
> > +#  FSP DXE Module INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
>
> Please put AMD copy right under Intel's.
>
> > +## @file
> > +# FSP DXE Module
> > +#
> > +# This driver will register two callbacks to call fsp's notifies.
> > +#
> > +#  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = FspsMultiPhaseSiInitDxe
> > +  FILE_GUID                      = B37267AD-4F52-41E2-BBD0-6BAEFD911A25
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = FspsMultiPhaseSiInitDxeEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources]
> > +  FspsMultiPhaseSiInitDxe.c
> > +  LoadBelow4G.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  AgesaPublic/AgesaPublic.dec
> > +
> > +[LibraryClasses]
> > +  UefiDriverEntryPoint
> > +  UefiBootServicesTableLib
> > +  DebugLib
> > +  BaseMemoryLib
> > +  UefiLib
> > +  FspWrapperApiLib
> > +  PeCoffLib
> > +  CacheMaintenanceLib
> > +  DxeServicesLib
> > +  PerformanceLib
> > +  HobLib
> > +  FspWrapperMultiPhaseProcessLib
> > +
> > +[Protocols]
> > +  gEfiSmbusHcProtocolGuid                           ## PRODUCES  FROM_FSP
> > +  gEfiSmmAccess2ProtocolGuid                        ## PRODUCES  FROM_FSP
> > +  gEfiSmmControl2ProtocolGuid                       ## PRODUCES  FROM_FSP
> > +  gEfiResetArchProtocolGuid                         ## PRODUCES  FROM_FSP
> > +  gFchInitDonePolicyProtocolGuid                    ## PRODUCES  FROM_FSP
> > +  gEfiSmmBase2ProtocolGuid                          ## CONSUMES  FOR_FSP
> > +  gEfiSmmCommunicationProtocolGuid                  ## CONSUMES  FOR_FSP
> > +  gEfiMmCommunication2ProtocolGuid                  ## CONSUMES  FOR_FSP
> > +  gAmdFspSetupTableInitDoneGuid                     ## CONSUMES  FOR_FSP
> > + #gEfiSmmReadyToLockProtocolGuid                    ## CONSUMES  FOR_FSP
> > +
> > +[Guids]
> > +  gFspApiPerformanceGuid                            ## SOMETIMES_CONSUMES ##
> > GUID
> > +  gEfiEventExitBootServicesGuid                     ## CONSUMES ## Event
> > +  gFspHobGuid                                       ## CONSUMES ## HOB
> > +
> > +[Pcd]
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdSkipFspApi       ## CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection
> > +
> >
> gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdFspSetupTableInitNeedsRe
> > set
> > +
> > +[Depex]
> > +  TRUE
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/LoadBelow4G.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/LoadBelow4G.c
> > new file mode 100644
> > index 0000000000..ae05556cc9
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMulti
> > PhaseSiInitDxe/LoadBelow4G.c
> > @@ -0,0 +1,148 @@
> > +/** @file
> > +Implements LoadBelow4G.C
> > +
> > +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PeCoffLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/DxeServicesLib.h>
> > +#include <Library/CacheMaintenanceLib.h>
> > +#include <Library/UefiLib.h>
> > +
> > +/**
> > +  Relocate this image under 4G memory.
> > +
> > +  @param  ImageHandle  Handle of driver image.
> > +  @param  SystemTable  Pointer to system table.
> > +
> > +  @retval EFI_SUCCESS  Image successfully relocated.
> > +  @retval EFI_ABORTED  Failed to relocate image.
> > +
> > +**/
> > +EFI_STATUS
> > +RelocateImageUnder4GIfNeeded (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  )
> > +{
> > +  EFI_STATUS                    Status;
> > +  UINT8                         *Buffer;
> > +  UINTN                         BufferSize;
> > +  EFI_HANDLE                    NewImageHandle;
> > +  UINTN                         Pages;
> > +  EFI_PHYSICAL_ADDRESS          FfsBuffer;
> > +  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
> > +  VOID                          *Interface;
> > +
> > +  //
> > +  // If it is already <4G, no need do relocate
> > +  //
> > +  if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // If locate gEfiCallerIdGuid success, it means 2nd entry.
> > +  //
> > +  Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);
> > +  if (!EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "FspNotifyDxe - 1st entry\n"));
> > +
> > +  //
> > +  // Here we install a dummy handle
> > +  //
> > +  NewImageHandle = NULL;
> > +  Status         = gBS->InstallProtocolInterface (
> > +                          &NewImageHandle,
> > +                          &gEfiCallerIdGuid,
> > +                          EFI_NATIVE_INTERFACE,
> > +                          NULL
> > +                          );
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Reload image itself to <4G mem
> > +  //
> > +  Status = GetSectionFromAnyFv (
> > +             &gEfiCallerIdGuid,
> > +             EFI_SECTION_PE32,
> > +             0,
> > +             (VOID **)&Buffer,
> > +             &BufferSize
> > +             );
> > +  ASSERT_EFI_ERROR (Status);
> > +  ImageContext.Handle    = Buffer;
> > +  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
> > +  //
> > +  // Get information about the image being loaded
> > +  //
> > +  Status = PeCoffLoaderGetImageInfo (&ImageContext);
> > +  ASSERT_EFI_ERROR (Status);
> > +  if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
> > +    Pages = EFI_SIZE_TO_PAGES ((UINTN)(ImageContext.ImageSize +
> > ImageContext.SectionAlignment));
> > +  } else {
> > +    Pages = EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize);
> > +  }
> > +
> > +  FfsBuffer = 0xFFFFFFFF;
> > +  Status    = gBS->AllocatePages (
> > +                     AllocateMaxAddress,
> > +                     EfiBootServicesCode,
> > +                     Pages,
> > +                     &FfsBuffer
> > +                     );
> > +  ASSERT_EFI_ERROR (Status);
> > +  ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
> > +  //
> > +  // Align buffer on section boundary
> > +  //
> > +  ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
> > +  ImageContext.ImageAddress &=
> > ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
> > +  //
> > +  // Load the image to our new buffer
> > +  //
> > +  Status = PeCoffLoaderLoadImage (&ImageContext);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Relocate the image in our new buffer
> > +  //
> > +  Status = PeCoffLoaderRelocateImage (&ImageContext);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Free the buffer allocated by ReadSection since the image has been
> > relocated in the new buffer
> > +  //
> > +  gBS->FreePool (Buffer);
> > +
> > +  //
> > +  // Flush the instruction cache so the image data is written before we
> execute
> > it
> > +  //
> > +  InvalidateInstructionCacheRange ((VOID
> > *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
> > +
> > +  DEBUG ((DEBUG_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n",
> > (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));
> > +  Status =
> >
> ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint))(NewImage
> > Handle, gST);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "Error: Image at 0x%08x start failed: %r\n",
> > ImageContext.ImageAddress, Status));
> > +    gBS->FreePages (FfsBuffer, Pages);
> > +  }
> > +
> > +  //
> > +  // return error to unload >4G copy, if we already relocate itself to <4G.
> > +  //
> > +  return EFI_ALREADY_STARTED;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrap
> > perPeim/FspsWrapperPeim.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrap
> > perPeim/FspsWrapperPeim.c
> > new file mode 100644
> > index 0000000000..e6a589bcb5
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrap
> > perPeim/FspsWrapperPeim.c
> > @@ -0,0 +1,632 @@
> > +/** @file
> > +  This will be invoked only once. It will call FspMemoryInit API,
> > +  register TemporaryRamDonePpi to call TempRamExit API, and register
> > MemoryDiscoveredPpi
> > +  notify to call FspSiliconInit API.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Library/PeimEntryPoint.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/PeiServicesTablePointerLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/FspWrapperPlatformLib.h>
> > +#include <Library/FspWrapperHobProcessLib.h>
> > +#include "../Include/Library/FspWrapperMultiPhaseProcessLib.h"
> > +#include "../Include/Library/FspWrapperPlatformMultiPhaseLib.h"
> > +#include <Library/TimerLib.h>
> > +#include <Library/PerformanceLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Ppi/FspSiliconInitDone.h>
> > +#include <Ppi/EndOfPeiPhase.h>
> > +#include <Ppi/MemoryDiscovered.h>
> > +#include <Ppi/TemporaryRamDone.h>
> > +#include <Ppi/SecPlatformInformation.h>
> > +#include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
> > +#include <Library/FspWrapperApiTestLib.h>
> > +#include <FspEas.h>
> > +#include <FspStatusCode.h>
> > +#include <FspGlobalData.h>
> > +#include
> > <Library/LzmaCustomDecompressLib/LzmaDecompressLibInternal.h>
> > +#include <FspExportedInterfaceHob.h>
> > +
> > +extern EFI_PEI_NOTIFY_DESCRIPTOR  mS3EndOfPeiNotifyDesc;
> > +extern EFI_GUID                   gFspHobGuid;
> > +
> > +STATIC CONST EFI_GUID  SmmDriverVolumeFileName =
> > +{
> > +  0x82DFABE7, 0xCD0E, 0x44D3, { 0xAF, 0xBE, 0x46, 0x82, 0x21, 0xD1,
> 0x08,
> > 0xC4 }
> > +};
> > +
> > +/**
> > +  This function handles S3 resume task at the end of PEI.
> > +
> > +  @param[in] PeiServices    Pointer to PEI Services Table.
> > +  @param[in] NotifyDesc     Pointer to the descriptor for the Notification
> event
> > that
> > +                            caused this function to execute.
> > +  @param[in] Ppi            Pointer to the PPI data associated with this function.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +S3EndOfPeiNotify (
> > +  IN EFI_PEI_SERVICES           **PeiServices,
> > +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,
> > +  IN VOID                       *Ppi
> > +  );
> > +
> > +EFI_PEI_NOTIFY_DESCRIPTOR  mS3EndOfPeiNotifyDesc = {
> > +  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > +  &gEfiEndOfPeiSignalPpiGuid,
> > +  S3EndOfPeiNotify
> > +};
> > +
> > +/**
> > +  This function handles S3 resume task at the end of PEI.
> > +
> > +  @param[in] PeiServices    Pointer to PEI Services Table.
> > +  @param[in] NotifyDesc     Pointer to the descriptor for the Notification
> event
> > that
> > +                            caused this function to execute.
> > +  @param[in] Ppi            Pointer to the PPI data associated with this function.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +S3EndOfPeiNotify (
> > +  IN EFI_PEI_SERVICES           **PeiServices,
> > +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,
> > +  IN VOID                       *Ppi
> > +  )
> > +{
> > +  NOTIFY_PHASE_PARAMS  NotifyPhaseParams;
> > +  EFI_STATUS           Status;
> > +
> > +  DEBUG ((DEBUG_INFO, "S3EndOfPeiNotify enter\n"));
> > +
> > +  NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;
> > +  Status                  = CallFspNotifyPhase (&NotifyPhaseParams);
> > +  DEBUG ((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status:
> > 0x%x\n", Status));
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration
> > requested reset 0x%x\n", Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;
> > +  Status                  = CallFspNotifyPhase (&NotifyPhaseParams);
> > +  DEBUG ((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status:
> 0x%x\n",
> > Status));
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot requested
> reset
> > 0x%x\n", Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;
> > +  Status                  = CallFspNotifyPhase (&NotifyPhaseParams);
> > +  DEBUG ((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status:
> > 0x%x\n", Status));
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware requested
> > reset 0x%x\n", Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Return Hob list produced by FSP.
> > +
> > +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> > +  @param[in]  This         The pointer to this instance of this PPI.
> > +  @param[out] FspHobList   The pointer to Hob list produced by FSP.
> > +
> > +  @return EFI_SUCCESS      Return Hob list produced by FSP successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspSiliconInitDoneGetFspHobList (
> > +  IN  CONST EFI_PEI_SERVICES     **PeiServices,
> > +  IN  FSP_SILICON_INIT_DONE_PPI  *This,
> > +  OUT VOID                       **FspHobList
> > +  );
> > +
> > +FSP_SILICON_INIT_DONE_PPI  mFspSiliconInitDonePpi = {
> > +  FspSiliconInitDoneGetFspHobList
> > +};
> > +
> > +EFI_PEI_PPI_DESCRIPTOR  mPeiFspSiliconInitDonePpi = {
> > +  EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> > +  &gFspSiliconInitDonePpiGuid,
> > +  &mFspSiliconInitDonePpi
> > +};
> > +
> > +/**
> > +  Return Hob list produced by FSP.
> > +
> > +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> > +  @param[in]  This         The pointer to this instance of this PPI.
> > +  @param[out] FspHobList   The pointer to Hob list produced by FSP.
> > +
> > +  @return EFI_SUCCESS      Return Hob list produced by FSP successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspSiliconInitDoneGetFspHobList (
> > +  IN  CONST EFI_PEI_SERVICES     **PeiServices,
> > +  IN  FSP_SILICON_INIT_DONE_PPI  *This,
> > +  OUT VOID                       **FspHobList
> > +  )
> > +{
> > +  EFI_HOB_GUID_TYPE  *GuidHob;
> > +
> > +  GuidHob = GetFirstGuidHob (&gFspHobGuid);
> > +  if (GuidHob != NULL) {
> > +    *FspHobList = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
> > +    return EFI_SUCCESS;
> > +  } else {
> > +    return EFI_NOT_FOUND;
> > +  }
> > +}
> > +
> > +/**
> > +  Get the FSP S UPD Data address
> > +
> > +  @return FSP-S UPD Data Address
> > +**/
> > +UINTN
> > +GetFspsUpdDataAddress (
> > +  VOID
> > +  )
> > +{
> > +  if (PcdGet64 (PcdFspsUpdDataAddress64) != 0) {
> > +    return (UINTN)PcdGet64 (PcdFspsUpdDataAddress64);
> > +  } else {
> > +    return (UINTN)PcdGet32 (PcdFspsUpdDataAddress);
> > +  }
> > +}
> > +
> > +/**
> > +  This function is for FSP dispatch mode to perform post FSP-S process.
> > +
> > +  @param[in] PeiServices    Pointer to PEI Services Table.
> > +  @param[in] NotifyDesc     Pointer to the descriptor for the Notification
> event
> > that
> > +                            caused this function to execute.
> > +  @param[in] Ppi            Pointer to the PPI data associated with this function.
> > +
> > +  @retval EFI_STATUS        Status returned by PeiServicesInstallPpi ()
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspsWrapperEndOfPeiNotify (
> > +  IN EFI_PEI_SERVICES           **PeiServices,
> > +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,
> > +  IN VOID                       *Ppi
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  //
> > +  // This step may include platform specific process in some boot loaders so
> > +  // aligning the same behavior between API and Dispatch modes.
> > +  // Note: In Dispatch mode no FspHobList so passing NULL to function and
> > +  //       expecting function will handle it.
> > +  //
> > +  PostFspsHobProcess (NULL);
> > +
> > +  //
> > +  // Install FspSiliconInitDonePpi so that any other driver can consume this
> > info.
> > +  //
> > +  Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  return Status;
> > +}
> > +
> > +EFI_PEI_NOTIFY_DESCRIPTOR  mFspsWrapperEndOfPeiNotifyDesc = {
> > +  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > +  &gEfiEndOfPeiSignalPpiGuid,
> > +  FspsWrapperEndOfPeiNotify
> > +};
> > +
> > +/**
> > +  This function is called after PEI core discover memory and finish migration.
> > +
> > +  @param[in] PeiServices    Pointer to PEI Services Table.
> > +  @param[in] NotifyDesc     Pointer to the descriptor for the Notification
> event
> > that
> > +                            caused this function to execute.
> > +  @param[in] Ppi            Pointer to the PPI data associated with this function.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PeiMemoryDiscoveredNotify (
> > +  IN EFI_PEI_SERVICES           **PeiServices,
> > +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,
> > +  IN VOID                       *Ppi
> > +  );
> > +
> > +EFI_PEI_NOTIFY_DESCRIPTOR  mPeiMemoryDiscoveredNotifyDesc = {
> > +  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > +  &gEfiPeiMemoryDiscoveredPpiGuid,
> > +  PeiMemoryDiscoveredNotify
> > +};
> > +
> > +extern
> > +RETURN_STATUS
> > +EFIAPI
> > +LzmaGuidedSectionGetInfo (
> > +  IN  CONST VOID  *InputSection,
> > +  OUT UINT32      *OutputBufferSize,
> > +  OUT UINT32      *ScratchBufferSize,
> > +  OUT UINT16      *SectionAttribute
> > +  )
> > +;
> > +
> > +extern
> > +RETURN_STATUS
> > +EFIAPI
> > +LzmaGuidedSectionExtraction (
> > +  IN CONST  VOID    *InputSection,
> > +  OUT       VOID    **OutputBuffer,
> > +  OUT       VOID    *ScratchBuffer         OPTIONAL,
> > +  OUT       UINT32  *AuthenticationStatus
> > +  )
> > +;
> > +
> > +/**
> > +  This function is called after PEI core discover memory and finish migration.
> > +
> > +  @param[in] PeiServices    Pointer to PEI Services Table.
> > +  @param[in] NotifyDesc     Pointer to the descriptor for the Notification
> event
> > that
> > +                            caused this function to execute.
> > +  @param[in] Ppi            Pointer to the PPI data associated with this function.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PeiMemoryDiscoveredNotify (
> > +  IN EFI_PEI_SERVICES           **PeiServices,
> > +  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDesc,
> > +  IN VOID                       *Ppi
> > +  )
> > +{
> > +  FSP_INFO_HEADER      *FspsHeaderPtr;
> > +  UINT64               TimeStampCounterStart;
> > +  EFI_STATUS           Status;
> > +  VOID                 *FspHobListPtr;
> > +  EFI_HOB_GUID_TYPE    *GuidHob;
> > +  FSPS_UPD_COMMON      *FspsUpdDataPtr;
> > +  UINTN                *SourceData;
> > +  EFI_PEI_FV_HANDLE    VolumeHandle;
> > +  EFI_PEI_FILE_HANDLE  FileHandle;
> > +  EFI_FV_FILE_INFO     FileInfo;
> > +  UINT32               FvIndex = 0;
> > +  UINT32               DecompressedSmmFvSize, TemporaryBufferSize;
> > +  VOID                 *DecompressedFv, *TemporaryBuffer;
> > +  EFI_BOOT_MODE        BootMode;
> > +
> > +  //
> > +  // Get boot mode
> > +  //
> > +  Status = PeiServicesGetBootMode (&BootMode);
> > +  ASSERT_EFI_ERROR (Status);
> > +  DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n"));
> > +  FspsUpdDataPtr = NULL;
> > +
> > +  VOID  *FspsBaseAddressInMem = (VOID *)(UINTN)PcdGet32
> > (PcdFspsBaseAddressInMemory);
> > +
> > +  FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader
> > ((EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32
> > (PcdFspsBaseAddressInMemory));
> > +  BuildMemoryAllocationHob (
> > +    (EFI_PHYSICAL_ADDRESS)(UINTN)FspsBaseAddressInMem,
> > +    (UINT64)PcdGet32 (PcdFspsRegionSize),
> > +    EfiACPIMemoryNVS
> > +    );
> > +  FspsHeaderPtr->ImageBase = (UINTN)FspsBaseAddressInMem;
> > +
> > +  if (BootMode != BOOT_ON_S3_RESUME) {
> > +    // Get SMM Driver Volume from flash, and extract/deflate it.
> > +    while (PeiServicesFfsFindNextVolume (FvIndex, &VolumeHandle) !=
> > EFI_NOT_FOUND) {
> > +      if (PeiServicesFfsFindFileByName (&SmmDriverVolumeFileName,
> > VolumeHandle, &FileHandle) == EFI_SUCCESS) {
> > +        break;
> > +      }
> > +
> > +      FvIndex++;
> > +    }
> > +
> > +    ASSERT (FileHandle != NULL);
> > +    PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
> > +    DEBUG ((DEBUG_INFO, "SMM Driver File:%p,0x%x bytes.\n",
> > FileInfo.Buffer, FileInfo.BufferSize));
> > +    UINT16  Attribute;
> > +    Status = LzmaGuidedSectionGetInfo (
> > +               FileInfo.Buffer,
> > +               &DecompressedSmmFvSize,
> > +               &TemporaryBufferSize,
> > +               &Attribute
> > +               );
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "Cannot Get LZMA Section info!\n"));
> > +      ASSERT (FALSE);
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    DEBUG ((DEBUG_INFO, "FV Decompress size:%d\n",
> > DecompressedSmmFvSize));
> > +    EFI_PHYSICAL_ADDRESS  PhysicalAddress;
> > +    Status =  PeiServicesAllocatePages (
> > +                EfiBootServicesData,
> > +                EFI_SIZE_TO_PAGES (DecompressedSmmFvSize),
> > +                &PhysicalAddress
> > +                );
> > +    DecompressedFv = (VOID *)(UINTN)PhysicalAddress;
> > +    Status        |= PeiServicesAllocatePages (
> > +                       EfiBootServicesData,
> > +                       EFI_SIZE_TO_PAGES (TemporaryBufferSize),
> > +                       &PhysicalAddress
> > +                       );
> > +    TemporaryBuffer = (VOID *)(UINTN)PhysicalAddress;
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "Cannot allocate memory!%r\n", Status));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    UINT32  AuthenticationStatus;
> > +    Status = LzmaGuidedSectionExtraction (FileInfo.Buffer,
> &DecompressedFv,
> > TemporaryBuffer, &AuthenticationStatus);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "Cannot Decompress LZMA Section!:%r\n",
> > Status));
> > +      ASSERT (FALSE);
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    PeiServicesFreePages (PhysicalAddress, EFI_SIZE_TO_PAGES
> > (TemporaryBufferSize));
> > +
> > +    FSP_EXPORTED_INTERFACE_HOB  *ExportedInterfaceHob;
> > +    GuidHob = GetFirstGuidHob (&gFspHobGuid);
> > +    if (GuidHob != NULL) {
> > +      GuidHob              = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
> > +      GuidHob              = GetNextGuidHob (&gFspExportedInterfaceHobGuid,
> > GuidHob);
> > +      ExportedInterfaceHob = GET_GUID_HOB_DATA (GuidHob);
> > +      DEBUG ((DEBUG_INFO, "FSP Exported interface HOB:%p\n",
> > ExportedInterfaceHob));
> > +      DEBUG ((DEBUG_INFO, "FSP DecompressedFv:%p\n", (UINT8
> > *)DecompressedFv+0x10)); // Skip RAW section.
> > +      ExportedInterfaceHob->SmmDriverVolume     = (UINT8
> > *)DecompressedFv+0x10;      // Skip RAW section.
> > +      ExportedInterfaceHob->SmmDriverVolumeSize =
> > DecompressedSmmFvSize;
> > +    }
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "FspsHeaderPtr - 0x%x\n", FspsHeaderPtr));
> > +  if (FspsHeaderPtr == NULL) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  if ((GetFspsUpdDataAddress () == 0) && (FspsHeaderPtr->CfgRegionSize !=
> > 0) && (FspsHeaderPtr->CfgRegionOffset != 0)) {
> > +    //
> > +    // Copy default FSP-S UPD data from Flash
> > +    //
> > +    FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool
> > ((UINTN)FspsHeaderPtr->CfgRegionSize);
> > +    ASSERT (FspsUpdDataPtr != NULL);
> > +    SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase +
> > (UINTN)FspsHeaderPtr->CfgRegionOffset);
> > +    CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr-
> > >CfgRegionSize);
> > +  } else {
> > +    FspsUpdDataPtr = (FSPS_UPD_COMMON *)GetFspsUpdDataAddress ();
> > +    ASSERT (FspsUpdDataPtr != NULL);
> > +  }
> > +
> > +  UpdateFspsUpdData ((VOID *)FspsUpdDataPtr);
> > +
> > +  TimeStampCounterStart = AsmReadTsc ();
> > +  PERF_START_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE |
> > FSP_STATUS_CODE_API_ENTRY);
> > +  Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr);
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FspSiliconInitApi requested reset %r\n",
> Status));
> > +    CallFspWrapperResetSystem (Status);
> > +  }
> > +
> > +  if ((Status != FSP_STATUS_VARIABLE_REQUEST) && EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(),
> > Status = %r\n", Status));
> > +    ASSERT_EFI_ERROR (Status);
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "FspSiliconInit status: %r\n", Status));
> > +
> > +  if (Status == FSP_STATUS_VARIABLE_REQUEST) {
> > +    //
> > +    // call to Variable request handler
> > +    //
> > +    FspWrapperVariableRequestHandler (&FspHobListPtr,
> > FspMultiPhaseSiInitApiIndex);
> > +  }
> > +
> > +  //
> > +  // See if MultiPhase process is required or not
> > +  //
> > +  FspWrapperMultiPhaseHandler (&FspHobListPtr,
> > FspMultiPhaseSiInitApiIndex);    // FspS MultiPhase
> > +
> > +  PERF_END_EX (&gFspApiPerformanceGuid, "EventRec", NULL, 0,
> > FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE |
> > FSP_STATUS_CODE_API_EXIT);
> > +  DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d
> > millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () -
> > TimeStampCounterStart), 1000000)));
> > +
> > +  Status = TestFspSiliconInitApiOutput ((VOID *)NULL);
> > +  if (RETURN_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail,
> > Status = %r\n", Status));
> > +  }
> > +
> > +  //
> > +  // Now FspHobList complete, process it
> > +  //
> > +  GuidHob = GetFirstGuidHob (&gFspHobGuid);
> > +  ASSERT (GuidHob != NULL);
> > +  FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
> > +  DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr));
> > +  PostFspsHobProcess (FspHobListPtr);
> > +
> > +  //
> > +  // Install FspSiliconInitDonePpi so that any other driver can consume this
> > info.
> > +  //
> > +  Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Do FSP initialization in API mode.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +**/
> > +EFI_STATUS
> > +FspsWrapperInitApiMode (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS     Status;
> > +  EFI_BOOT_MODE  BootMode;
> > +
> > +  //
> > +  // Register MemoryDiscovered Notify to run FspSiliconInit
> > +  //
> > +  Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Register EndOfPei Notify for S3 to run FSP NotifyPhase
> > +  //
> > +  PeiServicesGetBootMode (&BootMode);
> > +  if (BootMode == BOOT_ON_S3_RESUME) {
> > +    Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
> > +    ASSERT_EFI_ERROR (Status);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Do FSP initialization in Dispatch mode.
> > +
> > +  @retval FSP initialization status.
> > +**/
> > +EFI_STATUS
> > +FspsWrapperInitDispatchMode (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS                                             Status;
> > +  EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
> > *MeasurementExcludedFvPpi;
> > +  EFI_PEI_PPI_DESCRIPTOR                                 *MeasurementExcludedPpiList;
> > +  EFI_BOOT_MODE                                          BootMode;
> > +
> > +  PeiServicesGetBootMode (&BootMode);
> > +  Status = EFI_SUCCESS;
> > +
> > +  if (BootMode != BOOT_ON_S3_RESUME) {
> > +    MeasurementExcludedFvPpi = AllocatePool (sizeof
> > (*MeasurementExcludedFvPpi));
> > +    ASSERT (MeasurementExcludedFvPpi != NULL);
> > +    MeasurementExcludedFvPpi->Count          = 1;
> > +    MeasurementExcludedFvPpi->Fv[0].FvBase   = PcdGet32
> > (PcdFspsBaseAddressInMemory);
> > +    MeasurementExcludedFvPpi->Fv[0].FvLength = PcdGet32
> > (PcdFspsRegionSize);
> > +
> > +    MeasurementExcludedPpiList = AllocatePool (sizeof
> > (*MeasurementExcludedPpiList));
> > +    ASSERT (MeasurementExcludedPpiList != NULL);
> > +    MeasurementExcludedPpiList->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
> > +    MeasurementExcludedPpiList->Guid  =
> > &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid;
> > +    MeasurementExcludedPpiList->Ppi   = MeasurementExcludedFvPpi;
> > +
> > +    Status = PeiServicesInstallPpi (MeasurementExcludedPpiList);
> > +    ASSERT_EFI_ERROR (Status);
> > +
> > +    EFI_FIRMWARE_VOLUME_HEADER  *FspsBaseAddressInMem = (VOID
> > *)(UINTN)PcdGet32 (PcdFspsBaseAddressInMemory);
> > +    //
> > +    // FSP-S Wrapper running in Dispatch mode and reports FSP-S FV to PEI
> > dispatcher.
> > +    //
> > +    PeiServicesInstallFvInfoPpi (
> > +      NULL,
> > +      (VOID *)(UINTN)FspsBaseAddressInMem,
> > +      (UINT32)PcdGet32 (PcdFspsRegionSize),
> > +      NULL,
> > +      NULL
> > +      );
> > +
> > +    VOID  *FspoDxeBaseAddressInMem = (VOID *)(UINTN)PcdGet32
> > (PcdFspoDxeBaseAddressInMemory);
> > +    PeiServicesInstallFvInfoPpi (
> > +      NULL,
> > +      FspoDxeBaseAddressInMem,
> > +      (UINT32)PcdGet32 (PcdFspoDxeRegionSize),
> > +      NULL,
> > +      NULL
> > +      );
> > +    BuildFvHob ((EFI_PHYSICAL_ADDRESS)(UINTN)FspsBaseAddressInMem,
> > PcdGet32 (PcdFspsRegionSize));
> > +    BuildFvHob
> > ((EFI_PHYSICAL_ADDRESS)(UINTN)FspoDxeBaseAddressInMem, PcdGet32
> > (PcdFspoDxeRegionSize));
> > +
> > +    //
> > +    // Register EndOfPei Nofity to run post FSP-S process.
> > +    //
> > +    Status = PeiServicesNotifyPpi (&mFspsWrapperEndOfPeiNotifyDesc);
> > +    ASSERT_EFI_ERROR (Status);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This is the entrypoint of PEIM.
> > +
> > +  @param[in] FileHandle  Handle of the file being invoked.
> > +  @param[in] PeiServices Describes the list of possible PEI Services.
> > +
> > +  @retval EFI_SUCCESS if it completed successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspsWrapperPeimEntryPoint (
> > +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> > +  IN CONST EFI_PEI_SERVICES     **PeiServices
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n"));
> > +
> > + #ifndef COMPRESS_FSP_REGION
> > +  CopyMem ((VOID *)(UINTN)PcdGet32
> > (PcdFspoDxeBaseAddressInMemory), (VOID *)(UINTN)PcdGet32
> > (PcdFspoDxeBaseAddressInFlash), PcdGet32 (PcdFspoDxeRegionSize));
> > +  CopyMem ((VOID *)(UINTN)PcdGet32 (PcdFspsBaseAddressInMemory),
> > (VOID *)(UINTN)PcdGet32 (PcdFspsBaseAddressInFlash), PcdGet32
> > (PcdFspsRegionSize));
> > + #endif
> > +  BuildMemoryAllocationHob (
> > +    (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32
> > (PcdFspsBaseAddressInMemory),
> > +    (UINT64)PcdGet32 (PcdFspsRegionSize),
> > +    EfiACPIMemoryNVS
> > +    );
> > +
> > +  BuildMemoryAllocationHob (
> > +    (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32
> > (PcdFspoDxeBaseAddressInMemory),
> > +    (UINT64)PcdGet32 (PcdFspoDxeRegionSize),
> > +    EfiACPIMemoryNVS
> > +    );
> > +
> > +  if (PcdGet8 (PcdFspModeSelection) == 1) {
> > +    FspsWrapperInitApiMode ();
> > +  } else {
> > +    FspsWrapperInitDispatchMode ();
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrap
> > perPeim/FspsWrapperPeim.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrap
> > perPeim/FspsWrapperPeim.inf
> > new file mode 100644
> > index 0000000000..e43a8c941f
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrap
> > perPeim/FspsWrapperPeim.inf
> > @@ -0,0 +1,98 @@
> > +## @file
> > +#  FSP-S wrapper PEI Module INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +## @file
> > +# FSP-S wrapper PEI Module
> > +#
> > +# This PEIM initialize FSP.
> > +# This will be invoked only once. It will call FspMemoryInit API,
> > +# register TemporaryRamDonePpi to call TempRamExit API, and register
> > MemoryDiscoveredPpi
> > +# notify to call FspSiliconInit API.
> > +#
> > +#  Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010017
> > +  BASE_NAME                      = FspsWrapperPeim
> > +  FILE_GUID                      = 0D244DF9-6CE3-4133-A1CF-53200AB663AC
> > +  VERSION_STRING                 = 1.0
> > +  MODULE_TYPE                    = PEIM
> > +  ENTRY_POINT                    = FspsWrapperPeimEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32
> > +#
> > +
> > +[LibraryClasses]
> > +  PeimEntryPoint
> > +  PeiServicesLib
> > +  PeiServicesTablePointerLib
> > +  BaseLib
> > +  BaseMemoryLib
> > +  TimerLib
> > +  DebugLib
> > +  HobLib
> > +  MemoryAllocationLib
> > +  FspWrapperPlatformLib
> > +  FspWrapperHobProcessLib
> > +  CpuLib
> > +  UefiCpuLib
> > +  PeCoffGetEntryPointLib
> > +  PeCoffExtraActionLib
> > +  PerformanceLib
> > +  FspWrapperApiLib
> > +  FspWrapperApiTestLib
> > +  FspWrapperMultiPhaseProcessLib
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  UefiCpuPkg/UefiCpuPkg.dec
> > +  SecurityPkg/SecurityPkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  ChachaniBoardPkg/Project.dec
> > +
> > +[Ppis]
> > +  gTopOfTemporaryRamPpiGuid                              ## PRODUCES
> > +  gFspSiliconInitDonePpiGuid                             ## PRODUCES
> > +  gEfiEndOfPeiSignalPpiGuid                              ## PRODUCES
> > +  gEfiTemporaryRamDonePpiGuid                            ## PRODUCES
> > +  gEfiPeiMemoryDiscoveredPpiGuid                         ## NOTIFY
> > +#-  gEdkiiTcgPpiGuid                                       ## NOTIFY
> > +  gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid    ## PRODUCES
> > +
> > +[Pcd]
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress    ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection      ##
> CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig  ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspsUpdDataAddress64  ##
> > CONSUMES
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInFlash
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInMemory
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspoDxeBaseAddressInFlash
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspoDxeBaseAddressInMemory
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspsRegionSize
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspoDxeRegionSize
> > +
> > +[Guids]
> > +  gFspHobGuid                           ## CONSUMES ## HOB
> > +  gFspApiPerformanceGuid                ## SOMETIMES_CONSUMES ## GUID
> > +  gFspExportedInterfaceHobGuid
> > +  gPlatformPkgTokenSpaceGuid
> > +
> > +[Sources]
> > +  FspsWrapperPeim.c
> > +
> > +[Depex]
> > +  gEfiPeiMemoryDiscoveredPpiGuid
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spExportedInterfaceHob.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spExportedInterfaceHob.h
> > new file mode 100644
> > index 0000000000..66778b0143
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spExportedInterfaceHob.h
> > @@ -0,0 +1,146 @@
> > +/** @file
> > +  Implements FspExportedInterfaceHob.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_EXPORTED_INTERFACE_HOB_H
> > +#define FSP_EXPORTED_INTERFACE_HOB_H
> > +#include <Uefi.h>
> > +#include <FspsUpd.h>
> > +#define MAX_SMBIOS_TABLE_COUNT     20
> > +#define MAX_ACPI_SSDT_TABLE_COUNT  9
> > +
> > +#define FSP_TO_BOOTLOADER
> > +#define BOOTLOADER_TO_FSP
> > +#define IMPROPRIATE_ARCH
> > +
> > +typedef VOID  (EFIAPI
> > *FSP_VIRTUAL_ADDRESS_CHANGE_CALLBACK)(FSPS_UPD
> > *NewUpdAddress);
> > +typedef VOID  *(EFIAPI *BOOTLOADER_CONVERT_POINTER)(VOID *In);
> > +
> > +// Use "placeholder" for structure coherence under different CPU modes.
> > +// The GUID of HOB.
> > +extern EFI_GUID  gFspExportedInterfaceHobGuid;
> > +
> > +// Include goes here.
> > +
> > +#ifndef MDE_CPU_X64
> > +  #include <Ppi/Reset2.h>
> > +#else
> > +  #include <Protocol/SmbusHc.h>
> > +  #include <Protocol/SmmAccess2.h>
> > +  #include <Protocol/SmmControl2.h>
> > +  #include <Protocol/SmmBase2.h>
> > +  #include <Protocol/SmmCommunication.h>
> > +  #include <Protocol/MmCommunication2.h>
> > +  #include <Protocol/HiiDatabase.h>
> > +  #include <Protocol/HiiConfigRouting.h>
> > +  #include <Protocol/HiiString.h>
> > +  #include <Protocol/PciIo.h>
> > +  #include <Protocol/AmdPspFtpmProtocol.h>
> > +  #include <Uefi/UefiSpec.h>
> > +#endif
> > +
> > +#pragma pack (push,1)
> > +typedef struct _FSP_EXPORTED_INTERFACE_HOB
> > FSP_EXPORTED_INTERFACE_HOB;
> > +#ifndef MDE_CPU_X64
> > +struct _FSP_EXPORTED_INTERFACE_HOB {
> > +  BOOTLOADER_TO_FSP VOID                  *SmmDriverVolume;
> > +  BOOTLOADER_TO_FSP UINT32                SmmDriverVolumeSize;
> > +  FSP_TO_BOOTLOADER VOID                  *PspFtpmPpi;
> > +  FSP_TO_BOOTLOADER VOID                  *PspFtpmFactoryResetPpi;
> > +  FSP_TO_BOOTLOADER EFI_PEI_RESET2_PPI    *Reset2Ppi;
> > +  IMPROPRIATE_ARCH UINT64                 SmbusProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 SmmAccessProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 SmmControl2Protocol;
> > +  IMPROPRIATE_ARCH UINT64                 PspCommonServiceProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 ApobCommonServiceProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 ApcbDxeServiceProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 SmmBase2Protocol;
> > +  IMPROPRIATE_ARCH UINT64                 SmmCommunicationProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 MmCommunication2Protocol;
> > +  IMPROPRIATE_ARCH UINT64                 FchResetSystem;
> > +  IMPROPRIATE_ARCH UINT64
> PcdAmdSmmCommunicationAddress;
> > +  IMPROPRIATE_ARCH UINT64                 PcdAmdS3LibPrivateDataAddress;
> > +  IMPROPRIATE_ARCH UINT64                 PcdAmdS3LibTableAddress;
> > +  IMPROPRIATE_ARCH UINT64                 PcdAmdS3LibTableSize;
> > +  IMPROPRIATE_ARCH UINT64
> > SmbiosPointers[MAX_SMBIOS_TABLE_COUNT];
> > +  IMPROPRIATE_ARCH UINT64
> > AcpiSsdtTables[MAX_ACPI_SSDT_TABLE_COUNT];
> > +  IMPROPRIATE_ARCH UINT64                 AcpiTpm2Table;
> > +  IMPROPRIATE_ARCH UINT64                 AcpiCratTable;
> > +  IMPROPRIATE_ARCH UINT64                 AcpiCditTable;
> > +  IMPROPRIATE_ARCH UINT64                 AcpiIvrsTable;
> > +  IMPROPRIATE_ARCH UINT64                 VirtualAddressChangeCallback;
> > +  IMPROPRIATE_ARCH UINT64                 FinalMemoryMap;
> > +  IMPROPRIATE_ARCH UINT64                 FinalMemoryMapSize;
> > +  IMPROPRIATE_ARCH UINT64                 FinalMemoryDescriptorSize;
> > +  IMPROPRIATE_ARCH UINT64                 ConvertPointer;
> > +  IMPROPRIATE_ARCH UINT64
> > ExportedInterfaceHobAddressAfterNotifyPhase;
> > +  IMPROPRIATE_ARCH UINT64                 PspPlatformProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 GetVariable;
> > +  IMPROPRIATE_ARCH UINT64                 GetNextVariableName;
> > +  IMPROPRIATE_ARCH UINT64                 QueryVariableInfo;
> > +  IMPROPRIATE_ARCH UINT64                 SetVariable;
> > +  IMPROPRIATE_ARCH UINT64                 HiiProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 HiiStringProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 HiiConfigRoutingProtocol;
> > +  IMPROPRIATE_ARCH UINT64
> > S3BootScriptTablePrivateSmmDataPtr;
> > +  IMPROPRIATE_ARCH UINT64                 S3BootScriptTablePrivateDataPtr;
> > +  IMPROPRIATE_ARCH UINT64                 EfiPciIoProtocol;
> > +  IMPROPRIATE_ARCH UINT64                 EfiPciIoProtocolCount;
> > +  IMPROPRIATE_ARCH UINT64                 PspFtpmProtocol;
> > +};
> > +
> > +#else
> > +struct _FSP_EXPORTED_INTERFACE_HOB {
> > +  IMPROPRIATE_ARCH UINT32                                  SmmDriverVolume;
> > +  IMPROPRIATE_ARCH UINT32                                  SmmDriverVolumeSize;
> > +  IMPROPRIATE_ARCH UINT32                                  PspFtpmPpi;
> > +  IMPROPRIATE_ARCH UINT32                                  PspFtpmFactoryResetPpi;
> > +  IMPROPRIATE_ARCH UINT32                                  Reset2Ppi;
> > +  FSP_TO_BOOTLOADER EFI_SMBUS_HC_PROTOCOL
> > *SmbusProtocol;
> > +  FSP_TO_BOOTLOADER EFI_SMM_ACCESS2_PROTOCOL
> > *SmmAccessProtocol;
> > +  FSP_TO_BOOTLOADER EFI_SMM_CONTROL2_PROTOCOL
> > *SmmControl2Protocol;
> > +  FSP_TO_BOOTLOADER VOID
> > *PspCommonServiceProtocol;
> > +  FSP_TO_BOOTLOADER VOID
> > *ApobCommonServiceProtocol;
> > +  FSP_TO_BOOTLOADER VOID                                   *ApcbDxeServiceProtocol;
> > +  FSP_TO_BOOTLOADER EFI_SMM_BASE2_PROTOCOL
> > *SmmBase2Protocol;
> > +  FSP_TO_BOOTLOADER EFI_SMM_COMMUNICATION_PROTOCOL
> > *SmmCommunicationProtocol;
> > +  FSP_TO_BOOTLOADER EFI_MM_COMMUNICATION2_PROTOCOL
> > *MmCommunication2Protocol;
> > +  FSP_TO_BOOTLOADER EFI_RESET_SYSTEM                       FchResetSystem;
> > +  FSP_TO_BOOTLOADER UINT64
> > PcdAmdSmmCommunicationAddress;
> > +  FSP_TO_BOOTLOADER UINT64
> > PcdAmdS3LibPrivateDataAddress;
> > +  FSP_TO_BOOTLOADER UINT64
> PcdAmdS3LibTableAddress;
> > +  FSP_TO_BOOTLOADER UINT64                                 PcdAmdS3LibTableSize;
> > +  FSP_TO_BOOTLOADER VOID
> > *SmbiosPointers[MAX_SMBIOS_TABLE_COUNT];
> > +  FSP_TO_BOOTLOADER VOID
> > *AcpiSsdtTables[MAX_ACPI_SSDT_TABLE_COUNT];
> > +  FSP_TO_BOOTLOADER VOID                                   *AcpiTpm2Table;
> > +  FSP_TO_BOOTLOADER VOID                                   *AcpiCratTable;
> > +  FSP_TO_BOOTLOADER VOID                                   *AcpiCditTable;
> > +  FSP_TO_BOOTLOADER VOID                                   *AcpiIvrsTable;
> > +  FSP_TO_BOOTLOADER FSP_VIRTUAL_ADDRESS_CHANGE_CALLBACK
> > VirtualAddressChangeCallback;
> > +  FSP_TO_BOOTLOADER VOID                                   *FinalMemoryMap;
> > +  FSP_TO_BOOTLOADER UINT64                                 FinalMemoryMapSize;
> > +  FSP_TO_BOOTLOADER UINT64
> FinalMemoryDescriptorSize;
> > +  BOOTLOADER_TO_FSP BOOTLOADER_CONVERT_POINTER
> > ConvertPointer;
> > +  FSP_TO_BOOTLOADER FSP_EXPORTED_INTERFACE_HOB
> > *ExportedInterfaceHobAddressAfterNotifyPhase;
> > +  BOOTLOADER_TO_FSP VOID                                   *PspPlatformProtocol;
> > +  BOOTLOADER_TO_FSP EFI_GET_VARIABLE                       GetVariable;
> > +  BOOTLOADER_TO_FSP EFI_GET_NEXT_VARIABLE_NAME
> > GetNextVariableName;
> > +  BOOTLOADER_TO_FSP EFI_QUERY_VARIABLE_INFO
> > QueryVariableInfo;
> > +  BOOTLOADER_TO_FSP EFI_SET_VARIABLE                       SetVariable;
> > +  BOOTLOADER_TO_FSP EFI_HII_DATABASE_PROTOCOL              *HiiProtocol;
> > +  BOOTLOADER_TO_FSP EFI_HII_STRING_PROTOCOL
> > *HiiStringProtocol;
> > +  BOOTLOADER_TO_FSP EFI_HII_CONFIG_ROUTING_PROTOCOL
> > *HiiConfigRoutingProtocol;
> > +  FSP_TO_BOOTLOADER UINT64
> > S3BootScriptTablePrivateSmmDataPtr;
> > +  FSP_TO_BOOTLOADER UINT64
> > S3BootScriptTablePrivateDataPtr;
> > +  BOOTLOADER_TO_FSP EFI_PCI_IO_PROTOCOL
> **EfiPciIoProtocol;
> > +  BOOTLOADER_TO_FSP UINT64                                 EfiPciIoProtocolCount;
> > +  FSP_TO_BOOTLOADER PSP_FTPM_PROTOCOL
> > *PspFtpmProtocol;
> > +};
> > +
> > +#endif
> > +#pragma pack (pop)
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spMemoryRegionHob.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spMemoryRegionHob.h
> > new file mode 100644
> > index 0000000000..3319cad3bc
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spMemoryRegionHob.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > +  Implements FspMemoryRegionHob.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#pragma pack(push,1)
> > +typedef struct {
> > +  EFI_PHYSICAL_ADDRESS    BeginAddress;
> > +  EFI_PHYSICAL_ADDRESS    Length;
> > +} FSP_MEMORY_REGION_HOB;
> > +#pragma pack(pop)
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spSmmDataExchangeBuffer.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spSmmDataExchangeBuffer.h
> > new file mode 100644
> > index 0000000000..1eaa187bb8
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spSmmDataExchangeBuffer.h
> > @@ -0,0 +1,24 @@
> > +/** @file
> > +  Implements FspSmmDataExchangeBuffer.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Protocol/GlobalNvsArea.h>
> > +#include <Protocol/Tcg2Protocol.h>
> > +#include <Protocol/TcgService.h>
> > +#include <Protocol/Variable.h>
> > +
> > +// You may define a customized callback function whenever the exchange
> > buffer is updated.
> > +
> > +typedef EFI_STATUS (EFIAPI
> > *DETECT_AND_INSTALL_NEW_PROTOCOL)(VOID);
> > +
> > +#pragma pack(push,1)
> > +typedef struct _FSP_SMM_DATA_EXCHANGE_BUFFER {
> > +  EFI_GLOBAL_NVS_AREA_PROTOCOL    *NvsAreaProtocol;               //
> > gEfiGlobalNvsAreaProtocolGuid
> > +  EFI_TCG2_PROTOCOL               *EfiTcg2Protocol;               //
> > gEfiTcg2ProtocolGuid
> > +} FSP_SMM_DATA_EXCHANGE_BUFFER;
> > +#pragma pack(pop)
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spUpd.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spUpd.h
> > new file mode 100644
> > index 0000000000..a4827a0068
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spUpd.h
> > @@ -0,0 +1,23 @@
> > +/** @file
> > +  Implements FspUpd.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSPUPD_H____
> > +#define FSPUPD_H____
> > +
> > +#ifdef USE_EDKII_HEADER_FILE
> > +  #include <FspEas.h>
> > +  #include <stdint.h>
> > +#else
> > +  #include <fsp_h_c99.h>
> > +#endif
> > +
> > +#define FSPM_UPD_SIGNATURE  0x4D5F48474F474E56                     /*
> > 'VNGOGH_M' */
> > +
> > +#define FSPS_UPD_SIGNATURE  0x535F48474F474E56                     /*
> > 'VNGOGH_S' */
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spmUpd.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spmUpd.h
> > new file mode 100644
> > index 0000000000..ed9a6c79a3
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spmUpd.h
> > @@ -0,0 +1,66 @@
> > +/** @file
> > +  Implements FspmUpd.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSPMUPD_H____
> > +#define FSPMUPD_H____
> > +
> > +#include <FspUpd.h>
> > +
> > +#pragma pack(1)
> > +
> > +/** Fsp M Configuration
> > +**/
> > +typedef struct {
> > +  /** Offset 0x0040**/ UINT32    bert_size;
> > +  /** Offset 0x0044**/ UINT32    tseg_size;
> > +  /** Offset 0x0048**/ UINT32    dxio_descriptor_table_pointer;
> > +  /** Offset 0x004C**/ UINT32    pcie_reset_function_pointer;
> > +  /** Offset 0x0050**/ UINT32    ddi_descriptor_table_pointer;
> > +  /** Offset 0x0054**/ UINT32    temp_memory_base_addr;
> > +  /** Offset 0x0058**/ UINT32    temp_memory_size;
> > +  /** Offset 0x005C**/ UINT32    fsp_o_pei_volume_address;
> > +  /** Offset 0x0060**/ UINT32    fsp_o_pei_upd_address;
> > +  /** Offset 0x0064**/ UINT32    pei_reset_ppi_addr;
> > +  /** Offset 0x0068**/ UINT32    resource_size_for_each_rb_ptr;
> > +  /** Offset 0x006C**/ UINT32    resource_size_for_each_rb_size;
> > +  /** Offset 0x0070**/ UINT32    total_number_of_root_bridges_ptr;
> > +  /** Offset 0x0074**/ UINT32    total_number_of_root_bridges_size;
> > +  /** Offset 0x0078**/ UINT32    amd_pbs_setup_ptr;
> > +  /** Offset 0x007C**/ UINT32    amd_pbs_setup_size;
> > +  /** Offset 0x0080**/ UINT32    ap_sync_flag_nv_ptr;
> > +  /** Offset 0x0084**/ UINT32    ap_sync_flag_nv_size;
> > +  /** Offset 0x0088**/ UINT8     DbgFchUsbUsb0DrdMode;
> > +  /** Offset 0x0089**/ UINT8     DbgFchUsbUsb2DrdMode;
> > +  /** Offset 0x008A**/ UINT32    CmnGnbGfxUmaFrameBufferSize;
> > +  /** Offset 0x008E**/ UINT8     CmnGnbNbIOMMU;
> > +  /** Offset 0x008F**/ UINT32    DbgFastPPTLimit;
> > +  /** Offset 0x0093**/ UINT32    DbgSlowPPTLimit;
> > +  /** Offset 0x0097**/ UINT32    CmnCpuVoltageOffset;
> > +  /** Offset 0x009B**/ UINT32    CmnGpuVoltageOffset;
> > +  /** Offset 0x009F**/ UINT32    CmnSocVoltageOffset;
> > +  /** Offset 0x00A3**/ UINT8     CmnGnbGfxUmaMode;
> > +  /** Offset 0x00A4**/ UINT8     CmnFchI2C0Config;
> > +  /** Offset 0x00A5**/ UINT8     CmnFchI2C1Config;
> > +  /** Offset 0x00A6**/ UINT8     CmnFchI2C2Config;
> > +  /** Offset 0x00A7**/ UINT8     CmnFchI2C3Config;
> > +  /** Offset 0x00A8**/ UINT32    ids_nv_table_address;
> > +  /** Offset 0x00AC**/ UINT32    ids_nv_table_size;
> > +  /** Offset 0x00B0**/ UINT16    UpdTerminator;
> > +} FSP_M_CONFIG;
> > +
> > +/** Fsp M UPD Configuration
> > +**/
> > +typedef struct {
> > +  /** Offset 0x0000**/ FSP_UPD_HEADER    FspUpdHeader;
> > +  /** Offset 0x0020**/ FSPM_ARCH_UPD     FspmArchUpd;
> > +  /** Offset 0x0040**/ FSP_M_CONFIG      FspmConfig;
> > +} FSPM_UPD;
> > +
> > +#pragma pack()
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spsUpd.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spsUpd.h
> > new file mode 100644
> > index 0000000000..c1fb89c63d
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > spsUpd.h
> > @@ -0,0 +1,45 @@
> > +/** @file
> > +  Implements FspsUpd.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSPSUPD_H____
> > +#define FSPSUPD_H____
> > +
> > +#include <FspUpd.h>
> > +
> > +#pragma pack(1)
> > +
> > +typedef struct {
> > +  /** Offset 0x0030**/ UINT32    page_address_below_1mb;
> > +  /** Offset 0x0034**/ UINT32    smram_hob_base_addr;
> > +  /** Offset 0x0038**/ UINT32    smram_hob_size;
> > +  /** Offset 0x003C**/ UINT32    nv_storage_variable_base;
> > +  /** Offset 0x0040**/ UINT32    nv_storage_variable_size;
> > +  /** Offset 0x0044**/ UINT32    nv_storage_ftw_working_base;
> > +  /** Offset 0x0048**/ UINT32    nv_storage_ftw_working_size;
> > +  /** Offset 0x004C**/ UINT32    nv_storage_ftw_spare_base;
> > +  /** Offset 0x0050**/ UINT32    nv_storage_ftw_spare_size;
> > +  /** Offset 0x0054**/ UINT32    dgpu_ssid;
> > +  /** Offset 0x0058**/ UINT32    dgpu_audio_ssid;
> > +  /** Offset 0x005C**/ UINT32    smram_hob_descriptor_base_addr;
> > +  /** Offset 0x0060**/ UINT32    smram_hob_descriptor_size;
> > +  /** Offset 0x0064**/ UINT64    smm_data_buffer_address;
> > +  /** Offset 0x006C**/ UINT32    fsp_o_dxe_volume_address;
> > +  /** Offset 0x0070**/ UINT32    fsp_o_dxe_upd_address;
> > +  /** Offset 0x0074**/ UINT16    UpdTerminator;
> > +} FSP_S_CONFIG;
> > +
> > +/** Fsp S UPD Configuration
> > +**/
> > +typedef struct {
> > +  /** Offset 0x0000**/ FSP_UPD_HEADER    FspUpdHeader;
> > +  /** Offset 0x0030**/ FSP_S_CONFIG      FspsConfig;
> > +} FSPS_UPD;
> > +
> > +#pragma pack()
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > sptUpd.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > sptUpd.h
> > new file mode 100644
> > index 0000000000..604efefa7d
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/F
> > sptUpd.h
> > @@ -0,0 +1,18 @@
> > +/** @file
> > +  Implements FsptUpd.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSPTUPD_H____
> > +#define FSPTUPD_H____
> > +
> > +#include <FspUpd.h>
> > +
> > +#pragma pack(1)
> > +
> > +#pragma pack()
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspMeasurementLib.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspMeasurementLib.h
> > new file mode 100644
> > index 0000000000..7172544b8a
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspMeasurementLib.h
> > @@ -0,0 +1,41 @@
> > +/** @file
> > +  This library is used by FSP modules to measure data to TPM.
> > +
> > +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_MEASUREMENT_LIB_H__
> > +#define FSP_MEASUREMENT_LIB_H__
> > +
> > +#define FSP_MEASURE_FSP     BIT0
> > +#define FSP_MEASURE_FSPT    BIT1
> > +#define FSP_MEASURE_FSPM    BIT2
> > +#define FSP_MEASURE_FSPS    BIT3
> > +#define FSP_MEASURE_FSPUPD  BIT31
> > +
> > +/**
> > +  Measure a FSP FirmwareBlob.
> > +
> > +  @param[in]  PcrIndex                PCR Index.
> > +  @param[in]  Description             Description for this FirmwareBlob.
> > +  @param[in]  FirmwareBlobBase        Base address of this FirmwareBlob.
> > +  @param[in]  FirmwareBlobLength      Size in bytes of this FirmwareBlob.
> > +
> > +  @retval EFI_SUCCESS           Operation completed successfully.
> > +  @retval EFI_UNSUPPORTED       TPM device not available.
> > +  @retval EFI_OUT_OF_RESOURCES  Out of memory.
> > +  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
> > +*/
> > +EFI_STATUS
> > +EFIAPI
> > +MeasureFspFirmwareBlob (
> > +  IN UINT32                PcrIndex,
> > +  IN CHAR8                 *Description OPTIONAL,
> > +  IN EFI_PHYSICAL_ADDRESS  FirmwareBlobBase,
> > +  IN UINT64                FirmwareBlobLength
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperApiLib.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperApiLib.h
> > new file mode 100644
> > index 0000000000..073c6e1d0e
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperApiLib.h
> > @@ -0,0 +1,82 @@
> > +/** @file
> > +  Provide FSP wrapper API related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_WRAPPER_API_LIB_H____
> > +#define FSP_WRAPPER_API_LIB_H____
> > +
> > +#include <FspEas.h>
> > +
> > +/**
> > +  Find FSP header pointer.
> > +
> > +  @param[in] FlashFvFspBase Flash address of FSP FV.
> > +
> > +  @return FSP header pointer.
> > +**/
> > +FSP_INFO_HEADER *
> > +EFIAPI
> > +FspFindFspHeader (
> > +  IN EFI_PHYSICAL_ADDRESS  FlashFvFspBase
> > +  );
> > +
> > +/**
> > +  Call FSP API - FspNotifyPhase.
> > +
> > +  @param[in] NotifyPhaseParams Address pointer to the
> > NOTIFY_PHASE_PARAMS structure.
> > +
> > +  @return EFI status returned by FspNotifyPhase API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspNotifyPhase (
> > +  IN NOTIFY_PHASE_PARAMS  *NotifyPhaseParams
> > +  );
> > +
> > +/**
> > +  Call FSP API - FspMemoryInit.
> > +
> > +  @param[in]  FspmUpdDataPtr          Pointer to the FSPM_UPD data
> > structure.
> > +  @param[out] HobListPtr              Pointer to receive the address of the HOB
> > list.
> > +
> > +  @return EFI status returned by FspMemoryInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspMemoryInit (
> > +  IN VOID   *FspmUpdDataPtr,
> > +  OUT VOID  **HobListPtr
> > +  );
> > +
> > +/**
> > +  Call FSP API - TempRamExit.
> > +
> > +  @param[in] TempRamExitParam    Address pointer to the TempRamExit
> > parameters structure.
> > +
> > +  @return EFI status returned by TempRamExit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallTempRamExit (
> > +  IN VOID  *TempRamExitParam
> > +  );
> > +
> > +/**
> > +  Call FSP API - FspSiliconInit.
> > +
> > +  @param[in] FspsUpdDataPtr     Pointer to the FSPS_UPD data structure.
> > +
> > +  @return EFI status returned by FspSiliconInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspSiliconInit (
> > +  IN VOID  *FspsUpdDataPtr
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperApiTestLib.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperApiTestLib.h
> > new file mode 100644
> > index 0000000000..c4e785e41e
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperApiTestLib.h
> > @@ -0,0 +1,56 @@
> > +/** @file
> > +  Provide FSP wrapper API test related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_WRAPPER_API_TEST_LIB_H____
> > +#define FSP_WRAPPER_API_TEST_LIB_H____
> > +
> > +#include <PiPei.h>
> > +
> > +/**
> > +  Test the output of FSP API - FspMemoryInit.
> > +
> > +  @param[in]  FspmUpdDataPtr Address pointer to the
> > FSP_MEMORY_INIT_PARAMS structure.
> > +  @param[in]  HobListPtr     Address of the HobList pointer.
> > +
> > +  @return test result on output of FspMemoryInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspMemoryInitApiOutput (
> > +  IN  VOID  *FspmUpdDataPtr,
> > +  IN  VOID  **HobListPtr
> > +  );
> > +
> > +/**
> > +  Test the output of FSP API - TempRamExit.
> > +
> > +  @param[in] TempRamExitParam    Address pointer to the TempRamExit
> > parameters structure.
> > +
> > +  @return test result on output of TempRamExit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspTempRamExitApiOutput (
> > +  IN VOID  *TempRamExitParam
> > +  );
> > +
> > +/**
> > +  Test the output of FSP API - FspSiliconInit.
> > +
> > +  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init
> parameters
> > structure.
> > +
> > +  @return test result on output of FspSiliconInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspSiliconInitApiOutput (
> > +  IN  VOID  *FspsUpdDataPtr
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperHobProcessLib.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperHobProcessLib.h
> > new file mode 100644
> > index 0000000000..8c0c244e43
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperHobProcessLib.h
> > @@ -0,0 +1,39 @@
> > +/** @file
> > +  Provide FSP wrapper hob process related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_WRAPPER_HOB_PROCESS_LIB_H____
> > +#define FSP_WRAPPER_HOB_PROCESS_LIB_H____
> > +
> > +/**
> > +  Post FSP-M HOB process for Memory Resource Descriptor.
> > +
> > +  @param[in] FspHobList  Pointer to the HOB data structure produced by
> FSP.
> > +
> > +  @return If platform process the FSP hob list successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PostFspmHobProcess (
> > +  IN VOID  *FspHobList
> > +  );
> > +
> > +/**
> > +  Post FSP-S HOB process (not Memory Resource Descriptor).
> > +
> > +  @param[in] FspHobList  Pointer to the HOB data structure produced by
> FSP.
> > +
> > +  @return If platform process the FSP hob list successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PostFspsHobProcess (
> > +  IN VOID  *FspHobList
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperMultiPhaseProcessLib.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperMultiPhaseProcessLib.h
> > new file mode 100644
> > index 0000000000..89cff5ea4a
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperMultiPhaseProcessLib.h
> > @@ -0,0 +1,45 @@
> > +/** @file
> > +  Provide FSP wrapper MultiPhase handling functions.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_WRAPPER_MULTI_PHASE_PROCESS_LIB_H____
> > +#define FSP_WRAPPER_MULTI_PHASE_PROCESS_LIB_H____
> > +
> > +/**
> > +  FSP Wrapper Variable Request Handler
> > +
> > +  @param[in] FspHobListPtr        - Pointer to FSP HobList (valid after FSP-M
> > completed)
> > +  @param[in] ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +
> > +  @retval EFI_UNSUPPORTED   FSP Wrapper cannot support the specific
> > variable request
> > +  @retval EFI_STATUS        Return FSP returned status
> > +
> > +**/EFI_STATUS
> > +EFIAPI
> > +FspWrapperVariableRequestHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  );
> > +
> > +/**
> > +  FSP Wrapper MultiPhase Handler
> > +
> > +  @param[in] FspHobListPtr        - Pointer to FSP HobList (valid after FSP-M
> > completed)
> > +  @param[in] ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspWrapperMultiPhaseHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperPlatformLib.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperPlatformLib.h
> > new file mode 100644
> > index 0000000000..529bc31145
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperPlatformLib.h
> > @@ -0,0 +1,81 @@
> > +/** @file
> > +  Provide FSP wrapper platform related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_WRAPPER_PLATFORM_LIB_H____
> > +#define FSP_WRAPPER_PLATFORM_LIB_H____
> > +
> > +/**
> > +  This function overrides the default configurations in the FSP-M UPD data
> > region.
> > +
> > +  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data
> > structure.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UpdateFspmUpdData (
> > +  IN OUT VOID  *FspUpdRgnPtr
> > +  );
> > +
> > +/**
> > +  This function overrides the default configurations in the FSP-S UPD data
> > region.
> > +
> > +  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data
> > structure.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UpdateFspsUpdData (
> > +  IN OUT VOID  *FspUpdRgnPtr
> > +  );
> > +
> > +/**
> > +  Update TempRamExit parameter.
> > +
> > +  @note At this point, memory is ready, PeiServices are available to use.
> > +
> > +  @return TempRamExit parameter.
> > +**/
> > +VOID *
> > +EFIAPI
> > +UpdateTempRamExitParam (
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Get S3 PEI memory information.
> > +
> > +  @note At this point, memory is ready, and PeiServices are available to use.
> > +  Platform can get some data from SMRAM directly.
> > +
> > +  @param[out] S3PeiMemSize  PEI memory size to be installed in S3 phase.
> > +  @param[out] S3PeiMemBase  PEI memory base to be installed in S3
> phase.
> > +
> > +  @return If S3 PEI memory information is got successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetS3MemoryInfo (
> > +  OUT UINT64                *S3PeiMemSize,
> > +  OUT EFI_PHYSICAL_ADDRESS  *S3PeiMemBase
> > +  );
> > +
> > +/**
> > +  Perform platform related reset in FSP wrapper.
> > +
> > +  This function will reset the system with requested ResetType.
> > +
> > +  @param[in] FspStatusResetType  The type of reset the platform has to
> > perform.
> > +**/
> > +VOID
> > +EFIAPI
> > +CallFspWrapperResetSystem (
> > +  IN EFI_STATUS  FspStatusResetType
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperPlatformMultiPhaseLib.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperPlatformMultiPhaseLib.h
> > new file mode 100644
> > index 0000000000..8e16ddb719
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Li
> > brary/FspWrapperPlatformMultiPhaseLib.h
> > @@ -0,0 +1,31 @@
> > +/** @file
> > +  Provide FSP wrapper Platform MultiPhase handling functions.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_WRAPPER_PLATFORM_MULTI_PHASE_LIB_H_
> > +#define FSP_WRAPPER_PLATFORM_MULTI_PHASE_LIB_H_
> > +
> > +/**
> > +  FSP Wrapper Platform MultiPhase Handler
> > +
> > +  @param[in] FspHobListPtr        - Pointer to FSP HobList (valid after FSP-M
> > completed)
> > +  @param[in] ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +  @param[in] PhaseIndex           - Indicates current execution phase of FSP
> > MultiPhase initialization.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +FspWrapperPlatformMultiPhaseHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex,
> > +  IN UINT32    PhaseIndex
> > +  );
> > +
> > +#endif //FSP_WRAPPER_PLATFORM_MULTI_PHASE_LIB_H_
> > diff --git
> > a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/
> > MultiPhaseSiPhases.h
> > b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/
> > MultiPhaseSiPhases.h
> > new file mode 100644
> > index 0000000000..9be1b17b29
> > --- /dev/null
> > +++
> > b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/
> > MultiPhaseSiPhases.h
> > @@ -0,0 +1,19 @@
> > +/** @file
> > +  Implements MultiPhaseSiPhases.h
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef MULTI_PHASE_SI_PHASES_H__
> > +#define MULTI_PHASE_SI_PHASES_H__
> > +
> > +typedef enum {
> > +  EnumMultiPhaseAmdCpmDxeTableReadyPhase = 1,  // In FSP Doc, the
> index
> > starts from 1.
> > +  EnumMultiPhaseAmdSmmCoreBroughtUpPhase,
> > +  EnumMultiPhaseAmdRuntimeServicesReadyPhase,
> > +  // ......
> > +  EnumMultiPhaseAmdMaxPhase
> > +} AMD_MULTI_PHASE_SI_PHASES_H;
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/P
> > pi/FspSiliconInitDone.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/P
> > pi/FspSiliconInitDone.h
> > new file mode 100644
> > index 0000000000..23d46ea1f1
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/P
> > pi/FspSiliconInitDone.h
> > @@ -0,0 +1,38 @@
> > +/** @file
> > +  Provides the services to return FSP hob list.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_SILICON_INIT_DONE_H__
> > +#define FSP_SILICON_INIT_DONE_H__
> > +
> > +typedef struct _FSP_SILICON_INIT_DONE_PPI
> FSP_SILICON_INIT_DONE_PPI;
> > +
> > +/**
> > +  Return Hob list produced by FSP.
> > +
> > +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> > +  @param[in]  This         The pointer to this instance of this PPI.
> > +  @param[out] FspHobList   The pointer to Hob list produced by FSP.
> > +
> > +  @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST)(
> > +  IN  CONST EFI_PEI_SERVICES         **PeiServices,
> > +  IN  FSP_SILICON_INIT_DONE_PPI      *This,
> > +  OUT VOID                           **FspHobList
> > +  );
> > +
> > +struct _FSP_SILICON_INIT_DONE_PPI {
> > +  FSP_SILICON_INIT_DONE_GET_FSP_HOB_LIST    GetFspHobList;
> > +};
> > +
> > +extern EFI_GUID  gFspSiliconInitDonePpiGuid;
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/P
> > pi/TopOfTemporaryRam.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/P
> > pi/TopOfTemporaryRam.h
> > new file mode 100644
> > index 0000000000..7bb32290cb
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/P
> > pi/TopOfTemporaryRam.h
> > @@ -0,0 +1,15 @@
> > +/** @file
> > +  Provides the pointer to top of temporary ram.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef TOP_OF_TEMPORARY_RAM_H__
> > +#define TOP_OF_TEMPORARY_RAM_H__
> > +
> > +extern EFI_GUID  gTopOfTemporaryRamPpiGuid;
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspMeasurementLib/BaseFspMeasurementLib.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspMeasurementLib/BaseFspMeasurementLib.inf
> > new file mode 100644
> > index 0000000000..48eb4991dd
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspMeasurementLib/BaseFspMeasurementLib.inf
> > @@ -0,0 +1,54 @@
> > +## @file
> > +#  Provides FSP measurement functions.
> > +#
> > +#  This library provides MeasureFspFirmwareBlob() to measure FSP binary.
> > +#
> > +# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = FspMeasurementLib
> > +  FILE_GUID                      = 890B12B4-56CC-453E-B062-4597FC6D3D8C
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FspMeasurementLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources]
> > +  FspMeasurementLib.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  SecurityPkg/SecurityPkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  BaseMemoryLib
> > +  DebugLib
> > +  PrintLib
> > +  PcdLib
> > +  PeiServicesLib
> > +  PeiServicesTablePointerLib
> > +  FspWrapperApiLib
> > +  TcgEventLogRecordLib
> > +  HashLib
> > +
> > +[Ppis]
> > +  gEdkiiTcgPpiGuid                                                   ## CONSUMES
> > +
> > +[Pcd]
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspMeasurementConfig            ##
> > CONSUMES
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInMemory
> ##
> > CONSUMES
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision
> ##
> > CONSUMES
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspMeasurementLib/FspMeasurementLib.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspMeasurementLib/FspMeasurementLib.c
> > new file mode 100644
> > index 0000000000..9a9368bb75
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspMeasurementLib/FspMeasurementLib.c
> > @@ -0,0 +1,254 @@
> > +/** @file
> > +  This library is used by FSP modules to measure data to TPM.
> > +
> > +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +Copyright (c) 2020, Intel Corporation. All rights reserved. <BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +#include <Uefi.h>
> > +
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/PeiServicesTablePointerLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/PrintLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/TpmMeasurementLib.h>
> > +#include <Library/FspMeasurementLib.h>
> > +#include <Library/TcgEventLogRecordLib.h>
> > +#include <Library/HashLib.h>
> > +
> > +#include <Ppi/Tcg.h>
> > +#include <IndustryStandard/UefiTcgPlatform.h>
> > +
> > +/**
> > +  Tpm measure and log data, and extend the measurement result into a
> > specific PCR.
> > +
> > +  @param[in]  PcrIndex         PCR Index.
> > +  @param[in]  EventType        Event type.
> > +  @param[in]  EventLog         Measurement event log.
> > +  @param[in]  LogLen           Event log length in bytes.
> > +  @param[in]  HashData         The start of the data buffer to be hashed,
> > extended.
> > +  @param[in]  HashDataLen      The length, in bytes, of the buffer referenced
> > by HashData
> > +  @param[in]  Flags            Bitmap providing additional information.
> > +
> > +  @retval EFI_SUCCESS           Operation completed successfully.
> > +  @retval EFI_UNSUPPORTED       TPM device not available.
> > +  @retval EFI_OUT_OF_RESOURCES  Out of memory.
> > +  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TpmMeasureAndLogDataWithFlags (
> > +  IN UINT32  PcrIndex,
> > +  IN UINT32  EventType,
> > +  IN VOID    *EventLog,
> > +  IN UINT32  LogLen,
> > +  IN VOID    *HashData,
> > +  IN UINT64  HashDataLen,
> > +  IN UINT64  Flags
> > +  )
> > +{
> > +  EFI_STATUS         Status;
> > +  EDKII_TCG_PPI      *TcgPpi;
> > +  TCG_PCR_EVENT_HDR  TcgEventHdr;
> > +
> > +  Status = PeiServicesLocatePpi (
> > +             &gEdkiiTcgPpiGuid,
> > +             0,
> > +             NULL,
> > +             (VOID **)&TcgPpi
> > +             );
> > +  if (EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  TcgEventHdr.PCRIndex  = PcrIndex;
> > +  TcgEventHdr.EventType = EventType;
> > +  TcgEventHdr.EventSize = LogLen;
> > +
> > +  Status = TcgPpi->HashLogExtendEvent (
> > +                     TcgPpi,
> > +                     Flags,
> > +                     HashData,
> > +                     (UINTN)HashDataLen,
> > +                     &TcgEventHdr,
> > +                     EventLog
> > +                     );
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Measure a FSP FirmwareBlob.
> > +
> > +  @param[in]  Description             Description for this FirmwareBlob.
> > +  @param[in]  FirmwareBlobBase        Base address of this FirmwareBlob.
> > +  @param[in]  FirmwareBlobLength      Size in bytes of this FirmwareBlob.
> > +  @param[in]  CfgRegionOffset         Configuration region offset in bytes.
> > +  @param[in]  CfgRegionSize           Configuration region in bytes.
> > +
> > +  @retval EFI_SUCCESS           Operation completed successfully.
> > +  @retval EFI_UNSUPPORTED       TPM device not available.
> > +  @retval EFI_OUT_OF_RESOURCES  Out of memory.
> > +  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +MeasureFspFirmwareBlobWithCfg (
> > +  IN CHAR8                 *Description OPTIONAL,
> > +  IN EFI_PHYSICAL_ADDRESS  FirmwareBlobBase,
> > +  IN UINT64                FirmwareBlobLength,
> > +  IN UINT32                CfgRegionOffset,
> > +  IN UINT32                CfgRegionSize
> > +  )
> > +{
> > +  EFI_PLATFORM_FIRMWARE_BLOB      FvBlob, UpdBlob;
> > +  PLATFORM_FIRMWARE_BLOB2_STRUCT  FvBlob2, UpdBlob2;
> > +  VOID                            *FvName;
> > +  UINT32                          FvEventType;
> > +  VOID                            *FvEventLog, *UpdEventLog;
> > +  UINT32                          FvEventLogSize, UpdEventLogSize;
> > +  EFI_STATUS                      Status;
> > +  HASH_HANDLE                     HashHandle;
> > +  UINT8                           *HashBase;
> > +  UINTN                           HashSize;
> > +  TPML_DIGEST_VALUES              DigestList;
> > +
> > +  FvName = TpmMeasurementGetFvName (FirmwareBlobBase,
> > FirmwareBlobLength);
> > +
> > +  if (((Description != NULL) || (FvName != NULL)) &&
> > +      (PcdGet32 (PcdTcgPfpMeasurementRevision) >=
> > TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105))
> > +  {
> > +    if (Description != NULL) {
> > +      AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof
> > (FvBlob2.BlobDescription), "%a", Description);
> > +      AsciiSPrint ((CHAR8 *)UpdBlob2.BlobDescription, sizeof
> > (UpdBlob2.BlobDescription), "%aUDP", Description);
> > +    } else {
> > +      AsciiSPrint ((CHAR8 *)FvBlob2.BlobDescription, sizeof
> > (FvBlob2.BlobDescription), "Fv(%g)", FvName);
> > +      AsciiSPrint ((CHAR8 *)UpdBlob2.BlobDescription, sizeof
> > (UpdBlob2.BlobDescription), "(%g)UDP", FvName);
> > +    }
> > +
> > +    FvBlob2.BlobDescriptionSize = sizeof (FvBlob2.BlobDescription);
> > +    FvBlob2.BlobBase            = FirmwareBlobBase;
> > +    FvBlob2.BlobLength          = FirmwareBlobLength;
> > +    FvEventType                 = EV_EFI_PLATFORM_FIRMWARE_BLOB2;
> > +    FvEventLog                  = &FvBlob2;
> > +    FvEventLogSize              = sizeof (FvBlob2);
> > +
> > +    UpdBlob2.BlobDescriptionSize = sizeof (UpdBlob2.BlobDescription);
> > +    UpdBlob2.BlobBase            = CfgRegionOffset;
> > +    UpdBlob2.BlobLength          = CfgRegionSize;
> > +    UpdEventLog                  = &UpdBlob2;
> > +    UpdEventLogSize              = sizeof (UpdBlob2);
> > +  } else {
> > +    FvBlob.BlobBase   = FirmwareBlobBase;
> > +    FvBlob.BlobLength = FirmwareBlobLength;
> > +    FvEventType       = EV_EFI_PLATFORM_FIRMWARE_BLOB;
> > +    FvEventLog        = &FvBlob;
> > +    FvEventLogSize    = sizeof (FvBlob);
> > +
> > +    UpdBlob.BlobBase   = CfgRegionOffset;
> > +    UpdBlob.BlobLength = CfgRegionSize;
> > +    UpdEventLog        = &UpdBlob;
> > +    UpdEventLogSize    = sizeof (UpdBlob);
> > +  }
> > +
> > +  /** Initialize a SHA hash context. **/
> > +  Status = HashStart (&HashHandle);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "HashStart failed - %r\n", Status));
> > +    return Status;
> > +  }
> > +
> > +  /** Hash FSP binary before UDP **/
> > +  HashBase = (UINT8 *)(UINTN)FirmwareBlobBase;
> > +  HashSize = (UINTN)CfgRegionOffset;
> > +  Status   = HashUpdate (HashHandle, HashBase, HashSize);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
> > +    return Status;
> > +  }
> > +
> > +  /** Hash FSP binary after UDP **/
> > +  HashBase = (UINT8 *)(UINTN)FirmwareBlobBase + CfgRegionOffset +
> > CfgRegionSize;
> > +  HashSize = (UINTN)(FirmwareBlobLength - CfgRegionOffset -
> > CfgRegionSize);
> > +  Status   = HashUpdate (HashHandle, HashBase, HashSize);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "HashUpdate failed - %r\n", Status));
> > +    return Status;
> > +  }
> > +
> > +  /** Finalize the SHA hash. **/
> > +  Status = HashCompleteAndExtend (HashHandle, 0, NULL, 0, &DigestList);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_ERROR, "HashCompleteAndExtend failed - %r\n",
> > Status));
> > +    return Status;
> > +  }
> > +
> > +  Status = TpmMeasureAndLogDataWithFlags (
> > +             0,
> > +             FvEventType,
> > +             FvEventLog,
> > +             FvEventLogSize,
> > +             (UINT8 *)&DigestList,
> > +             (UINTN)sizeof (DigestList),
> > +             EDKII_TCG_PRE_HASH_LOG_ONLY
> > +             );
> > +
> > +  Status = TpmMeasureAndLogData (
> > +             1,
> > +             EV_PLATFORM_CONFIG_FLAGS,
> > +             UpdEventLog,
> > +             UpdEventLogSize,
> > +             (UINT8 *)(UINTN)FirmwareBlobBase + CfgRegionOffset,
> > +             CfgRegionSize
> > +             );
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Measure a FSP FirmwareBlob.
> > +
> > +  @param[in]  PcrIndex                PCR Index.
> > +  @param[in]  Description             Description for this FirmwareBlob.
> > +  @param[in]  FirmwareBlobBase        Base address of this FirmwareBlob.
> > +  @param[in]  FirmwareBlobLength      Size in bytes of this FirmwareBlob.
> > +
> > +  @retval EFI_SUCCESS           Operation completed successfully.
> > +  @retval EFI_UNSUPPORTED       TPM device not available.
> > +  @retval EFI_OUT_OF_RESOURCES  Out of memory.
> > +  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +MeasureFspFirmwareBlob (
> > +  IN UINT32                PcrIndex,
> > +  IN CHAR8                 *Description OPTIONAL,
> > +  IN EFI_PHYSICAL_ADDRESS  FirmwareBlobBase,
> > +  IN UINT64                FirmwareBlobLength
> > +  )
> > +{
> > +  UINT32           FspMeasureMask;
> > +  FSP_INFO_HEADER  *FspHeaderPtr;
> > +
> > +  FspMeasureMask = PcdGet32 (PcdFspMeasurementConfig);
> > +  if ((FspMeasureMask & FSP_MEASURE_FSPUPD) != 0) {
> > +    FspHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader
> > (FirmwareBlobBase);
> > +    if (FspHeaderPtr != NULL) {
> > +      return MeasureFspFirmwareBlobWithCfg (
> > +               Description,
> > +               FirmwareBlobBase,
> > +               FirmwareBlobLength,
> > +               FspHeaderPtr->CfgRegionOffset,
> > +               FspHeaderPtr->CfgRegionSize
> > +               );
> > +    }
> > +  }
> > +
> > +  return MeasureFirmwareBlob (PcrIndex, Description, FirmwareBlobBase,
> > FirmwareBlobLength);
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/BaseFspWrapperApiLib.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/BaseFspWrapperApiLib.inf
> > new file mode 100644
> > index 0000000000..e41d17d67c
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/BaseFspWrapperApiLib.inf
> > @@ -0,0 +1,73 @@
> > +## @file
> > +#  FSP API related function INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
>
> Please put AMD copy right under Intel's.
>
>
>
> > +
> > +## @file
> > +#  Provide FSP API related function.
> > +#
> > +#  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Defines Section - statements that will be processed to create a Makefile.
> > +#
> >
> +##################################################################
> > ##############
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = BaseFspWrapperApiLib
> > +  FILE_GUID                      = F42C789F-4D66-49AF-8C73-1AADC00437AC
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FspWrapperApiLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Sources Section - list of files that are required for the build to succeed.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Sources]
> > +  FspWrapperApiLib.c
> > +
> > +[Sources.IA32]
> > +  IA32/DispatchExecute.c
> > +
> > +[Sources.X64]
> > +  X64/DispatchExecute.c
> > +  X64/Thunk64To32.nasm
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Package Dependency Section - list of Package files that are required for
> > +#                              this module.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  DebugLib
> > +[Guids]
> > +  gFspHeaderFileGuid            ## CONSUMES ## GUID
> > +
> > +[Pcd]
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInMemory ##
> > CONSUMES
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInMemory ##
> > CONSUMES
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/FspWrapperApiLib.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/FspWrapperApiLib.c
> > new file mode 100644
> > index 0000000000..80d64f9bd2
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/FspWrapperApiLib.c
> > @@ -0,0 +1,235 @@
> > +/** @file
> > +  Provide FSP API related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +
> > +/**
> > +  Wrapper for a thunk to transition from long mode to compatibility mode
> to
> > execute 32-bit code and then transit back to
> > +  long mode.
> > +
> > +  @param[in] Function     The 32bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 32bit code.
> > +  @param[in] Param2       The second parameter to pass to 32bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute32BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  );
> > +
> > +/**
> > +  Wrapper to execute 64-bit code directly from long mode.
> > +
> > +  @param[in] Function     The 64bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 64bit code.
> > +  @param[in] Param2       The second parameter to pass to 64bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute64BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  );
> > +
> > +/**
> > +  Find FSP header pointer.
> > +
> > +  @param[in] FlashFvFspBase Flash address of FSP FV.
> > +
> > +  @return FSP header pointer.
> > +**/
> > +FSP_INFO_HEADER *
> > +EFIAPI
> > +FspFindFspHeader (
> > +  IN EFI_PHYSICAL_ADDRESS  FlashFvFspBase
> > +  )
> > +{
> > +  UINT8  *CheckPointer;
> > +
> > +  CheckPointer = (UINT8 *)(UINTN)FlashFvFspBase;
> > +
> > +  if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature !=
> > EFI_FVH_SIGNATURE) {
> > +    return NULL;
> > +  }
> > +
> > +  if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)-
> > >ExtHeaderOffset != 0) {
> > +    CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER
> > *)CheckPointer)->ExtHeaderOffset;
> > +    CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER
> > *)CheckPointer)->ExtHeaderSize;
> > +    CheckPointer = (UINT8 *)ALIGN_POINTER (CheckPointer, 8);
> > +  } else {
> > +    CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER
> > *)CheckPointer)->HeaderLength;
> > +  }
> > +
> > +  CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER);
> > +
> > +  if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) {
> > +    return NULL;
> > +  }
> > +
> > +  CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION);
> > +
> > +  return (FSP_INFO_HEADER *)CheckPointer;
> > +}
> > +
> > +/**
> > +  Call FSP API - FspNotifyPhase.
> > +
> > +  @param[in] NotifyPhaseParams Address pointer to the
> > NOTIFY_PHASE_PARAMS structure.
> > +
> > +  @return EFI status returned by FspNotifyPhase API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspNotifyPhase (
> > +  IN NOTIFY_PHASE_PARAMS  *NotifyPhaseParams
> > +  )
> > +{
> > +  FSP_INFO_HEADER   *FspHeader;
> > +  FSP_NOTIFY_PHASE  NotifyPhaseApi;
> > +  EFI_STATUS        Status;
> > +  BOOLEAN           InterruptState;
> > +
> > +  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspsBaseAddressInMemory));
> > +  if (FspHeader == NULL) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  NotifyPhaseApi = (FSP_NOTIFY_PHASE)((UINTN)FspHeader->ImageBase +
> > FspHeader->NotifyPhaseEntryOffset);
> > +  InterruptState = SaveAndDisableInterrupts ();
> > +  DEBUG ((DEBUG_ERROR, "Before FSP interrupt status:%llx\n",
> > (UINT64)InterruptState));
> > +  if ((FspHeader->ImageAttribute &
> > IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT) == FSP_IA32) {
> > +    Status = Execute32BitCode ((UINTN)NotifyPhaseApi,
> > (UINTN)NotifyPhaseParams, (UINTN)NULL);
> > +  } else {
> > +    Status = Execute64BitCode ((UINTN)NotifyPhaseApi,
> > (UINTN)NotifyPhaseParams, (UINTN)NULL);
> > +  }
> > +
> > +  SetInterruptState (InterruptState);
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Call FSP API - FspMemoryInit.
> > +
> > +  @param[in]  FspmUpdDataPtr Address pointer to the
> > FSP_MEMORY_INIT_PARAMS structure.
> > +  @param[out] HobListPtr     Address of the HobList pointer.
> > +
> > +  @return EFI status returned by FspMemoryInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspMemoryInit (
> > +  IN VOID   *FspmUpdDataPtr,
> > +  OUT VOID  **HobListPtr
> > +  )
> > +{
> > +  FSP_INFO_HEADER  *FspHeader;
> > +  FSP_MEMORY_INIT  FspMemoryInitApi;
> > +  EFI_STATUS       Status;
> > +  BOOLEAN          InterruptState;
> > +
> > +  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspmBaseAddressInMemory));
> > +  if (FspHeader == NULL) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  FspMemoryInitApi = (FSP_MEMORY_INIT)((UINTN)FspHeader-
> >ImageBase
> > + FspHeader->FspMemoryInitEntryOffset);
> > +  InterruptState   = SaveAndDisableInterrupts ();
> > +  if ((FspHeader->ImageAttribute &
> > IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT) == FSP_IA32) {
> > +    Status = Execute32BitCode ((UINTN)FspMemoryInitApi,
> > (UINTN)FspmUpdDataPtr, (UINTN)HobListPtr);
> > +  } else {
> > +    Status = Execute64BitCode ((UINTN)FspMemoryInitApi,
> > (UINTN)FspmUpdDataPtr, (UINTN)HobListPtr);
> > +  }
> > +
> > +  SetInterruptState (InterruptState);
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Call FSP API - TempRamExit.
> > +
> > +  @param[in] TempRamExitParam    Address pointer to the TempRamExit
> > parameters structure.
> > +
> > +  @return EFI status returned by TempRamExit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallTempRamExit (
> > +  IN VOID  *TempRamExitParam
> > +  )
> > +{
> > +  FSP_INFO_HEADER    *FspHeader;
> > +  FSP_TEMP_RAM_EXIT  TempRamExitApi;
> > +  EFI_STATUS         Status;
> > +  BOOLEAN            InterruptState;
> > +
> > +  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspmBaseAddressInMemory));
> > +  if (FspHeader == NULL) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  TempRamExitApi = (FSP_TEMP_RAM_EXIT)((UINTN)FspHeader-
> >ImageBase
> > + FspHeader->TempRamExitEntryOffset);
> > +  InterruptState = SaveAndDisableInterrupts ();
> > +  if ((FspHeader->ImageAttribute &
> > IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT) == FSP_IA32) {
> > +    Status = Execute32BitCode ((UINTN)TempRamExitApi,
> > (UINTN)TempRamExitParam, (UINTN)NULL);
> > +  } else {
> > +    Status = Execute64BitCode ((UINTN)TempRamExitApi,
> > (UINTN)TempRamExitParam, (UINTN)NULL);
> > +  }
> > +
> > +  SetInterruptState (InterruptState);
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Call FSP API - FspSiliconInit.
> > +
> > +  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init
> parameters
> > structure.
> > +
> > +  @return EFI status returned by FspSiliconInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspSiliconInit (
> > +  IN VOID  *FspsUpdDataPtr
> > +  )
> > +{
> > +  FSP_INFO_HEADER   *FspHeader;
> > +  FSP_SILICON_INIT  FspSiliconInitApi;
> > +  EFI_STATUS        Status;
> > +  BOOLEAN           InterruptState;
> > +
> > +  FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspsBaseAddressInMemory));
> > +  if (FspHeader == NULL) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  FspSiliconInitApi = (FSP_SILICON_INIT)((UINTN)FspHeader->ImageBase +
> > FspHeader->FspSiliconInitEntryOffset);
> > +  InterruptState    = SaveAndDisableInterrupts ();
> > +  if ((FspHeader->ImageAttribute &
> > IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT) == FSP_IA32) {
> > +    Status = Execute32BitCode ((UINTN)FspSiliconInitApi,
> > (UINTN)FspsUpdDataPtr, (UINTN)NULL);
> > +  } else {
> > +    Status = Execute64BitCode ((UINTN)FspSiliconInitApi,
> > (UINTN)FspsUpdDataPtr, (UINTN)NULL);
> > +  }
> > +
> > +  SetInterruptState (InterruptState);
> > +
> > +  return Status;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/IA32/DispatchExecute.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/IA32/DispatchExecute.c
> > new file mode 100644
> > index 0000000000..434eb549a4
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/IA32/DispatchExecute.c
> > @@ -0,0 +1,71 @@
> > +/** @file
> > +  Execute 32-bit code in Protected Mode.
> > +
> > +  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <FspEas.h>
> > +
> > +/**
> > +  FSP API functions.
> > +
> > +  @param[in] Param1       The first parameter to pass to 32bit code.
> > +  @param[in] Param2       The second parameter to pass to 32bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *FSP_FUNCTION)(
> > +  IN VOID *Param1,
> > +  IN VOID *Param2
> > +  );
> > +
> > +/**
> > +  Wrapper for a thunk to transition from long mode to compatibility mode
> to
> > execute 32-bit code and then transit back to
> > +  long mode.
> > +
> > +  @param[in] Function     The 32bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 32bit code.
> > +  @param[in] Param2       The second parameter to pass to 32bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute32BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  )
> > +{
> > +  FSP_FUNCTION  EntryFunc;
> > +  EFI_STATUS    Status;
> > +
> > +  EntryFunc = (FSP_FUNCTION)(UINTN)(Function);
> > +  Status    = EntryFunc ((VOID *)(UINTN)Param1, (VOID *)(UINTN)Param2);
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Wrapper for a thunk to transition from compatibility mode to long mode
> to
> > execute 64-bit code and then transit back to
> > +  compatibility mode.
> > +
> > +  @param[in] Function     The 64bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 64bit code.
> > +  @param[in] Param2       The second parameter to pass to 64bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute64BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  )
> > +{
> > +  return EFI_UNSUPPORTED;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/X64/DispatchExecute.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/X64/DispatchExecute.c
> > new file mode 100644
> > index 0000000000..3c34806286
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/X64/DispatchExecute.c
> > @@ -0,0 +1,167 @@
> > +/** @file
> > +  Execute 64-bit code in Long Mode.
> > +  Provide a thunk function to transition from long mode to compatibility
> > mode to execute 32-bit code and then transit
> > +  back to long mode.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseLib.h>
> > +#include <FspEas.h>
> > +#include <Library/DebugLib.h>
> > +
> > +UINT64
> > +ReadRsp (
> > +  VOID
> > +  );
> > +
> > +/**
> > +  FSP API functions.
> > +
> > +  @param[in] Param1       The first parameter to pass to 64bit code.
> > +  @param[in] Param2       The second parameter to pass to 64bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *FSP_FUNCTION)(
> > +  IN VOID *Param1,
> > +  IN VOID *Param2
> > +  );
> > +
> > +#pragma pack(1)
> > +typedef union {
> > +  struct {
> > +    UINT32    LimitLow    : 16;
> > +    UINT32    BaseLow     : 16;
> > +    UINT32    BaseMid     : 8;
> > +    UINT32    Type        : 4;
> > +    UINT32    System      : 1;
> > +    UINT32    Dpl         : 2;
> > +    UINT32    Present     : 1;
> > +    UINT32    LimitHigh   : 4;
> > +    UINT32    Software    : 1;
> > +    UINT32    Reserved    : 1;
> > +    UINT32    DefaultSize : 1;
> > +    UINT32    Granularity : 1;
> > +    UINT32    BaseHigh    : 8;
> > +  } Bits;
> > +  UINT64    Uint64;
> > +} IA32_GDT;
> > +#pragma pack()
> > +
> > +GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT  mGdtEntries[] = {
> > +  {
> > +    { 0,      0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, 0 }
> > +  },                                                            /* 0x0:  reserve */
> > +  {
> > +    { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }
> > +  },                                                            /* 0x8:  compatibility mode */
> > +  {
> > +    { 0xFFFF, 0, 0, 0xB, 1, 0, 1, 0xF, 0, 1, 0, 1, 0 }
> > +  },                                                            /* 0x10: for long mode */
> > +  {
> > +    { 0xFFFF, 0, 0, 0x3, 1, 0, 1, 0xF, 0, 0, 1, 1, 0 }
> > +  },                                                            /* 0x18: data */
> > +  {
> > +    { 0,      0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0, 0 }
> > +  },                                                            /* 0x20: reserve */
> > +};
> > +
> > +//
> > +// IA32 Gdt register
> > +//
> > +GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR  mGdt = {
> > +  sizeof (mGdtEntries) - 1,
> > +  (UINTN)mGdtEntries
> > +};
> > +
> > +/**
> > +  Assembly function to transition from long mode to compatibility mode to
> > execute 32-bit code and then transit back to
> > +  long mode.
> > +
> > +  @param[in] Function     The 32bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 32bit code
> > +  @param[in] Param2       The second parameter to pass to 32bit code
> > +  @param[in] InternalGdtr The GDT and GDT descriptor used by this library
> > +
> > +  @return status.
> > +**/
> > +UINT32
> > +EFIAPI
> > +AsmExecute32BitCode (
> > +  IN UINT64           Function,
> > +  IN UINT64           Param1,
> > +  IN UINT64           Param2,
> > +  IN IA32_DESCRIPTOR  *InternalGdtr
> > +  );
> > +
> > +/**
> > +  Wrapper for a thunk to transition from long mode to compatibility mode
> to
> > execute 32-bit code and then transit back to
> > +  long mode.
> > +
> > +  @param[in] Function     The 32bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 32bit code.
> > +  @param[in] Param2       The second parameter to pass to 32bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +IA32_DESCRIPTOR  MemoryIdtr;
> > +EFI_STATUS
> > +Execute32BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  )
> > +{
> > +  EFI_STATUS       Status;
> > +  IA32_DESCRIPTOR  Idtr;
> > +
> > +  // Idtr might be changed inside of FSP. 32bit FSP only knows the <4G
> > address.
> > +  // If IDTR.Base is >4G, FSP can not handle. So we need save/restore IDTR
> > here for X64 only.
> > +  // Interrupt is already disabled here, so it is safety to update IDTR.
> > +  //
> > +  AsmReadIdtr (&Idtr);
> > +  MemoryIdtr = Idtr;
> > +  DEBUG ((DEBUG_ERROR, "Before FSP:%llx\n", ReadRsp ()));
> > +  Status = AsmExecute32BitCode (Function, Param1, Param2, &mGdt);
> > +  DEBUG ((DEBUG_ERROR, "After FSP:%llx\n", ReadRsp ()));
> > +  ASSERT (Idtr.Limit == MemoryIdtr.Limit && Idtr.Base == MemoryIdtr.Base);
> > +  //
> > +  // Convert FSP Status code from 32bit to 64bit to match caller
> expectation.
> > +  //
> > +  Status = (Status & ~(BIT31 + BIT30)) | LShiftU64 (Status & (BIT31 + BIT30),
> > 32);
> > +  AsmWriteIdtr (&Idtr);
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Wrapper to execute 64-bit code directly from long mode.
> > +
> > +  @param[in] Function     The 64bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 64bit code.
> > +  @param[in] Param2       The second parameter to pass to 64bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute64BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  )
> > +{
> > +  FSP_FUNCTION  EntryFunc;
> > +  EFI_STATUS    Status;
> > +
> > +  EntryFunc = (FSP_FUNCTION)(UINTN)(Function);
> > +  Status    = EntryFunc ((VOID *)(UINTN)Param1, (VOID *)(UINTN)Param2);
> > +
> > +  return Status;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/X64/Thunk64To32.nasm
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/X64/Thunk64To32.nasm
> > new file mode 100644
> > index 0000000000..f1a14b2446
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiLib/X64/Thunk64To32.nasm
> > @@ -0,0 +1,252 @@
> > +;/** @file
> > +;   This is the assembly code to transition from long mode to compatibility
> > mode to execute 32-bit code and then
> > +;   transit back to long mode.
> > +;
> > +; Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +;
> > +; Module Name:
> > +;
> > +;    Thunk64To32.nasm
> > +;
> > +; Abstract:
> > +;
> > +;   This is the assembly code to transition from long mode to compatibility
> > mode to execute 32-bit code and then
> > +;   transit back to long mode.
> > +;
> > +;-------------------------------------------------------------------------------
> > +    DEFAULT REL
> > +    SECTION .text
> > +;----------------------------------------------------------------------------
> > +; Procedure:    AsmExecute32BitCode
> > +;
> > +; Input:        None
> > +;
> > +; Output:       None
> > +;
> > +; Prototype:    UINT32
> > +;               AsmExecute32BitCode (
> > +;                 IN UINT64           Function,
> > +;                 IN UINT64           Param1,
> > +;                 IN UINT64           Param2,
> > +;                 IN IA32_DESCRIPTOR  *InternalGdtr
> > +;                 );
> > +;
> > +;
> > +; Description:  A thunk function to execute 32-bit code in long mode.
> > +;
> > +;----------------------------------------------------------------------------
> > +global ASM_PFX(AsmExecute32BitCode)
> > +ASM_PFX(AsmExecute32BitCode):
> > +    ;
> > +    ; save IFLAG and disable it
> > +    ;
> > +    pushfq
> > +    cli
> > +
> > +    ;
> > +    ; save original GDTR and CS
> > +    ;
> > +    mov     rax, ds
> > +    push    rax
> > +    mov     rax, cs
> > +    push    rax
> > +    sub     rsp, 0x10
> > +    sgdt    [rsp]
> > +    ;
> > +    ; load internal GDT
> > +    ;
> > +    lgdt    [r9]
> > +    ;
> > +    ; Save general purpose register and rflag register
> > +    ;
> > +    pushfq
> > +    ; push AMD64-specific r8~r15.
> > +    push    r8
> > +    push    r9
> > +    push    r10
> > +    push    r11
> > +    push    r12
> > +    push    r13
> > +    push    r14
> > +    push    r15
> > +
> > +    push    rdi
> > +    push    rsi
> > +    push    rbp
> > +    push    rbx
> > +
> > +    ;
> > +    ; save CR3
> > +    ;
> > +    mov     rax, cr3
> > +    mov     rbp, rax
> > +
> > +    ;
> > +    ; Prepare the CS and return address for the transition from 32-bit to 64-
> bit
> > mode
> > +    ;
> > +    mov     rax, dword 0x10              ; load long mode selector
> > +    shl     rax, 32
> > +    lea     r9,  [ReloadCS]          ;Assume the ReloadCS is under 4G
> > +    or      rax, r9
> > +    push    rax
> > +    ;
> > +    ; Save parameters for 32-bit function call
> > +    ;
> > +    mov     rax, r8
> > +    shl     rax, 32
> > +    or      rax, rdx
> > +    push    rax
> > +    ;
> > +    ; save the 32-bit function entry and the return address into stack which
> will
> > be
> > +    ; retrieve in compatibility mode.
> > +    ;
> > +    lea     rax, [ReturnBack]   ;Assume the ReloadCS is under 4G
> > +    shl     rax, 32
> > +    or      rax, rcx
> > +    push    rax
> > +
> > +    ;
> > +    ; let rax save DS
> > +    ;
> > +    mov     rax, dword 0x18
> > +
> > +    ;
> > +    ; Change to Compatible Segment
> > +    ;
> > +    mov     rcx, dword 0x8               ; load compatible mode selector
> > +    shl     rcx, 32
> > +    lea     rdx, [Compatible] ; assume address < 4G
> > +    or      rcx, rdx
> > +    push    rcx
> > +    retf
> > +
> > +Compatible:
> > +    ; reload DS/ES/SS to make sure they are correct referred to current GDT
> > +    mov     ds, ax
> > +    mov     es, ax
> > +    mov     ss, ax
> > +
> > +    ;
> > +    ; Disable paging
> > +    ;
> > +    mov     rcx, cr0
> > +    btc     ecx, 31
> > +    mov     cr0, rcx
> > +    ;
> > +    ; Clear EFER.LME
> > +    ;
> > +    mov     ecx, 0xC0000080
> > +    rdmsr
> > +    btc     eax, 8
> > +    wrmsr
> > +
> > +; Now we are in protected mode
> > +    ;
> > +    ; Call 32-bit function. Assume the function entry address and parameter
> > value is less than 4G
> > +    ;
> > +    pop    rax                 ; Here is the function entry
> > +    ;
> > +    ; Now the parameter is at the bottom of the stack,  then call in to IA32
> > function.
> > +    ;
> > +    jmp   rax
> > +ReturnBack:
> > +    mov   ebx, eax             ; save return status
> > +    pop   rcx                  ; drop param1
> > +    pop   rcx                  ; drop param2
> > +
> > +    ;
> > +    ; restore CR4
> > +    ;
> > +    mov     rax, cr4
> > +    bts     eax, 5
> > +    mov     cr4, rax
> > +
> > +    ;
> > +    ; restore CR3
> > +    ;
> > +    mov     eax, ebp
> > +    mov     cr3, rax
> > +
> > +    ;
> > +    ; Set EFER.LME to re-enable ia32-e
> > +    ;
> > +    mov     ecx, 0xC0000080
> > +    rdmsr
> > +    bts     eax, 8
> > +    wrmsr
> > +    ;
> > +    ; Enable paging
> > +    ;
> > +    mov     rax, cr0
> > +    bts     eax, 31
> > +    mov     cr0, rax
> > +; Now we are in compatible mode
> > +
> > +    ;
> > +    ; Reload cs register
> > +    ;
> > +    retf
> > +ReloadCS:
> > +    ;
> > +    ; Now we're in Long Mode
> > +    ;
> > +    ;
> > +    ; Restore C register and eax hold the return status from 32-bit function.
> > +    ; Note: Do not touch rax from now which hold the return value from IA32
> > function
> > +    ;
> > +    mov     eax, ebx ; put return status to EAX
> > +    pop     rbx
> > +    pop     rbp
> > +    pop     rsi
> > +    pop     rdi
> > +    ; pop AMD64-specific r8~r15
> > +    pop     r15
> > +    pop     r14
> > +    pop     r13
> > +    pop     r12
> > +    pop     r11
> > +    pop     r10
> > +    pop     r9
> > +    pop     r8
> > +
> > +    popfq
> > +    ;
> > +    ; Switch to original GDT and CS. here rsp is pointer to the original GDT
> > descriptor.
> > +    ;
> > +    lgdt    [rsp]
> > +    ;
> > +    ; drop GDT descriptor in stack
> > +    ;
> > +    add     rsp, 0x10
> > +    ;
> > +    ; switch to original CS and GDTR
> > +    ;
> > +    pop     r9                 ; get  CS
> > +    shl     r9,  32            ; rcx[32..47] <- Cs
> > +    lea     rcx, [.0]
> > +    or      rcx, r9
> > +    push    rcx
> > +    retf
> > +.0:
> > +    ;
> > +    ; Reload original DS/ES/SS
> > +    ;
> > +    pop     rcx
> > +    mov     ds, rcx
> > +    mov     es, rcx
> > +    mov     ss, rcx
> > +
> > +    ;
> > +    ; Restore IFLAG
> > +    ;
> > +    popfq
> > +
> > +    ret
> > +
> > +global ASM_PFX(ReadRsp)
> > +ASM_PFX(ReadRsp):
> > +    mov rax,rsp
> > +    ret
> > \ No newline at end of file
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
> > new file mode 100644
> > index 0000000000..4d40f86b3a
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
> > @@ -0,0 +1,56 @@
> > +## @file
> > +#  FSP wrapper API test related function INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
>
> > +### @file
> > +#  Provide FSP wrapper API test related function.
> > +#
> > +#  Copyright (C) 2016, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010017
> > +  BASE_NAME                      = BaseFspWrapperApiTestLibNull
> > +  FILE_GUID                      = E7E96F88-017B-417C-8DC8-B84C2B877020
> > +  VERSION_STRING                 = 1.0
> > +  MODULE_TYPE                    = PEIM
> > +  LIBRARY_CLASS                  = FspWrapperApiTestLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32
> > +#
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Sources Section - list of files that are required for the build to succeed.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Sources]
> > +  FspWrapperApiTestNull.c
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Package Dependency Section - list of Package files that are required for
> > +#                              this module.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +
> > +[LibraryClasses]
> > +  DebugLib
> > +
> > +[Guids]
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
> > new file mode 100644
> > index 0000000000..19bd3afc29
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
> > @@ -0,0 +1,60 @@
> > +/** @file
> > +  Provide FSP wrapper API test related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +/**
> > +  Test the output of FSP API - FspMemoryInit.
> > +
> > +  @param[in]  FspmUpdDataPtr Address pointer to the
> > FSP_MEMORY_INIT_PARAMS structure.
> > +  @param[in]  HobListPtr     Address of the HobList pointer.
> > +
> > +  @return test result on output of FspMemoryInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspMemoryInitApiOutput (
> > +  IN  VOID  *FspmUpdDataPtr,
> > +  IN  VOID  **HobListPtr
> > +  )
> > +{
> > +  return RETURN_UNSUPPORTED;
> > +}
> > +
> > +/**
> > +  Test the output of FSP API - TempRamExit.
> > +
> > +  @param[in] TempRamExitParam    Address pointer to the TempRamExit
> > parameters structure.
> > +
> > +  @return test result on output of TempRamExit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspTempRamExitApiOutput (
> > +  IN VOID  *TempRamExitParam
> > +  )
> > +{
> > +  return RETURN_UNSUPPORTED;
> > +}
> > +
> > +/**
> > +  Test the output of FSP API - FspSiliconInit.
> > +
> > +  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init
> parameters
> > structure.
> > +
> > +  @return test result on output of FspSiliconInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspSiliconInitApiOutput (
> > +  IN  VOID  *FspsUpdDataPtr
> > +  )
> > +{
> > +  return RETURN_UNSUPPORTED;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
> > new file mode 100644
> > index 0000000000..1f66593a52
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
> > @@ -0,0 +1,79 @@
> > +## @file
> > +#  FSP wrapper platform related function INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +## @file
> > +#  Sample to provide FSP wrapper platform related function.
> > +#
> > +#  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Defines Section - statements that will be processed to create a Makefile.
> > +#
> >
> +##################################################################
> > ##############
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = BaseFspWrapperPlatformLibSample
> > +  FILE_GUID                      = 12F38E73-B34D-4559-99E5-AE2DCD002156
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FspWrapperPlatformLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Sources Section - list of files that are required for the build to succeed.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Sources]
> > +  FspWrapperPlatformLibSample.c
> > +
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Package Dependency Section - list of Package files that are required for
> > +#                              this module.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  ChachaniBoardPkg/Project.dec
> > +  AgesaPublic/AgesaPublic.dec
> > +
> > +[Ppis]
> > +  gEfiPeiSmbus2PpiGuid
> > +
> > +[LibraryClasses]
> > +  AmdIdsHookExtLib
> > +
> > +[Guids]
> > +  gEfiSmmPeiSmramMemoryReserveGuid
> > +  gEfiAcpiVariableGuid
> > +  gAmdResourceSizeForEachRbGuid
> > +  gAmdTotalNumberOfRootBridgesGuid
> > +  gAmdPbsSystemConfigurationGuid
> > +  gApSyncFlagNvVariableGuid
> > +
> > +[Pcd]
> > +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress     # CONSUMES
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspoDxeBaseAddressInMemory
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
> > new file mode 100644
> > index 0000000000..1afcf68f85
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> > aseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
> > @@ -0,0 +1,347 @@
> > +/** @file
> > +  Sample to provide FSP wrapper related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +#include <Library/PcdLib.h>
> > +#include <FspEas/FspApi.h>
> > +#include <FspmUpd.h>
> > +#include <FspsUpd.h>
> > +#include <Library/HobLib.h>
> > +#include <Guid/SmramMemoryReserve.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/PeiServicesTablePointerLib.h>
> > +#include <Ppi/Smbus2.h>
> > +#include <Ppi/ReadOnlyVariable2.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Guid/AcpiS3Context.h>
> > +
> > +#pragma pack(push, 1)
> > +typedef struct {
> > +  UINT8    connector_type;
> > +  UINT8    aux_index;
> > +  UINT8    hdp_index;
> > +  UINT8    reserved;
> > +} fsp_ddi_descriptor;
> > +#pragma pack(pop)
> > +
> > +extern EFI_GUID  gEfiSmmPeiSmramMemoryReserveGuid;
> > +
> > +extern EFI_GUID  gAmdResourceSizeForEachRbGuid;
> > +extern EFI_GUID  gAmdTotalNumberOfRootBridgesGuid;
> > +extern EFI_GUID  gAmdPbsSystemConfigurationGuid;
> > +extern EFI_GUID  gApSyncFlagNvVariableGuid;
> > +
> > +typedef enum {
> > +  IDS_HOOK_SUCCESS = 0,         ///< The service completed normally
> > +  IDS_HOOK_UNSUPPORTED,         ///< Unsupported IDS HOOK
> > +  IDS_HOOK_BUFFER_TOO_SMALL,    ///< Too small buffer
> > +  IDS_HOOK_NOT_FOUND,           ///< Haven't found accordingly service
> entry
> > for specific IDS HOOK ID
> > +  IDS_HOOK_ERROR,               ///< Error happens during service IDS HOOK
> > +  IDS_HOOK_SKIP,                ///< Use to notify the IDS HOOK caller to skip a
> > block of codes, used for IDS_HOOK_SKIP
> > +  IDS_HOOK_NO_SKIP,             ///< Use to notify the IDS HOOK caller not skip
> a
> > block of codes, used for IDS_HOOK_SKIP
> > +  IDS_HOOK_MAX                  ///< Not a status, for limit checking.
> > +} IDS_HOOK_STATUS;
> > +
> > +IDS_HOOK_STATUS
> > +GetIdsNvTable (
> > +  IN OUT   VOID    *IdsNvTable,
> > +  IN OUT   UINT32  *IdsNvTableSize
> > +  );
> > +
> > +STATIC
> > +EFI_STATUS
> > +GetIdsNvData (
> > +  FSPM_UPD *volatile  FspmUpd
> > +  )
> > +{
> > +  VOID             *IdsNvTableData;
> > +  UINT32           IdsNvDataSize = 0;
> > +  IDS_HOOK_STATUS  Status        = GetIdsNvTable (NULL, &IdsNvDataSize);
> > +
> > +  if ((Status == IDS_HOOK_BUFFER_TOO_SMALL) || (Status ==
> > IDS_HOOK_SUCCESS)) {
> > +    // The CBS code doesn't follow its header!
> > +    IdsNvTableData = AllocatePool (IdsNvDataSize+100);
> > +    if (IdsNvTableData != NULL) {
> > +      Status = GetIdsNvTable (IdsNvTableData, &IdsNvDataSize);
> > +      if (Status == IDS_HOOK_SUCCESS) {
> > +        FspmUpd->FspmConfig.ids_nv_table_address =
> > (UINT32)(UINTN)IdsNvTableData;
> > +        FspmUpd->FspmConfig.ids_nv_table_size    = IdsNvDataSize;
> > +        DEBUG ((
> > +          DEBUG_INFO,
> > +          "IDS NV Table address:%x, size:%x\n", \
> > +          FspmUpd->FspmConfig.ids_nv_table_address,
> > +          FspmUpd->FspmConfig.ids_nv_table_size
> > +          ));
> > +        return EFI_SUCCESS;
> > +      } else {
> > +        DEBUG ((DEBUG_ERROR, "Get NV Table #3:%d\n", Status));
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "Get NV Table #2:%d\n", Status));
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_ERROR, "Get NV Table #1:%d\n", Status));
> > +  }
> > +
> > +  return EFI_UNSUPPORTED;
> > +}
> > +
> > +/**
> > +  This function overrides the default configurations in the FSP-S UPD data
> > region.
> > +
> > +  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data
> > structure.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UpdateFspsUpdData (
> > +  IN OUT VOID  *FspUpdRgnPtr
> > +  )
> > +{
> > +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *SmramHob = GetFirstGuidHob (
> > +                                                &gEfiSmmPeiSmramMemoryReserveGuid
> > +                                                );
> > +
> > +  if (SmramHob != NULL) {
> > +    ((FSPS_UPD *)FspUpdRgnPtr)->FspsConfig.smram_hob_base_addr =
> > (UINT32)(UINTN)GET_GUID_HOB_DATA (SmramHob);
> > +    ((FSPS_UPD *)FspUpdRgnPtr)->FspsConfig.smram_hob_size      =
> > (UINT32)GET_GUID_HOB_DATA_SIZE (SmramHob);
> > +  }
> > +
> > +  EFI_SMRAM_DESCRIPTOR  *SmramDescriptor = GetFirstGuidHob
> > (&gEfiAcpiVariableGuid);
> > +
> > +  if (SmramDescriptor != NULL) {
> > +    ((FSPS_UPD *)FspUpdRgnPtr)-
> > >FspsConfig.smram_hob_descriptor_base_addr =
> > (UINT32)(UINTN)GET_GUID_HOB_DATA (SmramDescriptor);
> > +    ((FSPS_UPD *)FspUpdRgnPtr)->FspsConfig.smram_hob_descriptor_size
> > =      (UINT32)GET_GUID_HOB_DATA_SIZE (SmramDescriptor);
> > +  } else {
> > +    DEBUG ((DEBUG_ERROR, "Cannot found SmramDescriptor!\n"));
> > +  }
> > +
> > +  ((FSPS_UPD *)FspUpdRgnPtr)->FspsConfig.fsp_o_dxe_volume_address =
> > PcdGet32 (PcdFspoDxeBaseAddressInMemory);
> > +  ((FSPS_UPD *)FspUpdRgnPtr)->FspsConfig.page_address_below_1mb   =
> > 0x10000;
> > +}
> > +
> > +/**
> > +  This function overrides the default configurations in the FSP-M UPD data
> > region.
> > +
> > +  @note At this point, memory is NOT ready, PeiServices are available to use.
> > +
> > +  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data
> > structure.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UpdateFspmUpdDataForFabric (
> > +  IN OUT VOID  *FspUpdRgnPtr
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "%a Enter\n", __FUNCTION__));
> > +  FSPM_UPD                         *Upd           = (FSPM_UPD *)FspUpdRgnPtr;
> > +  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *ReadVariable2 = NULL;
> > +  EFI_STATUS                       Status         = PeiServicesLocatePpi
> > (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&ReadVariable2);
> > +
> > +  ASSERT (Status == EFI_SUCCESS);
> > +  UINT32  VariableSize = 0;
> > +  VOID    *Buffer      = NULL;
> > +
> > +  Status = ReadVariable2->GetVariable (
> > +                            ReadVariable2,
> > +                            L"ResourceSizeForEachRb",
> > +                            &gAmdResourceSizeForEachRbGuid,
> > +                            NULL,
> > +                            &VariableSize,
> > +                            NULL
> > +                            );
> > +  if (Status == EFI_BUFFER_TOO_SMALL) {
> > +    Buffer = AllocatePool (VariableSize);
> > +    ASSERT (Buffer != NULL);
> > +    Status = ReadVariable2->GetVariable (
> > +                              ReadVariable2,
> > +                              L"ResourceSizeForEachRb",
> > +                              &gAmdResourceSizeForEachRbGuid,
> > +                              NULL,
> > +                              &VariableSize,
> > +                              Buffer
> > +                              );
> > +    if (!EFI_ERROR (Status)) {
> > +      Upd->FspmConfig.resource_size_for_each_rb_ptr  =
> > (UINT32)(UINTN)Buffer;
> > +      Upd->FspmConfig.resource_size_for_each_rb_size = VariableSize;
> > +    }
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "Get variable %s returns %r\n",
> > L"ResourceSizeForEachRb", Status));
> > +  VariableSize = 0;
> > +  Buffer       = NULL;
> > +  Status       = ReadVariable2->GetVariable (
> > +                                  ReadVariable2,
> > +                                  L"TotalNumberOfRootBridges",
> > +                                  &gAmdTotalNumberOfRootBridgesGuid,
> > +                                  NULL,
> > +                                  &VariableSize,
> > +                                  NULL
> > +                                  );
> > +  if (Status == EFI_BUFFER_TOO_SMALL) {
> > +    Buffer = AllocatePool (VariableSize);
> > +    ASSERT (Buffer != NULL);
> > +    Status = ReadVariable2->GetVariable (
> > +                              ReadVariable2,
> > +                              L"TotalNumberOfRootBridges",
> > +                              &gAmdTotalNumberOfRootBridgesGuid,
> > +                              NULL,
> > +                              &VariableSize,
> > +                              Buffer
> > +                              );
> > +    if (!EFI_ERROR (Status)) {
> > +      Upd->FspmConfig.total_number_of_root_bridges_ptr  =
> > (UINT32)(UINTN)Buffer;
> > +      Upd->FspmConfig.total_number_of_root_bridges_size = VariableSize;
> > +    }
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "Get variable %s returns %r\n",
> > L"TotalNumberOfRootBridges", Status));
> > +  VariableSize = 0;
> > +  Buffer       = NULL;
> > +  Status       = ReadVariable2->GetVariable (
> > +                                  ReadVariable2,
> > +                                  L"AMD_PBS_SETUP",
> > +                                  &gAmdPbsSystemConfigurationGuid,
> > +                                  NULL,
> > +                                  &VariableSize,
> > +                                  NULL
> > +                                  );
> > +  if (Status == EFI_BUFFER_TOO_SMALL) {
> > +    Buffer = AllocatePool (VariableSize);
> > +    ASSERT (Buffer != NULL);
> > +    Status = ReadVariable2->GetVariable (
> > +                              ReadVariable2,
> > +                              L"AMD_PBS_SETUP",
> > +                              &gAmdPbsSystemConfigurationGuid,
> > +                              NULL,
> > +                              &VariableSize,
> > +                              Buffer
> > +                              );
> > +    if (!EFI_ERROR (Status)) {
> > +      Upd->FspmConfig.amd_pbs_setup_ptr  = (UINT32)(UINTN)Buffer;
> > +      Upd->FspmConfig.amd_pbs_setup_size = VariableSize;
> > +    }
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "Get variable %s returns %r\n",
> > L"AMD_PBS_SETUP", Status));
> > +  VariableSize = 0;
> > +  Buffer       = NULL;
> > +  Status       = ReadVariable2->GetVariable (
> > +                                  ReadVariable2,
> > +                                  L"ApSyncFlagNv",
> > +                                  &gApSyncFlagNvVariableGuid,
> > +                                  NULL,
> > +                                  &VariableSize,
> > +                                  NULL
> > +                                  );
> > +  if (Status == EFI_BUFFER_TOO_SMALL) {
> > +    Buffer = AllocatePool (VariableSize);
> > +    ASSERT (Buffer != NULL);
> > +    Status = ReadVariable2->GetVariable (
> > +                              ReadVariable2,
> > +                              L"ApSyncFlagNv",
> > +                              &gApSyncFlagNvVariableGuid,
> > +                              NULL,
> > +                              &VariableSize,
> > +                              Buffer
> > +                              );
> > +    if (!EFI_ERROR (Status)) {
> > +      Upd->FspmConfig.ap_sync_flag_nv_ptr  = (UINT32)(UINTN)Buffer;
> > +      Upd->FspmConfig.ap_sync_flag_nv_size = VariableSize;
> > +    }
> > +
> > +    DEBUG ((DEBUG_INFO, "Get variable %s returns %r\n",
> L"ApSyncFlagNv",
> > Status));
> > +  }
> > +}
> > +
> > +/**
> > +  This function overrides the default configurations in the FSP-M UPD data
> > region.
> > +
> > +  @note At this point, memory is NOT ready, PeiServices are available to use.
> > +
> > +  @param[in,out] FspUpdRgnPtr   A pointer to the UPD data region data
> > structure.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UpdateFspmUpdData (
> > +  IN OUT VOID  *FspUpdRgnPtr
> > +  )
> > +{
> > +  FSPM_UPD  *FspmUpd;
> > +
> > +  FspmUpd = (FSPM_UPD *)FspUpdRgnPtr;
> > +  EFI_BOOT_MODE  BootMode = BOOT_WITH_FULL_CONFIGURATION;
> > +
> > +  PeiServicesGetBootMode (&BootMode);
> > +  FspmUpd->FspmArchUpd.BootMode  = BootMode;
> > +  FspmUpd->FspmArchUpd.StackBase = (VOID *)0x11000; // 1 Page for
> CPU
> > reset in DXE.
> > +  FspmUpd->FspmArchUpd.StackSize = 0x20000;
> > +  DEBUG ((DEBUG_INFO, "Getting IDS NV Table returns status %r\n",
> > GetIdsNvData (FspmUpd)));
> > +  UpdateFspmUpdDataForFabric (FspUpdRgnPtr);
> > +}
> > +
> > +/**
> > +  Update TempRamExit parameter.
> > +
> > +  @note At this point, memory is ready, PeiServices are available to use.
> > +
> > +  @return TempRamExit parameter.
> > +**/
> > +VOID *
> > +EFIAPI
> > +UpdateTempRamExitParam (
> > +  VOID
> > +  )
> > +{
> > +  return NULL;
> > +}
> > +
> > +/**
> > +  Get S3 PEI memory information.
> > +
> > +  @note At this point, memory is ready, and PeiServices are available to use.
> > +  Platform can get some data from SMRAM directly.
> > +
> > +  @param[out] S3PeiMemSize  PEI memory size to be installed in S3 phase.
> > +  @param[out] S3PeiMemBase  PEI memory base to be installed in S3
> phase.
> > +
> > +  @return If S3 PEI memory information is got successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetS3MemoryInfo (
> > +  OUT UINT64                *S3PeiMemSize,
> > +  OUT EFI_PHYSICAL_ADDRESS  *S3PeiMemBase
> > +  )
> > +{
> > +  return EFI_UNSUPPORTED;
> > +}
> > +
> > +/**
> > +  Perform platform related reset in FSP wrapper.
> > +
> > +  This function will reset the system with requested ResetType.
> > +
> > +  @param[in] FspStatusResetType  The type of reset the platform has to
> > perform.
> > +**/
> > +VOID
> > +EFIAPI
> > +CallFspWrapperResetSystem (
> > +  IN EFI_STATUS  FspStatusResetType
> > +  )
> > +{
> > +  //
> > +  // Perform reset according to the type.
> > +  //
> > +
> > +  CpuDeadLoop ();
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> >
> aseFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPha
> > seLibNull.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> >
> aseFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPha
> > seLibNull.inf
> > new file mode 100644
> > index 0000000000..f9f1a12c2f
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> >
> aseFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPha
> > seLibNull.inf
> > @@ -0,0 +1,45 @@
> > +## @file
> > +#  FSP Wrapper to handle platform specific actions for
> > +#  FSP MultiPhase (SeparatePhase) Initialization.
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +## @file
> > +#  FSP Wrapper to handle platform specific actions for
> > +#  FSP MultiPhase (SeparatePhase) Initialization.
> > +#
> > +#  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = BaseFspWrapperPlatformMultiPhaseLibNull
> > +  FILE_GUID                      = DB63E5AA-21C6-40BB-879A-CD1762C8427B
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FspWrapperPlatformMultiPhaseLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources]
> > +  FspWrapperPlatformMultiPhaseLibNull.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +
> > +[LibraryClasses]
> > +  DebugLib
> > +  BaseLib
> > +  PcdLib
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> >
> aseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLi
> > bNull.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> >
> aseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLi
> > bNull.c
> > new file mode 100644
> > index 0000000000..3a0d0e6088
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/B
> >
> aseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLi
> > bNull.c
> > @@ -0,0 +1,51 @@
> > +/** @file
> > +  FSP Wrapper to handle platform specific actions for
> > +  FSP MultiPhase (SeparatePhase) Initialization.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PcdLib.h>
> > +
> > +/**
> > +  FSP Wrapper Platform MultiPhase Handler
> > +
> > +  @param[in] FspHobListPtr        - Pointer to FSP HobList (valid after FSP-M
> > completed)
> > +  @param[in] ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +  @param[in] PhaseIndex           - Indicates current execution phase of FSP
> > MultiPhase initialization.
> > +
> > +  @retval EFI_STATUS        Always return EFI_SUCCESS
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +FspWrapperPlatformMultiPhaseHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex,
> > +  IN UINT32    PhaseIndex
> > +  )
> > +{
> > +  /* Example platform actions as below
> > +  switch (ComponentIndex) {
> > +  case FspMultiPhaseMemInitApiIndex:
> > +    switch (PhaseIndex) {
> > +      case 1:
> > +        PlatformAction1 ();
> > +      break;
> > +    }
> > +    break;
> > +  case FspMultiPhaseSiInitApiIndex:
> > +    switch (PhaseIndex) {
> > +      case 1:
> > +        PlatformAction2 ();
> > +      break;
> > +    }
> > +    break;
> > +  }
> > +  */
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/D
> >
> xeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/D
> >
> xeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c
> > new file mode 100644
> > index 0000000000..cfda44bc71
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/D
> >
> xeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c
> > @@ -0,0 +1,531 @@
> > +/** @file
> > +  Support FSP Wrapper MultiPhase process.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/FspWrapperPlatformLib.h>
> > +#include <FspEas.h>
> > +#include <FspGlobalData.h>
> > +#include <Ppi/Variable.h>
> > +#include "../../Include/Library/FspWrapperPlatformMultiPhaseLib.h"
> > +#include <FspsUpd.h>
> > +#include <Protocol/SmbusHc.h>
> > +#include <Protocol/SmmAccess2.h>
> > +#include <Protocol/SmmControl2.h>
> > +#include <Protocol/Reset.h>
> > +#include <MultiPhaseSiPhases.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <FspExportedInterfaceHob.h>
> > +#include <Protocol/Smbios.h>
> > +#include <Pi/PiHob.h>
> > +
> > +extern EFI_GUID  gFspsUpdDataPointerAddressGuid;
> > +extern EFI_GUID  gEfiSmmBase2ProtocolGuid;
> > +extern EFI_GUID  gEfiSmmCommunicationProtocolGuid;
> > +extern EFI_GUID  gEfiMmCommunication2ProtocolGuid;
> > +extern EFI_GUID  gFchInitDonePolicyProtocolGuid;
> > +extern EFI_GUID  gEfiVariableArchProtocolGuid;
> > +extern EFI_GUID  gEfiSmmVariableProtocolGuid;
> > +extern EFI_GUID  gSmmVariableWriteGuid;
> > +extern EFI_GUID  gEfiHiiDatabaseProtocolGuid;
> > +extern EFI_GUID  gEfiHiiStringProtocolGuid;
> > +extern EFI_GUID  gEfiHiiConfigRoutingProtocolGuid;
> > +extern EFI_GUID  gPspFlashAccSmmCommReadyProtocolGuid;
> > +extern EFI_GUID  gFspSmmDependencyReadyProtocolGuid;
> > +extern EFI_GUID  gFspHobGuid;
> > +extern EFI_GUID  gFspExportedInterfaceHobGuid;
> > +
> > +STATIC FSPS_UPD *volatile  FspsUpd;
> > +static VOID                **mFspHobListPtr;
> > +
> > +// The EDK 202208 Doesn't hold these structs.
> > +typedef enum {
> > +  EnumMultiPhaseGetVariableRequestInfo  = 0x2,
> > +  EnumMultiPhaseCompleteVariableRequest = 0x3
> > +} FSP_MULTI_PHASE_ACTION_23;
> > +
> > +typedef enum {
> > +  FspMultiPhaseMemInitApiIndex = 8
> > +} FSP_API_INDEX_23;
> > +///
> > +/// Action definition for FspMultiPhaseSiInit API
> > +///
> > +typedef enum {
> > +  EnumFspVariableRequestGetVariable         = 0x0,
> > +  EnumFspVariableRequestGetNextVariableName = 0x1,
> > +  EnumFspVariableRequestSetVariable         = 0x2,
> > +  EnumFspVariableRequestQueryVariableInfo   = 0x3
> > +} FSP_VARIABLE_REQUEST_TYPE;
> > +
> > +#pragma pack(16)
> > +typedef struct {
> > +  IN     FSP_VARIABLE_REQUEST_TYPE    VariableRequest;
> > +  IN OUT CHAR16                       *VariableName;
> > +  IN OUT UINT64                       *VariableNameSize;
> > +  IN OUT EFI_GUID                     *VariableGuid;
> > +  IN OUT UINT32                       *Attributes;
> > +  IN OUT UINT64                       *DataSize;
> > +  IN OUT VOID                         *Data;
> > +  OUT    UINT64                       *MaximumVariableStorageSize;
> > +  OUT    UINT64                       *RemainingVariableStorageSize;
> > +  OUT    UINT64                       *MaximumVariableSize;
> > +} FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS;
> > +
> > +typedef struct {
> > +  EFI_STATUS    VariableRequestStatus;
> > +} FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS;
> > +
> > +#pragma pack()
> > +
> > +FSP_EXPORTED_INTERFACE_HOB  *ExportedInterfaceHob;
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspMultiPhaseEntry (
> > +  IN VOID      *FspMultiPhaseParams,
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  );
> > +
> > +/**
> > +  Execute 32-bit FSP API entry code.
> > +
> > +  @param[in] Function     The 32bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 32bit code.
> > +  @param[in] Param2       The second parameter to pass to 32bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute32BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  );
> > +
> > +/**
> > +  Execute 64-bit FSP API entry code.
> > +
> > +  @param[in] Function     The 64bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 64bit code.
> > +  @param[in] Param2       The second parameter to pass to 64bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute64BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  );
> > +
> > +/**
> > +  Call FspsMultiPhase API.
> > +
> > +  @param[in] FspsMultiPhaseParams - Parameters for MultiPhase API.
> > +  @param[in] FspHobListPtr        - Pointer to FSP HobList (valid after FSP-M
> > completed)
> > +  @param[in] ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +
> > +  @return EFI_UNSUPPORTED  - the requested FspsMultiPhase API is not
> > supported.
> > +  @return EFI_DEVICE_ERROR - the FSP header was not found.
> > +  @return EFI status returned by FspsMultiPhase API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspMultiPhaseEntry (
> > +  IN VOID      *FspMultiPhaseParams,
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  )
> > +{
> > +  mFspHobListPtr = FspHobListPtr;
> > +  FSP_INFO_HEADER  *FspHeader;
> > +  //
> > +  // FSP_MULTI_PHASE_INIT and FSP_MULTI_PHASE_SI_INIT API functions
> > having same prototype.
> > +  //
> > +  UINTN                   FspMultiPhaseApiEntry;
> > +  UINTN                   FspMultiPhaseApiOffset = 0;
> > +  EFI_STATUS              Status;
> > +  BOOLEAN                 InterruptState;
> > +  BOOLEAN                 IsVariableServiceRequest;
> > +  FSP_MULTI_PHASE_PARAMS  *FspMultiPhaseParamsPtr;
> > +
> > +  FspMultiPhaseParamsPtr   = (FSP_MULTI_PHASE_PARAMS
> > *)FspMultiPhaseParams;
> > +  IsVariableServiceRequest = FALSE;
> > +  if ((FspMultiPhaseParamsPtr->MultiPhaseAction ==
> > (int)EnumMultiPhaseGetVariableRequestInfo) ||
> > +      (FspMultiPhaseParamsPtr->MultiPhaseAction ==
> > (int)EnumMultiPhaseCompleteVariableRequest))
> > +  {
> > +    IsVariableServiceRequest = TRUE;
> > +  }
> > +
> > +  if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {
> > +    FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspmBaseAddressInMemory));
> > +    if (FspHeader == NULL) {
> > +      return EFI_DEVICE_ERROR;
> > +    } else if (FspHeader->SpecVersion < 0x24) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    FspMultiPhaseApiOffset = FspHeader-
> >FspMultiPhaseMemInitEntryOffset;
> > +  } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {
> > +    FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspsBaseAddressInMemory));
> > +    if (FspHeader == NULL) {
> > +      return EFI_DEVICE_ERROR;
> > +    } else if (FspHeader->SpecVersion < 0x22) {
> > +      return EFI_UNSUPPORTED;
> > +    } else if ((FspHeader->SpecVersion < 0x24) && (IsVariableServiceRequest
> ==
> > TRUE)) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;
> > +  }
> > +
> > +  if (FspMultiPhaseApiOffset == 0) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  FspMultiPhaseApiEntry = FspHeader->ImageBase +
> > FspMultiPhaseApiOffset;
> > +  InterruptState        = SaveAndDisableInterrupts ();
> > +  if ((FspHeader->ImageAttribute & BIT2) == 0) {
> > +    // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT
> > +    Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry,
> > (UINTN)FspMultiPhaseParams, (UINTN)NULL);
> > +  } else {
> > +    Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry,
> > (UINTN)FspMultiPhaseParams, (UINTN)NULL);
> > +  }
> > +
> > +  SetInterruptState (InterruptState);
> > +
> > +  DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n",
> > Status));
> > +
> > +  return Status;
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +OnRuntimeServiceReady (
> > +  EFI_EVENT  Event,
> > +  VOID       *Extra
> > +  )
> > +{
> > +  gBS->CloseEvent (Event);
> > +  DEBUG ((DEBUG_ERROR, "Runtime Service ready.\n"));
> > +  FSP_MULTI_PHASE_PARAMS  FspMultiPhaseParams;
> > +
> > +  FspMultiPhaseParams.MultiPhaseAction   =
> EnumMultiPhaseExecutePhase;
> > +  FspMultiPhaseParams.PhaseIndex         =
> > EnumMultiPhaseAmdRuntimeServicesReadyPhase;
> > +  FspMultiPhaseParams.MultiPhaseParamPtr = NULL;
> > + #if 1
> > +  ExportedInterfaceHob->GetVariable         = gST->RuntimeServices-
> > >GetVariable;
> > +  ExportedInterfaceHob->GetNextVariableName = gST->RuntimeServices-
> > >GetNextVariableName;
> > +  ExportedInterfaceHob->SetVariable         = gST->RuntimeServices-
> > >SetVariable;
> > +  ExportedInterfaceHob->QueryVariableInfo   = gST->RuntimeServices-
> > >QueryVariableInfo;
> > +  ASSERT (gST->RuntimeServices->GetVariable && gST->RuntimeServices-
> > >SetVariable);
> > +  VOID        *HiiProtocol;
> > +  EFI_STATUS  Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid,
> > NULL, &HiiProtocol);
> > +  ASSERT (Status == EFI_SUCCESS);
> > +  ExportedInterfaceHob->HiiProtocol = HiiProtocol;
> > +  Status                            = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid,
> > NULL, &HiiProtocol);
> > +  ASSERT (Status == EFI_SUCCESS);
> > +  ExportedInterfaceHob->HiiStringProtocol = HiiProtocol;
> > +  Status                                  = gBS->LocateProtocol
> > (&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiProtocol);
> > +  ASSERT (Status == EFI_SUCCESS);
> > +  ExportedInterfaceHob->HiiConfigRoutingProtocol = HiiProtocol;
> > + #endif
> > +  CallFspMultiPhaseEntry (&FspMultiPhaseParams, NULL,
> > FspMultiPhaseSiInitApiIndex);
> > +}
> > +
> > +/**
> > +  FSP Wrapper MultiPhase Handler
> > +
> > +  @param[in, out] FspHobListPtr        - Pointer to FSP HobList (valid after
> FSP-
> > M completed)
> > +  @param[in]      ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +
> > +  @retval EFI_UNSUPPORTED   Specific MultiPhase action was not
> supported.
> > +  @retval EFI_SUCCESS       MultiPhase action were completed successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspWrapperMultiPhaseHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  )
> > +{
> > +  EFI_STATUS              Status;
> > +  FSP_MULTI_PHASE_PARAMS  FspMultiPhaseParams;
> > +  UINT32                  Index;
> > +  EFI_HANDLE              Handle      = NULL;
> > +  VOID                    *FspsUpdHob = GetFirstGuidHob
> > (&gFspsUpdDataPointerAddressGuid);
> > +
> > +  if ( FspsUpdHob != NULL ) {
> > +    FspsUpd = ((FSPS_UPD *)(UINTN)(*(UINT32 *)GET_GUID_HOB_DATA
> > (FspsUpdHob)));
> > +  }
> > +
> > +  FspsUpd->FspsConfig.nv_storage_variable_base    = PcdGet32
> > (PcdFlashNvStorageVariableBase);
> > +  FspsUpd->FspsConfig.nv_storage_variable_size    = PcdGet32
> > (PcdFlashNvStorageVariableSize);
> > +  FspsUpd->FspsConfig.nv_storage_ftw_working_base = PcdGet32
> > (PcdFlashNvStorageFtwWorkingBase);
> > +  FspsUpd->FspsConfig.nv_storage_ftw_working_size = PcdGet32
> > (PcdFlashNvStorageFtwWorkingSize);
> > +  FspsUpd->FspsConfig.nv_storage_ftw_spare_base   = PcdGet32
> > (PcdFlashNvStorageFtwSpareBase);
> > +  FspsUpd->FspsConfig.nv_storage_ftw_spare_size   = PcdGet32
> > (PcdFlashNvStorageFtwSpareSize);
> > +
> > +  for (Index = 1; Index <= EnumMultiPhaseAmdCpmDxeTableReadyPhase;
> > Index++) {
> > +    //
> > +    // Platform actions can be added in below function for each component
> > and phase before returning control back to FSP.
> > +    //
> > +    FspWrapperPlatformMultiPhaseHandler (FspHobListPtr,
> ComponentIndex,
> > Index);
> > +
> > +    FspMultiPhaseParams.MultiPhaseAction   =
> > EnumMultiPhaseExecutePhase;
> > +    FspMultiPhaseParams.PhaseIndex         = Index;
> > +    FspMultiPhaseParams.MultiPhaseParamPtr = NULL;
> > +    Status                                 = CallFspMultiPhaseEntry
> (&FspMultiPhaseParams,
> > FspHobListPtr, ComponentIndex);
> > +
> > +    //
> > +    // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +    //
> > +    if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +      DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n",
> > ComponentIndex, Status));
> > +      CallFspWrapperResetSystem ((UINTN)Status);
> > +    }
> > +
> > +    ASSERT_EFI_ERROR (Status);
> > +  }
> > +
> > +  DEBUG ((DEBUG_ERROR, " FSP Multi Phase Silicon Phase #2 init done.
> > Installing Protocol.\n"));
> > +  DEBUG ((DEBUG_ERROR, " *FspHobListPtr:%011p\n", *FspHobListPtr));
> > +  VOID  *ExportedInterfaceRawHob = GetNextGuidHob
> > (&gFspExportedInterfaceHobGuid, *FspHobListPtr);
> > +
> > +  DEBUG ((DEBUG_ERROR, " ExportedInterfaceRawHob:%011p\n",
> > ExportedInterfaceRawHob));
> > +  if ( ExportedInterfaceRawHob != NULL) {
> > +    ExportedInterfaceHob = GET_GUID_HOB_DATA
> > (ExportedInterfaceRawHob);
> > +  } else {
> > +    DEBUG ((DEBUG_ERROR, " Cannot found Exported Interface HOB!\n"));
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  DEBUG ((DEBUG_ERROR, "ExportedInterfaceHob:%011p\n",
> > ExportedInterfaceHob));
> > +  if ( FspsUpd != NULL ) {
> > +    DEBUG ((DEBUG_ERROR, "FSP-S UPD Ptr:%011p\n", FspsUpd));
> > +    // SMBUS Protocol
> > +    if (ExportedInterfaceHob->SmbusProtocol != 0) {
> > +      Status = gBS->InstallMultipleProtocolInterfaces (
> > +                      &Handle,
> > +                      &gEfiSmbusHcProtocolGuid,
> > +                      ExportedInterfaceHob->SmbusProtocol,
> > +                      NULL
> > +                      );
> > +      Handle  = NULL;
> > +      Status |= gBS->InstallProtocolInterface (
> > +                       &Handle,
> > +                       &gFchInitDonePolicyProtocolGuid,
> > +                       EFI_NATIVE_INTERFACE,
> > +                       NULL
> > +                       );
> > +      if ( EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_ERROR, "Failed to install SMBUS Protocol!\n"));
> > +        return Status;
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "SMBUS operation address is 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    // SMRAM Access 2 Protocol
> > +    if (ExportedInterfaceHob->SmmAccessProtocol != 0) {
> > +      Handle = NULL;
> > +      Status = gBS->InstallMultipleProtocolInterfaces (
> > +                      &Handle,
> > +                      &gEfiSmmAccess2ProtocolGuid,
> > +                      ExportedInterfaceHob->SmmAccessProtocol,
> > +                      NULL
> > +                      );
> > +      if ( EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_ERROR, "Failed to install SMRAM Access
> Protocol!\n"));
> > +        return Status;
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "SMRAM access address is 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    // SMRAM Control 2 Protocol
> > +    if (ExportedInterfaceHob->SmmControl2Protocol != 0) {
> > +      Handle = NULL;
> > +      Status = gBS->InstallMultipleProtocolInterfaces (
> > +                      &Handle,
> > +                      &gEfiSmmControl2ProtocolGuid,
> > +                      ExportedInterfaceHob->SmmControl2Protocol,
> > +                      NULL
> > +                      );
> > +      if ( EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_ERROR, "Failed to install SMRAM Control
> > Protocol!\n"));
> > +        return Status;
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "SMRAM control address is 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    // SMM Related Protocol
> > +    if (ExportedInterfaceHob->SmmBase2Protocol != 0) {
> > +      Handle = NULL;
> > +      Status = gBS->InstallMultipleProtocolInterfaces (
> > +                      &Handle,
> > +                      &gEfiSmmBase2ProtocolGuid,
> > +                      ExportedInterfaceHob->SmmBase2Protocol,
> > +                      NULL
> > +                      );
> > +      if ( EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_ERROR, "Failed to install SMM Base 2 Protocol!\n"));
> > +        return Status;
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "SMM Base 2 Protocol address is 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    if (ExportedInterfaceHob->SmmCommunicationProtocol != 0) {
> > +      Handle = NULL;
> > +      Status = gBS->InstallMultipleProtocolInterfaces (
> > +                      &Handle,
> > +                      &gEfiSmmCommunicationProtocolGuid,
> > +                      ExportedInterfaceHob->SmmCommunicationProtocol,
> > +                      NULL
> > +                      );
> > +      if ( EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_ERROR, "Failed to install SMM Communication
> > Protocol!\n"));
> > +        return Status;
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "SMM Communication Protocol address is
> > 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    if (ExportedInterfaceHob->MmCommunication2Protocol != 0) {
> > +      Handle = NULL;
> > +      Status = gBS->InstallMultipleProtocolInterfaces (
> > +                      &Handle,
> > +                      &gEfiMmCommunication2ProtocolGuid,
> > +                      ExportedInterfaceHob->MmCommunication2Protocol,
> > +                      NULL
> > +                      );
> > +      if ( EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_ERROR, "Failed to install MM Communication 2
> > Protocol!\n"));
> > +        return Status;
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "MM Communication 2 Protocol address is
> > 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    if (ExportedInterfaceHob->PspFtpmProtocol != 0) {
> > +      Handle = NULL;
> > +      Status = gBS->InstallMultipleProtocolInterfaces (
> > +                      &Handle,
> > +                      &gAmdPspFtpmProtocolGuid,
> > +                      ExportedInterfaceHob->PspFtpmProtocol,
> > +                      NULL
> > +                      );
> > +      if ( EFI_ERROR (Status)) {
> > +        DEBUG ((DEBUG_ERROR, "Failed to install PSP fTPM Protocol!\n"));
> > +        return Status;
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "PSP fTPM Protocol address is 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    if (ExportedInterfaceHob->FchResetSystem != 0) {
> > +      gST->RuntimeServices->ResetSystem = ExportedInterfaceHob-
> > >FchResetSystem;
> > +      Handle                            = NULL;
> > +      gBS->InstallProtocolInterface (
> > +             &Handle,
> > +             &gEfiResetArchProtocolGuid,
> > +             EFI_NATIVE_INTERFACE,
> > +             NULL
> > +             );
> > +    } else {
> > +      DEBUG ((DEBUG_ERROR, "Runtime Reset address is 0!\n"));
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    // Install SMBIOS Protocol.
> > +    EFI_SMBIOS_PROTOCOL  *SmbiosProtocol;
> > +    VOID                 **SmbiosTableAddress = ExportedInterfaceHob-
> > >SmbiosPointers;
> > +    Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID
> > **)&SmbiosProtocol);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_ERROR, "SMBIOS Protocol not found!\n"));
> > +      return EFI_NOT_FOUND;
> > +    }
> > +
> > +    for (UINT32 Count = 0; Count < MAX_SMBIOS_TABLE_COUNT; Count++)
> {
> > +      if (SmbiosTableAddress[Count]) {
> > +        EFI_SMBIOS_TABLE_HEADER  *Header = (VOID
> > *)((UINTN)SmbiosTableAddress[Count]);
> > +        Header->Handle = SMBIOS_HANDLE_PI_RESERVED; // Re-allocate one.
> > +        Status         = SmbiosProtocol->Add (SmbiosProtocol, NULL, &Header-
> > >Handle, Header);
> > +        if (EFI_ERROR (Status)) {
> > +          DEBUG ((DEBUG_ERROR, "Failed to add SMBIOS Entry #%d
> > @0x%x:%r!\n", Count, SmbiosTableAddress[Count], Status));
> > +          break;
> > +        }
> > +
> > +        DEBUG ((DEBUG_INFO, "Added SMBIOS Entry #%d @0x%x\n", Count,
> > SmbiosTableAddress[Count]));
> > +      }
> > +    }
> > +
> > +    // Set PcdAmdSmmCommunicationAddress.
> > +    PcdSet64S (PcdAmdSmmCommunicationAddress, ExportedInterfaceHob-
> > >PcdAmdSmmCommunicationAddress);
> > +    PcdSet64S (PcdAmdS3LibPrivateDataAddress, ExportedInterfaceHob-
> > >PcdAmdS3LibPrivateDataAddress);
> > +    PcdSet64S (PcdAmdS3LibTableAddress, ExportedInterfaceHob-
> > >PcdAmdS3LibTableAddress);
> > +    PcdSet64S (PcdAmdS3LibTableSize, ExportedInterfaceHob-
> > >PcdAmdS3LibTableSize);
> > +    PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, ExportedInterfaceHob-
> > >S3BootScriptTablePrivateDataPtr);
> > +    PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr,
> > ExportedInterfaceHob->S3BootScriptTablePrivateSmmDataPtr);
> > +    DEBUG ((
> > +      DEBUG_INFO,
> > +
> >
> "PcdS3BootScriptTablePrivateDataPtr:%011p,PcdS3BootScriptTablePrivateSm
> > mDataPtr:%011p\n",
> > +      ExportedInterfaceHob->S3BootScriptTablePrivateDataPtr,
> > +      ExportedInterfaceHob->S3BootScriptTablePrivateSmmDataPtr
> > +      ));
> > +    DEBUG ((DEBUG_INFO, "Offset:%p,%p\n", &ExportedInterfaceHob-
> > >S3BootScriptTablePrivateDataPtr, &ExportedInterfaceHob-
> > >S3BootScriptTablePrivateSmmDataPtr));
> > +    ASSERT (
> > +      EfiNamedEventListen (
> > +        &gFspSmmDependencyReadyProtocolGuid,
> > +        TPL_CALLBACK,
> > +        OnRuntimeServiceReady,
> > +        NULL,
> > +        NULL
> > +        ) == EFI_SUCCESS
> > +      );
> > +    gBS->InstallProtocolInterface (
> > +           &Handle,
> > +           &gPspFlashAccSmmCommReadyProtocolGuid,
> > +           EFI_NATIVE_INTERFACE,
> > +           NULL
> > +           );
> > +    // Install Smm Variable Write protocol.
> > +    Handle = NULL;
> > +    gBS->InstallMultipleProtocolInterfaces (
> > +           &Handle,
> > +           &gEfiSmmVariableProtocolGuid,
> > +           NULL,
> > +           &gSmmVariableWriteGuid,
> > +           NULL,
> > +           &gEfiLockBoxProtocolGuid,
> > +           NULL,
> > +           NULL
> > +           );
> > +  } else {
> > +    DEBUG ((DEBUG_ERROR, "FspsUpdHob is NULL!\n"));
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/D
> >
> xeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.in
> > f
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/D
> >
> xeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.in
> > f
> > new file mode 100644
> > index 0000000000..21912fba99
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/D
> >
> xeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.in
> > f
> > @@ -0,0 +1,87 @@
> > +## @file
> > +#  FSP wrapper DXE FSP MultiPhase (SeparatePhase) INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +## @file
> > +#  FSP wrapper to handle FSP MultiPhase (SeparatePhase) Initialization.
> > +#
> > +#  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +#  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = DxeFspWrapperMultiPhaseProcessLib
> > +  FILE_GUID                      = 221219AB-C75F-450B-A961-978C59E42C83
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FspWrapperMultiPhaseProcessLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = X64
> > +#
> > +
> > +[Sources]
> > +  DxeFspWrapperMultiPhaseProcessLib.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  AgesaPublic/AgesaPublic.dec
> > +  ChachaniBoardPkg/Project.dec
> > +
> > +[LibraryClasses]
> > +  BaseMemoryLib
> > +  DebugLib
> > +  BaseLib
> > +  PcdLib
> > +  FspWrapperPlatformMultiPhaseLib
> > +
> > +[Guids]
> > +  gFspsUpdDataPointerAddressGuid        ## CONSUMES
> > +  gSmmVariableWriteGuid                 ## PRODUCES
> > +  gFspHobGuid                           ## CONSUMES
> > +  gFspExportedInterfaceHobGuid          ## CONSUMES
> > +
> > +[Protocols]
> > +  gEfiSmbiosProtocolGuid                ## CONSUMES
> > +  gEfiVariableArchProtocolGuid          ## CONSUMES
> > +  gEfiSmmVariableProtocolGuid           ## PRODUCES
> > +  gPspFlashAccSmmCommReadyProtocolGuid  ## PRODUCES
> > +  gEfiGlobalNvsAreaProtocolGuid         ## CONSUMES
> > +  gFspSmmDependencyReadyProtocolGuid    ## CONSUMES
> > +  gEfiHiiDatabaseProtocolGuid           ## CONSUMES
> > +  gEfiHiiStringProtocolGuid             ## CONSUMES
> > +  gEfiHiiConfigRoutingProtocolGuid      ## CONSUMES
> > +  gEfiLockBoxProtocolGuid               ## PRODUCES
> > +  gAmdPspFtpmProtocolGuid               ## PRODUCES
> > +
> > +[Ppis]
> > +
> > +[Pcd]
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInMemory      ##
> > CONSUMES
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInMemory      ##
> > CONSUMES
> > +
> >
> gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdSmmCommunicationAddr
> > ess ## PRODUCES FROM_FSP
> > +
> > gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdS3LibPrivateDataAddress
> > ## PRODUCES FROM_FSP
> > +  gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdS3LibTableAddress
> ##
> > PRODUCES FROM_FSP
> > +  gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdS3LibTableSize          ##
> > PRODUCES FROM_FSP
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr
> ##
> > PRODUCES FROM_FSP
> > +
> >
> gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr
> > ## PRODUCES FROM_FSP
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase      ##
> > CONSUMES   BY_FSP
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize      ##
> > CONSUMES   BY_FSP
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
> > ## CONSUMES   BY_FSP
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> > ## CONSUMES   BY_FSP
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
> ##
> > CONSUMES   BY_FSP
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> ##
> > CONSUMES   BY_FSP
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fs
> > pWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fs
> > pWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf
> > new file mode 100644
> > index 0000000000..6f681780e3
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fs
> > pWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf
> > @@ -0,0 +1,56 @@
> > +## @file
> > +#  FSP wrapper PEI FSP MultiPhase (SeparatePhase) INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +## @file
> > +#  FSP wrapper to handle FSP MultiPhase (SeparatePhase) Initialization.
> > +#
> > +#  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = FspWrapperMultiPhaseProcessLib
> > +  FILE_GUID                      = 11E657B7-C3D8-405B-94C5-516840E67B75
> > +  MODULE_TYPE                    = PEIM
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FspWrapperMultiPhaseProcessLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32
> > +#
> > +
> > +[Sources]
> > +  PeiFspWrapperMultiPhaseProcessLib.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseMemoryLib
> > +  DebugLib
> > +  BaseLib
> > +  PcdLib
> > +  FspWrapperPlatformLib
> > +  PeiServicesLib
> > +  FspWrapperPlatformMultiPhaseLib
> > +
> > +[Ppis]
> > +  gEfiPeiReadOnlyVariable2PpiGuid
> > +  gEdkiiPeiVariablePpiGuid
> > +
> > +[Pcd]
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInMemory      ##
> > CONSUMES
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInMemory      ##
> > CONSUMES
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fs
> > pWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fs
> > pWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
> > new file mode 100644
> > index 0000000000..e072efbb04
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Fs
> > pWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
> > @@ -0,0 +1,385 @@
> > +/** @file
> > +  Support FSP Wrapper MultiPhase process.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/FspWrapperPlatformLib.h>
> > +#include <FspEas.h>
> > +#include <FspGlobalData.h>
> > +#include <Ppi/ReadOnlyVariable2.h>
> > +#include <Ppi/Variable.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include "../../Include/Library/FspWrapperPlatformMultiPhaseLib.h"
> > +#include <MultiPhaseSiPhases.h>
> > +
> > +// The EDK 202208 Doesn't hold these structs.
> > +typedef enum {
> > +  EnumMultiPhaseGetVariableRequestInfo  = 0x2,
> > +  EnumMultiPhaseCompleteVariableRequest = 0x3
> > +} FSP_MULTI_PHASE_ACTION_23;
> > +
> > +typedef enum {
> > +  FspMultiPhaseMemInitApiIndex = 8
> > +} FSP_API_INDEX_23;
> > +///
> > +/// Action definition for FspMultiPhaseSiInit API
> > +///
> > +typedef enum {
> > +  EnumFspVariableRequestGetVariable         = 0x0,
> > +  EnumFspVariableRequestGetNextVariableName = 0x1,
> > +  EnumFspVariableRequestSetVariable         = 0x2,
> > +  EnumFspVariableRequestQueryVariableInfo   = 0x3
> > +} FSP_VARIABLE_REQUEST_TYPE;
> > +
> > +#pragma pack(16)
> > +typedef struct {
> > +  IN     FSP_VARIABLE_REQUEST_TYPE    VariableRequest;
> > +  IN OUT CHAR16                       *VariableName;
> > +  IN OUT UINT64                       *VariableNameSize;
> > +  IN OUT EFI_GUID                     *VariableGuid;
> > +  IN OUT UINT32                       *Attributes;
> > +  IN OUT UINT64                       *DataSize;
> > +  IN OUT VOID                         *Data;
> > +  OUT    UINT64                       *MaximumVariableStorageSize;
> > +  OUT    UINT64                       *RemainingVariableStorageSize;
> > +  OUT    UINT64                       *MaximumVariableSize;
> > +} FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS;
> > +
> > +typedef struct {
> > +  EFI_STATUS    VariableRequestStatus;
> > +} FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS;
> > +
> > +#pragma pack()
> > +
> > +/**
> > +  Execute 32-bit FSP API entry code.
> > +
> > +  @param[in] Function     The 32bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 32bit code.
> > +  @param[in] Param2       The second parameter to pass to 32bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute32BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  );
> > +
> > +/**
> > +  Execute 64-bit FSP API entry code.
> > +
> > +  @param[in] Function     The 64bit code entry to be executed.
> > +  @param[in] Param1       The first parameter to pass to 64bit code.
> > +  @param[in] Param2       The second parameter to pass to 64bit code.
> > +
> > +  @return EFI_STATUS.
> > +**/
> > +EFI_STATUS
> > +Execute64BitCode (
> > +  IN UINT64  Function,
> > +  IN UINT64  Param1,
> > +  IN UINT64  Param2
> > +  );
> > +
> > +/**
> > +  Call FspsMultiPhase API.
> > +
> > +  @param[in] FspsMultiPhaseParams - Parameters for MultiPhase API.
> > +  @param[in] FspHobListPtr        - Pointer to FSP HobList (valid after FSP-M
> > completed)
> > +  @param[in] ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +
> > +  @return EFI_UNSUPPORTED  - the requested FspsMultiPhase API is not
> > supported.
> > +  @return EFI_DEVICE_ERROR - the FSP header was not found.
> > +  @return EFI status returned by FspsMultiPhase API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +CallFspMultiPhaseEntry (
> > +  IN VOID      *FspMultiPhaseParams,
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  )
> > +{
> > +  FSP_INFO_HEADER  *FspHeader;
> > +  //
> > +  // FSP_MULTI_PHASE_INIT and FSP_MULTI_PHASE_SI_INIT API functions
> > having same prototype.
> > +  //
> > +  UINTN                   FspMultiPhaseApiEntry;
> > +  UINTN                   FspMultiPhaseApiOffset = 0;
> > +  EFI_STATUS              Status;
> > +  BOOLEAN                 InterruptState;
> > +  BOOLEAN                 IsVariableServiceRequest;
> > +  FSP_MULTI_PHASE_PARAMS  *FspMultiPhaseParamsPtr;
> > +
> > +  FspMultiPhaseParamsPtr   = (FSP_MULTI_PHASE_PARAMS
> > *)FspMultiPhaseParams;
> > +  IsVariableServiceRequest = FALSE;
> > +  if ((FspMultiPhaseParamsPtr->MultiPhaseAction ==
> > (int)EnumMultiPhaseGetVariableRequestInfo) ||
> > +      (FspMultiPhaseParamsPtr->MultiPhaseAction ==
> > (int)EnumMultiPhaseCompleteVariableRequest))
> > +  {
> > +    IsVariableServiceRequest = TRUE;
> > +  }
> > +
> > +  if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {
> > +    FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspmBaseAddressInMemory));
> > +    if (FspHeader == NULL) {
> > +      return EFI_DEVICE_ERROR;
> > +    } else if (FspHeader->SpecVersion < 0x24) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    FspMultiPhaseApiOffset = FspHeader-
> >FspMultiPhaseMemInitEntryOffset;
> > +  } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {
> > +    FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32
> > (PcdFspsBaseAddressInMemory));
> > +    if (FspHeader == NULL) {
> > +      return EFI_DEVICE_ERROR;
> > +    } else if (FspHeader->SpecVersion < 0x22) {
> > +      return EFI_UNSUPPORTED;
> > +    } else if ((FspHeader->SpecVersion < 0x24) && (IsVariableServiceRequest
> ==
> > TRUE)) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +
> > +    FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;
> > +  }
> > +
> > +  if (FspMultiPhaseApiOffset == 0) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  FspMultiPhaseApiEntry = FspHeader->ImageBase +
> > FspMultiPhaseApiOffset;
> > +  InterruptState        = SaveAndDisableInterrupts ();
> > +  if ((FspHeader->ImageAttribute & BIT2) == 0) {
> > +    // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT
> > +    Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry,
> > (UINTN)FspMultiPhaseParams, (UINTN)NULL);
> > +  } else {
> > +    Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry,
> > (UINTN)FspMultiPhaseParams, (UINTN)NULL);
> > +  }
> > +
> > +  SetInterruptState (InterruptState);
> > +
> > +  DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n",
> > Status));
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  FSP Wrapper Variable Request Handler
> > +
> > +  @param[in, out] FspHobListPtr        - Pointer to FSP HobList (valid after
> FSP-
> > M completed)
> > +  @param[in]      ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +
> > +  @retval EFI_UNSUPPORTED   FSP Wrapper cannot support the specific
> > variable request,
> > +                            or FSP does not support VariableService
> > +  @retval EFI_STATUS        Return FSP returned status
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspWrapperVariableRequestHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  )
> > +{
> > +  EFI_STATUS                                        Status;
> > +  FSP_MULTI_PHASE_PARAMS                            FspMultiPhaseParams;
> > +  FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS
> > *FspVariableRequestParams;
> > +  EFI_PEI_READ_ONLY_VARIABLE2_PPI                   *ReadOnlyVariablePpi;
> > +  EDKII_PEI_VARIABLE_PPI                            *VariablePpi;
> > +  BOOLEAN                                           WriteVariableSupport;
> > +  FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS
> > CompleteVariableRequestParams;
> > +
> > +  WriteVariableSupport = TRUE;
> > +  Status               = PeiServicesLocatePpi (
> > +                           &gEdkiiPeiVariablePpiGuid,
> > +                           0,
> > +                           NULL,
> > +                           (VOID **)&VariablePpi
> > +                           );
> > +  if (EFI_ERROR (Status)) {
> > +    WriteVariableSupport = FALSE;
> > +    Status               = PeiServicesLocatePpi (
> > +                             &gEfiPeiReadOnlyVariable2PpiGuid,
> > +                             0,
> > +                             NULL,
> > +                             (VOID **)&ReadOnlyVariablePpi
> > +                             );
> > +    ASSERT_EFI_ERROR (Status);
> > +    if (EFI_ERROR (Status)) {
> > +      return EFI_UNSUPPORTED;
> > +    }
> > +  }
> > +
> > +  Status = FSP_STATUS_VARIABLE_REQUEST;
> > +  while (Status == FSP_STATUS_VARIABLE_REQUEST) {
> > +    //
> > +    // Get the variable request information from FSP.
> > +    //
> > +    FspMultiPhaseParams.MultiPhaseAction =
> > (int)EnumMultiPhaseGetVariableRequestInfo;
> > +    FspMultiPhaseParams.PhaseIndex       = 0;
> > +    Status                               = CallFspMultiPhaseEntry (&FspMultiPhaseParams,
> > FspHobListPtr, ComponentIndex);
> > +    ASSERT_EFI_ERROR (Status);
> > +    //
> > +    // FSP should output this pointer for variable request information.
> > +    //
> > +    FspVariableRequestParams =
> > (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS
> > *)FspMultiPhaseParams.MultiPhaseParamPtr;
> > +    switch (FspVariableRequestParams->VariableRequest) {
> > +      case EnumFspVariableRequestGetVariable:
> > +        if (WriteVariableSupport) {
> > +          Status = VariablePpi->GetVariable (
> > +                                  VariablePpi,
> > +                                  FspVariableRequestParams->VariableName,
> > +                                  FspVariableRequestParams->VariableGuid,
> > +                                  FspVariableRequestParams->Attributes,
> > +                                  (UINTN *)FspVariableRequestParams->DataSize,
> > +                                  FspVariableRequestParams->Data
> > +                                  );
> > +        } else {
> > +          Status = ReadOnlyVariablePpi->GetVariable (
> > +                                          ReadOnlyVariablePpi,
> > +                                          FspVariableRequestParams->VariableName,
> > +                                          FspVariableRequestParams->VariableGuid,
> > +                                          FspVariableRequestParams->Attributes,
> > +                                          (UINTN *)FspVariableRequestParams->DataSize,
> > +                                          FspVariableRequestParams->Data
> > +                                          );
> > +        }
> > +
> > +        CompleteVariableRequestParams.VariableRequestStatus = Status;
> > +        FspMultiPhaseParams.MultiPhaseParamPtr              = (VOID
> > *)&CompleteVariableRequestParams;
> > +        FspMultiPhaseParams.MultiPhaseAction                =
> > (int)EnumMultiPhaseCompleteVariableRequest;
> > +        Status                                              = CallFspMultiPhaseEntry
> > (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
> > +        break;
> > +
> > +      case EnumFspVariableRequestSetVariable:
> > +        if (WriteVariableSupport) {
> > +          Status = VariablePpi->SetVariable (
> > +                                  VariablePpi,
> > +                                  FspVariableRequestParams->VariableName,
> > +                                  FspVariableRequestParams->VariableGuid,
> > +                                  *FspVariableRequestParams->Attributes,
> > +                                  (UINTN)*FspVariableRequestParams->DataSize,
> > +                                  FspVariableRequestParams->Data
> > +                                  );
> > +        } else {
> > +          Status = EFI_UNSUPPORTED;
> > +        }
> > +
> > +        CompleteVariableRequestParams.VariableRequestStatus = Status;
> > +        FspMultiPhaseParams.MultiPhaseParamPtr              = (VOID
> > *)&CompleteVariableRequestParams;
> > +        FspMultiPhaseParams.MultiPhaseAction                =
> > (int)EnumMultiPhaseCompleteVariableRequest;
> > +        Status                                              = CallFspMultiPhaseEntry
> > (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
> > +        break;
> > +
> > +      case EnumFspVariableRequestGetNextVariableName:
> > +        if (WriteVariableSupport) {
> > +          Status = VariablePpi->GetNextVariableName (
> > +                                  VariablePpi,
> > +                                  (UINTN *)FspVariableRequestParams->VariableNameSize,
> > +                                  FspVariableRequestParams->VariableName,
> > +                                  FspVariableRequestParams->VariableGuid
> > +                                  );
> > +        } else {
> > +          Status = ReadOnlyVariablePpi->NextVariableName (
> > +                                          ReadOnlyVariablePpi,
> > +                                          (UINTN *)FspVariableRequestParams-
> > >VariableNameSize,
> > +                                          FspVariableRequestParams->VariableName,
> > +                                          FspVariableRequestParams->VariableGuid
> > +                                          );
> > +        }
> > +
> > +        CompleteVariableRequestParams.VariableRequestStatus = Status;
> > +        FspMultiPhaseParams.MultiPhaseParamPtr              = (VOID
> > *)&CompleteVariableRequestParams;
> > +        FspMultiPhaseParams.MultiPhaseAction                =
> > (int)EnumMultiPhaseCompleteVariableRequest;
> > +        Status                                              = CallFspMultiPhaseEntry
> > (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
> > +        break;
> > +
> > +      case EnumFspVariableRequestQueryVariableInfo:
> > +        if (WriteVariableSupport) {
> > +          Status = VariablePpi->QueryVariableInfo (
> > +                                  VariablePpi,
> > +                                  *FspVariableRequestParams->Attributes,
> > +                                  FspVariableRequestParams-
> >MaximumVariableStorageSize,
> > +                                  FspVariableRequestParams-
> >RemainingVariableStorageSize,
> > +                                  FspVariableRequestParams->MaximumVariableSize
> > +                                  );
> > +        } else {
> > +          Status = EFI_UNSUPPORTED;
> > +        }
> > +
> > +        CompleteVariableRequestParams.VariableRequestStatus = Status;
> > +        FspMultiPhaseParams.MultiPhaseParamPtr              = (VOID
> > *)&CompleteVariableRequestParams;
> > +        FspMultiPhaseParams.MultiPhaseAction                =
> > (int)EnumMultiPhaseCompleteVariableRequest;
> > +        Status                                              = CallFspMultiPhaseEntry
> > (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
> > +        break;
> > +
> > +      default:
> > +        DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n"));
> > +        Status = EFI_UNSUPPORTED;
> > +        break;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED
> > status
> > +  //
> > +  if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <=
> > FSP_STATUS_RESET_REQUIRED_8)) {
> > +    DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n",
> > ComponentIndex, Status));
> > +    CallFspWrapperResetSystem ((UINTN)Status);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  FSP Wrapper MultiPhase Handler
> > +
> > +  @param[in, out] FspHobListPtr        - Pointer to FSP HobList (valid after
> FSP-
> > M completed)
> > +  @param[in]      ComponentIndex       - FSP Component which executing
> > MultiPhase initialization.
> > +
> > +  @retval EFI_UNSUPPORTED   Specific MultiPhase action was not
> supported.
> > +  @retval EFI_SUCCESS       MultiPhase action were completed successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FspWrapperMultiPhaseHandler (
> > +  IN OUT VOID  **FspHobListPtr,
> > +  IN UINT8     ComponentIndex
> > +  )
> > +{
> > +  EFI_STATUS                                   Status;
> > +  FSP_MULTI_PHASE_PARAMS                       FspMultiPhaseParams;
> > +  FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS
> > FspMultiPhaseGetNumber;
> > +  // UINT32                                       Index;
> > +  UINT32  NumOfPhases;
> > +
> > +  //
> > +  // Query FSP for the number of phases supported.
> > +  //
> > +  FspMultiPhaseParams.MultiPhaseAction   =
> > EnumMultiPhaseGetNumberOfPhases;
> > +  FspMultiPhaseParams.PhaseIndex         = 0;
> > +  FspMultiPhaseParams.MultiPhaseParamPtr = (VOID
> > *)&FspMultiPhaseGetNumber;
> > +  Status                                 = CallFspMultiPhaseEntry (&FspMultiPhaseParams,
> > FspHobListPtr, ComponentIndex);
> > +  if (Status == EFI_UNSUPPORTED) {
> > +    //
> > +    // MultiPhase API was not supported
> > +    //
> > +    return Status;
> > +  } else {
> > +    ASSERT_EFI_ERROR (Status);
> > +  }
> > +
> > +  NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases;
> > +  DEBUG ((DEBUG_INFO, "Multi Phase Si Init: Total %d phases.\n",
> > NumOfPhases));
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Pe
> > iFspWrapperApiTestLib/FspWrapperApiTest.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperApiTestLib/FspWrapperApiTest.c
> > new file mode 100644
> > index 0000000000..caffada924
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperApiTestLib/FspWrapperApiTest.c
> > @@ -0,0 +1,85 @@
> > +/** @file
> > +  Provide FSP wrapper API test related function.
> > +
> > +  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Guid/GuidHobFspEas.h>
> > +
> > +/**
> > +  Test the output of FSP API - FspMemoryInit.
> > +
> > +  @param[in]  FspmUpdDataPtr Address pointer to the
> > FSP_MEMORY_INIT_PARAMS structure.
> > +  @param[in]  HobListPtr     Address of the HobList pointer.
> > +
> > +  @return test result on output of FspMemoryInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspMemoryInitApiOutput (
> > +  IN  VOID  *FspmUpdDataPtr,
> > +  IN  VOID  **HobListPtr
> > +  )
> > +{
> > +  DEBUG_CODE_BEGIN ();
> > +  EFI_PEI_HOB_POINTERS  Hob;
> > +
> > +  Hob.Raw = (UINT8 *)(*(HobListPtr));
> > +  while (TRUE) {
> > +    if (END_OF_HOB_LIST (Hob) == TRUE) {
> > +      DEBUG ((DEBUG_INFO, "gFspBootLoaderTolumHobGuid not
> Found\n"));
> > +      break;
> > +    }
> > +
> > +    if ((CompareGuid (&Hob.ResourceDescriptor->Owner,
> > &gFspBootLoaderTolumHobGuid))) {
> > +      DEBUG ((DEBUG_INFO, "gFspBootLoaderTolumHobGuid Found\n"));
> > +      DEBUG ((DEBUG_INFO, "Fill Boot Loader reserved memory range with
> > 0x5A for testing purpose\n"));
> > +      SetMem ((VOID *)(UINTN)Hob.ResourceDescriptor->PhysicalStart,
> > (UINTN)Hob.ResourceDescriptor->ResourceLength, 0x5A);
> > +      break;
> > +    }
> > +
> > +    Hob.Raw = GET_NEXT_HOB (Hob);
> > +  }
> > +
> > +  DEBUG_CODE_END ();
> > +
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Test the output of FSP API - TempRamExit.
> > +
> > +  @param[in] TempRamExitParam    Address pointer to the TempRamExit
> > parameters structure.
> > +
> > +  @return test result on output of TempRamExit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspTempRamExitApiOutput (
> > +  IN VOID  *TempRamExitParam
> > +  )
> > +{
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Test the output of FSP API - FspSiliconInit.
> > +
> > +  @param[in] FspsUpdDataPtr Address pointer to the Silicon Init
> parameters
> > structure.
> > +
> > +  @return test result on output of FspSiliconInit API.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +TestFspSiliconInitApiOutput (
> > +  IN  VOID  *FspsUpdDataPtr
> > +  )
> > +{
> > +  return RETURN_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Pe
> > iFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
> > new file mode 100644
> > index 0000000000..5b378c6c55
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
> > @@ -0,0 +1,59 @@
> > +## @file
> > +#  FSP wrapper FSP-M wrapper API test INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +### @file
> > +#  Provide FSP-M wrapper API test related function.
> > +#
> > +#  Copyright (C) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010017
> > +  BASE_NAME                      = PeiFspWrapperApiTestLib
> > +  FILE_GUID                      = 87DC266A-C8F7-4A66-A0CB-018A6F5305B4
> > +  VERSION_STRING                 = 1.0
> > +  MODULE_TYPE                    = PEIM
> > +  LIBRARY_CLASS                  = FspWrapperApiTestLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32
> > +#
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Sources Section - list of files that are required for the build to succeed.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Sources]
> > +  FspWrapperApiTest.c
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Package Dependency Section - list of Package files that are required for
> > +#                              this module.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseMemoryLib
> > +  DebugLib
> > +  HobLib
> > +
> > +[Guids]
> > +  gFspBootLoaderTolumHobGuid            ## SOMETIMES_CONSUMES ## GUID
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Pe
> > iFspWrapperHobProcessLibSample/CommonHeader.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperHobProcessLibSample/CommonHeader.h
> > new file mode 100644
> > index 0000000000..d512feaa5b
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperHobProcessLibSample/CommonHeader.h
> > @@ -0,0 +1,91 @@
> > +/** @file
> > +  Implements CommonHeader.h
> > +
> > +  Copyright (c) 2013 - 2016 Intel Corporation. All rights reserved.<BR>
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef COMMON_HEADER_H___
> > +#define COMMON_HEADER_H___
> > +
> > +#include <PiPei.h>
> > +#include <Ppi/Stall.h>
> > +#include <Ppi/MasterBootMode.h>
> > +#include <Ppi/MemoryDiscovered.h>
> > +#include <Ppi/Capsule.h>
> > +#include <Library/IoLib.h>
> > +#include <Guid/DebugMask.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/PeimEntryPoint.h>
> > +#include <Library/PcdLib.h>
> > +// #include <Fch.h>
> > +#include <Library/PeiServicesTablePointerLib.h>
> > +#include <Library/PciExpressLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/MtrrLib.h>
> > +#include <Guid/MemoryTypeInformation.h>
> > +#include <Guid/SmramMemoryReserve.h>
> > +#include <Ppi/ReadOnlyVariable2.h>
> > +#include <Guid/AcpiS3Context.h>
> > +#include "MemoryInstall.h"
> > +
> > +#define   B_SLP_TYPE                        (BIT10 + BIT11 + BIT12)
> > +#define     V_SLP_TYPE_S0                   (0 << 10)
> > +#define     V_SLP_TYPE_S1                   (1 << 10)
> > +#define     V_SLP_TYPE_S3                   (3 << 10)
> > +#define     V_SLP_TYPE_S4                   (4 << 10)
> > +#define     V_SLP_TYPE_S5                   (5 << 10)
> > +#define   B_ACPI_SLP_EN                     BIT13
> > +#define     V_ACPI_SLP_EN                   BIT13
> > +#define   SPI_BASE                          0xFEC10000ul
> > +#define   EFI_CPUID_EXTENDED_FUNCTION       0x80000000
> > +#define   EFI_CPUID_VIRT_PHYS_ADDRESS_SIZE  0x80000008
> > +
> > +#define ACPI_MMIO_BASE         0xFED80000ul
> > +#define SMI_BASE               0x200                     // DWORD
> > +#define FCH_PMIOA_REG60        0x60                      // AcpiPm1EvtBlk
> > +#define FCH_PMIOA_REG62        0x62                      // AcpiPm1CntBlk
> > +#define FCH_PMIOA_REG64        0x64                      // AcpiPmTmrBlk
> > +#define PMIO_BASE              0x300                     // DWORD
> > +#define FCH_SMI_REGA0          0xA0
> > +#define FCH_SMI_REGC4          0xC4
> > +#define R_FCH_ACPI_PM_CONTROL  0x04
> > +
> > +EFI_STATUS
> > +GetAvailableMemoryRanges (
> > +  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> *MemoryMap,
> > +  IN OUT UINT8                                  *NumRanges,
> > +  IN VOID                                       *FspHobList
> > +  );
> > +
> > +EFI_STATUS
> > +GetReservedMemoryRanges (
> > +  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> *MemoryMap,
> > +  IN OUT UINT8                                  *NumRanges,
> > +  IN VOID                                       *FspHobList
> > +  );
> > +
> > +EFI_STATUS
> > +GetMemorySize (
> > +  IN  CONST EFI_PEI_SERVICES  **PeiServices,
> > +  OUT UINT64                  *LowMemoryLength,
> > +  OUT UINT64                  *HighMemoryLength,
> > +  OUT UINT64                  *GraphicMemoryBase OPTIONAL,
> > +  OUT UINT64                  *GraphicMemoryLength OPTIONAL,
> > +  IN VOID                     *FspHobList
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +SetPeiCacheMode (
> > +  IN  CONST EFI_PEI_SERVICES  **PeiServices,
> > +  IN  VOID                    *FspHobList
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Pe
> > iFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
> > new file mode 100644
> > index 0000000000..3100f4635e
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
> > @@ -0,0 +1,1439 @@
> > +/** @file
> > +  Sample to provide FSP wrapper hob process related function.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "CommonHeader.h"
> > +#include <Ppi/AmdPspFtpmPpi.h>
> > +#include <Ppi/Reset2.h>
> > +#include <FspEas/FspApi.h>
> > +#include <FspmUpd.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <FspMemoryRegionHob.h>
> > +#include <FspExportedInterfaceHob.h>
> > +
> > +#define MTRR_LIB_CACHE_MTRR_ENABLED  0x800
> > +
> > +extern EFI_GUID  gAmdResourceSizeForEachRbGuid;
> > +
> > +EFI_MEMORY_TYPE_INFORMATION  mDefaultMemoryTypeInformation[] =
> {
> > +  { EfiACPIReclaimMemory,       0x40   },
> > +  { EfiACPIMemoryNVS,           0x20   },
> > +  { EfiReservedMemoryType,      0x10   },
> > +  { EfiMemoryMappedIO,          0      },
> > +  { EfiMemoryMappedIOPortSpace, 0      },
> > +  { EfiPalCode,                 0      },
> > +  { EfiRuntimeServicesCode,     0x80   },
> > +  { EfiRuntimeServicesData,     0x40   },
> > +  { EfiLoaderCode,              0      },
> > +  { EfiLoaderData,              0      },
> > +  { EfiBootServicesCode,        0x400  },
> > +  { EfiBootServicesData,        0x1000 },
> > +  { EfiConventionalMemory,      0x4    },
> > +  { EfiUnusableMemory,          0      },
> > +  { EfiMaxMemoryType,           0      }
> > +};
> > +
> > +#pragma pack (push,4) // AGESA BUG
> > +typedef struct _APOBLIB_INFO {
> > +  BOOLEAN    Supported;              ///<  Specify if APOB supported
> > +  UINT32     ApobSize;               ///<  ApobSize
> > +  UINT64     ApobAddr;               ///<  The Address of APOB
> > +} APOBLIB_INFO;
> > +#pragma pack (pop)
> > +STATIC_ASSERT (sizeof (APOBLIB_INFO) == 16, "APOB Hob not aligned as
> > MSVC behavior!");
> > +
> > +/**
> > +
> > +  This function returns the memory ranges to be enabled, along with
> > information
> > +  describing how the range should be used.
> > +
> > +  @param  PeiServices   PEI Services Table.
> > +  @param  MemoryMap     Buffer to record details of the memory ranges
> tobe
> > enabled.
> > +  @param  NumRanges     On input, this contains the maximum number of
> > memory ranges that can be described
> > +                        in the MemoryMap buffer.
> > +
> > +  @return MemoryMap     The buffer will be filled in
> > +          NumRanges     will contain the actual number of memory ranges that
> are
> > to be anabled.
> > +          EFI_SUCCESS   The function completed successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +GetMemoryMap (
> > +  IN     EFI_PEI_SERVICES                       **PeiServices,
> > +  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> *MemoryMap,
> > +  IN OUT UINT8                                  *NumRanges,
> > +  IN     VOID                                   *FspHobList
> > +  )
> > +{
> > +  EFI_PHYSICAL_ADDRESS                   MemorySize;
> > +  EFI_PHYSICAL_ADDRESS                   RowLength;
> > +  PEI_MEMORY_RANGE_SMRAM                 SmramMask;
> > +  PEI_MEMORY_RANGE_SMRAM                 TsegMask;
> > +  UINT32                                 BlockNum;
> > +  UINT8                                  ExtendedMemoryIndex;
> > +  UINT8                                  Index;
> > +  UINT64                                 SmRamTsegBase;
> > +  UINT64                                 SmRamTsegLength;
> > +  UINT64                                 SmRamTsegMask;
> > +  UINT64                                 LowMemoryLength;
> > +  PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> > TemMemoryMap[MAX_RANGES];
> > +  UINT8                                  TemNumRanges;
> > +
> > +  if ((*NumRanges) < MAX_RANGES) {
> > +    return EFI_BUFFER_TOO_SMALL;
> > +  }
> > +
> > +  //
> > +  // Get the Memory Map
> > +  //
> > +  TemNumRanges    = MAX_RANGES;
> > +  LowMemoryLength = 0;
> > +  *NumRanges      = 0;
> > +  ZeroMem (TemMemoryMap, sizeof
> > (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * MAX_RANGES);
> > +
> > +  GetAvailableMemoryRanges (TemMemoryMap, &TemNumRanges,
> > FspHobList);
> > +
> > +  for (Index = 0; Index < TemNumRanges; Index++) {
> > +    if (TemMemoryMap[Index].CpuAddress < SIZE_4GB) {
> > +      LowMemoryLength += TemMemoryMap[Index].RangeLength;
> > +    } else {
> > +      //
> > +      // Memory Map information Upper than 4G
> > +      //
> > +      MemoryMap[*NumRanges].PhysicalAddress =
> > TemMemoryMap[Index].PhysicalAddress;
> > +      MemoryMap[*NumRanges].CpuAddress      =
> > TemMemoryMap[Index].CpuAddress;
> > +      MemoryMap[*NumRanges].RangeLength     =
> > TemMemoryMap[Index].RangeLength;
> > +      MemoryMap[*NumRanges].Type            = DualChannelDdrMainMemory;
> > +      (*NumRanges)++;
> > +    }
> > +  }
> > +
> > +  TemNumRanges = MAX_RANGES;
> > +  ZeroMem (TemMemoryMap, sizeof
> > (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * MAX_RANGES);
> > +
> > +  GetReservedMemoryRanges (TemMemoryMap, &TemNumRanges,
> > FspHobList);
> > +  for (Index = 0; Index < TemNumRanges; Index++) {
> > +    MemoryMap[*NumRanges].PhysicalAddress =
> > TemMemoryMap[Index].PhysicalAddress;
> > +    MemoryMap[*NumRanges].CpuAddress      =
> > TemMemoryMap[Index].CpuAddress;
> > +    MemoryMap[*NumRanges].RangeLength     =
> > TemMemoryMap[Index].RangeLength;
> > +    MemoryMap[*NumRanges].Type            =
> > DualChannelDdrReservedMemory;
> > +    (*NumRanges)++;
> > +  }
> > +
> > +  //
> > +  // Choose regions to reserve for SMM use (AB/H SEG and TSEG). Size is in
> > 128K blocks
> > +  //
> > +  SmramMask = PEI_MR_SMRAM_ABSEG_128K_NOCACHE |
> > PEI_MR_SMRAM_TSEG_4096K_CACHE;
> > +
> > +  //
> > +  // Generate Memory ranges for the memory map.
> > +  //
> > +  MemorySize = 0;
> > +
> > +  RowLength = LowMemoryLength;
> > +
> > +  //
> > +  // Add memory below 640KB to the memory map. Make sure memory
> > between
> > +  // 640KB and 1MB are reserved, even if not used for SMRAM
> > +  //
> > +  MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
> > +  MemoryMap[*NumRanges].CpuAddress      = MemorySize;
> > +  MemoryMap[*NumRanges].RangeLength     = 0xA0000;
> > +  MemoryMap[*NumRanges].Type            = DualChannelDdrMainMemory;
> > +  (*NumRanges)++;
> > +
> > +  // Reserve ABSEG or HSEG SMRAM if needed
> > +  //
> > +  if (SmramMask & (PEI_MR_SMRAM_ABSEG_MASK |
> > PEI_MR_SMRAM_HSEG_MASK)) {
> > +    MemoryMap[*NumRanges].PhysicalAddress =
> > MC_ABSEG_HSEG_PHYSICAL_START;
> > +    MemoryMap[*NumRanges].RangeLength     =
> MC_ABSEG_HSEG_LENGTH;
> > +    MemoryMap[*NumRanges].CpuAddress      = (SmramMask &
> > PEI_MR_SMRAM_ABSEG_MASK) ?
> > +                                            MC_ABSEG_CPU_START : MC_HSEG_CPU_START;
> > +    //
> > +    // Chipset only supports cacheable SMRAM
> > +    //
> > +    MemoryMap[*NumRanges].Type = DualChannelDdrSmramCacheable;
> > +  } else {
> > +    //
> > +    // Just mark this range reserved
> > +    //
> > +    MemoryMap[*NumRanges].PhysicalAddress = 0xA0000;
> > +    MemoryMap[*NumRanges].CpuAddress      = 0xA0000;
> > +    MemoryMap[*NumRanges].RangeLength     = 0x60000;
> > +    MemoryMap[*NumRanges].Type            =
> > DualChannelDdrReservedMemory;
> > +  }
> > +
> > +  (*NumRanges)++;
> > +  RowLength -= (0x100000 - MemorySize);
> > +  MemorySize = 0x100000;
> > +
> > +  //
> > +  // Add remaining memory to the memory map
> > +  //
> > +  MemoryMap[*NumRanges].PhysicalAddress = MemorySize;
> > +  MemoryMap[*NumRanges].CpuAddress      = MemorySize;
> > +  MemoryMap[*NumRanges].RangeLength     = RowLength;
> > +  MemoryMap[*NumRanges].Type            = DualChannelDdrMainMemory;
> > +  (*NumRanges)++;
> > +  MemorySize += RowLength;
> > +
> > +  ExtendedMemoryIndex = (UINT8)(*NumRanges - 1);
> > +
> > +  // See if we need to trim TSEG out of the highest memory range
> > +  //
> > +  if (SmramMask & PEI_MR_SMRAM_TSEG_MASK) {
> > +    // pcd
> > +    //
> > +    // Create the new range for TSEG and remove that range from the
> previous
> > SdrDdrMainMemory range
> > +    //
> > +    TsegMask = (SmramMask & PEI_MR_SMRAM_SIZE_MASK);
> > +
> > +    BlockNum = 1;
> > +    while (TsegMask) {
> > +      TsegMask >>= 1;
> > +      BlockNum <<= 1;
> > +    }
> > +
> > +    BlockNum >>= 1;
> > +
> > +    if (BlockNum) {
> > +      SmRamTsegLength                             = (BlockNum * 128 * 1024);
> > +      MemoryMap[*NumRanges].RangeLength           = SmRamTsegLength;
> > +      MemorySize                                 -=
> MemoryMap[*NumRanges].RangeLength;
> > +      MemoryMap[*NumRanges].PhysicalAddress       = MemorySize;
> > +      MemoryMap[*NumRanges].CpuAddress            = MemorySize;
> > +      SmRamTsegBase                               = MemorySize;
> > +      MemoryMap[ExtendedMemoryIndex].RangeLength -=
> > MemoryMap[*NumRanges].RangeLength;
> > +
> > +      //
> > +      // Turn On Smram
> > +      //
> > +      SmRamTsegMask = (0x0000010000000000L-SmRamTsegLength) &
> > 0xFFFFFFFE0000UL; // TSegMask[47:17]
> > +      AsmWriteMsr64 (0xC0010112, SmRamTsegBase);
> > +      AsmWriteMsr64 (0xC0010113, SmRamTsegMask); // enable
> > +    }
> > +
> > +    //
> > +    // Chipset only supports non-cacheable SMRAM
> > +    //
> > +    MemoryMap[*NumRanges].Type =
> DualChannelDdrSmramNonCacheable;
> > +
> > +    (*NumRanges)++;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +
> > +  This function installs memory.
> > +
> > +  @param   PeiServices    PEI Services table.
> > +  @param   BootMode       The specific boot path that is being followed
> > +  @param   Mch            Pointer to the DualChannelDdrMemoryInit PPI
> > +  @param   RowConfArray   Row configuration information for each row in
> > the system.
> > +
> > +  @return  EFI_SUCCESS            The function completed successfully.
> > +           EFI_INVALID_PARAMETER  One of the input parameters was invalid.
> > +           EFI_ABORTED            An error occurred.
> > +
> > +**/
> > +EFI_STATUS
> > +InstallEfiMemory (
> > +  IN      EFI_PEI_SERVICES  **PeiServices,
> > +  IN      EFI_BOOT_MODE     BootMode,
> > +  IN      VOID              *FspHobList
> > +  )
> > +{
> > +  EFI_PHYSICAL_ADDRESS                   PeiMemoryBaseAddress;
> > +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK         *SmramHobDescriptorBlock;
> > +  EFI_STATUS                             Status;
> > +  EFI_PEI_HOB_POINTERS                   Hob;
> > +  PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> > MemoryMap[MAX_RANGES];
> > +  UINT8                                  Index;
> > +  UINT8                                  NumRanges;
> > +  UINT8                                  SmramIndex;
> > +  UINT8                                  SmramRanges;
> > +  UINT64                                 PeiMemoryLength;
> > +  UINTN                                  BufferSize;
> > +  UINTN                                  PeiMemoryIndex;
> > +  EFI_RESOURCE_ATTRIBUTE_TYPE            Attribute;
> > +  EFI_SMRAM_DESCRIPTOR                   DescriptorAcpiVariable;
> > +  VOID                                   *CapsuleBuffer;
> > +  UINTN                                  CapsuleBufferLength;
> > +  EFI_PEI_CAPSULE_PPI                    *Capsule;
> > +  VOID                                   *LargeMemRangeBuf;
> > +  UINTN                                  LargeMemRangeBufLen;
> > +
> > +  //
> > +  // Get the Memory Map
> > +  //
> > +  NumRanges = MAX_RANGES;
> > +
> > +  ZeroMem (MemoryMap, sizeof
> > (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * NumRanges);
> > +
> > +  Status = GetMemoryMap (
> > +             PeiServices,
> > +             (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *)MemoryMap,
> > +             &NumRanges,
> > +             FspHobList
> > +             );
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  DEBUG ((DEBUG_INFO, "NumRanges: %d\n", NumRanges));
> > +
> > +  DEBUG ((DEBUG_INFO, "GetMemoryMap:\n"));
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    DEBUG ((DEBUG_INFO, "Index: %d ", Index));
> > +    DEBUG ((DEBUG_INFO, "RangeLength: 0x%016lX\t",
> > MemoryMap[Index].RangeLength));
> > +    DEBUG ((DEBUG_INFO, "PhysicalAddress: 0x%016lX\t",
> > MemoryMap[Index].PhysicalAddress));
> > +    DEBUG ((DEBUG_INFO, "CpuAddress: 0x%016lX\t",
> > MemoryMap[Index].CpuAddress));
> > +    DEBUG ((DEBUG_INFO, "Type: %d\n", MemoryMap[Index].Type));
> > +  }
> > +
> > +  //
> > +  // Find the highest memory range in processor native address space to
> give
> > to
> > +  // PEI. Then take the top.
> > +  //
> > +  PeiMemoryBaseAddress = 0;
> > +
> > +  //
> > +  // Query the platform for the minimum memory size
> > +  //
> > +
> > +  Status = GetPlatformMemorySize (
> > +             PeiServices,
> > +             BootMode,
> > +             &PeiMemoryLength
> > +             );
> > +  ASSERT_EFI_ERROR (Status);
> > +  PeiMemoryLength = (PeiMemoryLength > PEI_MIN_MEMORY_SIZE) ?
> > PeiMemoryLength : PEI_MIN_MEMORY_SIZE;
> > +  //
> > +
> > +  PeiMemoryIndex = 0;
> > +
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    DEBUG ((DEBUG_INFO, "Found 0x%lx bytes at ",
> > MemoryMap[Index].RangeLength));
> > +    DEBUG ((DEBUG_INFO, "0x%lx.\t",
> MemoryMap[Index].PhysicalAddress));
> > +    DEBUG ((DEBUG_INFO, "Type: %d.\n", MemoryMap[Index].Type));
> > +
> > +    if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
> > +        (MemoryMap[Index].PhysicalAddress +
> > MemoryMap[Index].RangeLength < MAX_ADDRESS) &&
> > +        (MemoryMap[Index].PhysicalAddress >= PeiMemoryBaseAddress) &&
> > +        (MemoryMap[Index].RangeLength >= PeiMemoryLength))
> > +    {
> > +      PeiMemoryBaseAddress = MemoryMap[Index].PhysicalAddress +
> > +                             MemoryMap[Index].RangeLength -
> > +                             PeiMemoryLength;
> > +      PeiMemoryIndex = Index;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Find the largest memory range excluding that given to PEI.
> > +  //
> > +  LargeMemRangeBuf    = NULL;
> > +  LargeMemRangeBufLen = 0;
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
> > +        (MemoryMap[Index].PhysicalAddress +
> > MemoryMap[Index].RangeLength < MAX_ADDRESS))
> > +    {
> > +      if (Index != PeiMemoryIndex) {
> > +        if (MemoryMap[Index].RangeLength > LargeMemRangeBufLen) {
> > +          LargeMemRangeBuf    = (VOID
> > *)((UINTN)MemoryMap[Index].PhysicalAddress);
> > +          LargeMemRangeBufLen = (UINTN)MemoryMap[Index].RangeLength;
> > +        }
> > +      } else {
> > +        if ((MemoryMap[Index].RangeLength - PeiMemoryLength) >=
> > LargeMemRangeBufLen) {
> > +          LargeMemRangeBuf    = (VOID
> > *)((UINTN)MemoryMap[Index].PhysicalAddress);
> > +          LargeMemRangeBufLen = (UINTN)(MemoryMap[Index].RangeLength
> -
> > PeiMemoryLength);
> > +        }
> > +      }
> > +    }
> > +  }
> > +
> > +  Capsule             = NULL;
> > +  CapsuleBuffer       = NULL;
> > +  CapsuleBufferLength = 0;
> > +  if (BootMode == BOOT_ON_FLASH_UPDATE) {
> > +    Status = PeiServicesLocatePpi (
> > +               &gEfiPeiCapsulePpiGuid,  // GUID
> > +               0,                       // INSTANCE
> > +               NULL,                    // EFI_PEI_PPI_DESCRIPTOR
> > +               (VOID **)&Capsule        // PPI
> > +               );
> > +    ASSERT_EFI_ERROR (Status);
> > +
> > +    if (Status == EFI_SUCCESS) {
> > +      CapsuleBuffer       = LargeMemRangeBuf;
> > +      CapsuleBufferLength = LargeMemRangeBufLen;
> > +      DEBUG ((DEBUG_INFO, "CapsuleBuffer: %x, CapsuleBufferLength:
> %x\n",
> > CapsuleBuffer, CapsuleBufferLength));
> > +
> > +      //
> > +      // Call the Capsule PPI Coalesce function to coalesce the capsule data.
> > +      //
> > +      Status = Capsule->Coalesce (
> > +                          PeiServices,
> > +                          &CapsuleBuffer,
> > +                          &CapsuleBufferLength
> > +                          );
> > +      //
> > +      // If it failed, then NULL out our capsule PPI pointer so that the capsule
> > +      // HOB does not get created below.
> > +      //
> > +      if (Status != EFI_SUCCESS) {
> > +        Capsule = NULL;
> > +      }
> > +    }
> > +  }
> > +
> > +  //
> > +  // Carve out the top memory reserved for PEI
> > +  //
> > +  Status = PeiServicesInstallPeiMemory (PeiMemoryBaseAddress,
> > PeiMemoryLength);
> > +  ASSERT_EFI_ERROR (Status);
> > +  BuildResourceDescriptorHob (
> > +    EFI_RESOURCE_SYSTEM_MEMORY,                      // MemoryType,
> > +    (
> > +     EFI_RESOURCE_ATTRIBUTE_PRESENT |
> > +     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> > +     EFI_RESOURCE_ATTRIBUTE_TESTED |
> > +     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> > +    ),
> > +    PeiMemoryBaseAddress,                            // MemoryBegin
> > +    PeiMemoryLength                                  // MemoryLength
> > +    );
> > +  // Report first 640KB of system memory
> > +  BuildResourceDescriptorHob (
> > +    EFI_RESOURCE_SYSTEM_MEMORY,
> > +    (
> > +     EFI_RESOURCE_ATTRIBUTE_PRESENT |
> > +     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> > +     EFI_RESOURCE_ATTRIBUTE_TESTED |
> > +     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> > +    ),
> > +    (EFI_PHYSICAL_ADDRESS)(0),
> > +    (UINT64)(0xA0000)
> > +    );
> > +
> > +  //
> > +  // Install physical memory descriptor hobs for each memory range.
> > +  //
> > +  SmramRanges = 0;
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    Attribute = 0;
> > +    if (MemoryMap[Index].Type == DualChannelDdrMainMemory) {
> > +      if (Index == PeiMemoryIndex) {
> > +        //
> > +        // This is a partially tested Main Memory range, give it to EFI
> > +        //
> > +        BuildResourceDescriptorHob (
> > +          EFI_RESOURCE_SYSTEM_MEMORY,
> > +          (
> > +           EFI_RESOURCE_ATTRIBUTE_PRESENT |
> > +           EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> > +           EFI_RESOURCE_ATTRIBUTE_TESTED     |
> > +           EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> > +           EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> > +           EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> > +           EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> > +          ),
> > +          MemoryMap[Index].PhysicalAddress,
> > +          MemoryMap[Index].RangeLength - PeiMemoryLength
> > +          );
> > +      } else {
> > +        //
> > +        // This is an untested Main Memory range, give it to EFI
> > +        //
> > +        BuildResourceDescriptorHob (
> > +          EFI_RESOURCE_SYSTEM_MEMORY,       // MemoryType,
> > +          (
> > +           EFI_RESOURCE_ATTRIBUTE_PRESENT |
> > +           EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> > +           EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> > +           EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> > +           EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> > +           EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> > +          ),
> > +          MemoryMap[Index].PhysicalAddress, // MemoryBegin
> > +          MemoryMap[Index].RangeLength      // MemoryLength
> > +          );
> > +      }
> > +    } else {
> > +      //
> > +      // Only report TSEG range to align
> > AcpiVariableHobOnSmramReserveHobThunk
> > +      //
> > +      if ((MemoryMap[Index].PhysicalAddress > 0x100000) &&
> > +          ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
> > +           (MemoryMap[Index].Type ==
> DualChannelDdrSmramNonCacheable)))
> > +      {
> > +        SmramRanges++;
> > +      }
> > +
> > +      //
> > +      // AMD CPU has different flow to SMM and normal mode cache
> attribute.
> > +      // SmmIPL will set TSEG and HSEG as UC when exit SMM.
> > +      // the Attribute only support 0 then it will fail to set them to UC
> > +      // otherwise the SmmIPL will hang at set memory attribute.
> > +      //
> > +      if (MemoryMap[Index].Type ==
> > DualChannelDdrGraphicsMemoryNonCacheable) {
> > +        Attribute |= EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
> > +      }
> > +
> > +      if (MemoryMap[Index].Type ==
> > DualChannelDdrGraphicsMemoryCacheable) {
> > +        Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> > EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
> > +      }
> > +
> > +      if (MemoryMap[Index].Type == DualChannelDdrReservedMemory) {
> > +        Attribute |= EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> > +                     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE;
> > +      }
> > +
> > +      //
> > +      // Make sure non-system memory is marked as reserved
> > +      //
> > +      BuildResourceDescriptorHob (
> > +        EFI_RESOURCE_MEMORY_RESERVED,     // MemoryType,
> > +        Attribute,                        // MemoryAttribute
> > +        MemoryMap[Index].PhysicalAddress, // MemoryBegin
> > +        MemoryMap[Index].RangeLength      // MemoryLength
> > +        );
> > +    }
> > +  }
> > +
> > +  //
> > +  // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of
> > SMRAM memory that contains a pointer
> > +  // to the SMM Services Table that is required on the S3 resume path
> > +  //
> > +  ASSERT (SmramRanges > 0);
> > +  BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
> > +  if (SmramRanges > 0) {
> > +    BufferSize += ((SmramRanges) * sizeof (EFI_SMRAM_DESCRIPTOR));
> > +  }
> > +
> > +  Hob.Raw = BuildGuidHob (
> > +              &gEfiSmmPeiSmramMemoryReserveGuid,
> > +              BufferSize
> > +              );
> > +  ASSERT (Hob.Raw);
> > +
> > +  SmramHobDescriptorBlock                             =
> > (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.Raw);
> > +  SmramHobDescriptorBlock->NumberOfSmmReservedRegions =
> > SmramRanges + 1;
> > +
> > +  SmramIndex = 0;
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    if ((MemoryMap[Index].PhysicalAddress > 0x100000) &&
> > +        ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
> > +         (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)))
> > +    {
> > +      //
> > +      // This is an SMRAM range, create an SMRAM descriptor
> > +      //
> > +      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart =
> > MemoryMap[Index].PhysicalAddress;
> > +      SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart      =
> > MemoryMap[Index].CpuAddress;
> > +      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize  =
> > MemoryMap[Index].RangeLength;
> > +      if (MemoryMap[Index].Type == DualChannelDdrSmramCacheable) {
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState =
> > EFI_SMRAM_CLOSED | EFI_CACHEABLE;
> > +      } else {
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState =
> > EFI_SMRAM_CLOSED;
> > +      }
> > +
> > +      if ( SmramIndex ==  SmramRanges - 1) {
> > +        //
> > +        // one extra EFI_SMRAM_DESCRIPTOR for a page of SMRAM memory
> > +        //
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize =
> > EFI_PAGE_SIZE;
> > +        SmramIndex++;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart  =
> > MemoryMap[Index].PhysicalAddress + EFI_PAGE_SIZE;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart       =
> > MemoryMap[Index].CpuAddress + EFI_PAGE_SIZE;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize   =
> > MemoryMap[Index].RangeLength - EFI_PAGE_SIZE;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState    =
> > SmramHobDescriptorBlock->Descriptor[SmramIndex-1].RegionState;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex-1].RegionState |=
> > EFI_ALLOCATED;
> > +      }
> > +
> > +      SmramIndex++;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Build a HOB with the location of the reserved memory range.
> > +  //
> > +  CopyMem (&DescriptorAcpiVariable, &SmramHobDescriptorBlock-
> > >Descriptor[SmramRanges-1], sizeof (EFI_SMRAM_DESCRIPTOR));
> > +  DescriptorAcpiVariable.CpuStart += RESERVED_CPU_S3_SAVE_OFFSET;
> > +  DEBUG ((DEBUG_INFO, "gEfiAcpiVariableGuid CpuStart: 0x%X\n",
> > (UINTN)DescriptorAcpiVariable.CpuStart));
> > +  BuildGuidDataHob (
> > +    &gEfiAcpiVariableGuid,
> > +    &DescriptorAcpiVariable,
> > +    sizeof (EFI_SMRAM_DESCRIPTOR)
> > +    );
> > +
> > +  //
> > +  // If we found the capsule PPI (and we didn't have errors), then
> > +  // call the capsule PEIM to allocate memory for the capsule.
> > +  //
> > +  if (Capsule != NULL) {
> > +    Status = Capsule->CreateState (PeiServices, CapsuleBuffer,
> > CapsuleBufferLength);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +
> > +  Find memory that is reserved so PEI has some to use.
> > +
> > +  @param  PeiServices      PEI Services table.
> > +  @param  VariableSevices  Variable PPI instance.
> > +
> > +  @return EFI_SUCCESS  The function completed successfully.
> > +                       Error value from LocatePpi()
> > +
> > +**/
> > +EFI_STATUS
> > +InstallS3Memory (
> > +  IN      EFI_PEI_SERVICES  **PeiServices,
> > +  IN      EFI_BOOT_MODE     BootMode,
> > +  IN      VOID              *FspHobList
> > +  )
> > +{
> > +  EFI_STATUS                             Status;
> > +  UINTN                                  S3MemoryBase;
> > +  UINTN                                  S3MemorySize;
> > +  UINT8                                  SmramRanges;
> > +  UINT8                                  NumRanges;
> > +  UINT8                                  Index;
> > +  UINT8                                  SmramIndex;
> > +  UINTN                                  BufferSize;
> > +  EFI_PEI_HOB_POINTERS                   Hob;
> > +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK         *SmramHobDescriptorBlock;
> > +  PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> > MemoryMap[MAX_RANGES];
> > +  RESERVED_ACPI_S3_RANGE                 *S3MemoryRangeData;
> > +  EFI_SMRAM_DESCRIPTOR                   DescriptorAcpiVariable;
> > +
> > +  //
> > +  // Get the Memory Map
> > +  //
> > +  NumRanges = MAX_RANGES;
> > +
> > +  ZeroMem (MemoryMap, sizeof
> > (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE) * NumRanges);
> > +
> > +  Status = GetMemoryMap (
> > +             PeiServices,
> > +             (PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE *)MemoryMap,
> > +             &NumRanges,
> > +             FspHobList
> > +             );
> > +  ASSERT_EFI_ERROR (Status);
> > +  DEBUG ((DEBUG_INFO, "NumRanges = 0x%x\n", NumRanges));
> > +
> > +  //
> > +  // Install physical memory descriptor hobs for each memory range.
> > +  //
> > +  SmramRanges = 0;
> > +  DEBUG ((DEBUG_INFO, "GetMemoryMap:\n"));
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    DEBUG ((DEBUG_INFO, "Index: %d ", Index));
> > +    DEBUG ((DEBUG_INFO, "RangeLength: 0x%016lX\t",
> > MemoryMap[Index].RangeLength));
> > +    DEBUG ((DEBUG_INFO, "PhysicalAddress: 0x%016lX\t",
> > MemoryMap[Index].PhysicalAddress));
> > +    DEBUG ((DEBUG_INFO, "CpuAddress: 0x%016lX\t",
> > MemoryMap[Index].CpuAddress));
> > +    DEBUG ((DEBUG_INFO, "Type: %d\n", MemoryMap[Index].Type));
> > +    if ((MemoryMap[Index].PhysicalAddress > 0x100000) &&
> > +        ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
> > +         (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable)))
> > +    {
> > +      SmramRanges++;
> > +    }
> > +  }
> > +
> > +  ASSERT (SmramRanges > 0);
> > +  DEBUG ((DEBUG_INFO, "SmramRanges = 0x%x\n", SmramRanges));
> > +
> > +  //
> > +  // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of
> > SMRAM memory that contains a pointer
> > +  // to the SMM Services Table that is required on the S3 resume path
> > +  //
> > +  BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK);
> > +  if (SmramRanges > 0) {
> > +    BufferSize += ((SmramRanges) * sizeof (EFI_SMRAM_DESCRIPTOR));
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "BufferSize = 0x%x\n", BufferSize));
> > +
> > +  Hob.Raw = BuildGuidHob (
> > +              &gEfiSmmPeiSmramMemoryReserveGuid,
> > +              BufferSize
> > +              );
> > +  ASSERT (Hob.Raw);
> > +  DEBUG ((DEBUG_INFO,
> > "gEfiSmmPeiSmramMemoryReserveGuid/SmramHobDescriptorBlock: 0x%X
> > \n", (UINTN)Hob.Raw));
> > +
> > +  SmramHobDescriptorBlock                             =
> > (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)(Hob.Raw);
> > +  SmramHobDescriptorBlock->NumberOfSmmReservedRegions =
> > SmramRanges + 1;
> > +
> > +  SmramIndex = 0;
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    DEBUG ((DEBUG_INFO, "Index: 0x%X \t", Index));
> > +    DEBUG ((DEBUG_INFO, "SmramIndex: 0x%X \n", SmramIndex));
> > +    if ((MemoryMap[Index].PhysicalAddress > 0x100000) &&
> > +        ((MemoryMap[Index].Type == DualChannelDdrSmramCacheable) ||
> > +         (MemoryMap[Index].Type == DualChannelDdrSmramNonCacheable))
> > +        )
> > +    {
> > +      //
> > +      // This is an SMRAM range, create an SMRAM descriptor
> > +      //
> > +      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart =
> > MemoryMap[Index].PhysicalAddress;
> > +      SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart      =
> > MemoryMap[Index].CpuAddress;
> > +      SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize  =
> > MemoryMap[Index].RangeLength;
> > +      if (MemoryMap[Index].Type == DualChannelDdrSmramCacheable) {
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState =
> > EFI_SMRAM_CLOSED | EFI_CACHEABLE;
> > +      } else {
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState =
> > EFI_SMRAM_CLOSED;
> > +      }
> > +
> > +      DEBUG ((DEBUG_INFO, "SmramIndex: 0x%X \n", SmramIndex));
> > +      DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock-
> >Descriptor[SmramIndex].PhysicalStart));
> > +      DEBUG ((DEBUG_INFO, "CpuStart     : 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart));
> > +      DEBUG ((DEBUG_INFO, "PhysicalSize : 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock-
> >Descriptor[SmramIndex].PhysicalSize));
> > +      DEBUG ((DEBUG_INFO, "RegionState  : 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock-
> >Descriptor[SmramIndex].RegionState));
> > +      if ( SmramIndex ==  SmramRanges - 1) {
> > +        //
> > +        // one extra EFI_SMRAM_DESCRIPTOR for a page of SMRAM memory
> > +        //
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize =
> > EFI_PAGE_SIZE;
> > +        SmramIndex++;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart  =
> > MemoryMap[Index].PhysicalAddress + EFI_PAGE_SIZE;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart       =
> > MemoryMap[Index].CpuAddress + EFI_PAGE_SIZE;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize   =
> > MemoryMap[Index].RangeLength - EFI_PAGE_SIZE;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState    =
> > SmramHobDescriptorBlock->Descriptor[SmramIndex-1].RegionState;
> > +        SmramHobDescriptorBlock->Descriptor[SmramIndex-1].RegionState |=
> > EFI_ALLOCATED;
> > +        DEBUG ((DEBUG_INFO, "SmramIndex: 0x%X \n", SmramIndex));
> > +        DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock-
> >Descriptor[SmramIndex].PhysicalStart));
> > +        DEBUG ((DEBUG_INFO, "CpuStart     : 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart));
> > +        DEBUG ((DEBUG_INFO, "PhysicalSize : 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock-
> >Descriptor[SmramIndex].PhysicalSize));
> > +        DEBUG ((DEBUG_INFO, "RegionState  : 0x%X\n\n",
> > (UINTN)SmramHobDescriptorBlock-
> >Descriptor[SmramIndex].RegionState));
> > +
> > +        DEBUG ((DEBUG_INFO, "PhysicalSize : 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex-
> > 1].PhysicalSize));
> > +        DEBUG ((DEBUG_INFO, "RegionState  : 0x%X\n",
> > (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex-
> > 1].RegionState));
> > +      }
> > +
> > +      SmramIndex++;
> > +    }
> > +  }
> > +
> > +  //
> > +  // Build a HOB with the location of the reserved memory range.
> > +  //
> > +  CopyMem (&DescriptorAcpiVariable, &SmramHobDescriptorBlock-
> > >Descriptor[SmramRanges-1], sizeof (EFI_SMRAM_DESCRIPTOR));
> > +  DescriptorAcpiVariable.CpuStart += RESERVED_CPU_S3_SAVE_OFFSET;
> > +  DEBUG ((DEBUG_INFO, "gEfiAcpiVariableGuid CpuStart: 0x%X\n",
> > (UINTN)DescriptorAcpiVariable.CpuStart));
> > +  BuildGuidDataHob (
> > +    &gEfiAcpiVariableGuid,
> > +    &DescriptorAcpiVariable,
> > +    sizeof (EFI_SMRAM_DESCRIPTOR)
> > +    );
> > +
> > +  //
> > +  // Get the location and size of the S3 memory range in the reserved page
> > and
> > +  // install it as PEI Memory.
> > +  //
> > +
> > +  DEBUG ((DEBUG_INFO, "TSEG Base = 0x%08x\n",
> > SmramHobDescriptorBlock->Descriptor[SmramRanges].PhysicalStart));
> > +  DEBUG ((DEBUG_INFO, "SmramRanges = 0x%x\n", SmramRanges));
> > +  S3MemoryRangeData = (RESERVED_ACPI_S3_RANGE *)(UINTN)
> > +                      (SmramHobDescriptorBlock-
> > >Descriptor[SmramRanges].PhysicalStart +
> > RESERVED_ACPI_S3_RANGE_OFFSET);
> > +  DEBUG ((DEBUG_INFO, "S3MemoryRangeData = 0x%08x\n",
> > (UINTN)S3MemoryRangeData));
> > +
> > +  DEBUG ((DEBUG_INFO, "S3MemoryRangeData-
> >AcpiReservedMemoryBase
> > = 0x%X\n", (UINTN)S3MemoryRangeData->AcpiReservedMemoryBase));
> > +  DEBUG ((DEBUG_INFO, "S3MemoryRangeData-
> >AcpiReservedMemorySize
> > = 0x%X\n", (UINTN)S3MemoryRangeData->AcpiReservedMemorySize));
> > +  DEBUG ((DEBUG_INFO, "S3MemoryRangeData->SystemMemoryLength =
> > 0x%X\n", (UINTN)S3MemoryRangeData->SystemMemoryLength));
> > +
> > +  S3MemoryBase = (UINTN)(S3MemoryRangeData-
> > >AcpiReservedMemoryBase);
> > +  DEBUG ((DEBUG_INFO, "S3MemoryBase = 0x%08x\n", S3MemoryBase));
> > +  S3MemorySize = (UINTN)(S3MemoryRangeData-
> > >AcpiReservedMemorySize);
> > +  DEBUG ((DEBUG_INFO, "S3MemorySize = 0x%08x\n", S3MemorySize));
> > +
> > +  Status = PeiServicesInstallPeiMemory (S3MemoryBase, S3MemorySize);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  //
> > +  // Retrieve the system memory length and build memory hob for the
> system
> > +  // memory above 1MB. So Memory Callback can set cache for the system
> > memory
> > +  // correctly on S3 boot path, just like it does on Normal boot path.
> > +  //
> > +  ASSERT ((S3MemoryRangeData->SystemMemoryLength - 0x100000) > 0);
> > +  BuildResourceDescriptorHob (
> > +    EFI_RESOURCE_SYSTEM_MEMORY,
> > +    (
> > +     EFI_RESOURCE_ATTRIBUTE_PRESENT |
> > +     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> > +     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> > +    ),
> > +    0x100000,
> > +    S3MemoryRangeData->SystemMemoryLength - 0x100000
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "MemoryBegin: 0x%lX, MemoryLength: 0x%lX\n",
> > 0x100000, S3MemoryRangeData->SystemMemoryLength - 0x100000));
> > +
> > +  for (Index = 0; Index < NumRanges; Index++) {
> > +    if ((MemoryMap[Index].Type == DualChannelDdrMainMemory) &&
> > +        (MemoryMap[Index].PhysicalAddress +
> > MemoryMap[Index].RangeLength < 0x100000))
> > +    {
> > +      BuildResourceDescriptorHob (
> > +        EFI_RESOURCE_SYSTEM_MEMORY,
> > +        (
> > +         EFI_RESOURCE_ATTRIBUTE_PRESENT |
> > +         EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> > +         EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> > +         EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> > +         EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> > +         EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> > +        ),
> > +        MemoryMap[Index].PhysicalAddress,
> > +        MemoryMap[Index].RangeLength
> > +        );
> > +      DEBUG ((DEBUG_INFO, "MemoryBegin: 0x%lX, MemoryLength:
> 0x%lX\n",
> > MemoryMap[Index].PhysicalAddress, MemoryMap[Index].RangeLength));
> > +
> > +      DEBUG ((DEBUG_INFO, "Build resource HOB for Legacy Region on S3
> > patch :"));
> > +      DEBUG ((DEBUG_INFO, " Memory Base:0x%lX Length:0x%lX\n",
> > MemoryMap[Index].PhysicalAddress, MemoryMap[Index].RangeLength));
> > +    }
> > +  }
> > +
> > +  AsmMsrOr64 (0xC0010113, 0x4403); // Enable SMRAM
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +GetPlatformMemorySize (
> > +  IN       EFI_PEI_SERVICES  **PeiServices,
> > +  IN       EFI_BOOT_MODE     BootMode,
> > +  IN OUT   UINT64            *MemorySize
> > +  )
> > +{
> > +  EFI_STATUS                       Status;
> > +  EFI_PEI_READ_ONLY_VARIABLE2_PPI  *Variable;
> > +  UINTN                            DataSize;
> > +  EFI_MEMORY_TYPE_INFORMATION      MemoryData[EfiMaxMemoryType
> +
> > 1];
> > +  UINTN                            Index;
> > +
> > +  DataSize = sizeof (MemoryData);
> > +
> > +  if (BootMode == BOOT_IN_RECOVERY_MODE) {
> > +    //
> > +    // // Treat recovery as if variable not found (eg 1st boot).
> > +    //
> > +    Status = EFI_NOT_FOUND;
> > +  } else {
> > +    Status = PeiServicesLocatePpi (
> > +               &gEfiPeiReadOnlyVariable2PpiGuid,
> > +               0,
> > +               NULL,
> > +               (VOID **)&Variable
> > +               );
> > +
> > +    ASSERT_EFI_ERROR (Status);
> > +
> > +    DataSize = sizeof (MemoryData);
> > +    Status   = Variable->GetVariable (
> > +                           Variable,
> > +                           EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
> > +                           &gEfiMemoryTypeInformationGuid,
> > +                           NULL,
> > +                           &DataSize,
> > +                           &MemoryData
> > +                           );
> > +  }
> > +
> > +  //
> > +  // Accumulate maximum amount of memory needed
> > +  //
> > +  if (EFI_ERROR (Status)) {
> > +    //
> > +    // Start with minimum memory
> > +    //
> > +    *MemorySize = PEI_MIN_MEMORY_SIZE;
> > +
> > +    for (Index = 0; Index < sizeof (mDefaultMemoryTypeInformation) / sizeof
> > (EFI_MEMORY_TYPE_INFORMATION); Index++) {
> > +      *MemorySize +=
> > mDefaultMemoryTypeInformation[Index].NumberOfPages * EFI_PAGE_SIZE;
> > +    }
> > +
> > +    //
> > +    // Build the GUID'd HOB for DXE
> > +    //
> > +    BuildGuidDataHob (
> > +      &gEfiMemoryTypeInformationGuid,
> > +      mDefaultMemoryTypeInformation,
> > +      sizeof (mDefaultMemoryTypeInformation)
> > +      );
> > +  } else {
> > +    //
> > +    // Start with at least PEI_MIN_MEMORY_SIZE pages of memory for the
> DXE
> > Core and the DXE Stack
> > +    //
> > +
> > +    *MemorySize = PEI_MIN_MEMORY_SIZE;
> > +    for (Index = 0; Index < DataSize / sizeof
> > (EFI_MEMORY_TYPE_INFORMATION); Index++) {
> > +      DEBUG ((DEBUG_INFO, "Index %d, Page: %d\n", Index,
> > MemoryData[Index].NumberOfPages));
> > +      *MemorySize += MemoryData[Index].NumberOfPages * EFI_PAGE_SIZE;
> > +    }
> > +
> > +    //
> > +    // Build the GUID'd HOB for DXE
> > +    //
> > +    BuildGuidDataHob (
> > +      &gEfiMemoryTypeInformationGuid,
> > +      MemoryData,
> > +      DataSize
> > +      );
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "GetPlatformMemorySize, MemorySize: 0x%lX\n",
> > *MemorySize));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Post FSP-M HOB process for Memory Resource Descriptor.
> > +
> > +  @param[in] FspHobList  Pointer to the HOB data structure produced by
> FSP.
> > +
> > +  @return If platform process the FSP hob list successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PostFspmHobProcess (
> > +  IN VOID  *FspHobList
> > +  )
> > +{
> > +  EFI_STATUS        Status;
> > +  EFI_BOOT_MODE     BootMode;
> > +  EFI_PEI_SERVICES  **PeiServices;
> > +
> > +  PreFspmHobProcess (FspHobList);
> > +
> > +  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
> > +  //
> > +  // Get boot mode
> > +  //
> > +  SetPeiCacheMode ((const EFI_PEI_SERVICES **)PeiServices, FspHobList);
> > +
> > +  Status = PeiServicesGetBootMode (&BootMode);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  if (BootMode == BOOT_ON_S3_RESUME) {
> > +    DEBUG ((DEBUG_INFO, "Following BOOT_ON_S3_RESUME boot
> > path.\n"));
> > +
> > +    Status = InstallS3Memory (PeiServices, BootMode, FspHobList);
> > +    ASSERT_EFI_ERROR (Status);
> > +    if (EFI_ERROR (Status)) {
> > +      PeiServicesResetSystem ();
> > +    }
> > +
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  Status = InstallEfiMemory (PeiServices, BootMode, FspHobList);
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Process FSP HOB list
> > +
> > +  @param[in] FspHobList  Pointer to the HOB data structure produced by
> FSP.
> > +
> > +**/
> > +VOID
> > +ProcessFspHobList (
> > +  IN VOID  *FspHobList
> > +  )
> > +{
> > +  EFI_PEI_HOB_POINTERS  FspHob;
> > +
> > +  FspHob.Raw = FspHobList;
> > +
> > +  //
> > +  // Add all the HOBs from FSP binary to FSP wrapper
> > +  //
> > +  while (!END_OF_HOB_LIST (FspHob)) {
> > +    if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
> > +      //
> > +      // Skip FSP binary creates PcdDataBaseHobGuid
> > +      //
> > +      if (!CompareGuid (&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) {
> > +        BuildGuidDataHob (
> > +          &FspHob.Guid->Name,
> > +          GET_GUID_HOB_DATA (FspHob),
> > +          GET_GUID_HOB_DATA_SIZE (FspHob)
> > +          );
> > +      }
> > +    }
> > +
> > +    FspHob.Raw = GET_NEXT_HOB (FspHob);
> > +  }
> > +}
> > +
> > +/**
> > +  Post FSP-S HOB process (not Memory Resource Descriptor).
> > +
> > +  @param[in] FspHobList  Pointer to the HOB data structure produced by
> FSP.
> > +
> > +  @return If platform process the FSP hob list successfully.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PostFspsHobProcess (
> > +  IN VOID  *FspHobList
> > +  )
> > +{
> > +  //
> > +  // PostFspsHobProcess () will be called in both FSP API and Dispatch
> modes
> > to
> > +  // align the same behavior and support a variety of boot loader
> > implementations.
> > +  // Boot loader provided library function is recommended to support both
> > API and
> > +  // Dispatch modes by checking PcdFspModeSelection.
> > +  //
> > +  if (PcdGet8 (PcdFspModeSelection) == 1) {
> > +    //
> > +    // Only in FSP API mode the wrapper has to build hobs basing on FSP
> > output data.
> > +    // In this case FspHobList cannot be NULL.
> > +    //
> > +    ASSERT (FspHobList != NULL);
> > +    ProcessFspHobList (FspHobList);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +GetAvailableMemoryRanges (
> > +  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> *MemoryMap,
> > +  IN OUT UINT8                                  *NumRanges,
> > +  IN VOID                                       *FspHobList
> > +  )
> > +{
> > +  EFI_PEI_HOB_POINTERS  Hob;
> > +
> > +  DEBUG ((DEBUG_INFO, "GetAvailableMemoryRanges++\n"));
> > +  if ((*NumRanges) < MAX_RANGES) {
> > +    return EFI_BUFFER_TOO_SMALL;
> > +  }
> > +
> > +  *NumRanges = 0;
> > +
> > +  // Get Pointer to HOB
> > +  Hob.Raw = (UINT8 *)(UINTN)FspHobList;
> > +  ASSERT (Hob.Raw != NULL);
> > +  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> > Hob.Raw)) != NULL) {
> > +    if ((Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_SYSTEM_MEMORY)) {
> > +      MemoryMap[*NumRanges].PhysicalAddress =
> Hob.ResourceDescriptor-
> > >PhysicalStart;
> > +      MemoryMap[*NumRanges].CpuAddress      =  Hob.ResourceDescriptor-
> > >PhysicalStart;
> > +      MemoryMap[*NumRanges].RangeLength     =  Hob.ResourceDescriptor-
> > >ResourceLength;
> > +      MemoryMap[*NumRanges].Type            =
> > DualChannelDdrReservedMemory;
> > +      (*NumRanges)++;
> > +      DEBUG ((
> > +        DEBUG_INFO,
> > +        " GetAvailableMemoryRanges Base:0x%016lX, Size: 0x%016lX\n", \
> > +        Hob.ResourceDescriptor->PhysicalStart, \
> > +        Hob.ResourceDescriptor->ResourceLength
> > +        ));
> > +    }
> > +
> > +    Hob.Raw = GET_NEXT_HOB (Hob);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +GetReservedMemoryRanges (
> > +  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> *MemoryMap,
> > +  IN OUT UINT8                                  *NumRanges,
> > +  IN VOID                                       *FspHobList
> > +  )
> > +{
> > +  EFI_PEI_HOB_POINTERS  Hob;
> > +
> > +  DEBUG ((DEBUG_INFO, "GetReservedMemoryRanges\n"));
> > +  if ((*NumRanges) < MAX_RANGES) {
> > +    return EFI_BUFFER_TOO_SMALL;
> > +  }
> > +
> > +  *NumRanges = 0;
> > +
> > +  // Get Pointer to HOB
> > +  Hob.Raw = (UINT8 *)(UINTN)FspHobList;
> > +  ASSERT (Hob.Raw != NULL);
> > +  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> > Hob.Raw)) != NULL) {
> > +    if ((Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_MEMORY_RESERVED)) {
> > +      MemoryMap[*NumRanges].PhysicalAddress =
> Hob.ResourceDescriptor-
> > >PhysicalStart;
> > +      MemoryMap[*NumRanges].CpuAddress      =  Hob.ResourceDescriptor-
> > >PhysicalStart;
> > +      MemoryMap[*NumRanges].RangeLength     =  Hob.ResourceDescriptor-
> > >ResourceLength;
> > +      MemoryMap[*NumRanges].Type            =
> > DualChannelDdrReservedMemory;
> > +      (*NumRanges)++;
> > +      DEBUG ((
> > +        DEBUG_INFO,
> > +        " GetReservedMemoryRanges Base:0x%016lX, Size: 0x%016lX\n", \
> > +        Hob.ResourceDescriptor->PhysicalStart, \
> > +        Hob.ResourceDescriptor->ResourceLength
> > +        ));
> > +    }
> > +
> > +    Hob.Raw = GET_NEXT_HOB (Hob);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +PreFspmHobProcess (
> > +  IN VOID  *FspHobList
> > +  )
> > +{
> > +  EFI_PEI_HOB_POINTERS  Hob;
> > +  UINT64                FspMemorySize;
> > +  EFI_PHYSICAL_ADDRESS  FspMemoryBase;
> > +  BOOLEAN               FoundFspMemHob;
> > +  UINT64                SpaceAfterFSPReservedMemory = 0;
> > +
> > +  FspMemorySize  = 0;
> > +  FspMemoryBase  = 0;
> > +  FoundFspMemHob = FALSE;
> > +
> > +  //
> > +  // Parse the hob list from fsp
> > +  // Report all the resource hob except the memory between 1M and 4G
> > +  //
> > +  Hob.Raw = (UINT8 *)(UINTN)FspHobList;
> > +  DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
> > +
> > +  // In HOBs returned by FSP-M, there is an unintended memory region
> > overlap:
> > +  // e.g.:
> > +  // 0x00000000 - 0x80000000 Empty Memory
> > +  // 0x80000000 - 0xFFFFFFFF Reserved
> > +  // ......
> > +  // 0x7F000000 - 0x80000000 Taken by FSP
> > +  // Since AMD's current FSP implementation doesn't FIX empty memory
> size,
> > so we do it here.
> > +
> > +  // Firstly we pick up FSP Memory information.
> > +  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> > Hob.Raw)) != NULL) {
> > +    if (  (Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length
> below
> > 4G
> > +       && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
> > +       && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor-
> > >ResourceLength <= BASE_4GB)
> > +       && (CompareGuid (&Hob.ResourceDescriptor->Owner,
> > &gFspReservedMemoryResourceHobGuid)))
> > +    {
> > +      FoundFspMemHob = TRUE;
> > +      FspMemoryBase  = Hob.ResourceDescriptor->PhysicalStart;
> > +      FspMemorySize  = Hob.ResourceDescriptor->ResourceLength;
> > +      DEBUG ((DEBUG_INFO, "Find fsp mem hob, base 0x%llx, len 0x%llx\n",
> > FspMemoryBase, FspMemorySize));
> > +      FSP_MEMORY_REGION_HOB  *FspRegion = BuildGuidHob
> > (&gFspReservedMemoryResourceHobGuid, sizeof
> > (FSP_MEMORY_REGION_HOB));
> > +      FspRegion->BeginAddress = Hob.ResourceDescriptor->PhysicalStart;
> > +      FspRegion->Length       = Hob.ResourceDescriptor->ResourceLength;
> > +    }
> > +
> > +    Hob.Raw = GET_NEXT_HOB (Hob);
> > +  }
> > +
> > +  Hob.Raw = (UINT8 *)(UINTN)FspHobList;
> > +
> > +  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> > Hob.Raw)) != NULL) {
> > +    DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n",
> > Hob.ResourceDescriptor->ResourceType));
> > +    if ((Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_SYSTEM_MEMORY) ||
> > +        (Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_MEMORY_RESERVED))
> > +    {
> > +      DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n",
> > Hob.ResourceDescriptor->ResourceAttribute));
> > +      DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n",
> > Hob.ResourceDescriptor->PhysicalStart));
> > +      DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n",
> > Hob.ResourceDescriptor->ResourceLength));
> > +      DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor-
> > >Owner));
> > +    }
> > +
> > +    if (  (Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below
> > 4G
> > +       && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor-
> > >ResourceLength <= BASE_4GB))
> > +    {
> > +      // Now we fix the FSP memory overlap issue.
> > +      if (  (Hob.ResourceDescriptor->PhysicalStart < FspMemoryBase)
> > +         && (Hob.ResourceDescriptor->PhysicalStart+Hob.ResourceDescriptor-
> > >ResourceLength >= FspMemoryBase+FspMemorySize))
> > +      {
> > +        DEBUG ((DEBUG_ERROR, "Found overlap! Adjusting (%llx->%llx)\n",
> > Hob.ResourceDescriptor->ResourceLength, Hob.ResourceDescriptor-
> > >ResourceLength-FspMemorySize));
> > +        SpaceAfterFSPReservedMemory             = (Hob.ResourceDescriptor-
> > >PhysicalStart+Hob.ResourceDescriptor->ResourceLength)-
> > (FspMemoryBase+FspMemorySize);
> > +        Hob.ResourceDescriptor->ResourceLength -=
> > (FspMemorySize+SpaceAfterFSPReservedMemory);
> > +      }
> > +
> > +      Hob.Raw = GET_NEXT_HOB (Hob);
> > +      continue;
> > +    }
> > +
> > +    if (  (Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length
> below
> > 4G
> > +       && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
> > +       && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor-
> > >ResourceLength <= BASE_4GB)
> > +       && (CompareGuid (&Hob.ResourceDescriptor->Owner,
> > &gFspReservedMemoryResourceHobGuid)))
> > +    {
> > +      FoundFspMemHob = TRUE;
> > +      FspMemoryBase  = Hob.ResourceDescriptor->PhysicalStart;
> > +      FspMemorySize  = Hob.ResourceDescriptor->ResourceLength;
> > +      DEBUG ((DEBUG_INFO, "Find fsp mem hob, base 0x%llx, len 0x%llx\n",
> > FspMemoryBase, FspMemorySize));
> > +    }
> > +
> > +    Hob.Raw = GET_NEXT_HOB (Hob);
> > +  }
> > +
> > +  if (!FoundFspMemHob) {
> > +    DEBUG ((DEBUG_INFO, "Didn't find the fsp used memory
> > information.\n"));
> > +    // ASSERT(FALSE);
> > +  }
> > +
> > +  if (SpaceAfterFSPReservedMemory) {
> > +    DEBUG ((DEBUG_INFO, "Left some space after FSP. Creating space for
> > them.\n"));
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
> > +  DEBUG ((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));
> > +  BuildResourceDescriptorHob (
> > +    EFI_RESOURCE_SYSTEM_MEMORY,                     // MemoryType,
> > +    (
> > +     EFI_RESOURCE_ATTRIBUTE_PRESENT |
> > +     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> > +     EFI_RESOURCE_ATTRIBUTE_TESTED |
> > +     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> > +     EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
> > +    ),
> > +    FspMemoryBase,                            // MemoryBegin
> > +    FspMemorySize                             // MemoryLength
> > +    );
> > +  BuildMemoryAllocationHob (FspMemoryBase, FspMemorySize,
> > EfiRuntimeServicesCode);
> > +
> > +  Hob.Raw = GetNextGuidHob (&gFspExportedInterfaceHobGuid,
> > FspHobList);
> > +  FSP_EXPORTED_INTERFACE_HOB  *ExportedInterfaceHob =
> > GET_GUID_HOB_DATA (Hob.Raw);
> > +  EFI_PEI_PPI_DESCRIPTOR      *FspProvidedPpiList   = AllocatePool (sizeof
> > (EFI_PEI_PPI_DESCRIPTOR)*2);
> > +
> > +  if (FspProvidedPpiList != NULL) {
> > +    FspProvidedPpiList[0].Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI);
> > +    FspProvidedPpiList[0].Guid  = &gAmdPspFtpmPpiGuid;
> > +    FspProvidedPpiList[0].Ppi   = ExportedInterfaceHob->PspFtpmPpi;
> > +    FspProvidedPpiList[1].Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
> > +    FspProvidedPpiList[1].Guid  = &gEfiPeiReset2PpiGuid;
> > +    FspProvidedPpiList[1].Ppi   = ExportedInterfaceHob->Reset2Ppi;
> > +  }
> > +
> > +  PeiServicesInstallPpi (FspProvidedPpiList);
> > +
> > +  Hob.Raw = GetNextGuidHob (&gAmdPspApobHobGuid, FspHobList);
> > +  APOBLIB_INFO  *ApobHob = GET_GUID_HOB_DATA (Hob.Raw);
> > +
> > +  if (ApobHob->Supported) {
> > +    DEBUG ((DEBUG_INFO, "FSP-M Wrapper: Reserving APOB region
> > %p+%x\n", (UINTN)ApobHob->ApobAddr, ApobHob->ApobSize));
> > +    BuildMemoryAllocationHob (ApobHob->ApobAddr, ApobHob-
> >ApobSize,
> > EfiACPIMemoryNVS);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +VOID
> > +MtrrLibInitializeMtrrMask (
> > +  OUT UINT64  *MtrrValidBitsMask,
> > +  OUT UINT64  *MtrrValidAddressMask
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +SetPeiCacheMode (
> > +  IN  CONST EFI_PEI_SERVICES  **PeiServices,
> > +  IN  VOID                    *FspHobList
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  EFI_BOOT_MODE  BootMode;
> > +  UINT64         MemoryLength;
> > +  UINT64         MemOverflow;
> > +  UINT64         MemoryLengthUc;
> > +  UINT64         MaxMemoryLength;
> > +  UINT64         LowMemoryLength;
> > +  UINT64         HighMemoryLength;
> > +  UINT8          Index;
> > +  MTRR_SETTINGS  MtrrSetting;
> > +  UINT64         MsrData;
> > +  UINT64         MtrrValidBitsMask;
> > +  UINT64         MtrrValidAddressMask;
> > +
> > +  MtrrLibInitializeMtrrMask (
> > +    &MtrrValidBitsMask,
> > +    &MtrrValidAddressMask
> > +    );
> > +
> > +  //
> > +  // Variable initialization
> > +  //
> > +  LowMemoryLength  = 0;
> > +  HighMemoryLength = 0;
> > +  MemoryLengthUc   = 0;
> > +
> > +  Status = (*PeiServices)->GetBootMode (
> > +                             PeiServices,
> > +                             &BootMode
> > +                             );
> > +
> > +  //
> > +  // Determine memory usage
> > +  //
> > +  GetMemorySize (
> > +    PeiServices,
> > +    &LowMemoryLength,
> > +    &HighMemoryLength,
> > +    NULL,
> > +    NULL,
> > +    FspHobList
> > +    );
> > +
> > +  MaxMemoryLength = LowMemoryLength;
> > +
> > +  //
> > +  // Round up to nearest 256MB with high memory and 64MB w/o high
> > memory
> > +  //
> > +  if (HighMemoryLength != 0 ) {
> > +    MemOverflow = (LowMemoryLength & 0x0fffffff);
> > +    if (MemOverflow != 0) {
> > +      MaxMemoryLength = LowMemoryLength + (0x10000000 -
> > MemOverflow);
> > +    }
> > +  } else {
> > +    MemOverflow = (LowMemoryLength & 0x03ffffff);
> > +    if (MemOverflow != 0) {
> > +      MaxMemoryLength = LowMemoryLength + (0x4000000 -
> > MemOverflow);
> > +    }
> > +  }
> > +
> > +  ZeroMem (&MtrrSetting, sizeof (MTRR_SETTINGS));
> > +  for (Index = 0; Index < 2; Index++) {
> > +    MtrrSetting.Fixed.Mtrr[Index] = 0x1E1E1E1E1E1E1E1Eul;
> > +  }
> > +
> > +  // 0xA0000-0xBFFFF used for ASEG which cache type is controlled by bit
> > 10:8 of SMMMask(MSR 0xC0010113)
> > +  for (Index = 3; Index < 11; Index++) {
> > +    MtrrSetting.Fixed.Mtrr[Index] = 0x1C1C1C1C1C1C1C1Cul;
> > +  }
> > +
> > +  //
> > +  // Cache the flash area to improve the boot performance in PEI phase
> > +  //
> > +  Index                                  = 0;
> > +  MtrrSetting.Variables.Mtrr[Index].Base = FixedPcdGet32
> > (PcdFlashAreaBaseAddress) | CacheWriteProtected;
> > +  MtrrSetting.Variables.Mtrr[Index].Mask = ((~((UINT64)(FixedPcdGet32
> > (PcdFlashAreaSize) - 1))) & MtrrValidBitsMask) |
> > MTRR_LIB_CACHE_MTRR_ENABLED;
> > +
> > +  Index++;
> > +
> > +  MemOverflow = 0;
> > +  while (MaxMemoryLength > MemOverflow) {
> > +    MtrrSetting.Variables.Mtrr[Index].Base = (MemOverflow &
> > MtrrValidAddressMask) | CacheWriteBack;
> > +    MemoryLength                           = MaxMemoryLength - MemOverflow;
> > +    MemoryLength                           = GetPowerOfTwo64 (MemoryLength);
> > +    MtrrSetting.Variables.Mtrr[Index].Mask = ((~(MemoryLength - 1)) &
> > MtrrValidBitsMask) | MTRR_LIB_CACHE_MTRR_ENABLED;
> > +
> > +    MemOverflow += MemoryLength;
> > +    Index++;
> > +  }
> > +
> > +  MemoryLength = LowMemoryLength;
> > +
> > +  while (MaxMemoryLength != MemoryLength) {
> > +    MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength -
> > MemoryLength);
> > +
> > +    MtrrSetting.Variables.Mtrr[Index].Base = ((MaxMemoryLength -
> > MemoryLengthUc) & MtrrValidAddressMask) | CacheUncacheable;
> > +    MtrrSetting.Variables.Mtrr[Index].Mask = ((~(MemoryLengthUc   - 1)) &
> > MtrrValidBitsMask) | MTRR_LIB_CACHE_MTRR_ENABLED;
> > +    MaxMemoryLength                       -= MemoryLengthUc;
> > +    Index++;
> > +  }
> > +
> > +  if (HighMemoryLength > 0) {
> > +    MsrData  = AsmReadMsr64 (0xC0010010ul);
> > +    MsrData |= BIT22;
> > +    AsmWriteMsr64 (0xC0010010ul, MsrData);
> > +  }
> > +
> > +  for (Index = 0; Index < MTRR_NUMBER_OF_VARIABLE_MTRR; Index++) {
> > +    if (MtrrSetting.Variables.Mtrr[Index].Base == 0) {
> > +      break;
> > +    }
> > +
> > +    DEBUG ((DEBUG_INFO, "Base=%lx, Mask=%lx\n",
> > MtrrSetting.Variables.Mtrr[Index].Base,
> > MtrrSetting.Variables.Mtrr[Index].Mask));
> > +  }
> > +
> > +  //
> > +  // set FE/E bits for IA32_MTRR_DEF_TYPE
> > +  //
> > +  MtrrSetting.MtrrDefType |=  3 <<10;
> > +
> > +  AsmWriteMsr64 (0xC0010010ul, (AsmReadMsr64 (0xC0010010ul) | (1
> <<
> > 19)));
> > +  MtrrSetAllMtrrs (&MtrrSetting);
> > +  AsmWriteMsr64 (0xC0010010ul, (AsmReadMsr64 (0xC0010010ul) &
> (~(1
> > << 19))));
> > +  //
> > +  // Dump MTRR Setting
> > +  //
> > +  MtrrDebugPrintAllMtrrs ();
> > +
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +GetMemorySize (
> > +  IN  CONST EFI_PEI_SERVICES  **PeiServices,
> > +  OUT UINT64                  *LowMemoryLength,
> > +  OUT UINT64                  *HighMemoryLength,
> > +  OUT UINT64                  *GraphicMemoryBase OPTIONAL,
> > +  OUT UINT64                  *GraphicMemoryLength OPTIONAL,
> > +  IN VOID                     *FspHobList
> > +  )
> > +{
> > +  EFI_PEI_HOB_POINTERS  Hob;
> > +  EFI_PEI_HOB_POINTERS  FspHob;
> > +
> > +  *HighMemoryLength = 0;
> > +  *LowMemoryLength  = 0x100000;
> > +  // We don't support getting UMA information from FSP hob for now.
> > +  if ((GraphicMemoryBase != NULL) || (GraphicMemoryLength != NULL)) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  // Get HOB Data
> > +  Hob.Raw    = (UINT8 *)(UINTN)FspHobList;
> > +  FspHob.Raw = NULL;
> > +  ASSERT (Hob.Raw != NULL);
> > +  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,
> > Hob.Raw)) != NULL) {
> > +    if (CompareGuid (&Hob.ResourceDescriptor->Owner,
> > &gFspReservedMemoryResourceHobGuid)) {
> > +      FspHob.Raw = Hob.Raw;
> > +    }
> > +
> > +    if (Hob.ResourceDescriptor->ResourceType ==
> > EFI_RESOURCE_SYSTEM_MEMORY) {
> > +      if (Hob.ResourceDescriptor->PhysicalStart < SIZE_4GB) {
> > +        if (LowMemoryLength != NULL) {
> > +          *LowMemoryLength = Hob.ResourceDescriptor->ResourceLength;
> > +        }
> > +      } else if (Hob.ResourceDescriptor->PhysicalStart >= SIZE_4GB) {
> > +        if (HighMemoryLength != NULL) {
> > +          *HighMemoryLength = Hob.ResourceDescriptor->ResourceLength;
> > +        }
> > +      }
> > +    }
> > +
> > +    Hob.Raw = GET_NEXT_HOB (Hob);
> > +  }
> > +
> > +  if ((FspHob.Raw != NULL) && (*LowMemoryLength ==
> > FspHob.ResourceDescriptor->PhysicalStart)) {
> > +    // FSP should also be cached.
> > +    *LowMemoryLength += FspHob.ResourceDescriptor->ResourceLength;
> > +    DEBUG ((DEBUG_INFO, "Patching cache region for FSP area!\n"));
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Pe
> > iFspWrapperHobProcessLibSample/MemoryInstall.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperHobProcessLibSample/MemoryInstall.h
> > new file mode 100644
> > index 0000000000..c9a58aea56
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> > eiFspWrapperHobProcessLibSample/MemoryInstall.h
> > @@ -0,0 +1,171 @@
> > +/** @file
> > +  Implements MemoryInstall.h
> > +  Framework PEIM to initialize memory on an DDR2 SDRAM Memory
> > Controller.
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  Copyright (c) 2013 - 2016 Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef MRC_WRAPPER_H_
> > +#define MRC_WRAPPER_H_
> > +
> > +//
> > +// Maximum number of memory ranges supported by the memory
> controller
> > +//
> > +#define MAX_RANGES  16
> > +
> > +//
> > +// Min. of 48MB PEI phase
> > +//
> > +#define  PEI_MIN_MEMORY_SIZE           (8 * 0x800000)
> > +#define  PEI_RECOVERY_MIN_MEMORY_SIZE  (8 * 0x800000)
> > +
> > +//
> > +// SMRAM Memory Range
> > +//
> > +#define PEI_MEMORY_RANGE_SMRAM       UINT32
> > +#define PEI_MR_SMRAM_ALL             0xFFFFFFFF
> > +#define PEI_MR_SMRAM_NONE            0x00000000
> > +#define PEI_MR_SMRAM_CACHEABLE_MASK  0x80000000
> > +#define PEI_MR_SMRAM_SEGTYPE_MASK    0x00FF0000
> > +#define PEI_MR_SMRAM_ABSEG_MASK      0x00010000
> > +#define PEI_MR_SMRAM_HSEG_MASK       0x00020000
> > +#define PEI_MR_SMRAM_TSEG_MASK       0x00040000
> > +
> > +//
> > +// SMRAM range definitions
> > +//
> > +#define MC_ABSEG_HSEG_PHYSICAL_START  0x000A0000
> > +#define MC_ABSEG_HSEG_LENGTH          0x00020000
> > +#define MC_ABSEG_CPU_START            0x000A0000
> > +#define MC_HSEG_CPU_START             0xFEDA0000
> > +
> > +//
> > +// If adding additional entries, SMRAM Size
> > +// is a multiple of 128KB.
> > +//
> > +#define PEI_MR_SMRAM_SIZE_MASK        0x0000FFFF
> > +#define PEI_MR_SMRAM_SIZE_128K_MASK   0x00000001
> > +#define PEI_MR_SMRAM_SIZE_256K_MASK   0x00000002
> > +#define PEI_MR_SMRAM_SIZE_512K_MASK   0x00000004
> > +#define PEI_MR_SMRAM_SIZE_1024K_MASK  0x00000008
> > +#define PEI_MR_SMRAM_SIZE_2048K_MASK  0x00000010
> > +#define PEI_MR_SMRAM_SIZE_4096K_MASK  0x00000020
> > +#define PEI_MR_SMRAM_SIZE_8192K_MASK  0x00000040
> > +
> > +#define PEI_MR_SMRAM_ABSEG_128K_NOCACHE  0x00010001
> > +#define PEI_MR_SMRAM_HSEG_128K_CACHE     0x80020001
> > +#define PEI_MR_SMRAM_HSEG_128K_NOCACHE   0x00020001
> > +#define PEI_MR_SMRAM_TSEG_128K_CACHE     0x80040001
> > +#define PEI_MR_SMRAM_TSEG_128K_NOCACHE   0x00040001
> > +#define PEI_MR_SMRAM_TSEG_256K_CACHE     0x80040002
> > +#define PEI_MR_SMRAM_TSEG_256K_NOCACHE   0x00040002
> > +#define PEI_MR_SMRAM_TSEG_512K_CACHE     0x80040004
> > +#define PEI_MR_SMRAM_TSEG_512K_NOCACHE   0x00040004
> > +#define PEI_MR_SMRAM_TSEG_1024K_CACHE    0x80040008
> > +#define PEI_MR_SMRAM_TSEG_1024K_NOCACHE  0x00040008
> > +#define PEI_MR_SMRAM_TSEG_2048K_CACHE    0x80040010
> > +#define PEI_MR_SMRAM_TSEG_2048K_NOCACHE  0x00040010
> > +#define PEI_MR_SMRAM_TSEG_4096K_CACHE    0x80040020
> > +#define PEI_MR_SMRAM_TSEG_4096K_NOCACHE  0x00040020
> > +#define PEI_MR_SMRAM_TSEG_8192K_CACHE    0x80040040
> > +#define PEI_MR_SMRAM_TSEG_8192K_NOCACHE  0x00040040
> > +
> > +//
> > +// Pci Memory Hole
> > +//
> > +#define PEI_MEMORY_RANGE_PCI_MEMORY  UINT32
> > +
> > +typedef enum {
> > +  Ignore,
> > +  Quick,
> > +  Sparse,
> > +  Extensive
> > +} PEI_MEMORY_TEST_OP;
> > +
> > +// Memory range types
> > +//
> > +typedef enum {
> > +  DualChannelDdrMainMemory,
> > +  DualChannelDdrSmramCacheable,
> > +  DualChannelDdrSmramNonCacheable,
> > +  DualChannelDdrGraphicsMemoryCacheable,
> > +  DualChannelDdrGraphicsMemoryNonCacheable,
> > +  DualChannelDdrReservedMemory,
> > +  DualChannelDdrMaxMemoryRangeType
> > +} PEI_DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE;
> > +
> > +//
> > +// Memory map range information
> > +//
> > +typedef struct {
> > +  EFI_PHYSICAL_ADDRESS                      PhysicalAddress;
> > +  EFI_PHYSICAL_ADDRESS                      CpuAddress;
> > +  EFI_PHYSICAL_ADDRESS                      RangeLength;
> > +  PEI_DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE    Type;
> > +} PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE;
> > +
> > +//
> > +// This structure stores the base and size of the ACPI reserved memory
> used
> > when
> > +// resuming from S3.  This region must be allocated by the platform code.
> > +//
> > +typedef struct {
> > +  UINT32    AcpiReservedMemoryBase;
> > +  UINT32    AcpiReservedMemorySize;
> > +  UINT32    SystemMemoryLength;
> > +} RESERVED_ACPI_S3_RANGE;
> > +
> > +#define RESERVED_ACPI_S3_RANGE_OFFSET  (EFI_PAGE_SIZE - sizeof
> > (RESERVED_ACPI_S3_RANGE))
> > +
> > +//
> > +// ------------------------ TSEG Base
> > +//
> > +// ------------------------ RESERVED_CPU_S3_SAVE_OFFSET
> > +// CPU S3 data
> > +// ------------------------ RESERVED_ACPI_S3_RANGE_OFFSET
> > +// S3 Memory base structure
> > +// ------------------------ TSEG + 1 page
> > +
> > +#define RESERVED_CPU_S3_SAVE_OFFSET
> > (RESERVED_ACPI_S3_RANGE_OFFSET - sizeof (SMM_S3_RESUME_STATE))
> > +
> > +//
> > +// Function prototypes.
> > +//
> > +
> > +EFI_STATUS
> > +InstallEfiMemory (
> > +  IN      EFI_PEI_SERVICES  **PeiServices,
> > +  IN      EFI_BOOT_MODE     BootMode,
> > +  IN      VOID              *FspHobList
> > +  );
> > +
> > +EFI_STATUS
> > +InstallS3Memory (
> > +  IN      EFI_PEI_SERVICES  **PeiServices,
> > +  IN      EFI_BOOT_MODE     BootMode,
> > +  IN      VOID              *FspHobList
> > +  );
> > +
> > +EFI_STATUS
> > +GetMemoryMap (
> > +  IN     EFI_PEI_SERVICES                       **PeiServices,
> > +  IN OUT PEI_DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE
> *MemoryMap,
> > +  IN OUT UINT8                                  *NumRanges,
> > +  IN      VOID                                  *FspHobList
> > +  );
> > +
> > +EFI_STATUS
> > +GetPlatformMemorySize (
> > +  IN      EFI_PEI_SERVICES  **PeiServices,
> > +  IN      EFI_BOOT_MODE     BootMode,
> > +  IN OUT  UINT64            *MemorySize
> > +  );
> > +
> > +EFI_STATUS
> > +PreFspmHobProcess (
> > +  IN VOID  *FspHobList
> > +  );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Pe
> > iFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> >
> eiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
> > new file mode 100644
> > index 0000000000..6fdfb8e34c
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/P
> >
> eiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
> > @@ -0,0 +1,128 @@
> > +## @file
> > +#  FSP wrapper hob process INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +## @file
> > +#  Sample to provide FSP wrapper hob process related function.
> > +#
> > +#  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Defines Section - statements that will be processed to create a Makefile.
> > +#
> >
> +##################################################################
> > ##############
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = PeiFspWrapperHobProcessLibSample
> > +  FILE_GUID                      = 864693E2-EDE8-4DF8-8871-38C0BAA157EB
> > +  MODULE_TYPE                    = SEC
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = FspWrapperHobProcessLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Sources Section - list of files that are required for the build to succeed.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Sources]
> > +  FspWrapperHobProcessLibSample.c
> > +
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Package Dependency Section - list of Package files that are required for
> > +#                              this module.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  UefiCpuPkg/UefiCpuPkg.dec
> > +  PcAtChipsetPkg/PcAtChipsetPkg.dec
> > +  ChachaniBoardPkg/Project.dec
> > +  VanGoghCommonPkg/AmdCommonPkg.dec
> > +  AgesaPublic/AgesaPublic.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  BaseMemoryLib
> > +  HobLib
> > +  DebugLib
> > +  FspWrapperPlatformLib
> > +  PeiServicesLib
> > +  PeiServicesTablePointerLib
> > +  PrintLib
> > +  PcdLib
> > +  ReportStatusCodeLib
> > +  IoLib
> > +  PeimEntryPoint
> > +  MemoryAllocationLib
> > +  MtrrLib
> > +  PciExpressLib
> > +
> > +[Pcd]
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdPeiMinMemSize          ##
> CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize  ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection       ##
> > CONSUMES
> > +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> > +  gPcAtChipsetPkgTokenSpaceGuid.PcdIoApicBaseAddress
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
> > +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> > +  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashAreaSize
> > +  gPlatformPkgTokenSpaceGuid.PcdMemoryFvRecoveryBase
> > +  gAmdCommonPkgTokenSpaceGuid.PcdMemoryFvMainSize
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashFvRecoverySize
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashFvMainBase
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashFvMainSize
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashFvMainUnCompressBase
> > +  gPlatformPkgTokenSpaceGuid.PcdFlashFvMainUnCompressSize
> > +  gPlatformPkgTokenSpaceGuid.PcdBootState
> > +
> >
> gEfiAmdAgesaModulePkgTokenSpaceGuid.PcdAmdFabricResourceDefaultSize
> > Ptr
> > +[Guids]
> > +  gFspReservedMemoryResourceHobGuid                       ## CONSUMES ##
> HOB
> > +  gEfiMemoryTypeInformationGuid                           ## CONSUMES ## GUID
> > +  gPcdDataBaseHobGuid                                     ## CONSUMES ## HOB
> > +  gEfiAcpiVariableGuid                          # ALWAYS_CONSUMED
> > L"AcpiGlobalVariab"
> > +  gEfiSmmPeiSmramMemoryReserveGuid              # ALWAYS_PRODUCED
> Hob:
> > GUID_EXTENSION
> > +  gAmdMemoryInfoHobGuid
> > +  gPlatformChargerPresentGuid
> > +  gAmdResourceSizeForEachRbGuid
> > +  gAmdFspMemoryUnder1MGuid
> > +  gFspExportedInterfaceHobGuid
> > +  gAmdPspApobHobGuid
> > +
> > +[Ppis]
> > +  gEfiPeiCapsulePpiGuid                                   ## CONSUMES
> > +  gEfiPeiStallPpiGuid
> > +  gEfiPeiMasterBootModePpiGuid
> > +  gEfiPeiMemoryDiscoveredPpiGuid
> > +  gEfiPeiBootInRecoveryModePpiGuid
> > +  gAmdMemoryInfoHobPpiGuid
> > +  gEfiPeiReadOnlyVariable2PpiGuid
> > +  gPeiSmmControlPpiGuid
> > +  gPeiPostScriptTablePpiGuid
> > +  gEfiEndOfPeiSignalPpiGuid
> > +  gEfiPeiSmbus2PpiGuid
> > +  gEfiPeiReset2PpiGuid
> > +  gAmdPspFtpmPpiGuid
> > \ No newline at end of file
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/Fsp.h
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Fsp.h
> > new file mode 100644
> > index 0000000000..0bb612ea87
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Fsp.h
> > @@ -0,0 +1,45 @@
> > +/** @file
> > +  Fsp related definitions
> > +
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef FSP_H____
> > +#define FSP_H____
> > +
> > +//
> > +// Fv Header
> > +//
> > +#define FVH_FV_LENGTH_OFFSET         0x20
> > +#define FVH_SIGINATURE_OFFSET        0x28
> > +#define FVH_SIGINATURE_VALID_VALUE   0x4856465F   // valid
> > signature:_FVH
> > +#define FVH_HEADER_LENGTH_OFFSET     0x30
> > +#define FVH_EXTHEADER_OFFSET_OFFSET  0x34
> > +#define FVH_EXTHEADER_SIZE_OFFSET    0x10
> > +
> > +//
> > +// Ffs Header
> > +//
> > +#define FSP_HEADER_SIGNATURE_OFFSET  0x1C
> > +#define FSP_HEADER_SIGNATURE         0x48505346    ; valid signature:FSPH
> > +#define FSP_HEADER_GUID_DWORD1       0x912740BE
> > +#define FSP_HEADER_GUID_DWORD2       0x47342284
> > +#define FSP_HEADER_GUID_DWORD3       0xB08471B9
> > +#define FSP_HEADER_GUID_DWORD4       0x0C3F3527
> > +#define FFS_HEADER_SIZE_VALUE        0x18
> > +
> > +//
> > +// Section Header
> > +//
> > +#define SECTION_HEADER_TYPE_OFFSET     0x03
> > +#define RAW_SECTION_HEADER_SIZE_VALUE  0x04
> > +
> > +//
> > +// Fsp Header
> > +//
> > +#define FSP_HEADER_IMAGEBASE_OFFSET    0x1C
> > +#define FSP_HEADER_TEMPRAMINIT_OFFSET  0x30
> > +
> > +#endif
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
> > new file mode 100644
> > index 0000000000..54f363e59d
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
> > @@ -0,0 +1,129 @@
> > +/** @file
> > +  Sample to provide FSP wrapper platform sec related function.
> > +
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Ppi/SecPlatformInformation.h>
> > +#include <Ppi/SecPerformance.h>
> > +
> > +#include <Library/LocalApicLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +
> > +/**
> > +  This interface conveys state information out of the Security (SEC) phase
> into
> > PEI.
> > +
> > +  @param[in]     PeiServices               Pointer to the PEI Services Table.
> > +  @param[in,out] StructureSize             Pointer to the variable describing size
> of
> > the input buffer.
> > +  @param[out]    PlatformInformationRecord Pointer to the
> > EFI_SEC_PLATFORM_INFORMATION_RECORD.
> > +
> > +  @retval EFI_SUCCESS           The data was successfully returned.
> > +  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SecPlatformInformation (
> > +  IN CONST EFI_PEI_SERVICES                  **PeiServices,
> > +  IN OUT   UINT64                            *StructureSize,
> > +  OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD
> > *PlatformInformationRecord
> > +  );
> > +
> > +/**
> > +  This interface conveys performance information out of the Security (SEC)
> > phase into PEI.
> > +
> > +  This service is published by the SEC phase. The SEC phase handoff has an
> > optional
> > +  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed
> > from SEC into the
> > +  PEI Foundation. As such, if the platform supports collecting performance
> > data in SEC,
> > +  this information is encapsulated into the data structure abstracted by this
> > service.
> > +  This information is collected for the boot-strap processor (BSP) on IA-32.
> > +
> > +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> > +  @param[in]  This         The pointer to this instance of the
> > PEI_SEC_PERFORMANCE_PPI.
> > +  @param[out] Performance  The pointer to performance data collected in
> > SEC phase.
> > +
> > +  @retval EFI_SUCCESS  The data was successfully returned.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SecGetPerformance (
> > +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> > +  IN       PEI_SEC_PERFORMANCE_PPI   *This,
> > +  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
> > +  );
> > +
> > +PEI_SEC_PERFORMANCE_PPI  mSecPerformancePpi = {
> > +  SecGetPerformance
> > +};
> > +
> > +EFI_PEI_PPI_DESCRIPTOR  mPeiSecPlatformPpi[] = {
> > +  {
> > +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> > +    &gTopOfTemporaryRamPpiGuid,
> > +    NULL // To be patched later.
> > +  },
> > +  {
> > +    EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> > +    &gPeiSecPerformancePpiGuid,
> > +    &mSecPerformancePpi
> > +  },
> > +};
> > +
> > +/**
> > +  A developer supplied function to perform platform specific operations.
> > +
> > +  It's a developer supplied function to perform any operations appropriate
> to
> > a
> > +  given platform. It's invoked just before passing control to PEI core by SEC
> > +  core. Platform developer may modify the SecCoreData passed to PEI Core.
> > +  It returns a platform specific PPI list that platform wishes to pass to PEI
> core.
> > +  The Generic SEC core module will merge this list to join the final list passed
> to
> > +  PEI core.
> > +
> > +  @param[in,out] SecCoreData           The same parameter as passing to PEI
> > core. It
> > +                                       could be overridden by this function.
> > +
> > +  @return The platform specific PPI list to be passed to PEI core or
> > +          NULL if there is no need of such platform specific PPI list.
> > +
> > +**/
> > +EFI_PEI_PPI_DESCRIPTOR *
> > +EFIAPI
> > +SecPlatformMain (
> > +  IN OUT   EFI_SEC_PEI_HAND_OFF  *SecCoreData
> > +  )
> > +{
> > +  EFI_PEI_PPI_DESCRIPTOR  *PpiList;
> > +
> > +  DEBUG ((DEBUG_INFO, "SecPlatformMain\n"));
> > +
> > +  DEBUG ((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n",
> > SecCoreData->BootFirmwareVolumeBase));
> > +  DEBUG ((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n",
> SecCoreData-
> > >BootFirmwareVolumeSize));
> > +  DEBUG ((DEBUG_INFO, "TemporaryRamBase       - 0x%x\n", SecCoreData-
> > >TemporaryRamBase));
> > +  DEBUG ((DEBUG_INFO, "TemporaryRamSize       - 0x%x\n", SecCoreData-
> > >TemporaryRamSize));
> > +  DEBUG ((DEBUG_INFO, "PeiTemporaryRamBase    - 0x%x\n", SecCoreData-
> > >PeiTemporaryRamBase));
> > +  DEBUG ((DEBUG_INFO, "PeiTemporaryRamSize    - 0x%x\n", SecCoreData-
> > >PeiTemporaryRamSize));
> > +  DEBUG ((DEBUG_INFO, "StackBase              - 0x%x\n", SecCoreData-
> > >StackBase));
> > +  DEBUG ((DEBUG_INFO, "StackSize              - 0x%x\n", SecCoreData-
> > >StackSize));
> > +
> > +  InitializeApicTimer (0, (UINT32)-1, TRUE, 5);
> > +
> > +  //
> > +  // Use middle of Heap as temp buffer, it will be copied by caller.
> > +  // Do not use Stack, because it will cause wrong calculation on stack by
> > PeiCore
> > +  //
> > +  PpiList = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase +
> > (UINTN)SecCoreData->PeiTemporaryRamSize/2);
> > +  CopyMem (PpiList, mPeiSecPlatformPpi, sizeof (mPeiSecPlatformPpi));
> > +
> > +  //
> > +  // Patch TopOfTemporaryRamPpi
> > +  //
> > +  PpiList[0].Ppi = (VOID *)((UINTN)SecCoreData->TemporaryRamBase +
> > SecCoreData->TemporaryRamSize);
> > +
> > +  return PpiList;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
> > new file mode 100644
> > index 0000000000..cf443aa267
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
> > @@ -0,0 +1,130 @@
> > +;------------------------------------------------------------------------------
> > +;
> > +; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +; Module Name:
> > +;
> > +;  PeiCoreEntry.nasm
> > +;
> > +; Abstract:
> > +;
> > +;   Find and call SecStartup
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +SECTION .text
> > +
> > +extern ASM_PFX(SecStartup)
> > +extern ASM_PFX(PlatformInit)
> > +
> > +global ASM_PFX(CallPeiCoreEntryPoint)
> > +ASM_PFX(CallPeiCoreEntryPoint):
> > +  ;
> > +  ; Obtain the hob list pointer
> > +  ;
> > +  mov     eax, [esp+4]
> > +  ;
> > +  ; Obtain the stack information
> > +  ;   ECX: start of range
> > +  ;   EDX: end of range
> > +  ;
> > +  mov     ecx, [esp+8]
> > +  mov     edx, [esp+0xC]
> > +
> > +  ;
> > +  ; Platform init
> > +  ;
> > +  pushad
> > +  push edx
> > +  push ecx
> > +  push eax
> > +  call ASM_PFX(PlatformInit)
> > +  pop  eax
> > +  pop  eax
> > +  pop  eax
> > +  popad
> > +
> > +  ;
> > +  ; Set stack top pointer
> > +  ;
> > +  mov     esp, edx
> > +
> > +  ;
> > +  ; Push the hob list pointer
> > +  ;
> > +  push    eax
> > +
> > +  ;
> > +  ; Save the value
> > +  ;   ECX: start of range
> > +  ;   EDX: end of range
> > +  ;
> > +  mov     ebp, esp
> > +  push    ecx
> > +  push    edx
> > +
> > +  ;
> > +  ; Push processor count to stack first, then BIST status (AP then BSP)
> > +  ;
> > +  mov     eax, 1
> > +  cpuid
> > +  shr     ebx, 16
> > +  and     ebx, 0xFF
> > +  cmp     bl, 1
> > +  jae     PushProcessorCount
> > +
> > +  ;
> > +  ; Some processors report 0 logical processors.  Effectively 0 = 1.
> > +  ; So we fix up the processor count
> > +  ;
> > +  inc     ebx
> > +
> > +PushProcessorCount:
> > +  push    ebx
> > +
> > +  ;
> > +  ; We need to implement a long-term solution for BIST capture.  For now,
> we
> > just copy BSP BIST
> > +  ; for all processor threads
> > +  ;
> > +  xor     ecx, ecx
> > +  mov     cl, bl
> > +PushBist:
> > +  movd    eax, mm0
> > +  push    eax
> > +  loop    PushBist
> > +
> > +  ; Save Time-Stamp Counter
> > +  movd eax, mm5
> > +  push eax
> > +
> > +  movd eax, mm6
> > +  push eax
> > +
> > +  ;
> > +  ; Pass entry point of the PEI core
> > +  ;
> > +  mov     edi, 0xFFFFFFE0
> > +  push    DWORD [edi]
> > +
> > +  ;
> > +  ; Pass BFV into the PEI Core
> > +  ;
> > +  mov     edi, 0xFFFFFFFC
> > +  push    DWORD [edi]
> > +
> > +  ;
> > +  ; Pass stack size into the PEI Core
> > +  ;
> > +  mov     ecx, [ebp - 4]
> > +  mov     edx, [ebp - 8]
> > +  push    ecx       ; RamBase
> > +
> > +  sub     edx, ecx
> > +  push    edx       ; RamSize
> > +
> > +  ;
> > +  ; Pass Control into the PEI Core
> > +  ;
> > +  call ASM_PFX(SecStartup)
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
> > new file mode 100644
> > index 0000000000..b506212bfa
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
> > @@ -0,0 +1,335 @@
> > +;------------------------------------------------------------------------------
> > +;
> > +; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +; Module Name:
> > +;
> > +;  SecEntry.asm
> > +;
> > +; Abstract:
> > +;
> > +;  This is the code that goes from real-mode to protected mode.
> > +;  It consumes the reset vector, calls TempRamInit API from FSP binary.
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +#include "Fsp.h"
> > +
> > +SECTION .text
> > +
> > +extern   ASM_PFX(CallPeiCoreEntryPoint)
> > +extern   ASM_PFX(FsptUpdDataPtr)
> > +
> > +; Pcds
> > +extern   ASM_PFX(PcdGet32 (PcdFsptBaseAddress))
> > +
> > +;----------------------------------------------------------------------------
> > +;
> > +; Procedure:    _ModuleEntryPoint
> > +;
> > +; Input:        None
> > +;
> > +; Output:       None
> > +;
> > +; Destroys:     Assume all registers
> > +;
> > +; Description:
> > +;
> > +;   Transition to non-paged flat-model protected mode from a
> > +;   hard-coded GDT that provides exactly two descriptors.
> > +;   This is a bare bones transition to protected mode only
> > +;   used for a while in PEI and possibly DXE.
> > +;
> > +;   After enabling protected mode, a far jump is executed to
> > +;   transfer to PEI using the newly loaded GDT.
> > +;
> > +; Return:       None
> > +;
> > +;  MMX Usage:
> > +;              MM0 = BIST State
> > +;              MM5 = Save time-stamp counter value high32bit
> > +;              MM6 = Save time-stamp counter value low32bit.
> > +;
> > +;----------------------------------------------------------------------------
> > +
> > +BITS 16
> > +align 4
> > +global ASM_PFX(ModuleEntryPoint)
> > +ASM_PFX(ModuleEntryPoint):
> > +  fninit                                ; clear any pending Floating point exceptions
> > +  ;
> > +  ; Store the BIST value in mm0
> > +  ;
> > +  movd    mm0, eax
> > +
> > +  ;
> > +  ; Save time-stamp counter value
> > +  ; rdtsc load 64bit time-stamp counter to EDX:EAX
> > +  ;
> > +  rdtsc
> > +  movd    mm5, edx
> > +  movd    mm6, eax
> > +
> > +  ;
> > +  ; Load the GDT table in GdtDesc
> > +  ;
> > +  mov     esi,  GdtDesc
> > +  DB      66h
> > +  lgdt    [cs:si]
> > +
> > +  ;
> > +  ; Transition to 16 bit protected mode
> > +  ;
> > +  mov     eax, cr0                   ; Get control register 0
> > +  or      eax, 00000003h             ; Set PE bit (bit #0) & MP bit (bit #1)
> > +  mov     cr0, eax                   ; Activate protected mode
> > +
> > +  mov     eax, cr4                   ; Get control register 4
> > +  or      eax, 00000600h             ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit
> > (bit #10)
> > +  mov     cr4, eax
> > +
> > +  ;
> > +  ; Now we're in 16 bit protected mode
> > +  ; Set up the selectors for 32 bit protected mode entry
> > +  ;
> > +  mov     ax, SYS_DATA_SEL
> > +  mov     ds, ax
> > +  mov     es, ax
> > +  mov     fs, ax
> > +  mov     gs, ax
> > +  mov     ss, ax
> > +
> > +  ;
> > +  ; Transition to Flat 32 bit protected mode
> > +  ; The jump to a far pointer causes the transition to 32 bit mode
> > +  ;
> > +  mov esi, ProtectedModeEntryLinearAddress
> > +  jmp   dword far  [cs:si]
> > +
> > +;----------------------------------------------------------------------------
> > +;
> > +; Procedure:    ProtectedModeEntryPoint
> > +;
> > +; Input:        None
> > +;
> > +; Output:       None
> > +;
> > +; Destroys:     Assume all registers
> > +;
> > +; Description:
> > +;
> > +; This function handles:
> > +;   Call two basic APIs from FSP binary
> > +;   Initializes stack with some early data (BIST, PEI entry, etc)
> > +;
> > +; Return:       None
> > +;
> > +;----------------------------------------------------------------------------
> > +
> > +BITS 32
> > +align 4
> > +ProtectedModeEntryPoint:
> > +
> > +  ; Find the fsp info header
> > +  mov  edi, [ASM_PFX(PcdGet32 (PcdFsptBaseAddress))]
> > +
> > +  mov  eax, dword [edi + FVH_SIGINATURE_OFFSET]
> > +  cmp  eax, FVH_SIGINATURE_VALID_VALUE
> > +  jnz  FspHeaderNotFound
> > +
> > +  xor  eax, eax
> > +  mov  ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]
> > +  cmp  ax, 0
> > +  jnz  FspFvExtHeaderExist
> > +
> > +  xor  eax, eax
> > +  mov  ax, word [edi + FVH_HEADER_LENGTH_OFFSET]   ; Bypass Fv Header
> > +  add  edi, eax
> > +  jmp  FspCheckFfsHeader
> > +
> > +FspFvExtHeaderExist:
> > +  add  edi, eax
> > +  mov  eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv
> > Header
> > +  add  edi, eax
> > +
> > +  ; Round up to 8 byte alignment
> > +  mov  eax, edi
> > +  and  al,  07h
> > +  jz   FspCheckFfsHeader
> > +
> > +  and  edi, 0FFFFFFF8h
> > +  add  edi, 08h
> > +
> > +FspCheckFfsHeader:
> > +  ; Check the ffs guid
> > +  mov  eax, dword [edi]
> > +  cmp  eax, FSP_HEADER_GUID_DWORD1
> > +  jnz  FspHeaderNotFound
> > +
> > +  mov  eax, dword [edi + 4]
> > +  cmp  eax, FSP_HEADER_GUID_DWORD2
> > +  jnz  FspHeaderNotFound
> > +
> > +  mov  eax, dword [edi + 8]
> > +  cmp  eax, FSP_HEADER_GUID_DWORD3
> > +  jnz  FspHeaderNotFound
> > +
> > +  mov  eax, dword [edi + 0Ch]
> > +  cmp  eax, FSP_HEADER_GUID_DWORD4
> > +  jnz  FspHeaderNotFound
> > +
> > +  add  edi, FFS_HEADER_SIZE_VALUE       ; Bypass the ffs header
> > +
> > +  ; Check the section type as raw section
> > +  mov  al, byte [edi + SECTION_HEADER_TYPE_OFFSET]
> > +  cmp  al, 019h
> > +  jnz FspHeaderNotFound
> > +
> > +  add  edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header
> > +  jmp FspHeaderFound
> > +
> > +FspHeaderNotFound:
> > +  jmp  $
> > +
> > +FspHeaderFound:
> > +  ; Get the fsp TempRamInit Api address
> > +  mov eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]
> > +  add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
> > +
> > +  ; Setup the hardcode stack
> > +  mov esp, TempRamInitStack
> > +
> > +  ; Call the fsp TempRamInit Api
> > +  jmp eax
> > +
> > +TempRamInitDone:
> > +  cmp eax, 8000000Eh      ;Check if EFI_NOT_FOUND returned. Error code
> for
> > Microcode Update not found.
> > +  je  CallSecFspInit      ;If microcode not found, don't hang, but continue.
> > +
> > +  cmp eax, 0              ;Check if EFI_SUCCESS returned.
> > +  jnz FspApiFailed
> > +
> > +  ;   ECX: start of range
> > +  ;   EDX: end of range
> > +CallSecFspInit:
> > +  xor     eax, eax
> > +  mov     esp, edx
> > +
> > +  ; Align the stack at DWORD
> > +  add  esp,  3
> > +  and  esp, 0FFFFFFFCh
> > +
> > +  push    edx
> > +  push    ecx
> > +  push    eax ; zero - no hob list yet
> > +  call    ASM_PFX(CallPeiCoreEntryPoint)
> > +
> > +FspApiFailed:
> > +  jmp $
> > +
> > +align 10h
> > +TempRamInitStack:
> > +    DD  TempRamInitDone
> > +    DD  ASM_PFX(FsptUpdDataPtr); TempRamInitParams
> > +
> > +;
> > +; ROM-based Global-Descriptor Table for the Tiano PEI Phase
> > +;
> > +align 16
> > +global  ASM_PFX(BootGdtTable)
> > +
> > +;
> > +; GDT[0]: 0x00: Null entry, never used.
> > +;
> > +NULL_SEL            EQU $ - GDT_BASE    ; Selector [0]
> > +GDT_BASE:
> > +ASM_PFX(BootGdtTable):
> > +                    DD  0
> > +                    DD  0
> > +;
> > +; Linear data segment descriptor
> > +;
> > +LINEAR_SEL          EQU $ - GDT_BASE    ; Selector [0x8]
> > +    DW  0FFFFh                          ; limit 0xFFFFF
> > +    DW  0                               ; base 0
> > +    DB  0
> > +    DB  092h                            ; present, ring 0, data, expand-up, writable
> > +    DB  0CFh                            ; page-granular, 32-bit
> > +    DB  0
> > +;
> > +; Linear code segment descriptor
> > +;
> > +LINEAR_CODE_SEL     EQU $ - GDT_BASE    ; Selector [0x10]
> > +    DW  0FFFFh                          ; limit 0xFFFFF
> > +    DW  0                               ; base 0
> > +    DB  0
> > +    DB  09Bh                            ; present, ring 0, data, expand-up, not-writable
> > +    DB  0CFh                            ; page-granular, 32-bit
> > +    DB  0
> > +;
> > +; System data segment descriptor
> > +;
> > +SYS_DATA_SEL        EQU $ - GDT_BASE    ; Selector [0x18]
> > +    DW  0FFFFh                          ; limit 0xFFFFF
> > +    DW  0                               ; base 0
> > +    DB  0
> > +    DB  093h                            ; present, ring 0, data, expand-up, not-writable
> > +    DB  0CFh                            ; page-granular, 32-bit
> > +    DB  0
> > +
> > +;
> > +; System code segment descriptor
> > +;
> > +SYS_CODE_SEL        EQU $ - GDT_BASE    ; Selector [0x20]
> > +    DW  0FFFFh                          ; limit 0xFFFFF
> > +    DW  0                               ; base 0
> > +    DB  0
> > +    DB  09Ah                            ; present, ring 0, data, expand-up, writable
> > +    DB  0CFh                            ; page-granular, 32-bit
> > +    DB  0
> > +;
> > +; Spare segment descriptor
> > +;
> > +SYS16_CODE_SEL      EQU $ - GDT_BASE    ; Selector [0x28]
> > +    DW  0FFFFh                          ; limit 0xFFFFF
> > +    DW  0                               ; base 0
> > +    DB  0Eh                             ; Changed from F000 to E000.
> > +    DB  09Bh                            ; present, ring 0, code, expand-up, writable
> > +    DB  00h                             ; byte-granular, 16-bit
> > +    DB  0
> > +;
> > +; Spare segment descriptor
> > +;
> > +SYS16_DATA_SEL      EQU $ - GDT_BASE    ; Selector [0x30]
> > +    DW  0FFFFh                          ; limit 0xFFFF
> > +    DW  0                               ; base 0
> > +    DB  0
> > +    DB  093h                            ; present, ring 0, data, expand-up, not-writable
> > +    DB  00h                             ; byte-granular, 16-bit
> > +    DB  0
> > +
> > +;
> > +; Spare segment descriptor
> > +;
> > +SPARE5_SEL          EQU $ - GDT_BASE    ; Selector [0x38]
> > +    DW  0                               ; limit 0
> > +    DW  0                               ; base 0
> > +    DB  0
> > +    DB  0                               ; present, ring 0, data, expand-up, writable
> > +    DB  0                               ; page-granular, 32-bit
> > +    DB  0
> > +GDT_SIZE            EQU $ - GDT_BASE    ; Size, in bytes
> > +
> > +;
> > +; GDT Descriptor
> > +;
> > +GdtDesc:                                ; GDT descriptor
> > +    DW  GDT_SIZE - 1                    ; GDT limit
> > +    DD  GDT_BASE                        ; GDT base address
> > +
> > +
> > +ProtectedModeEntryLinearAddress:
> > +ProtectedModeEntryLinear:
> > +  DD      ProtectedModeEntryPoint  ; Offset of our 32 bit code
> > +  DW      LINEAR_CODE_SEL
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
> > new file mode 100644
> > index 0000000000..48101131fa
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
> > @@ -0,0 +1,73 @@
> > +;------------------------------------------------------------------------------
> > +;
> > +; Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +; Abstract:
> > +;
> > +;   Switch the stack from temporary memory to permanent memory.
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +    SECTION .text
> > +
> > +;------------------------------------------------------------------------------
> > +; VOID
> > +; EFIAPI
> > +; SecSwitchStack (
> > +;   UINT32   TemporaryMemoryBase,
> > +;   UINT32   PermanentMemoryBase
> > +;   );
> > +;------------------------------------------------------------------------------
> > +global ASM_PFX(SecSwitchStack)
> > +ASM_PFX(SecSwitchStack):
> > +    ;
> > +    ; Save four register: eax, ebx, ecx, edx
> > +    ;
> > +    push  eax
> > +    push  ebx
> > +    push  ecx
> > +    push  edx
> > +
> > +    ;
> > +    ; !!CAUTION!! this function address's is pushed into stack after
> > +    ; migration of whole temporary memory, so need save it to permanent
> > +    ; memory at first!
> > +    ;
> > +
> > +    mov   ebx, [esp + 20]          ; Save the first parameter
> > +    mov   ecx, [esp + 24]          ; Save the second parameter
> > +
> > +    ;
> > +    ; Save this function's return address into permanent memory at first.
> > +    ; Then, Fixup the esp point to permanent memory
> > +    ;
> > +    mov   eax, esp
> > +    sub   eax, ebx
> > +    add   eax, ecx
> > +    mov   edx, dword [esp]         ; copy pushed register's value to permanent
> > memory
> > +    mov   dword [eax], edx
> > +    mov   edx, dword [esp + 4]
> > +    mov   dword [eax + 4], edx
> > +    mov   edx, dword [esp + 8]
> > +    mov   dword [eax + 8], edx
> > +    mov   edx, dword [esp + 12]
> > +    mov   dword [eax + 12], edx
> > +    mov   edx, dword [esp + 16]    ; Update this function's return address into
> > permanent memory
> > +    mov   dword [eax + 16], edx
> > +    mov   esp, eax                 ; From now, esp is pointed to permanent memory
> > +
> > +    ;
> > +    ; Fixup the ebp point to permanent memory
> > +    ;
> > +    mov   eax, ebp
> > +    sub   eax, ebx
> > +    add   eax, ecx
> > +    mov   ebp, eax                 ; From now, ebp is pointed to permanent memory
> > +
> > +    pop   edx
> > +    pop   ecx
> > +    pop   ebx
> > +    pop   eax
> > +    ret
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/PlatformInit.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/PlatformInit.c
> > new file mode 100644
> > index 0000000000..237aeead51
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/PlatformInit.c
> > @@ -0,0 +1,38 @@
> > +/** @file
> > +  Sample to provide platform init function.
> > +
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/SerialPortLib.h>
> > +
> > +/**
> > +  Platform initialization.
> > +
> > +  @param[in] FspHobList   HobList produced by FSP.
> > +  @param[in] StartOfRange Start of temporary RAM.
> > +  @param[in] EndOfRange   End of temporary RAM.
> > +**/
> > +VOID
> > +EFIAPI
> > +PlatformInit (
> > +  IN VOID  *FspHobList,
> > +  IN VOID  *StartOfRange,
> > +  IN VOID  *EndOfRange
> > +  )
> > +{
> > +  //
> > +  // Platform initialization
> > +  // Enable Serial port here
> > +  //
> > +  SerialPortInitialize ();
> > +
> > +  DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam in
> PlatformInit\n"));
> > +  DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
> > +  DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange));
> > +  DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange));
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> >
> cFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> >
> ecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.in
> > f
> > new file mode 100644
> > index 0000000000..ac417c8e59
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> >
> ecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.in
> > f
> > @@ -0,0 +1,87 @@
> > +## @file
> > +#  Sample to provide FSP wrapper platform sec related function.
> > +#
> > +#  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Defines Section - statements that will be processed to create a Makefile.
> > +#
> >
> +##################################################################
> > ##############
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = SecFspWrapperPlatformSecLibSample
> > +  FILE_GUID                      = 8F1AC44A-CE7E-4E29-95BB-92E321BB1573
> > +  MODULE_TYPE                    = SEC
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = PlatformSecLib
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Sources Section - list of files that are required for the build to succeed.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Sources]
> > +  FspWrapperPlatformSecLibSample.c
> > +  SecRamInitData.c
> > +  SecPlatformInformation.c
> > +  SecGetPerformance.c
> > +  SecTempRamDone.c
> > +  PlatformInit.c
> > +  Fsp.h
> > +
> > +[Sources.IA32]
> > +  Ia32/SecEntry.nasm
> > +  Ia32/PeiCoreEntry.nasm
> > +  Ia32/Stack.nasm
> > +
> > +[Sources.X64]
> > +  X64/SecEntry.nasm
> > +  X64/PeiCoreEntry.nasm
> > +  X64/Stack.nasm
> > +
> >
> +##################################################################
> > ##############
> > +#
> > +# Package Dependency Section - list of Package files that are required for
> > +#                              this module.
> > +#
> >
> +##################################################################
> > ##############
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  UefiCpuPkg/UefiCpuPkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec
> > +
> > +[LibraryClasses]
> > +  LocalApicLib
> > +  SerialPortLib
> > +  DebugLib
> > +  BaseMemoryLib
> > +
> > +[Ppis]
> > +  gEfiSecPlatformInformationPpiGuid       ## CONSUMES
> > +  gPeiSecPerformancePpiGuid               ## CONSUMES
> > +  gTopOfTemporaryRamPpiGuid               ## PRODUCES
> > +
> > +[Pcd]
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFsptBaseAddress              ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress              ##
> > CONSUMES
> > +
> > +[FixedPcd]
> > +  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress           ##
> > CONSUMES
> > +  gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize        ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheAddress        ##
> > CONSUMES
> > +  gIntelFsp2WrapperTokenSpaceGuid.PcdFlashCodeCacheSize           ##
> > CONSUMES
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/SecGetPerformance.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecGetPerformance.c
> > new file mode 100644
> > index 0000000000..449a2d6e99
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecGetPerformance.c
> > @@ -0,0 +1,84 @@
> > +/** @file
> > +  Sample to provide SecGetPerformance function.
> > +
> > +  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Ppi/SecPerformance.h>
> > +#include <Ppi/TopOfTemporaryRam.h>
> > +
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/TimerLib.h>
> > +#include <Library/DebugLib.h>
> > +
> > +/**
> > +  This interface conveys performance information out of the Security (SEC)
> > phase into PEI.
> > +
> > +  This service is published by the SEC phase. The SEC phase handoff has an
> > optional
> > +  EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed
> > from SEC into the
> > +  PEI Foundation. As such, if the platform supports collecting performance
> > data in SEC,
> > +  this information is encapsulated into the data structure abstracted by this
> > service.
> > +  This information is collected for the boot-strap processor (BSP) on IA-32.
> > +
> > +  @param[in]  PeiServices  The pointer to the PEI Services Table.
> > +  @param[in]  This         The pointer to this instance of the
> > PEI_SEC_PERFORMANCE_PPI.
> > +  @param[out] Performance  The pointer to performance data collected in
> > SEC phase.
> > +
> > +  @retval EFI_SUCCESS  The data was successfully returned.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SecGetPerformance (
> > +  IN CONST EFI_PEI_SERVICES          **PeiServices,
> > +  IN       PEI_SEC_PERFORMANCE_PPI   *This,
> > +  OUT      FIRMWARE_SEC_PERFORMANCE  *Performance
> > +  )
> > +{
> > +  UINT32      Size;
> > +  UINT32      Count;
> > +  UINT32      TopOfTemporaryRam;
> > +  UINT64      Ticker;
> > +  VOID        *TopOfTemporaryRamPpi;
> > +  EFI_STATUS  Status;
> > +
> > +  DEBUG ((DEBUG_INFO, "SecGetPerformance\n"));
> > +
> > +  Status = (*PeiServices)->LocatePpi (
> > +                             PeiServices,
> > +                             &gTopOfTemporaryRamPpiGuid,
> > +                             0,
> > +                             NULL,
> > +                             (VOID **)&TopOfTemporaryRamPpi
> > +                             );
> > +  if (EFI_ERROR (Status)) {
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  //
> > +  // |--------------| <- TopOfTemporaryRam
> > +  // |Number of BSPs|
> > +  // |--------------|
> > +  // |     BIST     |
> > +  // |--------------|
> > +  // |     ....     |
> > +  // |--------------|
> > +  // |  TSC[63:32]  |
> > +  // |--------------|
> > +  // |  TSC[31:00]  |
> > +  // |--------------|
> > +  //
> > +  TopOfTemporaryRam  = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof
> > (UINT32);
> > +  TopOfTemporaryRam -= sizeof (UINT32) * 2;
> > +  Count              = *(UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof
> > (UINT32));
> > +  Size               = Count * sizeof (UINT64);
> > +
> > +  Ticker                = *(UINT64 *)(UINTN)(TopOfTemporaryRam - sizeof
> (UINT32)
> > - Size - sizeof (UINT32) * 2);
> > +  Performance->ResetEnd = GetTimeInNanoSecond (Ticker);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/SecPlatformInformation.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecPlatformInformation.c
> > new file mode 100644
> > index 0000000000..b96f38432e
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecPlatformInformation.c
> > @@ -0,0 +1,78 @@
> > +/** @file
> > +  Sample to provide SecPlatformInformation function.
> > +
> > +  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Ppi/SecPlatformInformation.h>
> > +#include <Ppi/TopOfTemporaryRam.h>
> > +
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +
> > +/**
> > +  This interface conveys state information out of the Security (SEC) phase
> into
> > PEI.
> > +
> > +  @param[in]     PeiServices               Pointer to the PEI Services Table.
> > +  @param[in,out] StructureSize             Pointer to the variable describing size
> of
> > the input buffer.
> > +  @param[out]    PlatformInformationRecord Pointer to the
> > EFI_SEC_PLATFORM_INFORMATION_RECORD.
> > +
> > +  @retval EFI_SUCCESS           The data was successfully returned.
> > +  @retval EFI_BUFFER_TOO_SMALL  The buffer was too small.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SecPlatformInformation (
> > +  IN CONST EFI_PEI_SERVICES                  **PeiServices,
> > +  IN OUT   UINT64                            *StructureSize,
> > +  OUT   EFI_SEC_PLATFORM_INFORMATION_RECORD
> > *PlatformInformationRecord
> > +  )
> > +{
> > +  UINT32      *Bist;
> > +  UINT32      Size;
> > +  UINT32      Count;
> > +  UINT32      TopOfTemporaryRam;
> > +  VOID        *TopOfTemporaryRamPpi;
> > +  EFI_STATUS  Status;
> > +
> > +  DEBUG ((DEBUG_INFO, "SecPlatformInformation\n"));
> > +
> > +  Status = (*PeiServices)->LocatePpi (
> > +                             PeiServices,
> > +                             &gTopOfTemporaryRamPpiGuid,
> > +                             0,
> > +                             NULL,
> > +                             (VOID **)&TopOfTemporaryRamPpi
> > +                             );
> > +  if (EFI_ERROR (Status)) {
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  //
> > +  // The entries of BIST information, together with the number of them,
> > +  // reside in the bottom of stack, left untouched by normal stack operation.
> > +  // This routine copies the BIST information to the buffer pointed by
> > +  // PlatformInformationRecord for output.
> > +  //
> > +  TopOfTemporaryRam  = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof
> > (UINT32);
> > +  TopOfTemporaryRam -= sizeof (UINT32) * 2;
> > +  Count              = *((UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof
> > (UINT32)));
> > +  Size               = Count * sizeof (IA32_HANDOFF_STATUS);
> > +
> > +  if ((*StructureSize) < (UINT64)Size) {
> > +    *StructureSize = Size;
> > +    return EFI_BUFFER_TOO_SMALL;
> > +  }
> > +
> > +  *StructureSize = Size;
> > +  Bist           = (UINT32 *)(TopOfTemporaryRam - sizeof (UINT32) - Size);
> > +
> > +  CopyMem (PlatformInformationRecord, Bist, Size);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/SecRamInitData.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecRamInitData.c
> > new file mode 100644
> > index 0000000000..5e7f051bb6
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecRamInitData.c
> > @@ -0,0 +1,63 @@
> > +/** @file
> > +  Sample to provide TempRamInitParams data.
> > +
> > +  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Library/PcdLib.h>
> > +#include <FspEas.h>
> > +
> > +typedef struct {
> > +  EFI_PHYSICAL_ADDRESS    MicrocodeRegionBase;
> > +  UINT64                  MicrocodeRegionSize;
> > +  EFI_PHYSICAL_ADDRESS    CodeRegionBase;
> > +  UINT64                  CodeRegionSize;
> > +} FSPT_CORE_UPD;
> > +
> > +typedef struct {
> > +  FSP_UPD_HEADER    FspUpdHeader;
> > +  //
> > +  // If FSP spec version < 2.2, remove FSPT_ARCH_UPD structure.
> > +  // Else If FSP spec version >= 2.2 and FSP spec version < 2.4, use
> > FSPT_ARCH_UPD structure.
> > +  // Else, use FSPT_ARCH2_UPD structure.
> > +  //
> > +  FSPT_ARCH2_UPD    FsptArchUpd;
> > +  FSPT_CORE_UPD     FsptCoreUpd;
> > +} FSPT_UPD_CORE_DATA;
> > +
> > +GLOBAL_REMOVE_IF_UNREFERENCED CONST FSPT_UPD_CORE_DATA
> > FsptUpdDataPtr = {
> > +  {
> > +    0x4450555F54505346,
> > +    //
> > +    // UPD header revision must be equal or greater than 2 when the
> structure
> > is compliant with FSP spec 2.2.
> > +    //
> > +    0x02,
> > +    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
> > +  },
> > +  //
> > +  // If FSP spec version < 2.2, remove FSPT_ARCH_UPD structure.
> > +  // Else If FSP spec version >= 2.2 and FSP spec version < 2.4, use
> > FSPT_ARCH_UPD structure.
> > +  // Else, use FSPT_ARCH2_UPD structure.
> > +  //
> > +  {
> > +    0x02,
> > +    {
> > +      0x00, 0x00, 0x00
> > +    },
> > +    0x00000020,
> > +    0x00000000,
> > +    {
> > +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> > +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> > +    }
> > +  },
> > +  {
> > +    FixedPcdGet32 (PcdCpuMicrocodePatchAddress),
> > +    FixedPcdGet32 (PcdCpuMicrocodePatchRegionSize),
> > +    FixedPcdGet32 (PcdFlashCodeCacheAddress),
> > +    FixedPcdGet32 (PcdFlashCodeCacheSize),
> > +  }
> > +};
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/SecTempRamDone.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecTempRamDone.c
> > new file mode 100644
> > index 0000000000..fab488e668
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/SecTempRamDone.c
> > @@ -0,0 +1,43 @@
> > +/** @file
> > +  Sample to provide SecTemporaryRamDone function.
> > +
> > +  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <PiPei.h>
> > +
> > +#include <Library/DebugLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/FspWrapperPlatformLib.h>
> > +#include <Guid/FspHeaderFile.h>
> > +
> > +/**
> > +This interface disables temporary memory in SEC Phase.
> > +**/
> > +VOID
> > +EFIAPI
> > +SecPlatformDisableTemporaryMemory (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS       Status;
> > +  VOID             *TempRamExitParam;
> > +  FSP_INFO_HEADER  *FspHeader;
> > +
> > +  FspHeader = FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
> > +  if (FspHeader == NULL) {
> > +    return;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "SecPlatformDisableTemporaryMemory
> enter\n"));
> > +
> > +  TempRamExitParam = UpdateTempRamExitParam ();
> > +  Status           = CallTempRamExit (TempRamExitParam);
> > +  DEBUG ((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  return;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
> > new file mode 100644
> > index 0000000000..548474ccbb
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
> > @@ -0,0 +1,149 @@
> > +;------------------------------------------------------------------------------
> > +;
> > +; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +; Module Name:
> > +;
> > +;  PeiCoreEntry.nasm
> > +;
> > +; Abstract:
> > +;
> > +;   Find and call SecStartup
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +SECTION .text
> > +
> > +%include    "PushPopRegsNasm.inc"
> > +
> > +extern ASM_PFX(SecStartup)
> > +extern ASM_PFX(PlatformInit)
> > +
> > +;
> > +; args 1:XMM, 2:REG, 3:IDX
> > +;
> > +%macro LXMMN        3
> > +            pextrq  %2, %1, (%3 & 3)
> > +            %endmacro
> > +
> > +;
> > +; args 1:YMM, 2:XMM, 3:IDX (0 - lower 128bits, 1 - upper 128bits)
> > +;
> > +%macro LYMMN        3
> > +            vextractf128  %2, %1, %3
> > +            %endmacro
> > +
> > +%macro LOAD_TS      1
> > +            LYMMN   ymm6, xmm5, 1
> > +            LXMMN   xmm5, %1, 1
> > +            %endmacro
> > +
> > +global ASM_PFX(CallPeiCoreEntryPoint)
> > +ASM_PFX(CallPeiCoreEntryPoint):
> > +  ;
> > +  ; Per X64 calling convention, make sure RSP is 16-byte aligned.
> > +  ;
> > +  mov     rax, rsp
> > +  and     rax, 0fh
> > +  sub     rsp, rax
> > +
> > +  ;
> > +  ; Platform init
> > +  ;
> > +  PUSHA_64
> > +  sub     rsp, 20h
> > +  call    ASM_PFX(PlatformInit)
> > +  add     rsp, 20h
> > +  POPA_64
> > +
> > +  ;
> > +  ; Set stack top pointer
> > +  ;
> > +  mov     rsp, r8
> > +
> > +  ;
> > +  ; Push the hob list pointer
> > +  ;
> > +  push    rcx
> > +
> > +  ;
> > +  ; RBP holds start of BFV passed from Vtf0. Save it to r10.
> > +  ;
> > +  mov     r10, rbp
> > +
> > +  ;
> > +  ; Save the value
> > +  ;   RDX: start of range
> > +  ;   r8: end of range
> > +  ;
> > +  mov     rbp, rsp
> > +  push    rdx
> > +  push    r8
> > +  mov     r14, rdx
> > +  mov     r15, r8
> > +
> > +  ;
> > +  ; Push processor count to stack first, then BIST status (AP then BSP)
> > +  ;
> > +  mov     eax, 1
> > +  cpuid
> > +  shr     ebx, 16
> > +  and     ebx, 0000000FFh
> > +  cmp     bl, 1
> > +  jae     PushProcessorCount
> > +
> > +  ;
> > +  ; Some processors report 0 logical processors.  Effectively 0 = 1.
> > +  ; So we fix up the processor count
> > +  ;
> > +  inc     ebx
> > +
> > +PushProcessorCount:
> > +  sub     rsp, 4
> > +  mov     rdi, rsp
> > +  mov     DWORD [rdi], ebx
> > +
> > +  ;
> > +  ; We need to implement a long-term solution for BIST capture.  For now,
> we
> > just copy BSP BIST
> > +  ; for all processor threads
> > +  ;
> > +  xor     ecx, ecx
> > +  mov     cl, bl
> > +PushBist:
> > +  sub     rsp, 4
> > +  mov     rdi, rsp
> > +  movd    eax, mm0
> > +  mov     DWORD [rdi], eax
> > +  loop    PushBist
> > +
> > +  ; Save Time-Stamp Counter
> > +  LOAD_TS rax
> > +  push    rax
> > +
> > +  ;
> > +  ; Pass entry point of the PEI core
> > +  ;
> > +  mov     rdi, 0FFFFFFE0h
> > +  mov     edi, DWORD [rdi]
> > +  mov     r9, rdi
> > +
> > +  ;
> > +  ; Pass BFV into the PEI Core
> > +  ;
> > +  mov     r8, r10
> > +
> > +  ;
> > +  ; Pass stack size into the PEI Core
> > +  ;
> > +  mov     rcx, r15  ; Start of TempRam
> > +  mov     rdx, r14  ; End of TempRam
> > +
> > +  sub     rcx, rdx  ; Size of TempRam
> > +
> > +  ;
> > +  ; Pass Control into the PEI Core
> > +  ;
> > +  sub     rsp, 20h
> > +  call ASM_PFX(SecStartup)
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/X64/SecEntry.nasm
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm
> > new file mode 100644
> > index 0000000000..4025b4157c
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm
> > @@ -0,0 +1,173 @@
> > +;------------------------------------------------------------------------------
> > +;
> > +; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +; Module Name:
> > +;
> > +;  SecEntry.asm
> > +;
> > +; Abstract:
> > +;
> > +;  This is the code that calls TempRamInit API from FSP binary and passes
> > +;  control into PEI core.
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +#include "Fsp.h"
> > +
> > +IA32_CR4_OSFXSR           equ        200h
> > +IA32_CR4_OSXMMEXCPT       equ        400h
> > +IA32_CR0_MP               equ        2h
> > +
> > +IA32_CPUID_SSE2           equ        02000000h
> > +IA32_CPUID_SSE2_B         equ        26
> > +
> > +SECTION .text
> > +
> > +extern   ASM_PFX(CallPeiCoreEntryPoint)
> > +extern   ASM_PFX(FsptUpdDataPtr)
> > +
> > +; Pcds
> > +extern   ASM_PFX(PcdGet32 (PcdFsptBaseAddress))
> > +
> > +;----------------------------------------------------------------------------
> > +;
> > +; Procedure:    _ModuleEntryPoint
> > +;
> > +; Input:        None
> > +;
> > +; Output:       None
> > +;
> > +; Destroys:     Assume all registers
> > +;
> > +; Description:
> > +;
> > +;  Call TempRamInit API from FSP binary. After TempRamInit done, pass
> > +;  control into PEI core.
> > +;
> > +; Return:       None
> > +;
> > +;  MMX Usage:
> > +;              MM0 = BIST State
> > +;
> > +;----------------------------------------------------------------------------
> > +
> > +BITS 64
> > +align 16
> > +global ASM_PFX(ModuleEntryPoint)
> > +ASM_PFX(ModuleEntryPoint):
> > +  fninit                                ; clear any pending Floating point exceptions
> > +  ;
> > +  ; Store the BIST value in mm0
> > +  ;
> > +  movd    mm0, eax
> > +
> > +  ; Find the fsp info header
> > +  mov     rax, ASM_PFX(PcdGet32 (PcdFsptBaseAddress))
> > +  mov     edi, [eax]
> > +
> > +  mov     eax, dword [edi + FVH_SIGINATURE_OFFSET]
> > +  cmp     eax, FVH_SIGINATURE_VALID_VALUE
> > +  jnz     FspHeaderNotFound
> > +
> > +  xor     eax, eax
> > +  mov     ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]
> > +  cmp     ax, 0
> > +  jnz     FspFvExtHeaderExist
> > +
> > +  xor     eax, eax
> > +  mov     ax, word [edi + FVH_HEADER_LENGTH_OFFSET]     ; Bypass Fv
> Header
> > +  add     edi, eax
> > +  jmp     FspCheckFfsHeader
> > +
> > +FspFvExtHeaderExist:
> > +  add     edi, eax
> > +  mov     eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv
> > Header
> > +  add     edi, eax
> > +
> > +  ; Round up to 8 byte alignment
> > +  mov     eax, edi
> > +  and     al,  07h
> > +  jz      FspCheckFfsHeader
> > +
> > +  and     edi, 0FFFFFFF8h
> > +  add     edi, 08h
> > +
> > +FspCheckFfsHeader:
> > +  ; Check the ffs guid
> > +  mov     eax, dword [edi]
> > +  cmp     eax, FSP_HEADER_GUID_DWORD1
> > +  jnz     FspHeaderNotFound
> > +
> > +  mov     eax, dword [edi + 4]
> > +  cmp     eax, FSP_HEADER_GUID_DWORD2
> > +  jnz     FspHeaderNotFound
> > +
> > +  mov     eax, dword [edi + 8]
> > +  cmp     eax, FSP_HEADER_GUID_DWORD3
> > +  jnz     FspHeaderNotFound
> > +
> > +  mov     eax, dword [edi + 0Ch]
> > +  cmp     eax, FSP_HEADER_GUID_DWORD4
> > +  jnz     FspHeaderNotFound
> > +
> > +  add     edi, FFS_HEADER_SIZE_VALUE         ; Bypass the ffs header
> > +
> > +  ; Check the section type as raw section
> > +  mov     al, byte [edi + SECTION_HEADER_TYPE_OFFSET]
> > +  cmp     al, 019h
> > +  jnz FspHeaderNotFound
> > +
> > +  add     edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section
> header
> > +  jmp     FspHeaderFound
> > +
> > +FspHeaderNotFound:
> > +  jmp     $
> > +
> > +FspHeaderFound:
> > +  ; Get the fsp TempRamInit Api address
> > +  mov     eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]
> > +  add     eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]
> > +
> > +  ; Pass Fsp T Upd pointer as Input parameter
> > +  mov     rcx, ASM_PFX(FsptUpdDataPtr)
> > +
> > +  ; Setup the hardcode stack
> > +  mov     rsp, TempRamInitStack
> > +
> > +  ; Call the fsp TempRamInit Api
> > +  jmp     rax
> > +
> > +TempRamInitDone:
> > +  cmp     rax, 0800000000000000Eh ; Check if EFI_NOT_FOUND returned.
> > Error code for Microcode Update not found.
> > +  je      CallSecFspInit          ; If microcode not found, don't hang, but continue.
> > +
> > +  cmp     rax, 0                  ; Check if EFI_SUCCESS returned.
> > +  jnz     FspApiFailed
> > +
> > +  ; RDX: start of range
> > +  ; R8: end of range
> > +CallSecFspInit:
> > +
> > +  mov     r8,  rdx
> > +  mov     rdx, rcx
> > +  xor     ecx, ecx ; zero - no Hob List Yet
> > +  mov     rsp, r8
> > +
> > +  ;
> > +  ; Per X64 calling convention, make sure RSP is 16-byte aligned.
> > +  ;
> > +  mov     rax, rsp
> > +  and     rax, 0fh
> > +  sub     rsp, rax
> > +
> > +  call    ASM_PFX(CallPeiCoreEntryPoint)
> > +
> > +FspApiFailed:
> > +  jmp     $
> > +
> > +align 10h
> > +TempRamInitStack:
> > +    DQ  TempRamInitDone
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/Se
> > cFspWrapperPlatformSecLibSample/X64/Stack.nasm
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/X64/Stack.nasm
> > new file mode 100644
> > index 0000000000..6feb38ce02
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/S
> > ecFspWrapperPlatformSecLibSample/X64/Stack.nasm
> > @@ -0,0 +1,73 @@
> > +;------------------------------------------------------------------------------
> > +;
> > +; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
> > +; SPDX-License-Identifier: BSD-2-Clause-Patent
> > +;
> > +; Abstract:
> > +;
> > +;   Switch the stack from temporary memory to permanent memory.
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +    SECTION .text
> > +
> > +;------------------------------------------------------------------------------
> > +; VOID
> > +; EFIAPI
> > +; SecSwitchStack (
> > +;   UINT32   TemporaryMemoryBase,
> > +;   UINT32   PermanentMemoryBase
> > +;   );
> > +;------------------------------------------------------------------------------
> > +global ASM_PFX(SecSwitchStack)
> > +ASM_PFX(SecSwitchStack):
> > +    ;
> > +    ; Save four register: rax, rbx, rcx, rdx
> > +    ;
> > +    push  rax
> > +    push  rbx
> > +    push  rcx
> > +    push  rdx
> > +
> > +    ;
> > +    ; !!CAUTION!! this function address's is pushed into stack after
> > +    ; migration of whole temporary memory, so need save it to permanent
> > +    ; memory at first!
> > +    ;
> > +
> > +    mov   rbx, rcx                 ; Save the first parameter
> > +    mov   rcx, rdx                 ; Save the second parameter
> > +
> > +    ;
> > +    ; Save this function's return address into permanent memory at first.
> > +    ; Then, Fixup the esp point to permanent memory
> > +    ;
> > +    mov   rax, rsp
> > +    sub   rax, rbx
> > +    add   rax, rcx
> > +    mov   rdx, qword [rsp]         ; copy pushed register's value to permanent
> > memory
> > +    mov   qword [rax], rdx
> > +    mov   rdx, qword [rsp + 8]
> > +    mov   qword [rax + 8], rdx
> > +    mov   rdx, qword [rsp + 16]
> > +    mov   qword [rax + 16], rdx
> > +    mov   rdx, qword [rsp + 24]
> > +    mov   qword [rax + 24], rdx
> > +    mov   rdx, qword [rsp + 32]    ; Update this function's return address into
> > permanent memory
> > +    mov   qword [rax + 32], rdx
> > +    mov   rsp, rax                 ; From now, rsp is pointed to permanent memory
> > +
> > +    ;
> > +    ; Fixup the rbp point to permanent memory
> > +    ;
> > +    mov   rax, rbp
> > +    sub   rax, rbx
> > +    add   rax, rcx
> > +    mov   rbp, rax                 ; From now, rbp is pointed to permanent memory
> > +
> > +    pop   rdx
> > +    pop   rcx
> > +    pop   rbx
> > +    pop   rax
> > +    ret
> > +
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxe/PrepareForFspSmmDxe.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxe/PrepareForFspSmmDxe.c
> > new file mode 100644
> > index 0000000000..87abe27c09
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxe/PrepareForFspSmmDxe.c
> > @@ -0,0 +1,152 @@
> > +/** @file
> > +  Implements PrepareForFspSmmDxe.c
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <FspsUpd.h>
> > +#include <MultiPhaseSiPhases.h>
> > +#include <FspSmmDataExchangeBuffer.h>
> > +#include <Pi/PiHob.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/FspWrapperApiLib.h>
> > +#include <Protocol/MmCommunication2.h>
> > +
> > +#ifdef TPM_ENABLE
> > +#define TOTAL_DEPENDENCY_COUNT  2
> > +#else
> > +#define TOTAL_DEPENDENCY_COUNT  1// No TCG2.
> > +#endif
> > +
> > +STATIC FSPS_UPD *volatile                      FspsUpd;
> > +STATIC FSP_SMM_DATA_EXCHANGE_BUFFER *volatile  ExchangeBuffer;
> > +STATIC volatile UINTN                          DependencyCount = 0;
> > +
> > +extern EFI_GUID  gFspsUpdDataPointerAddressGuid;
> > +extern EFI_GUID  gExchangeBufferUpdateNotifyGuid;
> > +extern EFI_GUID  gFspSmmDependencyReadyProtocolGuid;
> > +
> > +STATIC
> > +EFI_STATUS
> > +CallFspAfterSmmConditionsMet (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_SUCCESS;
> > +  EFI_HANDLE  Handle = NULL;
> > +
> > +  gST->BootServices->InstallProtocolInterface (
> > +                       &Handle,
> > +                       &gFspSmmDependencyReadyProtocolGuid,
> > +                       EFI_NATIVE_INTERFACE,
> > +                       NULL
> > +                       );
> > +  // }
> > +  return Status;
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +OnRequiredProtocolReady (
> > +  IN  EFI_EVENT  Event,
> > +  IN  VOID       *Context
> > +  )
> > +{
> > +  VOID  *Interface;
> > +
> > +  gBS->CloseEvent (Event);
> > +  gBS->LocateProtocol (Context, NULL, &Interface);
> > +  DEBUG ((DEBUG_INFO, "%a:located %g at %011p\n", __FILE__, Context,
> > Interface));
> > +  if (CompareGuid (Context, &gEfiGlobalNvsAreaProtocolGuid)) {
> > +    ExchangeBuffer->NvsAreaProtocol = Interface;
> > +    DEBUG ((DEBUG_INFO, "%a:gEfiGlobalNvsAreaProtocolGuid\n",
> > __FILE__));
> > +    DependencyCount++;
> > +    goto check_dependencies_count;
> > +  }
> > +
> > +  if (CompareGuid (Context, &gEfiTcg2ProtocolGuid)) {
> > +    ExchangeBuffer->EfiTcg2Protocol = Interface;
> > +    DEBUG ((DEBUG_INFO, "%a:gEfiTcg2ProtocolGuid\n", __FILE__));
> > +    DependencyCount++;
> > +    goto check_dependencies_count;
> > +  }
> > +
> > +check_dependencies_count:
> > +  if (DependencyCount == TOTAL_DEPENDENCY_COUNT) {
> > +    DEBUG ((DEBUG_INFO, "All Dependencies are ready!\n"));
> > +    CallFspAfterSmmConditionsMet ();
> > +  }
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +PrepareForFSPSmmDxeEntryPoint (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +  VOID        *FspsUpdHob = GetFirstGuidHob
> > (&gFspsUpdDataPointerAddressGuid);
> > +  VOID        *Registration;
> > +
> > +  if ( FspsUpdHob != NULL ) {
> > +    FspsUpd        = ((FSPS_UPD *)(UINTN)(*(UINT32 *)GET_GUID_HOB_DATA
> > (FspsUpdHob)));
> > +    ExchangeBuffer = AllocateZeroPool (sizeof
> > (FSP_SMM_DATA_EXCHANGE_BUFFER));
> > +    if ( ExchangeBuffer == NULL ) {
> > +      DEBUG ((DEBUG_ERROR, "Cannot Allocate memory for SMM data
> > exchange!\n"));
> > +      return EFI_ABORTED;
> > +    }
> > +
> > +    FspsUpd->FspsConfig.smm_data_buffer_address =
> > (UINT64)(UINTN)ExchangeBuffer;
> > +    DEBUG ((DEBUG_ERROR, "Exchange Buffer is at %011p\n",
> > ExchangeBuffer));
> > +    // Create callbacks to acquire protocol base address.
> > +    Status = gBS->LocateProtocol (&gEfiGlobalNvsAreaProtocolGuid, NULL,
> > &(ExchangeBuffer->NvsAreaProtocol));
> > +    if (EFI_ERROR (Status)) {
> > +      EfiNamedEventListen (
> > +        &gEfiGlobalNvsAreaProtocolGuid,
> > +        TPL_NOTIFY,
> > +        OnRequiredProtocolReady,
> > +        &gEfiGlobalNvsAreaProtocolGuid,
> > +        &Registration
> > +        );
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "%a:gEfiGlobalNvsAreaProtocolGuid is installed
> > already\n", __FILE__));
> > +      DependencyCount++;
> > +    }
> > +
> > +    Status = gBS->LocateProtocol (&gEfiTcg2ProtocolGuid, NULL,
> > &(ExchangeBuffer->EfiTcg2Protocol));
> > +    if (EFI_ERROR (Status)) {
> > +      EfiNamedEventListen (
> > +        &gEfiTcg2ProtocolGuid,
> > +        TPL_NOTIFY,
> > +        OnRequiredProtocolReady,
> > +        &gEfiTcg2ProtocolGuid,
> > +        &Registration
> > +        );
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "%a:gEfiTcg2ProtocolGuid is installed
> already\n",
> > __FILE__));
> > +      DependencyCount++;
> > +    }
> > +
> > +    if (DependencyCount == 5) {
> > +      DEBUG ((DEBUG_INFO, "All Dependencies are ready!\n"));
> > +      CallFspAfterSmmConditionsMet ();
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_ERROR, "Cannot locate FSP-S UPD!\n"));
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxe/PrepareForFspSmmDxe.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxe/PrepareForFspSmmDxe.inf
> > new file mode 100644
> > index 0000000000..03d6c9d668
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxe/PrepareForFspSmmDxe.inf
> > @@ -0,0 +1,57 @@
> > +## @file
> > +#  FSP SMM DXE INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = PrepareForFspSmmDxe
> > +  FILE_GUID                      = 48FFA2F1-6F90-4009-8BA1-F6DDCF3F272D
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = PrepareForFSPSmmDxeEntryPoint
> > +
> > +
> > +[Sources]
> > +  PrepareForFspSmmDxe.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  AmdCommonPkg/AmdBct/AmdBctPkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  ChachaniBoardPkg/Project.dec
> > +  AgesaPublic/AgesaPublic.dec
> > +
> > +[LibraryClasses]
> > +  UefiBootServicesTableLib
> > +  UefiDriverEntryPoint
> > +  MemoryAllocationLib
> > +  FspWrapperApiLib
> > +  DebugLib
> > +  BaseLib
> > +  UefiLib
> > +  HobLib
> > +
> > +[Protocols]
> > +  gEfiGlobalNvsAreaProtocolGuid
> > +  gEfiHiiDatabaseProtocolGuid
> > +  gEfiTcg2ProtocolGuid
> > +  gEfiVariableArchProtocolGuid
> > +  gEfiVariableWriteArchProtocolGuid
> > +  gPspFlashAccSmmCommReadyProtocolGuid
> > +  gFspSmmDependencyReadyProtocolGuid
> > +
> > +[Guids]
> > +  gFspsUpdDataPointerAddressGuid
> > +  gExchangeBufferUpdateNotifyGuid                   ## FOR SMI
> > +
> > +[Pcd]
> > +  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInMemory #
> > CONSUMES
> > +
> > +[Depex]
> > +  TRUE                  ## FOR SMM Communication
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxeFsp/PrepareForFspSmmDxeFsp.c
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxeFsp/PrepareForFspSmmDxeFsp.c
> > new file mode 100644
> > index 0000000000..05e5a0bd08
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxeFsp/PrepareForFspSmmDxeFsp.c
> > @@ -0,0 +1,86 @@
> > +/** @file
> > +  Implements PrepareForFspSmmDxeFsp.c
> > +
> > +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <FspsUpd.h>
> > +#include <FspSmmDataExchangeBuffer.h>
> > +#include <Pi/PiHob.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/SmmServicesTableLib.h>
> > +
> > +extern EFI_GUID  gExchangeBufferUpdateNotifyGuid;
> > +
> > +STATIC FSPS_UPD *volatile                      FspsUpd;
> > +STATIC FSP_SMM_DATA_EXCHANGE_BUFFER *volatile  ExchangeBuffer;
> > +STATIC EFI_HANDLE                              ExchangeBufferHandle;
> > +
> > +STATIC EFI_GUID  *MonitoredGuids[] = {
> > +  &gEfiGlobalNvsAreaProtocolGuid,
> > +  &gEfiTcg2ProtocolGuid
> > +};
> > +STATIC BOOLEAN   ProtocolInstalled[sizeof (MonitoredGuids)/sizeof (VOID
> > *)];
> > +
> > +extern EFI_GUID  gFspsUpdDataPointerAddressGuid;
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DetectAndInstallNewProtocol (
> > +  VOID
> > +  )
> > +{
> > +  if ((ExchangeBuffer->NvsAreaProtocol != 0) && (ProtocolInstalled[0] ==
> > FALSE)) {
> > +    VOID  *Handle = NULL;
> > +    gBS->InstallMultipleProtocolInterfaces (
> > +           &Handle,
> > +           &gEfiGlobalNvsAreaProtocolGuid,
> > +           ExchangeBuffer->NvsAreaProtocol,
> > +           NULL
> > +           );
> > +    ProtocolInstalled[0] = TRUE;
> > +  }
> > +
> > +  if ((ExchangeBuffer->EfiTcg2Protocol != 0) && (ProtocolInstalled[4] ==
> > FALSE)) {
> > +    VOID  *Handle = NULL;
> > +    gBS->InstallMultipleProtocolInterfaces (
> > +           &Handle,
> > +           &gEfiTcg2ProtocolGuid,
> > +           ExchangeBuffer->EfiTcg2Protocol,
> > +           NULL
> > +           );
> > +    ProtocolInstalled[1] = TRUE;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +PrepareForFSPSmmDxeFspEntryPoint (
> > +  IN EFI_HANDLE        ImageHandle,
> > +  IN EFI_SYSTEM_TABLE  *SystemTable
> > +  )
> > +{
> > +  VOID  *FspsUpdHob = GetFirstGuidHob
> > (&gFspsUpdDataPointerAddressGuid);
> > +
> > +  if ( FspsUpdHob != NULL ) {
> > +    FspsUpd        = ((FSPS_UPD *)(UINTN)(*(UINT32 *)GET_GUID_HOB_DATA
> > (FspsUpdHob)));
> > +    ExchangeBuffer = (FSP_SMM_DATA_EXCHANGE_BUFFER
> > *)(UINTN)FspsUpd->FspsConfig.smm_data_buffer_address;
> > +    DEBUG ((DEBUG_ERROR, "Exchange Buffer is at %011p\n",
> > ExchangeBuffer));
> > +    DetectAndInstallNewProtocol ();
> > +  } else {
> > +    DEBUG ((DEBUG_ERROR, "Cannot locate FSP-S UPD!\n"));
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxeFsp/PrepareForFspSmmDxeFsp.inf
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxeFsp/PrepareForFspSmmDxeFsp.inf
> > new file mode 100644
> > index 0000000000..19dd25b27f
> > --- /dev/null
> > +++
> >
> b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareF
> > orFspSmmDxeFsp/PrepareForFspSmmDxeFsp.inf
> > @@ -0,0 +1,49 @@
> > +#  FSP SMM DXE for FSP INF file
> > +#
> > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> >
> +##****************************************************************
> > ********
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = PrepareForFspSmmDxeFsp
> > +  FILE_GUID                      = 6D4E6FB4-BA8D-4736-88A1-CC50EFFB2DC0
> > +  MODULE_TYPE                    = DXE_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = PrepareForFSPSmmDxeFspEntryPoint
> > +
> > +
> > +[Sources]
> > +  PrepareForFspSmmDxeFsp.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  MdeModulePkg/MdeModulePkg.dec
> > +  IntelFsp2Pkg/IntelFsp2Pkg.dec
> > +  Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
> > +  ChachaniBoardPkg/Project.dec
> > +
> > +[LibraryClasses]
> > +  UefiBootServicesTableLib
> > +  UefiDriverEntryPoint
> > +  MemoryAllocationLib
> > +  DebugLib
> > +  HobLib
> > +
> > +[Protocols]
> > +  gEfiGlobalNvsAreaProtocolGuid
> > +  gEfiHiiDatabaseProtocolGuid
> > +  gEfiTcg2ProtocolGuid
> > +  gEfiTcgProtocolGuid
> > +  gEfiVariableArchProtocolGuid
> > +  gEfiVariableWriteArchProtocolGuid
> > +
> > +[Guids]
> > +  gFspsUpdDataPointerAddressGuid
> > +  gExchangeBufferUpdateNotifyGuid                   ## FOR SMI
> > +
> > +[Pcd]
> > +
> > +[Depex]
> > +  gFspSmmDependencyReadyProtocolGuid
> > --
> > 2.31.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#114569): https://edk2.groups.io/g/devel/message/114569
Mute This Topic: https://groups.io/mt/103971425/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  reply	other threads:[~2024-01-26  9:36 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-26  6:00 [edk2-devel] [PATCH V2 00/32] Introduce AMD Vangogh platform reference code Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 01/32] AMD/AmdPlatformPkg: Check in AMD S3 logo Zhai, MingXin (Duke) via groups.io
2024-01-26  9:19   ` Chang, Abner via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 02/32] AMD/VanGoghBoard: Check in ACPI tables Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 03/32] AMD/VanGoghBoard: Check in Capsule update Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 04/32] AMD/VanGoghBoard: Check in AgesaPublic pkg Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 05/32]AMD/VanGoghBoard: Check in PlatformSecLib Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 06/32] AMD/VanGoghBoard: Check in AmdIdsExtLib Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 07/32] AMD/VanGoghBoard: Check in PciPlatform Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 08/32] AMD/VanGoghBoard: Check in UDKFlashUpdate Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 09/32] AMD/VanGoghBoard: Check in Flash_AB Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 10/32] AMD/VanGoghBoard: Check in FlashUpdate Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 11/32] AMD/VanGoghBoard: Check in FvbServices Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 12/32] AMD/VanGoghBoard: Check in AMD BaseSerialPortLib Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 13/32] AMD/VanGoghBoard: Check in PlatformFlashAccessLib Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 14/32] AMD/VanGoghBoard: Check in SmbiosLib Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 15/32] AMD/VanGoghBoard: Check in SpiFlashDeviceLib Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 16/32] AMD/VanGoghBoard: Check in BaseTscTimerLib Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 17/32] AMD/VanGoghBoard: Check in Smm access module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 18/32] AMD/VanGoghBoard: Check in PciHostBridge module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 19/32] AMD/VanGoghBoard: Check in PcatRealTimeClockRuntimeDxe module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 20/32] AMD/VanGoghBoard: Check in FTPM module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 21/32] AMD/VanGoghBoard: Check in SignedCapsule Zhai, MingXin (Duke) via groups.io
2024-01-26  9:28   ` Chang, Abner via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 22/32] AMD/VanGoghBoard: Check in Vtf0 Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 23/32] AMD/VanGoghBoard: Check in AcpiPlatform Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 24/32] AMD/VanGoghBoard: Check in FchSpi module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 25/32] AMD/VanGoghBoard: Check in PlatformInitPei module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 26/32] AMD/VanGoghBoard: Check in Smbios platform dxe drivers Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 27/32] AMD/VanGoghBoard: Check in Fsp2WrapperPkg Zhai, MingXin (Duke) via groups.io
2024-01-26  9:34   ` Chang, Abner via groups.io
2024-01-26  9:36     ` Chang, Abner via groups.io [this message]
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 28/32] AMD/VanGoghBoard: Check in SmmCpuFeaturesLibCommon module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 29/32] AMD/VanGoghBoard: Check in SmramSaveState module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 30/32] AMD/VanGoghBoard: Check in EDK2 override files Zhai, MingXin (Duke) via groups.io
2024-01-26  9:37   ` Chang, Abner via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 31/32] AMD/VanGoghBoard: Check in AMD SmmControlPei module Zhai, MingXin (Duke) via groups.io
2024-01-26  6:00 ` [edk2-devel] [PATCH V2 32/32] AMD/VanGoghBoard: Check in Chachani board project files and build script Zhai, MingXin (Duke) via groups.io
2024-01-26  9:48 ` [edk2-devel] [PATCH V2 00/32] Introduce AMD Vangogh platform reference code Chang, Abner via groups.io

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=LV8PR12MB9452EB3798BBE5F1F89005F7EA792@LV8PR12MB9452.namprd12.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