public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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]
-=-=-=-=-=-=-=-=-=-=-=-



  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