summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Fsp22SecCoreS.inf52
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf66
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf52
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf54
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Fsp22ApiEntryS.nasm99
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm73
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm247
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm67
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm539
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm35
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc10
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/ReadEsp.nasm22
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc181
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm72
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.c218
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.h93
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c91
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.c301
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.h138
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.rawbin0 -> 68 bytes
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py47
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm1697
-rw-r--r--src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm11
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py104
24 files changed, 2669 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Fsp22SecCoreS.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Fsp22SecCoreS.inf
new file mode 100644
index 00000000..c1630481
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Fsp22SecCoreS.inf
@@ -0,0 +1,52 @@
+## @file
+# Sec Core for FSP to support MultiPhase (SeparatePhase) SiInitialization.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Fsp22SecCoreS
+ FILE_GUID = DF0FCD70-264A-40BF-BBD4-06C76DB19CB1
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ SecFspApiChk.c
+ SecFsp.h
+
+[Sources.IA32]
+ Ia32/Stack.nasm
+ Ia32/Fsp22ApiEntryS.nasm
+ Ia32/FspApiEntryCommon.nasm
+ Ia32/FspHelper.nasm
+
+[Binaries.Ia32]
+ RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ PciCf8Lib
+ SerialPortLib
+ FspSwitchStackLib
+ FspCommonLib
+ FspSecPlatformLib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid ## PRODUCES
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
new file mode 100644
index 00000000..9c4b058e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
@@ -0,0 +1,66 @@
+## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FspSecCoreM
+ FILE_GUID = C2F9AE46-3437-4FEF-9CB1-9A568B282FEE
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ SecMain.c
+ SecMain.h
+ SecFsp.c
+ SecFsp.h
+ SecFspApiChk.c
+
+[Sources.IA32]
+ Ia32/Stack.nasm
+ Ia32/FspApiEntryM.nasm
+ Ia32/FspApiEntryCommon.nasm
+ Ia32/FspHelper.nasm
+ Ia32/ReadEsp.nasm
+
+[Binaries.Ia32]
+ RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ PciCf8Lib
+ SerialPortLib
+ FspSwitchStackLib
+ FspCommonLib
+ FspSecPlatformLib
+ UefiCpuLib
+
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid ## PRODUCES
+ gFspInApiModePpiGuid ## PRODUCES
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf
new file mode 100644
index 00000000..e57a9c69
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf
@@ -0,0 +1,52 @@
+## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FspSecCoreS
+ FILE_GUID = 53AB1ACD-EDB1-4E3A-A2C7-978D721D179D
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+ SecFspApiChk.c
+ SecFsp.h
+
+[Sources.IA32]
+ Ia32/Stack.nasm
+ Ia32/FspApiEntryS.nasm
+ Ia32/FspApiEntryCommon.nasm
+ Ia32/FspHelper.nasm
+
+[Binaries.Ia32]
+ RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ PciCf8Lib
+ SerialPortLib
+ FspSwitchStackLib
+ FspCommonLib
+ FspSecPlatformLib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid ## PRODUCES
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf
new file mode 100644
index 00000000..ab3e16f9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf
@@ -0,0 +1,54 @@
+## @file
+# Sec Core for FSP
+#
+# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FspSecCoreT
+ FILE_GUID = 5B94E419-C795-414D-A0D4-B80A877BE5FE
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32
+#
+
+[Sources]
+
+
+[Sources.IA32]
+ Ia32/Stack.nasm
+ Ia32/FspApiEntryT.nasm
+ Ia32/FspHelper.nasm
+
+[Binaries.Ia32]
+ RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFsp2Pkg/IntelFsp2Pkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ BaseLib
+ PciCf8Lib
+ SerialPortLib
+ FspSwitchStackLib
+ FspCommonLib
+ FspSecPlatformLib
+
+[Pcd]
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspReservedBufferSize ## CONSUMES
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid ## PRODUCES
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Fsp22ApiEntryS.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Fsp22ApiEntryS.nasm
new file mode 100644
index 00000000..ab634ff2
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Fsp22ApiEntryS.nasm
@@ -0,0 +1,99 @@
+;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+ SECTION .text
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(FspApiCommon)
+extern ASM_PFX(FspMultiPhaseSiInitApiHandler)
+
+;----------------------------------------------------------------------------
+; NotifyPhase API
+;
+; This FSP API will notify the FSP about the different phases in the boot
+; process
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(NotifyPhaseApi)
+ASM_PFX(NotifyPhaseApi):
+ mov eax, 2 ; FSP_API_INDEX.NotifyPhaseApiIndex
+ jmp ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspSiliconInit API
+;
+; This FSP API initializes the CPU and the chipset including the IO
+; controllers in the chipset to enable normal operation of these devices.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspSiliconInitApi)
+ASM_PFX(FspSiliconInitApi):
+ mov eax, 5 ; FSP_API_INDEX.FspSiliconInitApiIndex
+ jmp ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspMultiPhaseSiInitApi API
+;
+; This FSP API provides multi-phase silicon initialization, which brings greater
+; modularity beyond the existing FspSiliconInit() API.
+; Increased modularity is achieved by adding an extra API to FSP-S.
+; This allows the bootloader to add board specific initialization steps throughout
+; the SiliconInit flow as needed.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspMultiPhaseSiInitApi)
+ASM_PFX(FspMultiPhaseSiInitApi):
+ mov eax, 6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex
+ jmp ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspApiCommonContinue API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommonContinue)
+ASM_PFX(FspApiCommonContinue):
+ ;
+ ; Handle FspMultiPhaseSiInitApiIndex API
+ ;
+ cmp eax, 6
+ jnz NotMultiPhaseSiInitApi
+
+ pushad
+ push DWORD [esp + (4 * 8 + 4)] ; push ApiParam
+ push eax ; push ApiIdx
+ call ASM_PFX(FspMultiPhaseSiInitApiHandler)
+ add esp, 8
+ mov dword [esp + (4 * 7)], eax
+ popad
+ ret
+
+NotMultiPhaseSiInitApi:
+ jmp $
+ ret
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; Empty function for WHOLEARCHIVE build option
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+ jmp $
+ ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ jmp $
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
new file mode 100644
index 00000000..050bf9ed
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
@@ -0,0 +1,73 @@
+;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+ SECTION .text
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(Loader2PeiSwitchStack)
+extern ASM_PFX(FspApiCallingCheck)
+
+;
+; Following functions will be provided in ASM
+;
+extern ASM_PFX(FspApiCommonContinue)
+extern ASM_PFX(AsmGetFspInfoHeader)
+
+;----------------------------------------------------------------------------
+; FspApiCommon API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommon)
+ASM_PFX(FspApiCommon):
+ ;
+ ; EAX holds the API index
+ ;
+
+ ;
+ ; Stack must be ready
+ ;
+ push eax
+ add esp, 4
+ cmp eax, dword [esp - 4]
+ jz FspApiCommon1
+ mov eax, 080000003h
+ jmp exit
+
+FspApiCommon1:
+ ;
+ ; Verify the calling condition
+ ;
+ pushad
+ push DWORD [esp + (4 * 8 + 4)] ; push ApiParam
+ push eax ; push ApiIdx
+ call ASM_PFX(FspApiCallingCheck)
+ add esp, 8
+ cmp eax, 0
+ jz FspApiCommon2
+ mov dword [esp + (4 * 7)], eax
+ popad
+exit:
+ ret
+
+FspApiCommon2:
+ popad
+ cmp eax, 3 ; FspMemoryInit API
+ jz FspApiCommon3
+
+ cmp eax, 6 ; FspMultiPhaseSiInitApiIndex API
+ jz FspApiCommon3
+
+ call ASM_PFX(AsmGetFspInfoHeader)
+ jmp ASM_PFX(Loader2PeiSwitchStack)
+
+FspApiCommon3:
+ jmp ASM_PFX(FspApiCommonContinue)
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm
new file mode 100644
index 00000000..cc420059
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryM.nasm
@@ -0,0 +1,247 @@
+;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+ SECTION .text
+
+;
+; Following are fixed PCDs
+;
+extern ASM_PFX(PcdGet32(PcdTemporaryRamBase))
+extern ASM_PFX(PcdGet32(PcdTemporaryRamSize))
+extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))
+extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
+
+struc FSPM_UPD_COMMON
+ ; FSP_UPD_HEADER {
+ .FspUpdHeader: resd 8
+ ; }
+ ; FSPM_ARCH_UPD {
+ .Revision: resb 1
+ .Reserved: resb 3
+ .NvsBufferPtr: resd 1
+ .StackBase: resd 1
+ .StackSize: resd 1
+ .BootLoaderTolumSize: resd 1
+ .BootMode: resd 1
+ .Reserved1: resb 8
+ ; }
+ .size:
+endstruc
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(SecStartup)
+extern ASM_PFX(FspApiCommon)
+
+;
+; Following functions will be provided in PlatformSecLib
+;
+extern ASM_PFX(AsmGetFspBaseAddress)
+extern ASM_PFX(AsmGetFspInfoHeader)
+
+API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]
+FSP_HEADER_IMGBASE_OFFSET EQU 1Ch
+FSP_HEADER_CFGREG_OFFSET EQU 24h
+
+;----------------------------------------------------------------------------
+; FspMemoryInit API
+;
+; This FSP API is called after TempRamInit and initializes the memory.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspMemoryInitApi)
+ASM_PFX(FspMemoryInitApi):
+ mov eax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex
+ jmp ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; TempRamExitApi API
+;
+; This API tears down temporary RAM
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamExitApi)
+ASM_PFX(TempRamExitApi):
+ mov eax, 4 ; FSP_API_INDEX.TempRamExitApiIndex
+ jmp ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspApiCommonContinue API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommonContinue)
+ASM_PFX(FspApiCommonContinue):
+ ;
+ ; EAX holds the API index
+ ;
+
+ ;
+ ; FspMemoryInit API setup the initial stack frame
+ ;
+
+ ;
+ ; Place holder to store the FspInfoHeader pointer
+ ;
+ push eax
+
+ ;
+ ; Update the FspInfoHeader pointer
+ ;
+ push eax
+ call ASM_PFX(AsmGetFspInfoHeader)
+ mov [esp + 4], eax
+ pop eax
+
+ ;
+ ; Create a Task Frame in the stack for the Boot Loader
+ ;
+ pushfd ; 2 pushf for 4 byte alignment
+ cli
+ pushad
+
+ ; Reserve 8 bytes for IDT save/restore
+ sub esp, 8
+ sidt [esp]
+
+
+ ; Get Stackbase and StackSize from FSPM_UPD Param
+ mov edx, [esp + API_PARAM1_OFFSET]
+ cmp edx, 0
+ jnz FspStackSetup
+
+ ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null
+ push eax
+ call ASM_PFX(AsmGetFspInfoHeader)
+ mov edx, [eax + FSP_HEADER_IMGBASE_OFFSET]
+ add edx, [eax + FSP_HEADER_CFGREG_OFFSET]
+ pop eax
+
+FspStackSetup:
+ ;
+ ; StackBase = temp memory base, StackSize = temp memory size
+ ;
+ mov edi, [edx + FSPM_UPD_COMMON.StackBase]
+ mov ecx, [edx + FSPM_UPD_COMMON.StackSize]
+
+ ;
+ ; Keep using bootloader stack if heap size % is 0
+ ;
+ mov bl, BYTE [ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))]
+ cmp bl, 0
+ jz SkipStackSwitch
+
+ ;
+ ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0
+ ;
+ add edi, ecx
+ ;
+ ; Switch to new FSP stack
+ ;
+ xchg edi, esp ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size
+
+SkipStackSwitch:
+ ;
+ ; If heap size % is 0:
+ ; EDI is FSPM_UPD_COMMON.StackBase and will hold ESP later (boot loader stack pointer)
+ ; ECX is FSPM_UPD_COMMON.StackSize
+ ; ESP is boot loader stack pointer (no stack switch)
+ ; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON.StackBase later)
+ ;
+ ; If heap size % is not 0
+ ; EDI is boot loader stack pointer
+ ; ECX is FSPM_UPD_COMMON.StackSize
+ ; ESP is new stack (FSPM_UPD_COMMON.StackBase + FSPM_UPD_COMMON.StackSize)
+ ; BL is NOT 0 to indicate stack has switched
+ ;
+ cmp bl, 0
+ jnz StackHasBeenSwitched
+
+ mov ebx, edi ; Put FSPM_UPD_COMMON.StackBase to ebx as temp memory base
+ mov edi, esp ; Put boot loader stack pointer to edi
+ jmp StackSetupDone
+
+StackHasBeenSwitched:
+ mov ebx, esp ; Put Stack base + Stack size in ebx
+ sub ebx, ecx ; Stack base + Stack size - Stack size as temp memory base
+
+StackSetupDone:
+
+ ;
+ ; Pass the API Idx to SecStartup
+ ;
+ push eax
+
+ ;
+ ; Pass the BootLoader stack to SecStartup
+ ;
+ push edi
+
+ ;
+ ; Pass entry point of the PEI core
+ ;
+ call ASM_PFX(AsmGetFspBaseAddress)
+ mov edi, eax
+ call ASM_PFX(AsmGetPeiCoreOffset)
+ add edi, eax
+ push edi
+
+ ;
+ ; Pass BFV into the PEI Core
+ ; It uses relative address to calculate the actual boot FV base
+ ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and
+ ; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,
+ ; they are different. The code below can handle both cases.
+ ;
+ call ASM_PFX(AsmGetFspBaseAddress)
+ push eax
+
+ ;
+ ; Pass stack base and size into the PEI Core
+ ;
+ push ebx
+ push ecx
+
+ ;
+ ; Pass Control into the PEI Core
+ ;
+ call ASM_PFX(SecStartup)
+ add esp, 4
+exit:
+ ret
+
+global ASM_PFX(FspPeiCoreEntryOff)
+ASM_PFX(FspPeiCoreEntryOff):
+ ;
+ ; This value will be pached by the build script
+ ;
+ DD 0x12345678
+
+global ASM_PFX(AsmGetPeiCoreOffset)
+ASM_PFX(AsmGetPeiCoreOffset):
+ mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)]
+ ret
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; Empty function for WHOLEARCHIVE build option
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+ jmp $
+ ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ jmp $
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm
new file mode 100644
index 00000000..a7424c5f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryS.nasm
@@ -0,0 +1,67 @@
+;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+ SECTION .text
+
+;
+; Following functions will be provided in C
+;
+extern ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; NotifyPhase API
+;
+; This FSP API will notify the FSP about the different phases in the boot
+; process
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(NotifyPhaseApi)
+ASM_PFX(NotifyPhaseApi):
+ mov eax, 2 ; FSP_API_INDEX.NotifyPhaseApiIndex
+ jmp ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspSiliconInit API
+;
+; This FSP API initializes the CPU and the chipset including the IO
+; controllers in the chipset to enable normal operation of these devices.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspSiliconInitApi)
+ASM_PFX(FspSiliconInitApi):
+ mov eax, 5 ; FSP_API_INDEX.FspSiliconInitApiIndex
+ jmp ASM_PFX(FspApiCommon)
+
+;----------------------------------------------------------------------------
+; FspApiCommonContinue API
+;
+; This is the FSP API common entry point to resume the FSP execution
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(FspApiCommonContinue)
+ASM_PFX(FspApiCommonContinue):
+ jmp $
+ ret
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; Empty function for WHOLEARCHIVE build option
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+ jmp $
+ ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ jmp $
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm
new file mode 100644
index 00000000..c831a147
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryT.nasm
@@ -0,0 +1,539 @@
+;; @file
+; Provide FSP API entry points.
+;
+; Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+ SECTION .text
+
+%include "SaveRestoreSseNasm.inc"
+%include "MicrocodeLoadNasm.inc"
+
+;
+; Following are fixed PCDs
+;
+extern ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
+extern ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
+extern ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))
+
+;
+; Following functions will be provided in PlatformSecLib
+;
+extern ASM_PFX(AsmGetFspBaseAddress)
+extern ASM_PFX(AsmGetFspInfoHeader)
+;extern ASM_PFX(LoadMicrocode) ; @todo: needs a weak implementation
+extern ASM_PFX(SecPlatformInit) ; @todo: needs a weak implementation
+extern ASM_PFX(SecCarInit)
+
+;
+; Define the data length that we saved on the stack top
+;
+DATA_LEN_OF_PER0 EQU 18h
+DATA_LEN_OF_MCUD EQU 18h
+DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
+
+;
+; @todo: These structures are moved from MicrocodeLoadNasm.inc to avoid
+; build error. This needs to be fixed later on.
+;
+struc MicrocodeHdr
+ .MicrocodeHdrVersion: resd 1
+ .MicrocodeHdrRevision: resd 1
+ .MicrocodeHdrDate: resd 1
+ .MicrocodeHdrProcessor: resd 1
+ .MicrocodeHdrChecksum: resd 1
+ .MicrocodeHdrLoader: resd 1
+ .MicrocodeHdrFlags: resd 1
+ .MicrocodeHdrDataSize: resd 1
+ .MicrocodeHdrTotalSize: resd 1
+ .MicrocodeHdrRsvd: resd 3
+ .size:
+endstruc
+
+struc ExtSigHdr
+ .ExtSigHdrCount: resd 1
+ .ExtSigHdrChecksum: resd 1
+ .ExtSigHdrRsvd: resd 3
+ .size:
+endstruc
+
+struc ExtSig
+ .ExtSigProcessor: resd 1
+ .ExtSigFlags: resd 1
+ .ExtSigChecksum: resd 1
+ .size:
+endstruc
+
+struc LoadMicrocodeParams
+ ; FSP_UPD_HEADER {
+ .FspUpdHeader: resd 8
+ ; }
+ ; FSPT_CORE_UPD {
+ .MicrocodeCodeAddr: resd 1
+ .MicrocodeCodeSize: resd 1
+ .CodeRegionBase: resd 1
+ .CodeRegionSize: resd 1
+ ; }
+ .size:
+endstruc
+
+struc LoadMicrocodeParamsFsp22
+ ; FSP_UPD_HEADER {
+ .FspUpdHeaderSignature: resd 2
+ .FspUpdHeaderRevision: resb 1
+ .FspUpdHeaderReserved: resb 23
+ ; }
+ ; FSPT_ARCH_UPD{
+ .FsptArchUpd: resd 8
+ ; }
+ ; FSPT_CORE_UPD {
+ .MicrocodeCodeAddr: resd 1
+ .MicrocodeCodeSize: resd 1
+ .CodeRegionBase: resd 1
+ .CodeRegionSize: resd 1
+ ; }
+ .size:
+endstruc
+
+;
+; Define SSE macros
+;
+;
+;args 1: ReturnAddress 2:MmxRegister
+;
+%macro LOAD_MMX_EXT 2
+ mov esi, %1
+ movd %2, esi ; save ReturnAddress into MMX
+%endmacro
+
+;
+;args 1: RoutineLabel 2:MmxRegister
+;
+%macro CALL_MMX_EXT 2
+ mov esi, %%ReturnAddress
+ movd %2, esi ; save ReturnAddress into MMX
+ jmp %1
+%%ReturnAddress:
+%endmacro
+
+;
+;arg 1:MmxRegister
+;
+%macro RET_ESI_EXT 1
+ movd esi, %1 ; move ReturnAddress from MMX to ESI
+ jmp esi
+%endmacro
+
+;
+;arg 1:RoutineLabel
+;
+%macro CALL_MMX 1
+ CALL_MMX_EXT %1, mm7
+%endmacro
+
+%macro RET_ESI 0
+ RET_ESI_EXT mm7
+%endmacro
+
+;
+; @todo: The strong/weak implementation does not work.
+; This needs to be reviewed later.
+;
+;------------------------------------------------------------------------------
+;
+;;global ASM_PFX(SecPlatformInitDefault)
+;ASM_PFX(SecPlatformInitDefault):
+; ; Inputs:
+; ; mm7 -> Return address
+; ; Outputs:
+; ; eax -> 0 - Successful, Non-zero - Failed.
+; ; Register Usage:
+; ; eax is cleared and ebp is used for return address.
+; ; All others reserved.
+;
+; ; Save return address to EBP
+; movd ebp, mm7
+;
+; xor eax, eax
+;Exit1:
+; jmp ebp
+
+;------------------------------------------------------------------------------
+global ASM_PFX(LoadMicrocodeDefault)
+ASM_PFX(LoadMicrocodeDefault):
+ ; Inputs:
+ ; esp -> LoadMicrocodeParams pointer
+ ; Register Usage:
+ ; esp Preserved
+ ; All others destroyed
+ ; Assumptions:
+ ; No memory available, stack is hard-coded and used for return address
+ ; Executed by SBSP and NBSP
+ ; Beginning of microcode update region starts on paragraph boundary
+
+ ;
+ ;
+ ; Save return address to EBP
+ movd ebp, mm7
+
+ cmp esp, 0
+ jz ParamError
+ mov eax, dword [esp + 4] ; Parameter pointer
+ cmp eax, 0
+ jz ParamError
+ mov esp, eax
+
+ ; skip loading Microcode if the MicrocodeCodeSize is zero
+ ; and report error if size is less than 2k
+ ; first check UPD header revision
+ cmp byte [esp + LoadMicrocodeParamsFsp22.FspUpdHeaderRevision], 2
+ jae Fsp22UpdHeader
+
+ ; UPD structure is compliant with FSP spec 2.0/2.1
+ mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]
+ cmp eax, 0
+ jz Exit2
+ cmp eax, 0800h
+ jl ParamError
+
+ mov esi, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
+ cmp esi, 0
+ jnz CheckMainHeader
+ jmp ParamError
+
+Fsp22UpdHeader:
+ ; UPD structure is compliant with FSP spec 2.2
+ mov eax, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeSize]
+ cmp eax, 0
+ jz Exit2
+ cmp eax, 0800h
+ jl ParamError
+
+ mov esi, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeAddr]
+ cmp esi, 0
+ jnz CheckMainHeader
+
+ParamError:
+ mov eax, 080000002h
+ jmp Exit2
+
+CheckMainHeader:
+ ; Get processor signature and platform ID from the installed processor
+ ; and save into registers for later use
+ ; ebx = processor signature
+ ; edx = platform ID
+ mov eax, 1
+ cpuid
+ mov ebx, eax
+ mov ecx, MSR_IA32_PLATFORM_ID
+ rdmsr
+ mov ecx, edx
+ shr ecx, 50-32 ; shift (50d-32d=18d=0x12) bits
+ and ecx, 7h ; platform id at bit[52..50]
+ mov edx, 1
+ shl edx, cl
+
+ ; Current register usage
+ ; esp -> stack with parameters
+ ; esi -> microcode update to check
+ ; ebx = processor signature
+ ; edx = platform ID
+
+ ; Check for valid microcode header
+ ; Minimal test checking for header version and loader version as 1
+ mov eax, dword 1
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax
+ jne AdvanceFixedSize
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax
+ jne AdvanceFixedSize
+
+ ; Check if signature and plaform ID match
+ cmp ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor]
+ jne LoadMicrocodeDefault1
+ test edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ]
+ jnz LoadCheck ; Jif signature and platform ID match
+
+LoadMicrocodeDefault1:
+ ; Check if extended header exists
+ ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
+ xor eax, eax
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
+ je NextMicrocode
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax
+ je NextMicrocode
+
+ ; Then verify total size - sizeof header > data size
+ mov ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
+ sub ecx, MicrocodeHdr.size
+ cmp ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
+ jng NextMicrocode ; Jif extended header does not exist
+
+ ; Set edi -> extended header
+ mov edi, esi
+ add edi, MicrocodeHdr.size
+ add edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
+
+ ; Get count of extended structures
+ mov ecx, dword [edi + ExtSigHdr.ExtSigHdrCount]
+
+ ; Move pointer to first signature structure
+ add edi, ExtSigHdr.size
+
+CheckExtSig:
+ ; Check if extended signature and platform ID match
+ cmp dword [edi + ExtSig.ExtSigProcessor], ebx
+ jne LoadMicrocodeDefault2
+ test dword [edi + ExtSig.ExtSigFlags], edx
+ jnz LoadCheck ; Jif signature and platform ID match
+LoadMicrocodeDefault2:
+ ; Check if any more extended signatures exist
+ add edi, ExtSig.size
+ loop CheckExtSig
+
+NextMicrocode:
+ ; Advance just after end of this microcode
+ xor eax, eax
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
+ je LoadMicrocodeDefault3
+ add esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
+ jmp CheckAddress
+LoadMicrocodeDefault3:
+ add esi, dword 2048
+ jmp CheckAddress
+
+AdvanceFixedSize:
+ ; Advance by 4X dwords
+ add esi, dword 1024
+
+CheckAddress:
+ ; Check UPD header revision
+ cmp byte [esp + LoadMicrocodeParamsFsp22.FspUpdHeaderRevision], 2
+ jae Fsp22UpdHeader1
+
+ ; UPD structure is compliant with FSP spec 2.0/2.1
+ ; Is automatic size detection ?
+ mov eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeSize]
+ cmp eax, 0ffffffffh
+ jz LoadMicrocodeDefault4
+
+ ; Address >= microcode region address + microcode region size?
+ add eax, dword [esp + LoadMicrocodeParams.MicrocodeCodeAddr]
+ cmp esi, eax
+ jae Done ;Jif address is outside of microcode region
+ jmp CheckMainHeader
+
+Fsp22UpdHeader1:
+ ; UPD structure is compliant with FSP spec 2.2
+ ; Is automatic size detection ?
+ mov eax, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeSize]
+ cmp eax, 0ffffffffh
+ jz LoadMicrocodeDefault4
+
+ ; Address >= microcode region address + microcode region size?
+ add eax, dword [esp + LoadMicrocodeParamsFsp22.MicrocodeCodeAddr]
+ cmp esi, eax
+ jae Done ;Jif address is outside of microcode region
+ jmp CheckMainHeader
+
+LoadMicrocodeDefault4:
+ ; Is valid Microcode start point ?
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh
+ jz Done
+
+LoadCheck:
+ ; Get the revision of the current microcode update loaded
+ mov ecx, MSR_IA32_BIOS_SIGN_ID
+ xor eax, eax ; Clear EAX
+ xor edx, edx ; Clear EDX
+ wrmsr ; Load 0 to MSR at 8Bh
+
+ mov eax, 1
+ cpuid
+ mov ecx, MSR_IA32_BIOS_SIGN_ID
+ rdmsr ; Get current microcode signature
+
+ ; Verify this microcode update is not already loaded
+ cmp dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx
+ je Continue
+
+LoadMicrocode:
+ ; EAX contains the linear address of the start of the Update Data
+ ; EDX contains zero
+ ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)
+ ; Start microcode load with wrmsr
+ mov eax, esi
+ add eax, MicrocodeHdr.size
+ xor edx, edx
+ mov ecx, MSR_IA32_BIOS_UPDT_TRIG
+ wrmsr
+ mov eax, 1
+ cpuid
+
+Continue:
+ jmp NextMicrocode
+
+Done:
+ mov eax, 1
+ cpuid
+ mov ecx, MSR_IA32_BIOS_SIGN_ID
+ rdmsr ; Get current microcode signature
+ xor eax, eax
+ cmp edx, 0
+ jnz Exit2
+ mov eax, 08000000Eh
+
+Exit2:
+ jmp ebp
+
+
+global ASM_PFX(EstablishStackFsp)
+ASM_PFX(EstablishStackFsp):
+ ;
+ ; Save parameter pointer in edx
+ ;
+ mov edx, dword [esp + 4]
+
+ ;
+ ; Enable FSP STACK
+ ;
+ mov esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
+ add esp, DWORD [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
+
+ push DATA_LEN_OF_MCUD ; Size of the data region
+ push 4455434Dh ; Signature of the data region 'MCUD'
+
+ ; check UPD structure revision (edx + 8)
+ cmp byte [edx + LoadMicrocodeParamsFsp22.FspUpdHeaderRevision], 2
+ jae Fsp22UpdHeader2
+
+ ; UPD structure is compliant with FSP spec 2.0/2.1
+ push dword [edx + LoadMicrocodeParams.CodeRegionSize] ; Code size sizeof(FSPT_UPD_COMMON) + 12
+ push dword [edx + LoadMicrocodeParams.CodeRegionBase] ; Code base sizeof(FSPT_UPD_COMMON) + 8
+ push dword [edx + LoadMicrocodeParams.MicrocodeCodeSize] ; Microcode size sizeof(FSPT_UPD_COMMON) + 4
+ push dword [edx + LoadMicrocodeParams.MicrocodeCodeAddr] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0
+ jmp ContinueAfterUpdPush
+
+Fsp22UpdHeader2:
+ ; UPD structure is compliant with FSP spec 2.2
+ push dword [edx + LoadMicrocodeParamsFsp22.CodeRegionSize] ; Code size sizeof(FSPT_UPD_COMMON) + 12
+ push dword [edx + LoadMicrocodeParamsFsp22.CodeRegionBase] ; Code base sizeof(FSPT_UPD_COMMON) + 8
+ push dword [edx + LoadMicrocodeParamsFsp22.MicrocodeCodeSize] ; Microcode size sizeof(FSPT_UPD_COMMON) + 4
+ push dword [edx + LoadMicrocodeParamsFsp22.MicrocodeCodeAddr] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0
+
+ContinueAfterUpdPush:
+ ;
+ ; Save API entry/exit timestamp into stack
+ ;
+ push DATA_LEN_OF_PER0 ; Size of the data region
+ push 30524550h ; Signature of the data region 'PER0'
+ rdtsc
+ push edx
+ push eax
+ LOAD_EDX
+ push edx
+ LOAD_EAX
+ push eax
+
+ ;
+ ; Terminator for the data on stack
+ ;
+ push 0
+
+ ;
+ ; Set ECX/EDX to the BootLoader temporary memory range
+ ;
+ mov ecx, [ASM_PFX(PcdGet32 (PcdTemporaryRamBase))]
+ mov edx, ecx
+ add edx, [ASM_PFX(PcdGet32 (PcdTemporaryRamSize))]
+ sub edx, [ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))]
+
+ cmp ecx, edx ;If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error.
+ jb EstablishStackFspSuccess
+ mov eax, 80000003h ;EFI_UNSUPPORTED
+ jmp EstablishStackFspExit
+EstablishStackFspSuccess:
+ xor eax, eax
+
+EstablishStackFspExit:
+ RET_ESI
+
+;----------------------------------------------------------------------------
+; TempRamInit API
+;
+; This FSP API will load the microcode update, enable code caching for the
+; region specified by the boot loader and also setup a temporary stack to be
+; used till main memory is initialized.
+;
+;----------------------------------------------------------------------------
+global ASM_PFX(TempRamInitApi)
+ASM_PFX(TempRamInitApi):
+ ;
+ ; Ensure SSE is enabled
+ ;
+ ENABLE_SSE
+
+ ;
+ ; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
+ ;
+ SAVE_REGS
+
+ ;
+ ; Save timestamp into XMM6
+ ;
+ rdtsc
+ SAVE_EAX
+ SAVE_EDX
+
+ ;
+ ; Check Parameter
+ ;
+ mov eax, dword [esp + 4]
+ cmp eax, 0
+ mov eax, 80000002h
+ jz TempRamInitExit
+
+ ;
+ ; Sec Platform Init
+ ;
+ CALL_MMX ASM_PFX(SecPlatformInit)
+ cmp eax, 0
+ jnz TempRamInitExit
+
+ ; Load microcode
+ LOAD_ESP
+ CALL_MMX ASM_PFX(LoadMicrocodeDefault)
+ SXMMN xmm6, 3, eax ;Save microcode return status in ECX-SLOT 3 in xmm6.
+ ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot.
+
+ ; Call Sec CAR Init
+ LOAD_ESP
+ CALL_MMX ASM_PFX(SecCarInit)
+ cmp eax, 0
+ jnz TempRamInitExit
+
+ LOAD_ESP
+ CALL_MMX ASM_PFX(EstablishStackFsp)
+ cmp eax, 0
+ jnz TempRamInitExit
+
+ LXMMN xmm6, eax, 3 ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6.
+
+TempRamInitExit:
+ mov bl, al ; save al data in bl
+ mov al, 07Fh ; API exit postcode 7f
+ out 080h, al
+ mov al, bl ; restore al data from bl
+
+ ;
+ ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
+ ;
+ LOAD_REGS
+ ret
+
+;----------------------------------------------------------------------------
+; Module Entrypoint API
+;----------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ jmp $
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm
new file mode 100644
index 00000000..461c0bfb
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/FspHelper.nasm
@@ -0,0 +1,35 @@
+;; @file
+; Provide FSP helper function.
+;
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+ SECTION .text
+
+global ASM_PFX(FspInfoHeaderRelativeOff)
+ASM_PFX(FspInfoHeaderRelativeOff):
+ DD 0x12345678 ; This value must be patched by the build script
+
+global ASM_PFX(AsmGetFspBaseAddress)
+ASM_PFX(AsmGetFspBaseAddress):
+ call ASM_PFX(AsmGetFspInfoHeader)
+ add eax, 0x1C
+ mov eax, dword [eax]
+ ret
+
+global ASM_PFX(AsmGetFspInfoHeader)
+ASM_PFX(AsmGetFspInfoHeader):
+ call ASM_PFX(NextInstruction)
+ASM_PFX(NextInstruction):
+ pop eax
+ sub eax, ASM_PFX(NextInstruction)
+ add eax, ASM_PFX(AsmGetFspInfoHeader)
+ sub eax, dword [eax - ASM_PFX(AsmGetFspInfoHeader) + ASM_PFX(FspInfoHeaderRelativeOff)]
+ ret
+
+global ASM_PFX(AsmGetFspInfoHeaderNoStack)
+ASM_PFX(AsmGetFspInfoHeaderNoStack):
+ mov eax, ASM_PFX(AsmGetFspInfoHeader)
+ sub eax, dword [ASM_PFX(FspInfoHeaderRelativeOff)]
+ jmp edi
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc
new file mode 100644
index 00000000..2b53f5d9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/MicrocodeLoadNasm.inc
@@ -0,0 +1,10 @@
+;; @file
+;
+;@copyright
+; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+
+MSR_IA32_PLATFORM_ID equ 000000017h
+MSR_IA32_BIOS_UPDT_TRIG equ 000000079h
+MSR_IA32_BIOS_SIGN_ID equ 00000008bh \ No newline at end of file
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/ReadEsp.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/ReadEsp.nasm
new file mode 100644
index 00000000..e407435a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/ReadEsp.nasm
@@ -0,0 +1,22 @@
+;; @file
+; Provide read ESP function
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; UINT32
+; EFIAPI
+; AsmReadEsp (
+; VOID
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmReadEsp)
+ASM_PFX(AsmReadEsp):
+ mov eax, esp
+ ret
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc
new file mode 100644
index 00000000..1177e070
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/SaveRestoreSseNasm.inc
@@ -0,0 +1,181 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Abstract:
+;
+; Provide macro for register save/restore using SSE registers
+;
+;------------------------------------------------------------------------------
+
+;
+; Define SSE instruction set
+;
+%ifdef USE_SSE41_FLAG
+;
+; Define SSE macros using SSE 4.1 instructions
+; args 1:XMM, 2:IDX, 3:REG
+%macro SXMMN 3
+ pinsrd %1, %3, (%2 & 3)
+ %endmacro
+
+;
+;args 1:XMM, 2:REG, 3:IDX
+;
+%macro LXMMN 3
+ pextrd %2, %1, (%3 & 3)
+ %endmacro
+%else
+;
+; Define SSE macros using SSE 2 instructions
+; args 1:XMM, 2:IDX, 3:REG
+%macro SXMMN 3
+ pinsrw %1, %3, (%2 & 3) * 2
+ ror %3, 16
+ pinsrw %1, %3, (%2 & 3) * 2 + 1
+ rol %3, 16
+ %endmacro
+
+;
+;args 1:XMM, 2:REG, 3:IDX
+;
+%macro LXMMN 3
+ pshufd %1, %1, ((0E4E4E4h >> (%3 * 2)) & 0FFh)
+ movd %2, %1
+ pshufd %1, %1, ((0E4E4E4h >> (%3 * 2 + (%3 & 1) * 4)) & 0FFh)
+ %endmacro
+%endif
+
+;
+; XMM7 to save/restore EBP, EBX, ESI, EDI
+;
+%macro SAVE_REGS 0
+ SXMMN xmm7, 0, ebp
+ SXMMN xmm7, 1, ebx
+ SXMMN xmm7, 2, esi
+ SXMMN xmm7, 3, edi
+ SAVE_ESP
+ %endmacro
+
+%macro LOAD_REGS 0
+ LXMMN xmm7, ebp, 0
+ LXMMN xmm7, ebx, 1
+ LXMMN xmm7, esi, 2
+ LXMMN xmm7, edi, 3
+ LOAD_ESP
+ %endmacro
+
+;
+; XMM6 to save/restore EAX, EDX, ECX, ESP
+;
+%macro LOAD_EAX 0
+ LXMMN xmm6, eax, 1
+ %endmacro
+
+%macro SAVE_EAX 0
+ SXMMN xmm6, 1, eax
+ %endmacro
+
+%macro LOAD_EDX 0
+ LXMMN xmm6, edx, 2
+ %endmacro
+
+%macro SAVE_EDX 0
+ SXMMN xmm6, 2, edx
+ %endmacro
+
+%macro SAVE_ECX 0
+ SXMMN xmm6, 3, ecx
+ %endmacro
+
+%macro LOAD_ECX 0
+ LXMMN xmm6, ecx, 3
+ %endmacro
+
+%macro SAVE_ESP 0
+ SXMMN xmm6, 0, esp
+ %endmacro
+
+%macro LOAD_ESP 0
+ movd esp, xmm6
+ %endmacro
+;
+; XMM5 for calling stack
+; arg 1:Entry
+%macro CALL_XMM 1
+ mov esi, %%ReturnAddress
+ pslldq xmm5, 4
+%ifdef USE_SSE41_FLAG
+ pinsrd xmm5, esi, 0
+%else
+ pinsrw xmm5, esi, 0
+ ror esi, 16
+ pinsrw xmm5, esi, 1
+%endif
+ mov esi, %1
+ jmp esi
+%%ReturnAddress:
+ %endmacro
+
+%macro RET_XMM 0
+ movd esi, xmm5
+ psrldq xmm5, 4
+ jmp esi
+ %endmacro
+
+%macro ENABLE_SSE 0
+ ;
+ ; Initialize floating point units
+ ;
+ jmp NextAddress
+align 4
+ ;
+ ; Float control word initial value:
+ ; all exceptions masked, double-precision, round-to-nearest
+ ;
+FpuControlWord DW 027Fh
+ ;
+ ; Multimedia-extensions control word:
+ ; all exceptions masked, round-to-nearest, flush to zero for masked underflow
+ ;
+MmxControlWord DD 01F80h
+SseError:
+ ;
+ ; Processor has to support SSE
+ ;
+ jmp SseError
+NextAddress:
+ finit
+ fldcw [FpuControlWord]
+
+ ;
+ ; Use CpuId instruction (CPUID.01H:EDX.SSE[bit 25] = 1) to test
+ ; whether the processor supports SSE instruction.
+ ;
+ mov eax, 1
+ cpuid
+ bt edx, 25
+ jnc SseError
+
+%ifdef USE_SSE41_FLAG
+ ;
+ ; SSE 4.1 support
+ ;
+ bt ecx, 19
+ jnc SseError
+%endif
+
+ ;
+ ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+ ;
+ mov eax, cr4
+ or eax, 00000600h
+ mov cr4, eax
+
+ ;
+ ; The processor should support SSE instruction and we can use
+ ; ldmxcsr instruction
+ ;
+ ldmxcsr [MmxControlWord]
+ %endmacro
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm
new file mode 100644
index 00000000..a0fa9a20
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Ia32/Stack.nasm
@@ -0,0 +1,72 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015 - 2019, 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 PermenentMemoryBase
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(SecSwitchStack)
+ASM_PFX(SecSwitchStack):
+ ;
+ ; Save three register: eax, ebx, ecx
+ ;
+ 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/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.c
new file mode 100644
index 00000000..bee6d3c5
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.c
@@ -0,0 +1,218 @@
+/** @file
+
+ Copyright (c) 2014 - 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecFsp.h"
+
+/**
+
+ Calculate the FSP IDT gate descriptor.
+
+ @param[in] IdtEntryTemplate IDT gate descriptor template.
+
+ @return FSP specific IDT gate descriptor.
+
+**/
+UINT64
+FspGetExceptionHandler(
+ IN UINT64 IdtEntryTemplate
+ )
+{
+ UINT32 Entry;
+ UINT64 ExceptionHandler;
+ IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor;
+ FSP_INFO_HEADER *FspInfoHeader;
+
+ FspInfoHeader = (FSP_INFO_HEADER *)AsmGetFspInfoHeader();
+ ExceptionHandler = IdtEntryTemplate;
+ IdtGateDescriptor = (IA32_IDT_GATE_DESCRIPTOR *)&ExceptionHandler;
+ Entry = (IdtGateDescriptor->Bits.OffsetHigh << 16) | IdtGateDescriptor->Bits.OffsetLow;
+ Entry = FspInfoHeader->ImageBase + FspInfoHeader->ImageSize - (~Entry + 1);
+ IdtGateDescriptor->Bits.OffsetHigh = (UINT16)(Entry >> 16);
+ IdtGateDescriptor->Bits.OffsetLow = (UINT16)Entry;
+
+ return ExceptionHandler;
+}
+
+/**
+ This interface fills platform specific data.
+
+ @param[in,out] FspData Pointer to the FSP global data.
+
+**/
+VOID
+EFIAPI
+SecGetPlatformData (
+ IN OUT FSP_GLOBAL_DATA *FspData
+ )
+{
+ FSP_PLAT_DATA *FspPlatformData;
+ UINT32 TopOfCar;
+ UINT32 *StackPtr;
+ UINT32 DwordSize;
+
+ FspPlatformData = &FspData->PlatformData;
+
+ //
+ // The entries of platform information, together with the number of them,
+ // reside in the bottom of stack, left untouched by normal stack operation.
+ //
+
+ FspPlatformData->DataPtr = NULL;
+ FspPlatformData->MicrocodeRegionBase = 0;
+ FspPlatformData->MicrocodeRegionSize = 0;
+ FspPlatformData->CodeRegionBase = 0;
+ FspPlatformData->CodeRegionSize = 0;
+
+ //
+ // Pointer to the size field
+ //
+ TopOfCar = PcdGet32(PcdTemporaryRamBase) + PcdGet32(PcdTemporaryRamSize);
+ StackPtr = (UINT32 *)(TopOfCar - sizeof (UINT32));
+
+ if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
+ while (*StackPtr != 0) {
+ if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
+ //
+ // This following data was pushed onto stack after TempRamInit API
+ //
+ DwordSize = 4;
+ StackPtr = StackPtr - 1 - DwordSize;
+ CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2));
+ StackPtr--;
+ } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
+ //
+ // This is the performance data for InitTempMemory API entry/exit
+ //
+ DwordSize = 4;
+ StackPtr = StackPtr - 1 - DwordSize;
+ CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
+
+ ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY;
+ ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT;
+
+ StackPtr--;
+ } else {
+ StackPtr -= (*StackPtr);
+ }
+ }
+ }
+}
+
+/**
+
+ Initialize the FSP global data region.
+ It needs to be done as soon as possible after the stack is setup.
+
+ @param[in,out] PeiFspData Pointer of the FSP global data.
+ @param[in] BootLoaderStack BootLoader stack.
+ @param[in] ApiIdx The index of the FSP API.
+
+**/
+VOID
+FspGlobalDataInit (
+ IN OUT FSP_GLOBAL_DATA *PeiFspData,
+ IN UINT32 BootLoaderStack,
+ IN UINT8 ApiIdx
+ )
+{
+ VOID *FspmUpdDataPtr;
+ CHAR8 ImageId[9];
+ UINTN Idx;
+
+ //
+ // Set FSP Global Data pointer
+ //
+ SetFspGlobalDataPointer (PeiFspData);
+ ZeroMem ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA));
+
+ PeiFspData->Signature = FSP_GLOBAL_DATA_SIGNATURE;
+ PeiFspData->Version = 0;
+ PeiFspData->CoreStack = BootLoaderStack;
+ PeiFspData->PerfIdx = 2;
+ PeiFspData->PerfSig = FSP_PERFORMANCE_DATA_SIGNATURE;
+
+ SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);
+
+ //
+ // Get FSP Header offset
+ // It may have multiple FVs, so look into the last one for FSP header
+ //
+ PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)AsmGetFspInfoHeader();
+ SecGetPlatformData (PeiFspData);
+
+ //
+ // Set API calling mode
+ //
+ SetFspApiCallingIndex (ApiIdx);
+
+ //
+ // Set UPD pointer
+ //
+ FspmUpdDataPtr = (VOID *) GetFspApiParameter ();
+ if (FspmUpdDataPtr == NULL) {
+ FspmUpdDataPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset);
+ }
+ SetFspUpdDataPointer (FspmUpdDataPtr);
+ SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr);
+ SetFspSiliconInitUpdDataPointer (NULL);
+
+ //
+ // Initialize OnSeparateStack value.
+ //
+ if (PcdGet8 (PcdFspHeapSizePercentage) != 0) {
+ //
+ // FSP is running on its own stack and may need switching stack when calling bootloader functions.
+ //
+ GetFspGlobalDataPointer ()->OnSeparateStack = 1;
+ }
+
+ //
+ // Initialize serial port
+ // It might have been done in ProcessLibraryConstructorList(), however,
+ // the FSP global data is not initialized at that time. So do it again
+ // for safe.
+ //
+ SerialPortInitialize ();
+
+ //
+ // Ensure the global data pointer is valid
+ //
+ ASSERT (GetFspGlobalDataPointer () == PeiFspData);
+
+ for (Idx = 0; Idx < 8; Idx++) {
+ ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
+ }
+ ImageId[Idx] = 0;
+
+ DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
+ (PeiFspData->FspInfoHeader->SpecVersion >> 4) & 0xF, \
+ PeiFspData->FspInfoHeader->SpecVersion & 0xF, \
+ PeiFspData->FspInfoHeader->HeaderRevision, \
+ ImageId, \
+ (PeiFspData->FspInfoHeader->ImageRevision >> 24) & 0xFF, \
+ (PeiFspData->FspInfoHeader->ImageRevision >> 16) & 0xFF, \
+ (PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF, \
+ PeiFspData->FspInfoHeader->ImageRevision & 0xFF));
+}
+
+/**
+
+ Adjust the FSP data pointers after the stack is migrated to memory.
+
+ @param[in] OffsetGap The offset gap between the old stack and the new stack.
+
+**/
+VOID
+FspDataPointerFixUp (
+ IN UINT32 OffsetGap
+ )
+{
+ FSP_GLOBAL_DATA *NewFspData;
+
+ NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap);
+ SetFspGlobalDataPointer (NewFspData);
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.h
new file mode 100644
index 00000000..68ac9d2f
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFsp.h
@@ -0,0 +1,93 @@
+/** @file
+
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SEC_FSP_H_
+#define _SEC_FSP_H_
+
+#include <PiPei.h>
+#include <FspEas.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/FspCommonLib.h>
+#include <Library/FspSecPlatformLib.h>
+
+#define FSP_MCUD_SIGNATURE SIGNATURE_32 ('M', 'C', 'U', 'D')
+#define FSP_PER0_SIGNATURE SIGNATURE_32 ('P', 'E', 'R', '0')
+
+/**
+
+ Calculate the FSP IDT gate descriptor.
+
+ @param[in] IdtEntryTemplate IDT gate descriptor template.
+
+ @return FSP specific IDT gate descriptor.
+
+**/
+UINT64
+FspGetExceptionHandler(
+ IN UINT64 IdtEntryTemplate
+ );
+
+/**
+
+ Initialize the FSP global data region.
+ It needs to be done as soon as possible after the stack is setup.
+
+ @param[in,out] PeiFspData Pointer of the FSP global data.
+ @param[in] BootLoaderStack BootLoader stack.
+ @param[in] ApiIdx The index of the FSP API.
+
+**/
+VOID
+FspGlobalDataInit (
+ IN OUT FSP_GLOBAL_DATA *PeiFspData,
+ IN UINT32 BootLoaderStack,
+ IN UINT8 ApiIdx
+ );
+
+
+/**
+
+ Adjust the FSP data pointers after the stack is migrated to memory.
+
+ @param[in] OffsetGap The offset gap between the old stack and the new stack.
+
+**/
+VOID
+FspDataPointerFixUp (
+ IN UINT32 OffsetGap
+ );
+
+
+/**
+ This interface returns the base address of FSP binary.
+
+ @return FSP binary base address.
+
+**/
+UINT32
+EFIAPI
+AsmGetFspBaseAddress (
+ VOID
+ );
+
+/**
+ This interface gets FspInfoHeader pointer
+
+ @return FSP binary base address.
+
+**/
+UINT32
+EFIAPI
+AsmGetFspInfoHeader (
+ VOID
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
new file mode 100644
index 00000000..06044f9e
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
@@ -0,0 +1,91 @@
+/** @file
+
+ Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecFsp.h"
+
+
+/**
+ This function check the FSP API calling condition.
+
+ @param[in] ApiIdx Internal index of the FSP API.
+ @param[in] ApiParam Parameter of the FSP API.
+
+**/
+EFI_STATUS
+EFIAPI
+FspApiCallingCheck (
+ IN UINT8 ApiIdx,
+ IN VOID *ApiParam
+ )
+{
+ EFI_STATUS Status;
+ FSP_GLOBAL_DATA *FspData;
+
+ Status = EFI_SUCCESS;
+ FspData = GetFspGlobalDataPointer ();
+
+ if (ApiIdx == NotifyPhaseApiIndex) {
+ //
+ // NotifyPhase check
+ //
+ if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+ } else if (ApiIdx == FspMemoryInitApiIndex) {
+ //
+ // FspMemoryInit check
+ //
+ if ((UINT32)FspData != 0xFFFFFFFF) {
+ Status = EFI_UNSUPPORTED;
+ } else if (EFI_ERROR (FspUpdSignatureCheck (ApiIdx, ApiParam))) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ } else if (ApiIdx == TempRamExitApiIndex) {
+ //
+ // TempRamExit check
+ //
+ if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
+ Status = EFI_UNSUPPORTED;
+ }
+ }
+ } else if ((ApiIdx == FspSiliconInitApiIndex) || (ApiIdx == FspMultiPhaseSiInitApiIndex)) {
+ //
+ // FspSiliconInit check
+ //
+ if ((FspData == NULL) || ((UINT32)FspData == 0xFFFFFFFF)) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ if (FspData->Signature != FSP_GLOBAL_DATA_SIGNATURE) {
+ Status = EFI_UNSUPPORTED;
+ } else if (EFI_ERROR (FspUpdSignatureCheck (FspSiliconInitApiIndex, ApiParam))) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+ } else {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ if (!EFI_ERROR (Status)) {
+ if ((ApiIdx != FspMemoryInitApiIndex)) {
+ //
+ // For FspMemoryInit, the global data is not valid yet
+ // The API index will be updated by SecCore after the global data
+ // is initialized
+ //
+ SetFspApiCallingIndex (ApiIdx);
+ }
+ }
+
+ return Status;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.c b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.c
new file mode 100644
index 00000000..1d102fca
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.c
@@ -0,0 +1,301 @@
+/** @file
+
+ Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecMain.h"
+#include "SecFsp.h"
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
+ SecTemporaryRamSupport
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformationPpi[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gFspInApiModePpiGuid,
+ NULL
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamSupportPpiGuid,
+ &gSecTemporaryRamSupportPpi
+ }
+};
+
+//
+// These are IDT entries pointing to 08:FFFFFFE4h.
+//
+UINT64 mIdtEntryTemplate = 0xffff8e000008ffe4ULL;
+
+/**
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+
+ @param[in] SizeOfRam Size of the temporary memory available for use.
+ @param[in] TempRamBase Base address of temporary ram
+ @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
+ @param[in] PeiCore PeiCore entry point.
+ @param[in] BootLoaderStack BootLoader stack.
+ @param[in] ApiIdx the index of API.
+
+ @return This function never returns.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume,
+ IN PEI_CORE_ENTRY PeiCore,
+ IN UINT32 BootLoaderStack,
+ IN UINT32 ApiIdx
+ )
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ IA32_DESCRIPTOR IdtDescriptor;
+ SEC_IDT_TABLE IdtTableInStack;
+ UINT32 Index;
+ FSP_GLOBAL_DATA PeiFspData;
+ UINT64 ExceptionHandler;
+ UINTN IdtSize;
+
+ //
+ // Process all libraries constructor function linked to SecCore.
+ //
+ ProcessLibraryConstructorList ();
+
+ //
+ // Initialize floating point operating environment
+ // to be compliant with UEFI spec.
+ //
+ InitializeFloatingPointUnits ();
+
+ //
+ // Scenario 1 memory map when running on bootloader stack
+ //
+ // |-------------------|---->
+ // |Idt Table |
+ // |-------------------|
+ // |PeiService Pointer |
+ // |-------------------|
+ // | |
+ // | |
+ // | Heap |
+ // | |
+ // | |
+ // |-------------------|----> TempRamBase
+ //
+ //
+ // |-------------------|
+ // |Bootloader stack |----> somewhere in memory, FSP will share this stack.
+ // |-------------------|
+
+ //
+ // Scenario 2 memory map when running FSP on a separate stack
+ //
+ // |-------------------|---->
+ // |Idt Table |
+ // |-------------------|
+ // |PeiService Pointer | PeiStackSize
+ // |-------------------|
+ // | |
+ // | Stack |
+ // |-------------------|---->
+ // | |
+ // | |
+ // | Heap | PeiTemporaryRamSize
+ // | |
+ // | |
+ // |-------------------|----> TempRamBase
+ IdtTableInStack.PeiService = 0;
+ AsmReadIdtr (&IdtDescriptor);
+ if (IdtDescriptor.Base == 0) {
+ ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);
+ for (Index = 0; Index < FixedPcdGet8(PcdFspMaxInterruptSupported); Index ++) {
+ CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));
+ }
+ IdtSize = sizeof (IdtTableInStack.IdtTable);
+ } else {
+ IdtSize = IdtDescriptor.Limit + 1;
+ if (IdtSize > sizeof (IdtTableInStack.IdtTable)) {
+ //
+ // ERROR: IDT table size from boot loader is larger than FSP can support, DeadLoop here!
+ //
+ CpuDeadLoop();
+ } else {
+ CopyMem ((VOID *) (UINTN) &IdtTableInStack.IdtTable, (VOID *) IdtDescriptor.Base, IdtSize);
+ }
+ }
+ IdtDescriptor.Base = (UINTN) &IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(IdtSize - 1);
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Initialize the global FSP data region
+ //
+ FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx);
+
+ //
+ // Update the base address and length of Pei temporary memory
+ //
+ SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
+ SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;
+
+ //
+ // Support FSP reserved temporary memory from the whole temporary memory provided by bootloader.
+ // FSP reserved temporary memory will not be given to PeiCore.
+ //
+ SecCoreData.TemporaryRamBase = (UINT8 *)(UINTN) TempRamBase + PcdGet32 (PcdFspPrivateTemporaryRamSize);
+ SecCoreData.TemporaryRamSize = SizeOfRam - PcdGet32 (PcdFspPrivateTemporaryRamSize);
+ if (PcdGet8 (PcdFspHeapSizePercentage) == 0) {
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize;
+ SecCoreData.StackBase = (VOID *)GetFspEntryStack(); // Share the same boot loader stack
+ SecCoreData.StackSize = 0;
+ } else {
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;
+ SecCoreData.StackBase = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;
+ }
+
+ DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));
+ DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));
+ DEBUG ((DEBUG_INFO, "Fsp TemporaryRamBase - 0x%x\n", SecCoreData.TemporaryRamBase));
+ DEBUG ((DEBUG_INFO, "Fsp TemporaryRamSize - 0x%x\n", SecCoreData.TemporaryRamSize));
+ DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamBase - 0x%x\n", SecCoreData.PeiTemporaryRamBase));
+ DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamSize - 0x%x\n", SecCoreData.PeiTemporaryRamSize));
+ DEBUG ((DEBUG_INFO, "Fsp StackBase - 0x%x\n", SecCoreData.StackBase));
+ DEBUG ((DEBUG_INFO, "Fsp StackSize - 0x%x\n", SecCoreData.StackSize));
+
+ //
+ // Call PeiCore Entry
+ //
+ PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi);
+
+ //
+ // Should never be here
+ //
+ CpuDeadLoop ();
+}
+
+/**
+ This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ IA32_DESCRIPTOR IdtDescriptor;
+ VOID* OldHeap;
+ VOID* NewHeap;
+ VOID* OldStack;
+ VOID* NewStack;
+ UINTN HeapSize;
+ UINTN StackSize;
+
+ UINTN CurrentStack;
+ UINTN FspStackBase;
+
+ //
+ // Override OnSeparateStack to 1 because this function will switch stack to permanent memory
+ // which makes FSP running on different stack from bootloader temporary ram stack.
+ //
+ GetFspGlobalDataPointer ()->OnSeparateStack = 1;
+
+ if (PcdGet8 (PcdFspHeapSizePercentage) == 0) {
+
+ CurrentStack = AsmReadEsp();
+ FspStackBase = (UINTN)GetFspEntryStack();
+
+ StackSize = FspStackBase - CurrentStack;
+ HeapSize = CopySize;
+
+ OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID*)((UINTN)PermanentMemoryBase);
+
+ OldStack = (VOID*)CurrentStack;
+ //
+ //The old stack is copied at the end of the stack region because stack grows down.
+ //
+ NewStack = (VOID*)((UINTN)PermanentMemoryBase - StackSize);
+
+ } else {
+ HeapSize = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;
+ StackSize = CopySize - HeapSize;
+
+ OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);
+
+ OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);
+ NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+ }
+ //
+ // Migrate Heap
+ //
+ CopyMem (NewHeap, OldHeap, HeapSize);
+
+ //
+ // Migrate Stack
+ //
+ CopyMem (NewStack, OldStack, StackSize);
+
+
+ //
+ // We need *not* fix the return address because currently,
+ // The PeiCore is executed in flash.
+ //
+
+ //
+ // Rebase IDT table in permanent memory
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Fixed the FSP data pointer
+ //
+ FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);
+
+ //
+ // SecSwitchStack function must be invoked after the memory migration
+ // immediately, also we need fixup the stack change caused by new call into
+ // permanent memory.
+ //
+ SecSwitchStack (
+ (UINT32) (UINTN) OldStack,
+ (UINT32) (UINTN) NewStack
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.h b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.h
new file mode 100644
index 00000000..1487b846
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/SecMain.h
@@ -0,0 +1,138 @@
+/** @file
+
+ Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SEC_CORE_H_
+#define _SEC_CORE_H_
+
+
+#include <PiPei.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/FspSwitchStackLib.h>
+#include <Library/FspCommonLib.h>
+#include <Library/UefiCpuLib.h>
+#include <FspEas.h>
+
+typedef VOID (*PEI_CORE_ENTRY) ( \
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, \
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList \
+);
+
+typedef struct _SEC_IDT_TABLE {
+ //
+ // Reserved 8 bytes preceding IDT to store EFI_PEI_SERVICES**, since IDT base
+ // address should be 8-byte alignment.
+ // Note: For IA32, only the 4 bytes immediately preceding IDT is used to store
+ // EFI_PEI_SERVICES**
+ //
+ UINT64 PeiService;
+ UINT64 IdtTable[FixedPcdGet8 (PcdFspMaxInterruptSupported)];
+} SEC_IDT_TABLE;
+
+/**
+ Switch the stack in the temporary memory to the one in the permanent memory.
+
+ This function must be invoked after the memory migration immediately. The relative
+ position of the stack in the temporary and permanent memory is same.
+
+ @param[in] TemporaryMemoryBase Base address of the temporary memory.
+ @param[in] PermenentMemoryBase Base address of the permanent memory.
+**/
+VOID
+EFIAPI
+SecSwitchStack (
+ IN UINT32 TemporaryMemoryBase,
+ IN UINT32 PermenentMemoryBase
+ );
+
+/**
+ This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
+ permanent memory.
+
+ @param[in] PeiServices Pointer to the PEI Services Table.
+ @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the
+ Temporary RAM contents.
+ @param[in] CopySize Amount of memory to migrate from temporary to permanent memory.
+
+ @retval EFI_SUCCESS The data was successfully returned.
+ @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
+ TemporaryMemoryBase > PermanentMemoryBase.
+
+**/
+EFI_STATUS
+EFIAPI
+SecTemporaryRamSupport (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+
+/**
+
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+
+
+ @param[in] SizeOfRam Size of the temporary memory available for use.
+ @param[in] TempRamBase Base address of temporary ram
+ @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
+ @param[in] PeiCore PeiCore entry point.
+ @param[in] BootLoaderStack BootLoader stack.
+ @param[in] ApiIdx the index of API.
+
+ @return This function never returns.
+
+**/
+VOID
+EFIAPI
+SecStartup (
+ IN UINT32 SizeOfRam,
+ IN UINT32 TempRamBase,
+ IN VOID *BootFirmwareVolume,
+ IN PEI_CORE_ENTRY PeiCore,
+ IN UINT32 BootLoaderStack,
+ IN UINT32 ApiIdx
+ );
+
+/**
+ Autogenerated function that calls the library constructors for all of the module's
+ dependent libraries. This function must be called by the SEC Core once a stack has
+ been established.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
+/**
+
+ Return value of esp.
+
+ @return value of esp.
+
+**/
+UINT32
+EFIAPI
+AsmReadEsp (
+ VOID
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw
new file mode 100644
index 00000000..2dc9f178
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Bin/ResetVec.ia32.raw
Binary files differ
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py
new file mode 100755
index 00000000..fb1a25a0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Build.py
@@ -0,0 +1,47 @@
+## @file
+# Automate the process of building the various reset vector types
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+import glob
+import os
+import subprocess
+import sys
+
+def RunCommand(commandLine):
+ #print ' '.join(commandLine)
+ return subprocess.call(commandLine)
+
+for filename in glob.glob(os.path.join('Bin', '*.raw')):
+ os.remove(filename)
+
+arch = 'ia32'
+debugType = None
+output = os.path.join('Bin', 'ResetVec')
+output += '.' + arch
+if debugType is not None:
+ output += '.' + debugType
+output += '.raw'
+commandLine = (
+ 'nasm',
+ '-D', 'ARCH_%s' % arch.upper(),
+ '-D', 'DEBUG_%s' % str(debugType).upper(),
+ '-o', output,
+ 'ResetVectorCode.asm',
+ )
+ret = RunCommand(commandLine)
+print '\tASM\t' + output
+if ret != 0: sys.exit(ret)
+
+commandLine = (
+ 'python',
+ 'Tools/FixupForRawSection.py',
+ output,
+ )
+print '\tFIXUP\t' + output
+ret = RunCommand(commandLine)
+if ret != 0: sys.exit(ret)
+
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16 b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16
new file mode 100644
index 00000000..440d5ac1
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Ia16/ResetVec.asm16
@@ -0,0 +1,97 @@
+;; @file
+; Reset Vector Data structure
+; This structure is located at 0xFFFFFFC0
+;
+; Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;;
+
+BITS 16
+
+
+;
+; The layout of this file is fixed. The build tool makes assumption of the layout.
+;
+
+ORG 0x0
+;
+; Reserved
+;
+ReservedData: DD 0eeeeeeeeh, 0eeeeeeeeh
+
+ ; ORG 0x10
+ TIMES 0x10-($-$$) DB 0
+;
+; This is located at 0xFFFFFFD0h
+;
+ mov di, "AP"
+ jmp ApStartup
+
+ ; ORG 0x20
+
+ TIMES 0x20-($-$$) DB 0
+
+; Pointer to the entry point of the PEI core
+; It is located at 0xFFFFFFE0, and is fixed up by some build tool
+; So if the value 8..1 appears in the final FD image, tool failure occurs.
+;
+PeiCoreEntryPoint: DD 0x12345678
+
+;
+; This is the handler for all kinds of exceptions. Since it's for debugging
+; purpose only, nothing except a deadloop would be done here. Developers could
+; analyze the cause of the exception if a debugger had been attached.
+;
+InterruptHandler:
+ jmp $
+ iret
+
+ ; ORG 0x30
+ TIMES 0x30-($-$$) DB 0
+;
+; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte
+; Execution starts here upon power-on/platform-reset.
+;
+ResetHandler:
+ nop
+ nop
+
+ApStartup:
+ ;
+ ; Jmp Rel16 instruction
+ ; Use machine code directly in case of the assembler optimization
+ ; SEC entry point relative address will be fixed up by some build tool.
+ ;
+ ; Typically, SEC entry point is the function _ModuleEntryPoint() defined in
+ ; SecEntry.asm
+ ;
+ DB 0x0e9
+ DW -3
+
+ ; ORG 0x38
+
+ TIMES 0x38-($-$$) DB 0
+;
+; Ap reset vector segment address is at 0xFFFFFFF8
+; This will be fixed up by some build tool,
+; so if the value 1..8 appears in the final FD image,
+; tool failure occurs
+;
+ApSegAddress: dd 0x12345678
+
+ ; ORG 0x3c
+ TIMES 0x3c-($-$$) DB 0
+;
+; BFV Base is at 0xFFFFFFFC
+; This will be fixed up by some build tool,
+; so if the value 1..8 appears in the final FD image,
+; tool failure occurs.
+;
+BfvBase: DD 0x12345678
+
+;
+; Nothing can go here, otherwise the layout of this file would change.
+;
+
+ ; END
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm
new file mode 100644
index 00000000..acd65bde
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/ResetVectorCode.asm
@@ -0,0 +1,11 @@
+;------------------------------------------------------------------------------
+; @file
+; This file includes all other code files to assemble the reset vector code
+;
+; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+
+%include "Ia16/ResetVec.asm16"
diff --git a/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py
new file mode 100755
index 00000000..5ddddb6b
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/FspSecCore/Vtf0/Tools/FixupForRawSection.py
@@ -0,0 +1,104 @@
+## @file
+# Apply fixup to VTF binary image for FFS Raw section
+#
+# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+import sys
+
+filename = sys.argv[1]
+
+if filename.lower().find('ia32') >= 0:
+ d = open(sys.argv[1], 'rb').read()
+ c = ((len(d) + 4 + 7) & ~7) - 4
+ if c > len(d):
+ c -= len(d)
+ f = open(sys.argv[1], 'wb')
+ f.write('\x90' * c)
+ f.write(d)
+ f.close()
+else:
+ from struct import pack
+
+ PAGE_PRESENT = 0x01
+ PAGE_READ_WRITE = 0x02
+ PAGE_USER_SUPERVISOR = 0x04
+ PAGE_WRITE_THROUGH = 0x08
+ PAGE_CACHE_DISABLE = 0x010
+ PAGE_ACCESSED = 0x020
+ PAGE_DIRTY = 0x040
+ PAGE_PAT = 0x080
+ PAGE_GLOBAL = 0x0100
+ PAGE_2M_MBO = 0x080
+ PAGE_2M_PAT = 0x01000
+
+ def NopAlign4k(s):
+ c = ((len(s) + 0xfff) & ~0xfff) - len(s)
+ return ('\x90' * c) + s
+
+ def PageDirectoryEntries4GbOf2MbPages(baseAddress):
+
+ s = ''
+ for i in range(0x800):
+ i = (
+ baseAddress + long(i << 21) +
+ PAGE_2M_MBO +
+ PAGE_CACHE_DISABLE +
+ PAGE_ACCESSED +
+ PAGE_DIRTY +
+ PAGE_READ_WRITE +
+ PAGE_PRESENT
+ )
+ s += pack('Q', i)
+ return s
+
+ def PageDirectoryPointerTable4GbOf2MbPages(pdeBase):
+ s = ''
+ for i in range(0x200):
+ i = (
+ pdeBase +
+ (min(i, 3) << 12) +
+ PAGE_CACHE_DISABLE +
+ PAGE_ACCESSED +
+ PAGE_READ_WRITE +
+ PAGE_PRESENT
+ )
+ s += pack('Q', i)
+ return s
+
+ def PageMapLevel4Table4GbOf2MbPages(pdptBase):
+ s = ''
+ for i in range(0x200):
+ i = (
+ pdptBase +
+ (min(i, 0) << 12) +
+ PAGE_CACHE_DISABLE +
+ PAGE_ACCESSED +
+ PAGE_READ_WRITE +
+ PAGE_PRESENT
+ )
+ s += pack('Q', i)
+ return s
+
+ def First4GbPageEntries(topAddress):
+ PDE = PageDirectoryEntries4GbOf2MbPages(0L)
+ pml4tBase = topAddress - 0x1000
+ pdptBase = pml4tBase - 0x1000
+ pdeBase = pdptBase - len(PDE)
+ PDPT = PageDirectoryPointerTable4GbOf2MbPages(pdeBase)
+ PML4T = PageMapLevel4Table4GbOf2MbPages(pdptBase)
+ return PDE + PDPT + PML4T
+
+ def AlignAndAddPageTables():
+ d = open(sys.argv[1], 'rb').read()
+ code = NopAlign4k(d)
+ topAddress = 0x100000000 - len(code)
+ d = ('\x90' * 4) + First4GbPageEntries(topAddress) + code
+ f = open(sys.argv[1], 'wb')
+ f.write(d)
+ f.close()
+
+ AlignAndAddPageTables()
+