]> git.proxmox.com Git - mirror_edk2.git/commitdiff
IntelFsp2Pkg: Adopt FSP 2.4 MultiPhase functions.
authorChasel Chiu <chasel.chiu@intel.com>
Wed, 10 Aug 2022 00:35:30 +0000 (17:35 -0700)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 7 Sep 2022 04:21:15 +0000 (04:21 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3916

Adopt MultiPhase functions for both FspSecCoreS and FspSecCoreM.
For backward compatibility, new INF are created for new modules.

Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryS.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
IntelFsp2Pkg/FspSecCore/SecFsp.c
IntelFsp2Pkg/FspSecCore/SecFspApiChk.c
IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryS.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm

diff --git a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreM.inf
new file mode 100644 (file)
index 0000000..e93e176
--- /dev/null
@@ -0,0 +1,75 @@
+## @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
diff --git a/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf b/IntelFsp2Pkg/FspSecCore/Fsp24SecCoreS.inf
new file mode 100644 (file)
index 0000000..1d44fb6
--- /dev/null
@@ -0,0 +1,59 @@
+## @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
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm
new file mode 100644 (file)
index 0000000..997b9c0
--- /dev/null
@@ -0,0 +1,304 @@
+;; @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
diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryS.nasm
new file mode 100644 (file)
index 0000000..bda99cd
--- /dev/null
@@ -0,0 +1,101 @@
+;; @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
index 8d8deba28a9a096ba4eed0502ebe68f7d106f2d4..87446be779772fe4f7953a68268dfbb011230fb3 100644 (file)
@@ -67,6 +67,9 @@ FspApiCommon2:
   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
index d9085ef51fb94166d60bb9accd3e0c0ddeae9b02..11be1f97ca1560965bfa04f4c30059f84d5b3298 100644 (file)
@@ -135,6 +135,10 @@ FspGlobalDataInit (
   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
index 35d223a40467bf63a9982b7b4096db2d20ca1a3e..a44fbf2a50b56c07f24064d4663044e2b868212a 100644 (file)
@@ -69,8 +69,17 @@ FspApiCallingCheck (
         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
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm
new file mode 100644 (file)
index 0000000..8880721
--- /dev/null
@@ -0,0 +1,303 @@
+;; @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
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryS.nasm
new file mode 100644 (file)
index 0000000..5bbbc5d
--- /dev/null
@@ -0,0 +1,108 @@
+;; @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
index 718e672e020194bf5b8ef89cb9bd637b327d8122..dc6b8c99a1d2dbd04feb37c4f19ea2c2342bfa56 100644 (file)
@@ -68,6 +68,9 @@ FspApiCommon2:
   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