public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Zhai, MingXin (Duke) via groups.io" <duke.zhai=amd.com@groups.io>
To: <devel@edk2.groups.io>
Cc: Eric Xing <eric.xing@amd.com>, Duke Zhai <duke.zhai@amd.com>,
	Igniculus Fu <igniculus.fu@amd.com>,
	Abner Chang <abner.chang@amd.com>
Subject: [edk2-devel] [PATCH V2 27/32] AMD/VanGoghBoard: Check in Fsp2WrapperPkg
Date: Fri, 26 Jan 2024 14:00:45 +0800	[thread overview]
Message-ID: <20240126060050.1725-28-duke.zhai@amd.com> (raw)
In-Reply-To: <20240126060050.1725-1-duke.zhai@amd.com>

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/Fsp2WrapperPkg.dec
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/FspsMultiPhaseSiInitDxe.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/FspsMultiPhaseSiInitDxe.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/LoadBelow4G.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspExportedInterfaceHob.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspMemoryRegionHob.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspSmmDataExchangeBuffer.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspUpd.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspmUpd.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspsUpd.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FsptUpd.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspMeasurementLib.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperApiLib.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperMultiPhaseProcessLib.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperPlatformMultiPhaseLib.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/MultiPhaseSiPhases.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/BaseFspMeasurementLib/BaseFspMeasurementLib.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.nasm
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPhaseLibNull.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLibNull.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/CommonHeader.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/MemoryInstall.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Fsp.h
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/Stack.nasm
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxe/PrepareForFspSmmDxe.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxe/PrepareForFspSmmDxe.inf
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxeFsp/PrepareForFspSmmDxeFsp.c
 create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxeFsp/PrepareForFspSmmDxeFsp.inf

diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FSP_Release_Notes.txt b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FSP_Release_Notes.txt
new file mode 100644
index 0000000000..92e8f7a43b
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FSP_Release_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/Fsp2WrapperPkg.dec b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec
new file mode 100644
index 0000000000..25327755e6
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.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
+##
+
+## @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/FspWrapperMultiPhaseProcessLib.h
+
+  ##  @libraryclass  Provide MultiPhase platform actions related functions.
+  FspWrapperPlatformMultiPhaseLib|Include/Library/FspWrapperPlatformMultiPhaseLib.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|UINT32|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|UINT32|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|0x40000009
+
+  ## 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|UINT8|0x4000000A
+
+  #
+  ## These are the base address of FSP-M/S
+  #
+  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInFlash|0x00000000|UINT32|0x00001000
+  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInFlash|0x00000000|UINT32|0x00001001
+  gFsp2WrapperTokenSpaceGuid.PcdFspoPeiBaseAddressInFlash|0x00000000|UINT32|0x00001002
+  gFsp2WrapperTokenSpaceGuid.PcdFspoDxeBaseAddressInFlash|0x00000000|UINT32|0x00001003
+
+  gFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddressInMemory|0x00000000|UINT32|0x00002000
+  gFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddressInMemory|0x00000000|UINT32|0x00002001
+  gFsp2WrapperTokenSpaceGuid.PcdFspoPeiBaseAddressInMemory|0x00000000|UINT32|0x00002002
+  gFsp2WrapperTokenSpaceGuid.PcdFspoDxeBaseAddressInMemory|0x00000000|UINT32|0x00002003
+
+  gFsp2WrapperTokenSpaceGuid.PcdFspmRegionSize|0x00000000|UINT32|0x00003000
+  gFsp2WrapperTokenSpaceGuid.PcdFspsRegionSize|0x00000000|UINT32|0x00003001
+  gFsp2WrapperTokenSpaceGuid.PcdFspoPeiRegionSize|0x00000000|UINT32|0x00003002
+  gFsp2WrapperTokenSpaceGuid.PcdFspoDxeRegionSize|0x00000000|UINT32|0x00003003
+
+  gFsp2WrapperTokenSpaceGuid.FspoPeiWorkaroundShadowCopyAddress|0x09E00000|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|0x00000000|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/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c
new file mode 100644
index 0000000000..0c997b40d0
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/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/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf
new file mode 100644
index 0000000000..9ec6de6a13
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/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
+#
+##
+
+## @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/FspWrapperNotifyDxe/LoadBelow4G.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c
new file mode 100644
index 0000000000..9a49d3b492
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/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))(NewImageHandle, 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/FspmWrapperPeim/FspmWrapperPeim.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
new file mode 100644
index 0000000000..fc5a339e8b
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapperPeim/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/FspmWrapperPeim/FspmWrapperPeim.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.inf
new file mode 100644
index 0000000000..ced1873a44
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapperPeim/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
+#
+##
+
+## @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/FspsMultiPhaseSiInitDxe/FspsMultiPhaseSiInitDxe.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/FspsMultiPhaseSiInitDxe.c
new file mode 100644
index 0000000000..bb5e12cba9
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/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/FspsMultiPhaseSiInitDxe/FspsMultiPhaseSiInitDxe.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/FspsMultiPhaseSiInitDxe.inf
new file mode 100644
index 0000000000..7eefe691cf
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/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
+#
+##
+
+## @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.PcdAmdFspSetupTableInitNeedsReset
+
+[Depex]
+  TRUE
diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/LoadBelow4G.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/LoadBelow4G.c
new file mode 100644
index 0000000000..ae05556cc9
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/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))(NewImageHandle, 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/FspsWrapperPeim/FspsWrapperPeim.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
new file mode 100644
index 0000000000..e6a589bcb5
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapperPeim/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/FspsWrapperPeim/FspsWrapperPeim.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.inf
new file mode 100644
index 0000000000..e43a8c941f
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapperPeim/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/FspExportedInterfaceHob.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspExportedInterfaceHob.h
new file mode 100644
index 0000000000..66778b0143
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspExportedInterfaceHob.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/FspMemoryRegionHob.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspMemoryRegionHob.h
new file mode 100644
index 0000000000..3319cad3bc
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspMemoryRegionHob.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/FspSmmDataExchangeBuffer.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspSmmDataExchangeBuffer.h
new file mode 100644
index 0000000000..1eaa187bb8
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspSmmDataExchangeBuffer.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/FspUpd.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspUpd.h
new file mode 100644
index 0000000000..a4827a0068
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspUpd.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/FspmUpd.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspmUpd.h
new file mode 100644
index 0000000000..ed9a6c79a3
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspmUpd.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/FspsUpd.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspsUpd.h
new file mode 100644
index 0000000000..c1fb89c63d
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FspsUpd.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/FsptUpd.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FsptUpd.h
new file mode 100644
index 0000000000..604efefa7d
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/FsptUpd.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/Library/FspMeasurementLib.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspMeasurementLib.h
new file mode 100644
index 0000000000..7172544b8a
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/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/Library/FspWrapperApiLib.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperApiLib.h
new file mode 100644
index 0000000000..073c6e1d0e
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/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/Library/FspWrapperApiTestLib.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h
new file mode 100644
index 0000000000..c4e785e41e
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/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/Library/FspWrapperHobProcessLib.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h
new file mode 100644
index 0000000000..8c0c244e43
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/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/Library/FspWrapperMultiPhaseProcessLib.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperMultiPhaseProcessLib.h
new file mode 100644
index 0000000000..89cff5ea4a
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/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/Library/FspWrapperPlatformLib.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h
new file mode 100644
index 0000000000..529bc31145
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/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/Library/FspWrapperPlatformMultiPhaseLib.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperPlatformMultiPhaseLib.h
new file mode 100644
index 0000000000..8e16ddb719
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/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/Ppi/FspSiliconInitDone.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h
new file mode 100644
index 0000000000..23d46ea1f1
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi/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/Ppi/TopOfTemporaryRam.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h
new file mode 100644
index 0000000000..7bb32290cb
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi/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/BaseFspMeasurementLib/BaseFspMeasurementLib.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf
new file mode 100644
index 0000000000..48eb4991dd
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspMeasurementLib/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/BaseFspMeasurementLib/FspMeasurementLib.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
new file mode 100644
index 0000000000..9a9368bb75
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspMeasurementLib/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/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf
new file mode 100644
index 0000000000..e41d17d67c
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/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
+#
+##
+
+## @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/BaseFspWrapperApiLib/FspWrapperApiLib.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
new file mode 100644
index 0000000000..80d64f9bd2
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/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/BaseFspWrapperApiLib/IA32/DispatchExecute.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/IA32/DispatchExecute.c
new file mode 100644
index 0000000000..434eb549a4
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/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/BaseFspWrapperApiLib/X64/DispatchExecute.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
new file mode 100644
index 0000000000..3c34806286
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/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/BaseFspWrapperApiLib/X64/Thunk64To32.nasm b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.nasm
new file mode 100644
index 0000000000..f1a14b2446
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/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/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf
new file mode 100644
index 0000000000..4d40f86b3a
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/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/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
new file mode 100644
index 0000000000..19bd3afc29
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/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/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf
new file mode 100644
index 0000000000..1f66593a52
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/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/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
new file mode 100644
index 0000000000..1afcf68f85
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/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/BaseFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPhaseLibNull.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPhaseLibNull.inf
new file mode 100644
index 0000000000..f9f1a12c2f
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibNull/BaseFspWrapperPlatformMultiPhaseLibNull.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/BaseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLibNull.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLibNull.c
new file mode 100644
index 0000000000..3a0d0e6088
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLibNull.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/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c
new file mode 100644
index 0000000000..cfda44bc71
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/DxeFspWrapperMultiPhaseProcessLib/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,PcdS3BootScriptTablePrivateSmmDataPtr:%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/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.inf
new file mode 100644
index 0000000000..21912fba99
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.inf
@@ -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.PcdAmdSmmCommunicationAddress ## 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/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf
new file mode 100644
index 0000000000..6f681780e3
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/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/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
new file mode 100644
index 0000000000..e072efbb04
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/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/PeiFspWrapperApiTestLib/FspWrapperApiTest.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/FspWrapperApiTest.c
new file mode 100644
index 0000000000..caffada924
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/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/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/PeiFspWrapperApiTestLib.inf
new file mode 100644
index 0000000000..5b378c6c55
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperApiTestLib/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/PeiFspWrapperHobProcessLibSample/CommonHeader.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/CommonHeader.h
new file mode 100644
index 0000000000..d512feaa5b
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/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/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
new file mode 100644
index 0000000000..3100f4635e
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/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/PeiFspWrapperHobProcessLibSample/MemoryInstall.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/MemoryInstall.h
new file mode 100644
index 0000000000..c9a58aea56
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/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/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/PeiFspWrapperHobProcessLibSample.inf
new file mode 100644
index 0000000000..6fdfb8e34c
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/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.PcdAmdFabricResourceDefaultSizePtr
+[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/SecFspWrapperPlatformSecLibSample/Fsp.h b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Fsp.h
new file mode 100644
index 0000000000..0bb612ea87
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/FspWrapperPlatformSecLibSample.c
new file mode 100644
index 0000000000..54f363e59d
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/PeiCoreEntry.nasm
new file mode 100644
index 0000000000..cf443aa267
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..b506212bfa
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
new file mode 100644
index 0000000000..48101131fa
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/PlatformInit.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/PlatformInit.c
new file mode 100644
index 0000000000..237aeead51
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
new file mode 100644
index 0000000000..ac417c8e59
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
@@ -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/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecGetPerformance.c
new file mode 100644
index 0000000000..449a2d6e99
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecPlatformInformation.c
new file mode 100644
index 0000000000..b96f38432e
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/SecRamInitData.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
new file mode 100644
index 0000000000..5e7f051bb6
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecTempRamDone.c
new file mode 100644
index 0000000000..fab488e668
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
new file mode 100644
index 0000000000..548474ccbb
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm
new file mode 100644
index 0000000000..4025b4157c
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/SecFspWrapperPlatformSecLibSample/X64/Stack.nasm b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/Stack.nasm
new file mode 100644
index 0000000000..6feb38ce02
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/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/PrepareForFspSmmDxe/PrepareForFspSmmDxe.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxe/PrepareForFspSmmDxe.c
new file mode 100644
index 0000000000..87abe27c09
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxe/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/PrepareForFspSmmDxe/PrepareForFspSmmDxe.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxe/PrepareForFspSmmDxe.inf
new file mode 100644
index 0000000000..03d6c9d668
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxe/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/PrepareForFspSmmDxeFsp/PrepareForFspSmmDxeFsp.c b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxeFsp/PrepareForFspSmmDxeFsp.c
new file mode 100644
index 0000000000..05e5a0bd08
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxeFsp/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/PrepareForFspSmmDxeFsp/PrepareForFspSmmDxeFsp.inf b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxeFsp/PrepareForFspSmmDxeFsp.inf
new file mode 100644
index 0000000000..19dd25b27f
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/PrepareForFspSmmDxeFsp/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 (#114523): https://edk2.groups.io/g/devel/message/114523
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]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2024-01-26  6:04 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 ` Zhai, MingXin (Duke) via groups.io [this message]
2024-01-26  9:34   ` [edk2-devel] [PATCH V2 27/32] AMD/VanGoghBoard: Check in Fsp2WrapperPkg Chang, Abner via groups.io
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=20240126060050.1725-28-duke.zhai@amd.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