--- /dev/null
+## @file\r
+# Sec Core for FSP to support MultiPhase (SeparatePhase) MemInitialization.\r
+#\r
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = Fsp24SecCoreM\r
+ FILE_GUID = C5BC0719-4A23-4F6E-94DA-05FB6A0DFA9C\r
+ MODULE_TYPE = SEC\r
+ VERSION_STRING = 1.0\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64\r
+#\r
+\r
+[Sources]\r
+ SecMain.c\r
+ SecMain.h\r
+ SecFsp.c\r
+ SecFsp.h\r
+ SecFspApiChk.c\r
+\r
+[Sources.IA32]\r
+ Ia32/Stack.nasm\r
+ Ia32/Fsp24ApiEntryM.nasm\r
+ Ia32/FspApiEntryCommon.nasm\r
+ Ia32/FspHelper.nasm\r
+ Ia32/ReadEsp.nasm\r
+\r
+[Sources.X64]\r
+ X64/Stack.nasm\r
+ X64/Fsp24ApiEntryM.nasm\r
+ X64/FspApiEntryCommon.nasm\r
+ X64/FspHelper.nasm\r
+ X64/ReadRsp.nasm\r
+\r
+[Binaries.Ia32]\r
+ RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+ UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseMemoryLib\r
+ DebugLib\r
+ BaseLib\r
+ PciCf8Lib\r
+ SerialPortLib\r
+ FspSwitchStackLib\r
+ FspCommonLib\r
+ FspSecPlatformLib\r
+ CpuLib\r
+ UefiCpuLib\r
+ FspMultiPhaseLib\r
+\r
+[Pcd]\r
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES\r
+ gIntelFsp2PkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES\r
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspTemporaryRamSize ## CONSUMES\r
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspHeapSizePercentage ## CONSUMES\r
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspMaxInterruptSupported ## CONSUMES\r
+ gIntelFsp2PkgTokenSpaceGuid.PcdFspPrivateTemporaryRamSize ## CONSUMES\r
+\r
+[Ppis]\r
+ gEfiTemporaryRamSupportPpiGuid ## PRODUCES\r
+ gFspInApiModePpiGuid ## PRODUCES\r
--- /dev/null
+## @file\r
+# Sec Core for FSP to support MultiPhase (SeparatePhase) SiInitialization.\r
+#\r
+# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = Fsp24SecCoreS\r
+ FILE_GUID = E039988B-0F21-4D95-AE34-C469B10E13F8\r
+ MODULE_TYPE = SEC\r
+ VERSION_STRING = 1.0\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64\r
+#\r
+\r
+[Sources]\r
+ SecFspApiChk.c\r
+ SecFsp.h\r
+\r
+[Sources.IA32]\r
+ Ia32/Stack.nasm\r
+ Ia32/Fsp24ApiEntryS.nasm\r
+ Ia32/FspApiEntryCommon.nasm\r
+ Ia32/FspHelper.nasm\r
+\r
+[Sources.X64]\r
+ X64/Stack.nasm\r
+ X64/Fsp24ApiEntryS.nasm\r
+ X64/FspApiEntryCommon.nasm\r
+ X64/FspHelper.nasm\r
+\r
+[Binaries.Ia32]\r
+ RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ IntelFsp2Pkg/IntelFsp2Pkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseMemoryLib\r
+ DebugLib\r
+ BaseLib\r
+ PciCf8Lib\r
+ SerialPortLib\r
+ FspSwitchStackLib\r
+ FspCommonLib\r
+ FspSecPlatformLib\r
+ FspMultiPhaseLib\r
+\r
+[Ppis]\r
+ gEfiTemporaryRamSupportPpiGuid ## PRODUCES\r
+\r
--- /dev/null
+;; @file\r
+; Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;;\r
+\r
+ SECTION .text\r
+\r
+;\r
+; Following are fixed PCDs\r
+;\r
+extern ASM_PFX(PcdGet32(PcdTemporaryRamBase))\r
+extern ASM_PFX(PcdGet32(PcdTemporaryRamSize))\r
+extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize))\r
+extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))\r
+\r
+struc FSPM_UPD_COMMON\r
+ ; FSP_UPD_HEADER {\r
+ .FspUpdHeader: resd 8\r
+ ; }\r
+ ; FSPM_ARCH_UPD {\r
+ .Revision: resb 1\r
+ .Reserved: resb 3\r
+ .NvsBufferPtr: resd 1\r
+ .StackBase: resd 1\r
+ .StackSize: resd 1\r
+ .BootLoaderTolumSize: resd 1\r
+ .BootMode: resd 1\r
+ .Reserved1: resb 8\r
+ ; }\r
+ .size:\r
+endstruc\r
+\r
+struc FSPM_UPD_COMMON_FSP24\r
+ ; FSP_UPD_HEADER {\r
+ .FspUpdHeader: resd 8\r
+ ; }\r
+ ; FSPM_ARCH2_UPD {\r
+ .Revision: resb 1\r
+ .Reserved: resb 3\r
+ .Length resd 1\r
+ .StackBase: resq 1\r
+ .StackSize: resq 1\r
+ .BootLoaderTolumSize: resd 1\r
+ .BootMode: resd 1\r
+ .FspEventHandler resq 1\r
+ .Reserved1: resb 24\r
+ ; }\r
+ .size:\r
+endstruc\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(SecStartup)\r
+extern ASM_PFX(FspApiCommon)\r
+\r
+;\r
+; Following functions will be provided in PlatformSecLib\r
+;\r
+extern ASM_PFX(AsmGetFspBaseAddress)\r
+extern ASM_PFX(AsmGetFspInfoHeader)\r
+extern ASM_PFX(FspMultiPhaseMemInitApiHandler)\r
+\r
+STACK_SAVED_EAX_OFFSET EQU 4 * 7 ; size of a general purpose register * eax index\r
+API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call]\r
+FSP_HEADER_IMGBASE_OFFSET EQU 1Ch\r
+FSP_HEADER_CFGREG_OFFSET EQU 24h\r
+\r
+;----------------------------------------------------------------------------\r
+; FspMemoryInit API\r
+;\r
+; This FSP API is called after TempRamInit and initializes the memory.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspMemoryInitApi)\r
+ASM_PFX(FspMemoryInitApi):\r
+ mov eax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspMultiPhaseMemoryInitApi API\r
+;\r
+; This FSP API provides multi-phase Memory initialization, which brings greater\r
+; modularity beyond the existing FspMemoryInit() API.\r
+; Increased modularity is achieved by adding an extra API to FSP-M.\r
+; This allows the bootloader to add board specific initialization steps throughout\r
+; the MemoryInit flow as needed.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspMultiPhaseMemoryInitApi)\r
+ASM_PFX(FspMultiPhaseMemoryInitApi):\r
+ mov eax, 8 ; FSP_API_INDEX.FspMultiPhaseMemInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+;----------------------------------------------------------------------------\r
+; TempRamExitApi API\r
+;\r
+; This API tears down temporary RAM\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamExitApi)\r
+ASM_PFX(TempRamExitApi):\r
+ mov eax, 4 ; FSP_API_INDEX.TempRamExitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommonContinue API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommonContinue)\r
+ASM_PFX(FspApiCommonContinue):\r
+ ;\r
+ ; Handle FspMultiPhaseMemInitApiIndex API\r
+ ;\r
+ cmp eax, 8 ; FspMultiPhaseMemInitApiIndex\r
+ jnz NotMultiPhaseMemoryInitApi\r
+\r
+ pushad\r
+ push DWORD [esp + (4 * 8 + 4)] ; push ApiParam\r
+ push eax ; push ApiIdx\r
+ call ASM_PFX(FspMultiPhaseMemInitApiHandler)\r
+ add esp, 8\r
+ mov dword [esp + STACK_SAVED_EAX_OFFSET], eax\r
+ popad\r
+ ret\r
+\r
+NotMultiPhaseMemoryInitApi:\r
+\r
+ ;\r
+ ; FspMemoryInit API setup the initial stack frame\r
+ ;\r
+\r
+ ;\r
+ ; Place holder to store the FspInfoHeader pointer\r
+ ;\r
+ push eax\r
+\r
+ ;\r
+ ; Update the FspInfoHeader pointer\r
+ ;\r
+ push eax\r
+ call ASM_PFX(AsmGetFspInfoHeader)\r
+ mov [esp + 4], eax\r
+ pop eax\r
+\r
+ ;\r
+ ; Create a Task Frame in the stack for the Boot Loader\r
+ ;\r
+ pushfd ; 2 pushf for 4 byte alignment\r
+ cli\r
+ pushad\r
+\r
+ ; Reserve 8 bytes for IDT save/restore\r
+ sub esp, 8\r
+ sidt [esp]\r
+\r
+\r
+ ; Get Stackbase and StackSize from FSPM_UPD Param\r
+ mov edx, [esp + API_PARAM1_OFFSET]\r
+ cmp edx, 0\r
+ jnz FspStackSetup\r
+\r
+ ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null\r
+ push eax\r
+ call ASM_PFX(AsmGetFspInfoHeader)\r
+ mov edx, [eax + FSP_HEADER_IMGBASE_OFFSET]\r
+ add edx, [eax + FSP_HEADER_CFGREG_OFFSET]\r
+ pop eax\r
+\r
+FspStackSetup:\r
+ mov ecx, [edx + FSPM_UPD_COMMON.Revision]\r
+ cmp ecx, 3\r
+ jae FspmUpdCommon2\r
+\r
+ ;\r
+ ; StackBase = temp memory base, StackSize = temp memory size\r
+ ;\r
+ mov edi, [edx + FSPM_UPD_COMMON.StackBase]\r
+ mov ecx, [edx + FSPM_UPD_COMMON.StackSize]\r
+ jmp ChkFspHeapSize\r
+\r
+FspmUpdCommon2:\r
+ mov edi, [edx + FSPM_UPD_COMMON_FSP24.StackBase]\r
+ mov ecx, [edx + FSPM_UPD_COMMON_FSP24.StackSize]\r
+\r
+ChkFspHeapSize:\r
+ ;\r
+ ; Keep using bootloader stack if heap size % is 0\r
+ ;\r
+ mov bl, BYTE [ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))]\r
+ cmp bl, 0\r
+ jz SkipStackSwitch\r
+\r
+ ;\r
+ ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0\r
+ ;\r
+ add edi, ecx\r
+ ;\r
+ ; Switch to new FSP stack\r
+ ;\r
+ xchg edi, esp ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size\r
+\r
+SkipStackSwitch:\r
+ ;\r
+ ; If heap size % is 0:\r
+ ; EDI is FSPM_UPD_COMMON.StackBase and will hold ESP later (boot loader stack pointer)\r
+ ; ECX is FSPM_UPD_COMMON.StackSize\r
+ ; ESP is boot loader stack pointer (no stack switch)\r
+ ; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON.StackBase later)\r
+ ;\r
+ ; If heap size % is not 0\r
+ ; EDI is boot loader stack pointer\r
+ ; ECX is FSPM_UPD_COMMON.StackSize\r
+ ; ESP is new stack (FSPM_UPD_COMMON.StackBase + FSPM_UPD_COMMON.StackSize)\r
+ ; BL is NOT 0 to indicate stack has switched\r
+ ;\r
+ cmp bl, 0\r
+ jnz StackHasBeenSwitched\r
+\r
+ mov ebx, edi ; Put FSPM_UPD_COMMON.StackBase to ebx as temp memory base\r
+ mov edi, esp ; Put boot loader stack pointer to edi\r
+ jmp StackSetupDone\r
+\r
+StackHasBeenSwitched:\r
+ mov ebx, esp ; Put Stack base + Stack size in ebx\r
+ sub ebx, ecx ; Stack base + Stack size - Stack size as temp memory base\r
+\r
+StackSetupDone:\r
+\r
+ ;\r
+ ; Pass the API Idx to SecStartup\r
+ ;\r
+ push eax\r
+\r
+ ;\r
+ ; Pass the BootLoader stack to SecStartup\r
+ ;\r
+ push edi\r
+\r
+ ;\r
+ ; Pass entry point of the PEI core\r
+ ;\r
+ call ASM_PFX(AsmGetFspBaseAddress)\r
+ mov edi, eax\r
+ call ASM_PFX(AsmGetPeiCoreOffset)\r
+ add edi, eax\r
+ push edi\r
+\r
+ ;\r
+ ; Pass BFV into the PEI Core\r
+ ; It uses relative address to calculate the actual boot FV base\r
+ ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and\r
+ ; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,\r
+ ; they are different. The code below can handle both cases.\r
+ ;\r
+ call ASM_PFX(AsmGetFspBaseAddress)\r
+ push eax\r
+\r
+ ;\r
+ ; Pass stack base and size into the PEI Core\r
+ ;\r
+ push ebx\r
+ push ecx\r
+\r
+ ;\r
+ ; Pass Control into the PEI Core\r
+ ;\r
+ call ASM_PFX(SecStartup)\r
+ add esp, 4\r
+exit:\r
+ ret\r
+\r
+global ASM_PFX(FspPeiCoreEntryOff)\r
+ASM_PFX(FspPeiCoreEntryOff):\r
+ ;\r
+ ; This value will be patched by the build script\r
+ ;\r
+ DD 0x12345678\r
+\r
+global ASM_PFX(AsmGetPeiCoreOffset)\r
+ASM_PFX(AsmGetPeiCoreOffset):\r
+ mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)]\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; TempRamInit API\r
+;\r
+; Empty function for WHOLEARCHIVE build option\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamInitApi)\r
+ASM_PFX(TempRamInitApi):\r
+ jmp $\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; Module Entrypoint API\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+ jmp $\r
--- /dev/null
+;; @file\r
+; Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;;\r
+\r
+ SECTION .text\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(FspApiCommon)\r
+extern ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)\r
+\r
+STACK_SAVED_EAX_OFFSET EQU 4 * 7 ; size of a general purpose register * eax index\r
+\r
+;----------------------------------------------------------------------------\r
+; NotifyPhase API\r
+;\r
+; This FSP API will notify the FSP about the different phases in the boot\r
+; process\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(NotifyPhaseApi)\r
+ASM_PFX(NotifyPhaseApi):\r
+ mov eax, 2 ; FSP_API_INDEX.NotifyPhaseApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspSiliconInit API\r
+;\r
+; This FSP API initializes the CPU and the chipset including the IO\r
+; controllers in the chipset to enable normal operation of these devices.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspSiliconInitApi)\r
+ASM_PFX(FspSiliconInitApi):\r
+ mov eax, 5 ; FSP_API_INDEX.FspSiliconInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspMultiPhaseSiInitApi API\r
+;\r
+; This FSP API provides multi-phase silicon initialization, which brings greater\r
+; modularity beyond the existing FspSiliconInit() API.\r
+; Increased modularity is achieved by adding an extra API to FSP-S.\r
+; This allows the bootloader to add board specific initialization steps throughout\r
+; the SiliconInit flow as needed.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspMultiPhaseSiInitApi)\r
+ASM_PFX(FspMultiPhaseSiInitApi):\r
+ mov eax, 6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommonContinue API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommonContinue)\r
+ASM_PFX(FspApiCommonContinue):\r
+ ;\r
+ ; Handle FspMultiPhaseSiInitApiIndex API\r
+ ;\r
+ cmp eax, 6 ; FspMultiPhaseSiInitApiIndex\r
+ jnz NotMultiPhaseSiInitApi\r
+\r
+ pushad\r
+ push DWORD [esp + (4 * 8 + 4)] ; push ApiParam\r
+ push eax ; push ApiIdx\r
+ call ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)\r
+ add esp, 8\r
+ mov dword [esp + STACK_SAVED_EAX_OFFSET], eax\r
+ popad\r
+ ret\r
+\r
+NotMultiPhaseSiInitApi:\r
+ jmp $\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; TempRamInit API\r
+;\r
+; Empty function for WHOLEARCHIVE build option\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamInitApi)\r
+ASM_PFX(TempRamInitApi):\r
+ jmp $\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; Module Entrypoint API\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+ jmp $\r
+\r
cmp eax, 6 ; FspMultiPhaseSiInitApiIndex API\r
jz FspApiCommon3\r
\r
+ cmp eax, 8 ; FspMultiPhaseMemInitApiIndex API\r
+ jz FspApiCommon3\r
+\r
call ASM_PFX(AsmGetFspInfoHeader)\r
jmp ASM_PFX(Loader2PeiSwitchStack)\r
\r
PeiFspData->CoreStack = BootLoaderStack;\r
PeiFspData->PerfIdx = 2;\r
PeiFspData->PerfSig = FSP_PERFORMANCE_DATA_SIGNATURE;\r
+ //\r
+ // Cache FspHobList pointer passed by bootloader via ApiParameter2\r
+ //\r
+ PeiFspData->FspHobListPtr = (VOID **)GetFspApiParameter2 ();\r
\r
SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);\r
\r
Status = EFI_UNSUPPORTED;\r
} else if (EFI_ERROR (FspUpdSignatureCheck (FspSiliconInitApiIndex, ApiParam))) {\r
Status = EFI_INVALID_PARAMETER;\r
+ } else if (ApiIdx == FspSiliconInitApiIndex) {\r
+ //\r
+ // Reset MultiPhase NumberOfPhases to zero\r
+ //\r
+ FspData->NumberOfPhases = 0;\r
}\r
}\r
+ } else if (ApiIdx == FspMultiPhaseMemInitApiIndex) {\r
+ if ((FspData == NULL) || ((UINTN)FspData == MAX_ADDRESS) || ((UINTN)FspData == MAX_UINT32)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ }\r
} else if (ApiIdx == FspSmmInitApiIndex) {\r
//\r
// FspSmmInitApiIndex check\r
--- /dev/null
+;; @file\r
+; Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;;\r
+\r
+ SECTION .text\r
+\r
+%include "PushPopRegsNasm.inc"\r
+\r
+;\r
+; Following are fixed PCDs\r
+;\r
+extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))\r
+\r
+struc FSPM_UPD_COMMON_FSP24\r
+ ; FSP_UPD_HEADER {\r
+ .FspUpdHeader: resd 8\r
+ ; }\r
+ ; FSPM_ARCH2_UPD {\r
+ .Revision: resb 1\r
+ .Reserved: resb 3\r
+ .Length resd 1\r
+ .StackBase: resq 1\r
+ .StackSize: resq 1\r
+ .BootLoaderTolumSize: resd 1\r
+ .BootMode: resd 1\r
+ .FspEventHandler resq 1\r
+ .Reserved1: resb 24\r
+ ; }\r
+ .size:\r
+endstruc\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(SecStartup)\r
+extern ASM_PFX(FspApiCommon)\r
+\r
+;\r
+; Following functions will be provided in PlatformSecLib\r
+;\r
+extern ASM_PFX(AsmGetFspBaseAddress)\r
+extern ASM_PFX(AsmGetFspInfoHeader)\r
+extern ASM_PFX(FspMultiPhaseMemInitApiHandler)\r
+\r
+STACK_SAVED_RAX_OFFSET EQU 8 * 7 ; size of a general purpose register * rax index\r
+FSP_HEADER_IMGBASE_OFFSET EQU 1Ch\r
+FSP_HEADER_CFGREG_OFFSET EQU 24h\r
+\r
+;----------------------------------------------------------------------------\r
+; FspMemoryInit API\r
+;\r
+; This FSP API is called after TempRamInit and initializes the memory.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspMemoryInitApi)\r
+ASM_PFX(FspMemoryInitApi):\r
+ mov rax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspMultiPhaseMemoryInitApi API\r
+;\r
+; This FSP API provides multi-phase Memory initialization, which brings greater\r
+; modularity beyond the existing FspMemoryInit() API.\r
+; Increased modularity is achieved by adding an extra API to FSP-M.\r
+; This allows the bootloader to add board specific initialization steps throughout\r
+; the MemoryInit flow as needed.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspMultiPhaseMemoryInitApi)\r
+ASM_PFX(FspMultiPhaseMemoryInitApi):\r
+ mov rax, 8 ; FSP_API_INDEX.FspMultiPhaseMemInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+;----------------------------------------------------------------------------\r
+; TempRamExitApi API\r
+;\r
+; This API tears down temporary RAM\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamExitApi)\r
+ASM_PFX(TempRamExitApi):\r
+ mov rax, 4 ; FSP_API_INDEX.TempRamExitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommonContinue API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommonContinue)\r
+ASM_PFX(FspApiCommonContinue):\r
+ ;\r
+ ; Handle FspMultiPhaseMemoInitApiIndex API\r
+ ;\r
+ push rdx ; Push a QWORD data for stack alignment\r
+\r
+ cmp rax, 8 ; FspMultiPhaseMemInitApiIndex\r
+ jnz NotMultiPhaseMemoryInitApi\r
+\r
+ PUSHA_64\r
+ mov rdx, rcx ; move ApiParam to rdx\r
+ mov rcx, rax ; move ApiIdx to rcx\r
+ sub rsp, 0x20 ; calling C function may need shadow space\r
+ call ASM_PFX(FspMultiPhaseMemInitApiHandler)\r
+ add rsp, 0x20 ; restore shadow space\r
+ mov qword [rsp + STACK_SAVED_RAX_OFFSET], rax\r
+ POPA_64\r
+ add rsp, 0x08\r
+ ret\r
+\r
+NotMultiPhaseMemoryInitApi:\r
+ ; Push RDX and RCX to form CONTEXT_STACK_64\r
+ push rdx ; Push API Parameter2 on stack\r
+ push rcx ; Push API Parameter1 on stack\r
+\r
+ ;\r
+ ; FspMemoryInit API setup the initial stack frame\r
+ ;\r
+\r
+ ;\r
+ ; Place holder to store the FspInfoHeader pointer\r
+ ;\r
+ push rax\r
+\r
+ ;\r
+ ; Update the FspInfoHeader pointer\r
+ ;\r
+ push rax\r
+ call ASM_PFX(AsmGetFspInfoHeader)\r
+ mov [rsp + 8], rax\r
+ pop rax\r
+\r
+ ;\r
+ ; Create a Task Frame in the stack for the Boot Loader\r
+ ;\r
+ pushfq\r
+ cli\r
+ PUSHA_64\r
+\r
+ ; Reserve 16 bytes for IDT save/restore\r
+ sub rsp, 16\r
+ sidt [rsp]\r
+\r
+ ; Get Stackbase and StackSize from FSPM_UPD Param\r
+ mov rdx, rcx ; Put FSPM_UPD Param to rdx\r
+ cmp rdx, 0\r
+ jnz FspStackSetup\r
+\r
+ ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null\r
+ xchg rbx, rax\r
+ call ASM_PFX(AsmGetFspInfoHeader)\r
+ mov edx, [rax + FSP_HEADER_IMGBASE_OFFSET]\r
+ add edx, [rax + FSP_HEADER_CFGREG_OFFSET]\r
+ xchg rbx, rax\r
+\r
+FspStackSetup:\r
+ mov cl, [rdx + FSPM_UPD_COMMON_FSP24.Revision]\r
+ cmp cl, 3\r
+ jae FspmUpdCommonFsp24\r
+\r
+ mov rax, 08000000000000002h ; RETURN_INVALID_PARAMETER\r
+ sub rsp, 0b8h\r
+ ret\r
+\r
+FspmUpdCommonFsp24:\r
+ ;\r
+ ; StackBase = temp memory base, StackSize = temp memory size\r
+ ;\r
+ mov rdi, [rdx + FSPM_UPD_COMMON_FSP24.StackBase]\r
+ mov ecx, [rdx + FSPM_UPD_COMMON_FSP24.StackSize]\r
+\r
+ ;\r
+ ; Keep using bootloader stack if heap size % is 0\r
+ ;\r
+ mov rbx, ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))\r
+ mov bl, BYTE [rbx]\r
+ cmp bl, 0\r
+ jz SkipStackSwitch\r
+\r
+ ;\r
+ ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0\r
+ ;\r
+ add rdi, rcx\r
+ ;\r
+ ; Switch to new FSP stack\r
+ ;\r
+ xchg rdi, rsp ; Exchange rdi and rsp, rdi will be assigned to the current rsp pointer and rsp will be Stack base + Stack size\r
+\r
+SkipStackSwitch:\r
+ ;\r
+ ; If heap size % is 0:\r
+ ; EDI is FSPM_UPD_COMMON_FSP24.StackBase and will hold ESP later (boot loader stack pointer)\r
+ ; ECX is FSPM_UPD_COMMON_FSP24.StackSize\r
+ ; ESP is boot loader stack pointer (no stack switch)\r
+ ; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON_FSP24.StackBase later)\r
+ ;\r
+ ; If heap size % is not 0\r
+ ; EDI is boot loader stack pointer\r
+ ; ECX is FSPM_UPD_COMMON_FSP24.StackSize\r
+ ; ESP is new stack (FSPM_UPD_COMMON_FSP24.StackBase + FSPM_UPD_COMMON_FSP24.StackSize)\r
+ ; BL is NOT 0 to indicate stack has switched\r
+ ;\r
+ cmp bl, 0\r
+ jnz StackHasBeenSwitched\r
+\r
+ mov rbx, rdi ; Put FSPM_UPD_COMMON_FSP24.StackBase to rbx as temp memory base\r
+ mov rdi, rsp ; Put boot loader stack pointer to rdi\r
+ jmp StackSetupDone\r
+\r
+StackHasBeenSwitched:\r
+ mov rbx, rsp ; Put Stack base + Stack size in ebx\r
+ sub rbx, rcx ; Stack base + Stack size - Stack size as temp memory base\r
+\r
+StackSetupDone:\r
+\r
+ ;\r
+ ; Per X64 calling convention, make sure RSP is 16-byte aligned.\r
+ ;\r
+ mov rdx, rsp\r
+ and rdx, 0fh\r
+ sub rsp, rdx\r
+\r
+ ;\r
+ ; Pass the API Idx to SecStartup\r
+ ;\r
+ push rax\r
+\r
+ ;\r
+ ; Pass the BootLoader stack to SecStartup\r
+ ;\r
+ push rdi\r
+\r
+ ;\r
+ ; Pass BFV into the PEI Core\r
+ ; It uses relative address to calculate the actual boot FV base\r
+ ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and\r
+ ; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,\r
+ ; they are different. The code below can handle both cases.\r
+ ;\r
+ call ASM_PFX(AsmGetFspBaseAddress)\r
+ mov r8, rax\r
+\r
+ ;\r
+ ; Pass entry point of the PEI core\r
+ ;\r
+ call ASM_PFX(AsmGetPeiCoreOffset)\r
+ lea r9, [r8 + rax]\r
+\r
+ ;\r
+ ; Pass stack base and size into the PEI Core\r
+ ;\r
+ mov rcx, rcx\r
+ mov rdx, rbx\r
+\r
+ ;\r
+ ; Pass Control into the PEI Core\r
+ ; RCX = SizeOfRam, RDX = TempRamBase, R8 = BFV, R9 = PeiCoreEntry, Last 1 Stack = BL stack, Last 2 Stack = API index\r
+ ; According to X64 calling convention, caller has to allocate 32 bytes as a shadow store on call stack right before\r
+ ; calling the function.\r
+ ;\r
+ sub rsp, 20h\r
+ call ASM_PFX(SecStartup)\r
+ add rsp, 20h\r
+exit:\r
+ ret\r
+\r
+global ASM_PFX(FspPeiCoreEntryOff)\r
+ASM_PFX(FspPeiCoreEntryOff):\r
+ ;\r
+ ; This value will be patched by the build script\r
+ ;\r
+ DD 0x12345678\r
+\r
+global ASM_PFX(AsmGetPeiCoreOffset)\r
+ASM_PFX(AsmGetPeiCoreOffset):\r
+ push rbx\r
+ mov rbx, ASM_PFX(FspPeiCoreEntryOff)\r
+ mov eax, dword[ebx]\r
+ pop rbx\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; TempRamInit API\r
+;\r
+; Empty function for WHOLEARCHIVE build option\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamInitApi)\r
+ASM_PFX(TempRamInitApi):\r
+ jmp $\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; Module Entrypoint API\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+ jmp $\r
+\r
--- /dev/null
+;; @file\r
+; Provide FSP API entry points.\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;;\r
+\r
+ SECTION .text\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(FspApiCommon)\r
+extern ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)\r
+\r
+STACK_SAVED_RAX_OFFSET EQU 8 * 7 ; size of a general purpose register * rax index\r
+\r
+;----------------------------------------------------------------------------\r
+; NotifyPhase API\r
+;\r
+; This FSP API will notify the FSP about the different phases in the boot\r
+; process\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(NotifyPhaseApi)\r
+ASM_PFX(NotifyPhaseApi):\r
+ mov rax, 2 ; FSP_API_INDEX.NotifyPhaseApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspSiliconInit API\r
+;\r
+; This FSP API initializes the CPU and the chipset including the IO\r
+; controllers in the chipset to enable normal operation of these devices.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspSiliconInitApi)\r
+ASM_PFX(FspSiliconInitApi):\r
+ mov rax, 5 ; FSP_API_INDEX.FspSiliconInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspMultiPhaseSiInitApi API\r
+;\r
+; This FSP API provides multi-phase silicon initialization, which brings greater\r
+; modularity beyond the existing FspSiliconInit() API.\r
+; Increased modularity is achieved by adding an extra API to FSP-S.\r
+; This allows the bootloader to add board specific initialization steps throughout\r
+; the SiliconInit flow as needed.\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+%include "PushPopRegsNasm.inc"\r
+\r
+global ASM_PFX(FspMultiPhaseSiInitApi)\r
+ASM_PFX(FspMultiPhaseSiInitApi):\r
+ mov rax, 6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex\r
+ jmp ASM_PFX(FspApiCommon)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommonContinue API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommonContinue)\r
+ASM_PFX(FspApiCommonContinue):\r
+ ;\r
+ ; Handle FspMultiPhaseSiInitApiIndex API\r
+ ;\r
+ push rdx ; Push a QWORD data for stack alignment\r
+\r
+ cmp rax, 6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex\r
+ jnz NotMultiPhaseSiInitApi\r
+\r
+ PUSHA_64\r
+ mov rdx, rcx ; move ApiParam to rdx\r
+ mov rcx, rax ; move ApiIdx to rcx\r
+ sub rsp, 0x20 ; calling C function may need shadow space\r
+ call ASM_PFX(FspMultiPhaseSiInitApiHandlerV2)\r
+ add rsp, 0x20 ; restore shadow space\r
+ mov qword [rsp + STACK_SAVED_RAX_OFFSET], rax\r
+ POPA_64\r
+ add rsp, 0x08\r
+ ret\r
+\r
+NotMultiPhaseSiInitApi:\r
+ jmp $\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; TempRamInit API\r
+;\r
+; Empty function for WHOLEARCHIVE build option\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamInitApi)\r
+ASM_PFX(TempRamInitApi):\r
+ jmp $\r
+ ret\r
+\r
+;----------------------------------------------------------------------------\r
+; Module Entrypoint API\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(_ModuleEntryPoint)\r
+ASM_PFX(_ModuleEntryPoint):\r
+ jmp $\r
+\r
cmp rax, 6 ; FspMultiPhaseSiInitApiIndex API\r
jz FspApiCommon3\r
\r
+ cmp rax, 8 ; FspMultiPhaseMemInitApiIndex API\r
+ jz FspApiCommon3\r
+\r
call ASM_PFX(AsmGetFspInfoHeader)\r
jmp ASM_PFX(Loader2PeiSwitchStack)\r
\r