From: "duke.zhai 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 27/33] AMD/VanGoghBoard: Check in Fsp2WrapperPkg.
Date: Thu, 18 Jan 2024 14:50:40 +0800 [thread overview]
Message-ID: <20240118065046.961-28-duke.zhai@amd.com> (raw)
In-Reply-To: <20240118065046.961-1-duke.zhai@amd.com>
From: Duke Zhai <Duke.Zhai@amd.com>
BZ #:4640
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 | 685 ++++++++
.../FspWrapperNotifyDxe.inf | 82 +
.../FspWrapperNotifyDxe/LoadBelow4G.c | 156 ++
.../FspmWrapperPeim/FspmWrapperPeim.c | 487 ++++++
.../FspmWrapperPeim/FspmWrapperPeim.inf | 99 ++
.../FspsMultiPhaseSiInitDxe.c | 215 +++
.../FspsMultiPhaseSiInitDxe.inf | 81 +
.../FspsMultiPhaseSiInitDxe/LoadBelow4G.c | 156 ++
.../FspsWrapperPeim/FspsWrapperPeim.c | 641 ++++++++
.../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 | 50 +
.../Include/Library/FspWrapperApiLib.h | 91 ++
.../Include/Library/FspWrapperApiTestLib.h | 65 +
.../Include/Library/FspWrapperHobProcessLib.h | 48 +
.../Library/FspWrapperMultiPhaseProcessLib.h | 54 +
.../Include/Library/FspWrapperPlatformLib.h | 90 +
.../Library/FspWrapperPlatformMultiPhaseLib.h | 40 +
.../Include/MultiPhaseSiPhases.h | 19 +
.../Include/Ppi/FspSiliconInitDone.h | 47 +
.../Include/Ppi/TopOfTemporaryRam.h | 24 +
.../BaseFspMeasurementLib.inf | 54 +
.../BaseFspMeasurementLib/FspMeasurementLib.c | 263 +++
.../BaseFspWrapperApiLib.inf | 73 +
.../BaseFspWrapperApiLib/FspWrapperApiLib.c | 244 +++
.../IA32/DispatchExecute.c | 71 +
.../X64/DispatchExecute.c | 176 ++
.../BaseFspWrapperApiLib/X64/Thunk64To32.nasm | 257 +++
.../BaseFspWrapperApiTestLibNull.inf | 56 +
.../FspWrapperApiTestNull.c | 69 +
.../BaseFspWrapperPlatformLibSample.inf | 79 +
.../FspWrapperPlatformLibSample.c | 356 ++++
...aseFspWrapperPlatformMultiPhaseLibNull.inf | 45 +
.../FspWrapperPlatformMultiPhaseLibNull.c | 60 +
.../DxeFspWrapperMultiPhaseProcessLib.c | 540 ++++++
.../DxeFspWrapperMultiPhaseProcessLib.inf | 87 +
.../FspWrapperMultiPhaseProcessLib.inf | 56 +
.../PeiFspWrapperMultiPhaseProcessLib.c | 394 +++++
.../FspWrapperApiTest.c | 85 +
.../PeiFspWrapperApiTestLib.inf | 59 +
.../CommonHeader.h | 108 ++
.../FspWrapperHobProcessLibSample.c | 1448 +++++++++++++++++
.../MemoryInstall.h | 186 +++
.../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, 10474 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..e1b4bf169f
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c
@@ -0,0 +1,685 @@
+/** @file
+ Implements FspWrapperNotifyDxe.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ This driver will register two callbacks to call fsp's notifies.
+
+ 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..50e1d2a249
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c
@@ -0,0 +1,156 @@
+/** @file
+ Implements LoadBelow4G.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+
+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..9b0a17f607
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspmWrapperPeim/FspmWrapperPeim.c
@@ -0,0 +1,487 @@
+/** @file
+ Implements FspmWrapperPeim.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @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) 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..54dd3b02c7
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/FspsMultiPhaseSiInitDxe.c
@@ -0,0 +1,215 @@
+/** @file
+ Implements FspsMultiPhaseSiInitDxe.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ This driver will register two callbacks to call fsp's notifies.
+
+ 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..50e1d2a249
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsMultiPhaseSiInitDxe/LoadBelow4G.c
@@ -0,0 +1,156 @@
+/** @file
+ Implements LoadBelow4G.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+
+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..6912d23a7d
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/FspsWrapperPeim/FspsWrapperPeim.c
@@ -0,0 +1,641 @@
+/** @file
+ Implements FspsWrapperPeim.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @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) 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..e26688e0b9
--- /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..5ccf2aad34
--- /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..f31cf44ec8
--- /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..69fb29ed24
--- /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..b4b26623fd
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspMeasurementLib.h
@@ -0,0 +1,50 @@
+/** @file
+ Implements FspMeasurementLib.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ This library is used by FSP modules to measure data to TPM.
+
+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..e853cea537
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperApiLib.h
@@ -0,0 +1,91 @@
+/** @file
+ Implements FspWrapperApiLib.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provide FSP wrapper API related function.
+
+ 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..6b591def1b
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperApiTestLib.h
@@ -0,0 +1,65 @@
+/** @file
+ Implements FspWrapperApiTestLib.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provide FSP wrapper API test related function.
+
+ 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..05b0689ce7
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperHobProcessLib.h
@@ -0,0 +1,48 @@
+/** @file
+ Implements FspWrapperHobProcessLib.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provide FSP wrapper hob process related function.
+
+ 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..6403037cf6
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperMultiPhaseProcessLib.h
@@ -0,0 +1,54 @@
+/** @file
+ Implements FspWrapperMultiPhaseProcessLib.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provide FSP wrapper MultiPhase handling functions.
+
+ 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..e5fa14f9b7
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperPlatformLib.h
@@ -0,0 +1,90 @@
+/** @file
+ Implements FspWrapperPlatformLib.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provide FSP wrapper platform related function.
+
+ 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..56a75bb6fd
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Library/FspWrapperPlatformMultiPhaseLib.h
@@ -0,0 +1,40 @@
+/** @file
+ Implements FspWrapperPlatformMultiPhaseLib.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provide FSP wrapper Platform MultiPhase handling functions.
+
+ 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..c78b7ff83d
--- /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..5413aa9c69
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi/FspSiliconInitDone.h
@@ -0,0 +1,47 @@
+/** @file
+ Implements FspSiliconInitDone.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provides the services to return FSP hob list.
+
+ 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..9c87571630
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Include/Ppi/TopOfTemporaryRam.h
@@ -0,0 +1,24 @@
+/** @file
+ Implements TopOfTemporaryRam.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provides the pointer to top of temporary ram.
+
+ 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..33a3588019
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspMeasurementLib/FspMeasurementLib.c
@@ -0,0 +1,263 @@
+/** @file
+ Implements FspMeasurementLib.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ This library is used by FSP modules to measure data to TPM.
+
+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..3c4467646d
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/FspWrapperApiLib.c
@@ -0,0 +1,244 @@
+/** @file
+ Implements FspWrapperApiLib.c
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Provide FSP API related function.
+
+ 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..8c062a30de
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/DispatchExecute.c
@@ -0,0 +1,176 @@
+/** @file
+ Implements 64-bit DispatchExcute.c
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @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) 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..b89f00aadd
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiLib/X64/Thunk64To32.nasm
@@ -0,0 +1,257 @@
+;/** @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>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;**/
+; This file includes code originally published under the following license.
+;
+; 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..1fc11b14c5
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/FspWrapperApiTestNull.c
@@ -0,0 +1,69 @@
+/** @file
+ Implements FSP wrapper API test related function.
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @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>
+
+/**
+ 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..0b29df142c
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/FspWrapperPlatformLibSample.c
@@ -0,0 +1,356 @@
+/** @file
+ Implements FspWrapperPlatformLibSample.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Sample to provide FSP wrapper related function.
+
+ 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..4715c640c1
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibNull/FspWrapperPlatformMultiPhaseLibNull.c
@@ -0,0 +1,60 @@
+/** @file
+ Implements FspWrapperPlatformLibSample.C
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @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
+
+**/
+
+#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..7f5666f238
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/DxeFspWrapperMultiPhaseProcessLib/DxeFspWrapperMultiPhaseProcessLib.c
@@ -0,0 +1,540 @@
+/** @file
+ Implements DxeFspWrapperMultiPhaseProcessLib.c
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Support FSP Wrapper MultiPhase process.
+
+ 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..042b6a1e54
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
@@ -0,0 +1,394 @@
+/** @file
+ Implements PeiFspWrapperMultiPhaseProcessLib.c
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+ Support FSP Wrapper MultiPhase process.
+
+ 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..568e7b0079
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/CommonHeader.h
@@ -0,0 +1,108 @@
+/** @file
+ Implements CommonHeader.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+Common header file shared by all source files.
+
+This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#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..c2b09ec52f
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/FspWrapperHobProcessLibSample.c
@@ -0,0 +1,1448 @@
+/** @file
+ Implements FspWrapperHobProcessLibSample.c
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @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
+
+**/
+
+#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 ((EFI_D_INFO, "NumRanges: %d\n", NumRanges));
+
+ DEBUG ((EFI_D_INFO, "GetMemoryMap:\n"));
+ for (Index = 0; Index < NumRanges; Index++) {
+ DEBUG ((EFI_D_INFO, "Index: %d ", Index));
+ DEBUG ((EFI_D_INFO, "RangeLength: 0x%016lX\t", MemoryMap[Index].RangeLength));
+ DEBUG ((EFI_D_INFO, "PhysicalAddress: 0x%016lX\t", MemoryMap[Index].PhysicalAddress));
+ DEBUG ((EFI_D_INFO, "CpuAddress: 0x%016lX\t", MemoryMap[Index].CpuAddress));
+ DEBUG ((EFI_D_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 ((EFI_D_INFO, "Found 0x%lx bytes at ", MemoryMap[Index].RangeLength));
+ DEBUG ((EFI_D_INFO, "0x%lx.\t", MemoryMap[Index].PhysicalAddress));
+ DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "NumRanges = 0x%x\n", NumRanges));
+
+ //
+ // Install physical memory descriptor hobs for each memory range.
+ //
+ SmramRanges = 0;
+ DEBUG ((EFI_D_INFO, "GetMemoryMap:\n"));
+ for (Index = 0; Index < NumRanges; Index++) {
+ DEBUG ((EFI_D_INFO, "Index: %d ", Index));
+ DEBUG ((EFI_D_INFO, "RangeLength: 0x%016lX\t", MemoryMap[Index].RangeLength));
+ DEBUG ((EFI_D_INFO, "PhysicalAddress: 0x%016lX\t", MemoryMap[Index].PhysicalAddress));
+ DEBUG ((EFI_D_INFO, "CpuAddress: 0x%016lX\t", MemoryMap[Index].CpuAddress));
+ DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "BufferSize = 0x%x\n", BufferSize));
+
+ Hob.Raw = BuildGuidHob (
+ &gEfiSmmPeiSmramMemoryReserveGuid,
+ BufferSize
+ );
+ ASSERT (Hob.Raw);
+ DEBUG ((EFI_D_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 ((EFI_D_INFO, "Index: 0x%X \t", Index));
+ DEBUG ((EFI_D_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 ((EFI_D_INFO, "SmramIndex: 0x%X \n", SmramIndex));
+ DEBUG ((EFI_D_INFO, "PhysicalStart: 0x%X\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart));
+ DEBUG ((EFI_D_INFO, "CpuStart : 0x%X\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart));
+ DEBUG ((EFI_D_INFO, "PhysicalSize : 0x%X\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize));
+ DEBUG ((EFI_D_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 ((EFI_D_INFO, "SmramIndex: 0x%X \n", SmramIndex));
+ DEBUG ((EFI_D_INFO, "PhysicalStart: 0x%X\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalStart));
+ DEBUG ((EFI_D_INFO, "CpuStart : 0x%X\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].CpuStart));
+ DEBUG ((EFI_D_INFO, "PhysicalSize : 0x%X\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].PhysicalSize));
+ DEBUG ((EFI_D_INFO, "RegionState : 0x%X\n\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex].RegionState));
+
+ DEBUG ((EFI_D_INFO, "PhysicalSize : 0x%X\n", (UINTN)SmramHobDescriptorBlock->Descriptor[SmramIndex-1].PhysicalSize));
+ DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "TSEG Base = 0x%08x\n", SmramHobDescriptorBlock->Descriptor[SmramRanges].PhysicalStart));
+ DEBUG ((EFI_D_INFO, "SmramRanges = 0x%x\n", SmramRanges));
+ S3MemoryRangeData = (RESERVED_ACPI_S3_RANGE *)(UINTN)
+ (SmramHobDescriptorBlock->Descriptor[SmramRanges].PhysicalStart + RESERVED_ACPI_S3_RANGE_OFFSET);
+ DEBUG ((EFI_D_INFO, "S3MemoryRangeData = 0x%08x\n", (UINTN)S3MemoryRangeData));
+
+ DEBUG ((EFI_D_INFO, "S3MemoryRangeData->AcpiReservedMemoryBase = 0x%X\n", (UINTN)S3MemoryRangeData->AcpiReservedMemoryBase));
+ DEBUG ((EFI_D_INFO, "S3MemoryRangeData->AcpiReservedMemorySize = 0x%X\n", (UINTN)S3MemoryRangeData->AcpiReservedMemorySize));
+ DEBUG ((EFI_D_INFO, "S3MemoryRangeData->SystemMemoryLength = 0x%X\n", (UINTN)S3MemoryRangeData->SystemMemoryLength));
+
+ S3MemoryBase = (UINTN)(S3MemoryRangeData->AcpiReservedMemoryBase);
+ DEBUG ((EFI_D_INFO, "S3MemoryBase = 0x%08x\n", S3MemoryBase));
+ S3MemorySize = (UINTN)(S3MemoryRangeData->AcpiReservedMemorySize);
+ DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "MemoryBegin: 0x%lX, MemoryLength: 0x%lX\n", MemoryMap[Index].PhysicalAddress, MemoryMap[Index].RangeLength));
+
+ DEBUG ((EFI_D_INFO, "Build resource HOB for Legacy Region on S3 patch :"));
+ DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((
+ EFI_D_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 ((EFI_D_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 ((
+ EFI_D_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 ((EFI_D_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..8b67437ffa
--- /dev/null
+++ b/Platform/AMD/VanGoghBoard/Override/edk2/Fsp2WrapperPkg/Library/PeiFspWrapperHobProcessLibSample/MemoryInstall.h
@@ -0,0 +1,186 @@
+/** @file
+ Implements MemoryInstall.h
+
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/* This file includes code originally published under the following license. */
+
+/** @file
+Framework PEIM to initialize memory on an DDR2 SDRAM Memory Controller.
+
+Copyright (c) 2013 - 2016 Intel Corporation.
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#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..41bee3a613
--- /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..ed6917b27b
--- /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 (#114080): https://edk2.groups.io/g/devel/message/114080
Mute This Topic: https://groups.io/mt/103831203/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-01-19 14:58 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-18 6:50 [edk2-devel] [PATCH 00/33] Introduce AMD Vangogh platform reference code duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 01/33] AMD/AmdPlatformPkg: Check in AMD S3 logo duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 02/33] AMD/VanGoghBoard: Check in ACPI tables duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 03/33] AMD/VanGoghBoard: Check in Capsule update duke.zhai via groups.io
2024-01-23 4:42 ` Chang, Abner via groups.io
2024-01-25 8:25 ` Zhai, MingXin (Duke) via groups.io
2024-01-25 11:45 ` Chang, Abner via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 04/33] AMD/VanGoghBoard: Check in AgesaPublic pkg duke.zhai via groups.io
2024-01-23 4:44 ` Chang, Abner via groups.io
2024-01-25 8:17 ` Xing, Eric via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 05/33] AMD/VanGoghBoard: Check in PlatformSecLib duke.zhai via groups.io
2024-01-23 4:46 ` Chang, Abner via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 06/33] AMD/VanGoghBoard: Check in AmdIdsExtLib duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 07/33] AMD/VanGoghBoard: Check in PciPlatform duke.zhai via groups.io
2024-01-23 4:50 ` Chang, Abner via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 08/33] AMD/VanGoghBoard: Check in UDKFlashUpdate duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 09/33] AMD/VanGoghBoard: Check in Flash_AB duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 10/33] AMD/VanGoghBoard: Check in FlashUpdate duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 11/33] AMD/VanGoghBoard: Check in FvbServices duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 12/33] AMD/VanGoghBoard: Check in AMD BaseSerialPortLib duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 13/33] AMD/VanGoghBoard: Check in PlatformFlashAccessLib duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 14/33] AMD/VanGoghBoard: Check in SmbiosLib duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 15/33] AMD/VanGoghBoard: Check in SpiFlashDeviceLib duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 16/33] AMD/VanGoghBoard: Check in BaseTscTimerLib duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 17/33] AMD/VanGoghBoard: Check in Smm access module duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 18/33] AMD/VanGoghBoard: Check in PciHostBridge module duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 19/33] AMD/VanGoghBoard: Check in PcatRealTimeClockRuntimeDxe module duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 20/33] AMD/VanGoghBoard: Check in FTPM module duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 21/33] AMD/VanGoghBoard: Check in SignedCapsule duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 22/33] AMD/VanGoghBoard: Check in Vtf0 duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 23/33] AMD/VanGoghBoard: Check in AcpiPlatform duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 24/33] AMD/VanGoghBoard: Check in FchSpi module duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 25/33] AMD/VanGoghBoard: Check in PlatformInitPei module duke.zhai via groups.io
2024-01-23 6:35 ` Chang, Abner via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 26/33] AMD/VanGoghBoard: Check in Smbios platform dxe drivers duke.zhai via groups.io
2024-01-18 6:50 ` duke.zhai via groups.io [this message]
2024-01-18 6:50 ` [edk2-devel] [PATCH 28/33] AMD/VanGoghBoard: Check in SmmCpuFeaturesLibCommon module duke.zhai via groups.io
2024-01-23 5:14 ` Chang, Abner via groups.io
2024-01-23 10:20 ` Xing, Eric via groups.io
2024-01-23 10:44 ` Chang, Abner via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 29/33] AMD/VanGoghBoard: Check in SmramSaveState module duke.zhai via groups.io
2024-01-20 14:37 ` Abdul Lateef Attar via groups.io
2024-01-23 5:15 ` Chang, Abner via groups.io
2024-01-23 10:27 ` Xing, Eric via groups.io
2024-01-23 10:44 ` Chang, Abner via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 30/33] AMD/VanGoghBoard: Check in EDK2 override files duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 31/33] AMD/VanGoghBoard: Check in AMD SmmControlPei module duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 32/33] AMD/VanGoghBoard: Check in Chachani board project files and build script duke.zhai via groups.io
2024-01-18 6:50 ` [edk2-devel] [PATCH 33/33] AMD/VanGoghBoard: Improvement coding style duke.zhai 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=20240118065046.961-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