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:34:43 +0000	[thread overview]
Message-ID: <LV8PR12MB945204202B066E2D432908E8EA792@LV8PR12MB9452.namprd12.prod.outlook.com> (raw)
In-Reply-To: <20240126060050.1725-28-duke.zhai@amd.com>

[AMD Official Use Only - General]

> -----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 (#114567): https://edk2.groups.io/g/devel/message/114567
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:35 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 [this message]
2024-01-26  9:36     ` Chang, Abner via groups.io
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=LV8PR12MB945204202B066E2D432908E8EA792@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