]> git.proxmox.com Git - mirror_edk2.git/commitdiff
IntelFsp2Pkg: FspSecCore support for X64
authorTed Kuo <ted.kuo@intel.com>
Fri, 15 Apr 2022 08:37:39 +0000 (01:37 -0700)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sat, 16 Apr 2022 00:18:14 +0000 (00:18 +0000)
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3893
1.Added FspSecCore support for X64.
2.Bumped FSP header revision to 7 to indicate FSP 64bit is supported.
3.Corrected few typos.

Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Ashraf Ali S <ashraf.ali.s@intel.com>
Signed-off-by: Ted Kuo <ted.kuo@intel.com>
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
18 files changed:
IntelFsp2Pkg/FspSecCore/Fsp22SecCoreS.inf
IntelFsp2Pkg/FspSecCore/FspSecCoreM.inf
IntelFsp2Pkg/FspSecCore/FspSecCoreS.inf
IntelFsp2Pkg/FspSecCore/FspSecCoreT.inf
IntelFsp2Pkg/FspSecCore/Ia32/FspApiEntryCommon.nasm
IntelFsp2Pkg/FspSecCore/X64/Fsp22ApiEntryS.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/FspApiEntryS.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/FspHelper.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/MicrocodeLoadNasm.inc [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/ReadRsp.nasm [new file with mode: 0644]
IntelFsp2Pkg/FspSecCore/X64/Stack.nasm [new file with mode: 0644]
IntelFsp2Pkg/Include/Guid/FspHeaderFile.h
IntelFsp2Pkg/Include/SaveRestoreSseAvxNasm.inc [new file with mode: 0644]
IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
IntelFsp2Pkg/Library/BaseFspSwitchStackLib/X64/Stack.nasm

index 0a24eb2a8b3a1244df385136e92a51b1d38950fc..4a67388ddf118eea463edd2fe30797d42b6aa3e3 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  Sec Core for FSP to support MultiPhase (SeparatePhase) SiInitialization.\r
 #\r
-#  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -17,7 +17,7 @@
 #\r
 # The following information is for reference only and not required by the build tools.\r
 #\r
-#  VALID_ARCHITECTURES           = IA32\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
 #\r
 \r
 [Sources]\r
   Ia32/FspApiEntryCommon.nasm\r
   Ia32/FspHelper.nasm\r
 \r
+[Sources.X64]\r
+  X64/Stack.nasm\r
+  X64/Fsp22ApiEntryS.nasm\r
+  X64/FspApiEntryCommon.nasm\r
+  X64/FspHelper.nasm\r
+\r
 [Binaries.Ia32]\r
   RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
 \r
index 7b05cae64130e21b3a613dcc9541408b79dd57a5..a7fc07dc614a92e7d819d27b7065249c073b1163 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  Sec Core for FSP\r
 #\r
-#  Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -17,7 +17,7 @@
 #\r
 # The following information is for reference only and not required by the build tools.\r
 #\r
-#  VALID_ARCHITECTURES           = IA32\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
 #\r
 \r
 [Sources]\r
   Ia32/FspHelper.nasm\r
   Ia32/ReadEsp.nasm\r
 \r
+[Sources.X64]\r
+  X64/Stack.nasm\r
+  X64/FspApiEntryM.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
index 1d9c2554d1a8368bd9e423ea1b8b7291088052b5..fb80c0e33949c5854001c9cb4e9aced9f6dcfa2e 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  Sec Core for FSP\r
 #\r
-#  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -17,7 +17,7 @@
 #\r
 # The following information is for reference only and not required by the build tools.\r
 #\r
-#  VALID_ARCHITECTURES           = IA32\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
 #\r
 \r
 [Sources]\r
   Ia32/FspApiEntryCommon.nasm\r
   Ia32/FspHelper.nasm\r
 \r
+[Sources.X64]\r
+  X64/Stack.nasm\r
+  X64/FspApiEntryS.nasm\r
+  X64/FspApiEntryCommon.nasm\r
+  X64/FspHelper.nasm\r
+\r
 [Binaries.Ia32]\r
   RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
 \r
index 664bde56789b7378d48490068dd87ef38ed29041..e5a6eaa16406921397c06f50ece05b56b7709b65 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  Sec Core for FSP\r
 #\r
-#  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 #\r
 # The following information is for reference only and not required by the build tools.\r
 #\r
-#  VALID_ARCHITECTURES           = IA32\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
 #\r
 \r
-[Sources]\r
-\r
-\r
 [Sources.IA32]\r
   Ia32/Stack.nasm\r
   Ia32/FspApiEntryT.nasm\r
   Ia32/FspHelper.nasm\r
 \r
+[Sources.X64]\r
+  X64/Stack.nasm\r
+  X64/FspApiEntryT.nasm\r
+  X64/FspHelper.nasm\r
+\r
 [Binaries.Ia32]\r
   RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC\r
 \r
index 26ae7d9fd36daaeb60678fb98864f95d193ee6bb..8d8deba28a9a096ba4eed0502ebe68f7d106f2d4 100644 (file)
@@ -1,12 +1,14 @@
 ;; @file\r
 ;  Provide FSP API entry points.\r
 ;\r
-; Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>\r
 ; SPDX-License-Identifier: BSD-2-Clause-Patent\r
 ;;\r
 \r
     SECTION .text\r
 \r
+STACK_SAVED_EAX_OFFSET       EQU   4 * 7 ; size of a general purpose register * eax index\r
+\r
 ;\r
 ; Following functions will be provided in C\r
 ;\r
@@ -52,7 +54,7 @@ FspApiCommon1:
   add    esp, 8\r
   cmp    eax, 0\r
   jz     FspApiCommon2\r
-  mov    dword  [esp + (4 * 7)], eax\r
+  mov    dword  [esp + STACK_SAVED_EAX_OFFSET], eax\r
   popad\r
 exit:\r
   ret\r
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Fsp22ApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/X64/Fsp22ApiEntryS.nasm
new file mode 100644 (file)
index 0000000..c739793
--- /dev/null
@@ -0,0 +1,103 @@
+;; @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(FspMultiPhaseSiInitApiHandler)\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    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
+\r
+%include    "PushPopRegsNasm.inc"\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\r
+  jnz    NotMultiPhaseSiInitApi\r
+\r
+  PUSHA_64\r
+  mov    rdx, rcx           ; move ApiParam to rdx\r
+  mov    rcx, rax           ; move ApiIdx to rcx\r
+  call   ASM_PFX(FspMultiPhaseSiInitApiHandler)\r
+  mov    qword  [rsp + STACK_SAVED_RAX_OFFSET], rax\r
+  POPA_64\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
diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryCommon.nasm
new file mode 100644 (file)
index 0000000..718e672
--- /dev/null
@@ -0,0 +1,76 @@
+;; @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
+STACK_SAVED_RAX_OFFSET       EQU   8 * 7 ; size of a general purpose register * rax index\r
+\r
+;\r
+; Following functions will be provided in C\r
+;\r
+extern ASM_PFX(Loader2PeiSwitchStack)\r
+extern ASM_PFX(FspApiCallingCheck)\r
+\r
+;\r
+; Following functions will be provided in ASM\r
+;\r
+extern ASM_PFX(FspApiCommonContinue)\r
+extern ASM_PFX(AsmGetFspInfoHeader)\r
+\r
+;----------------------------------------------------------------------------\r
+; FspApiCommon API\r
+;\r
+; This is the FSP API common entry point to resume the FSP execution\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(FspApiCommon)\r
+ASM_PFX(FspApiCommon):\r
+  ;\r
+  ; RAX holds the API index\r
+  ;\r
+\r
+  ;\r
+  ; Stack must be ready\r
+  ;\r
+  push   rax\r
+  add    rsp, 8\r
+  cmp    rax, [rsp - 8]\r
+  jz     FspApiCommon1\r
+  mov    rax, 08000000000000003h\r
+  jmp    exit\r
+\r
+FspApiCommon1:\r
+  ;\r
+  ; Verify the calling condition\r
+  ;\r
+  PUSHA_64\r
+  mov    rdx, rcx           ; move ApiParam to rdx\r
+  mov    rcx, rax           ; move ApiIdx to rcx\r
+  call   ASM_PFX(FspApiCallingCheck)\r
+  cmp    rax, 0\r
+  jz     FspApiCommon2\r
+  mov    [rsp + STACK_SAVED_RAX_OFFSET], rax\r
+  POPA_64\r
+exit:\r
+  ret\r
+\r
+FspApiCommon2:\r
+  POPA_64\r
+  cmp    rax, 3   ; FspMemoryInit API\r
+  jz     FspApiCommon3\r
+\r
+  cmp    rax, 6   ; FspMultiPhaseSiInitApiIndex API\r
+  jz     FspApiCommon3\r
+\r
+  call   ASM_PFX(AsmGetFspInfoHeader)\r
+  jmp    ASM_PFX(Loader2PeiSwitchStack)\r
+\r
+FspApiCommon3:\r
+  jmp    ASM_PFX(FspApiCommonContinue)\r
+\r
diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm
new file mode 100644 (file)
index 0000000..4d965e1
--- /dev/null
@@ -0,0 +1,271 @@
+;; @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
+\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
+; 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
+  ; RAX holds the API index\r
+  ; Push RDX and RCX to form CONTEXT_STACK_64\r
+  ;\r
+  push   rdx    ; Push a QWORD data for stack alignment\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/FspApiEntryS.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryS.nasm
new file mode 100644 (file)
index 0000000..f863ef0
--- /dev/null
@@ -0,0 +1,67 @@
+;; @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
+\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
+; 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
+  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
diff --git a/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspApiEntryT.nasm
new file mode 100644 (file)
index 0000000..a9f5f28
--- /dev/null
@@ -0,0 +1,495 @@
+;; @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    "SaveRestoreSseAvxNasm.inc"\r
+%include    "MicrocodeLoadNasm.inc"\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 (PcdFspReservedBufferSize))\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(LoadMicrocode)    ; @todo: needs a weak implementation\r
+extern ASM_PFX(SecPlatformInit)   ; @todo: needs a weak implementation\r
+extern ASM_PFX(SecCarInit)\r
+\r
+;\r
+; Define the data length that we saved on the stack top\r
+;\r
+DATA_LEN_OF_PER0         EQU   18h\r
+DATA_LEN_OF_MCUD         EQU   18h\r
+DATA_LEN_AT_STACK_TOP    EQU   (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
+\r
+;\r
+; @todo: These structures are moved from MicrocodeLoadNasm.inc to avoid\r
+;        build error. This needs to be fixed later on.\r
+;\r
+struc MicrocodeHdr\r
+    .MicrocodeHdrVersion:      resd    1\r
+    .MicrocodeHdrRevision:     resd    1\r
+    .MicrocodeHdrDate:         resd    1\r
+    .MicrocodeHdrProcessor:    resd    1\r
+    .MicrocodeHdrChecksum:     resd    1\r
+    .MicrocodeHdrLoader:       resd    1\r
+    .MicrocodeHdrFlags:        resd    1\r
+    .MicrocodeHdrDataSize:     resd    1\r
+    .MicrocodeHdrTotalSize:    resd    1\r
+    .MicrocodeHdrRsvd:         resd    3\r
+    .size:\r
+endstruc\r
+\r
+struc ExtSigHdr\r
+    .ExtSigHdrCount:          resd    1\r
+    .ExtSigHdrChecksum:       resd    1\r
+    .ExtSigHdrRsvd:           resd    3\r
+    .size:\r
+endstruc\r
+\r
+struc ExtSig\r
+    .ExtSigProcessor:         resd    1\r
+    .ExtSigFlags:             resd    1\r
+    .ExtSigChecksum:          resd    1\r
+    .size:\r
+endstruc\r
+\r
+struc LoadMicrocodeParamsFsp24\r
+    ; FSP_UPD_HEADER {\r
+    .FspUpdHeaderSignature:   resd    2\r
+    .FspUpdHeaderRevision:    resb    1\r
+    .FspUpdHeaderReserved:    resb   23\r
+    ; }\r
+    ; FSPT_ARCH2_UPD {\r
+    .FsptArchRevision:        resb    1\r
+    .FsptArchReserved:        resb    3\r
+    .FsptArchLength:          resd    1\r
+    .FspDebugHandler          resq    1\r
+    .FsptArchUpd:             resd    4\r
+    ; }\r
+    ; FSPT_CORE_UPD {\r
+    .MicrocodeCodeAddr:       resq    1\r
+    .MicrocodeCodeSize:       resq    1\r
+    .CodeRegionBase:          resq    1\r
+    .CodeRegionSize:          resq    1\r
+    ; }\r
+    .size:\r
+endstruc\r
+\r
+;\r
+; @todo: The strong/weak implementation does not work.\r
+;        This needs to be reviewed later.\r
+;\r
+;------------------------------------------------------------------------------\r
+;\r
+;;global ASM_PFX(SecPlatformInitDefault)\r
+;ASM_PFX(SecPlatformInitDefault):\r
+;   ; Inputs:\r
+;   ;   ymm7 -> Return address\r
+;   ; Outputs:\r
+;   ;   rax -> 0 - Successful, Non-zero - Failed.\r
+;   ; Register Usage:\r
+;   ;   rax is cleared and rbp is used for return address.\r
+;   ;   All others reserved.\r
+;\r
+;   ; Save return address to RBP\r
+;   LOAD_RBP\r
+;\r
+;   xor   rax, rax\r
+;Exit1:\r
+;   jmp   rbp\r
+\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(LoadMicrocodeDefault)\r
+ASM_PFX(LoadMicrocodeDefault):\r
+   ; Inputs:\r
+   ;   rsp -> LoadMicrocodeParams pointer\r
+   ; Register Usage:\r
+   ;   rsp  Preserved\r
+   ;   All others destroyed\r
+   ; Assumptions:\r
+   ;   No memory available, stack is hard-coded and used for return address\r
+   ;   Executed by SBSP and NBSP\r
+   ;   Beginning of microcode update region starts on paragraph boundary\r
+\r
+   ;\r
+   ; Save return address to RBP\r
+   ;\r
+   LOAD_RBP\r
+\r
+   cmp    rsp, 0\r
+   jz     ParamError\r
+   mov    eax, dword [rsp + 8]    ; Parameter pointer\r
+   cmp    eax, 0\r
+   jz     ParamError\r
+   mov    esp, eax\r
+\r
+   ; skip loading Microcode if the MicrocodeCodeSize is zero\r
+   ; and report error if size is less than 2k\r
+   ; first check UPD header revision\r
+   cmp    byte [rsp + LoadMicrocodeParamsFsp24.FspUpdHeaderRevision], 2\r
+   jb     ParamError\r
+   cmp    byte [rsp + LoadMicrocodeParamsFsp24.FsptArchRevision], 2\r
+   jne    ParamError\r
+\r
+   ; UPD structure is compliant with FSP spec 2.4\r
+   mov    eax, dword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeSize]\r
+   cmp    eax, 0\r
+   jz     Exit2\r
+   cmp    eax, 0800h\r
+   jl     ParamError\r
+\r
+   mov    esi, dword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr]\r
+   cmp    esi, 0\r
+   jnz    CheckMainHeader\r
+\r
+ParamError:\r
+   mov    rax, 08000000000000002h\r
+   jmp    Exit2\r
+\r
+CheckMainHeader:\r
+   ; Get processor signature and platform ID from the installed processor\r
+   ; and save into registers for later use\r
+   ; ebx = processor signature\r
+   ; edx = platform ID\r
+   mov   eax, 1\r
+   cpuid\r
+   mov   ebx, eax\r
+   mov   ecx, MSR_IA32_PLATFORM_ID\r
+   rdmsr\r
+   mov   ecx, edx\r
+   shr   ecx, 50-32                          ; shift (50d-32d=18d=0x12) bits\r
+   and   ecx, 7h                             ; platform id at bit[52..50]\r
+   mov   edx, 1\r
+   shl   edx, cl\r
+\r
+   ; Current register usage\r
+   ; esp -> stack with parameters\r
+   ; esi -> microcode update to check\r
+   ; ebx = processor signature\r
+   ; edx = platform ID\r
+\r
+   ; Check for valid microcode header\r
+   ; Minimal test checking for header version and loader version as 1\r
+   mov   eax, dword 1\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax\r
+   jne   AdvanceFixedSize\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax\r
+   jne   AdvanceFixedSize\r
+\r
+   ; Check if signature and plaform ID match\r
+   cmp   ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor]\r
+   jne   LoadMicrocodeDefault1\r
+   test  edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ]\r
+   jnz   LoadCheck  ; Jif signature and platform ID match\r
+\r
+LoadMicrocodeDefault1:\r
+   ; Check if extended header exists\r
+   ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid\r
+   xor   rax, rax\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax\r
+   je    NextMicrocode\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax\r
+   je    NextMicrocode\r
+\r
+   ; Then verify total size - sizeof header > data size\r
+   mov   ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]\r
+   sub   ecx, MicrocodeHdr.size\r
+   cmp   ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]\r
+   jng   NextMicrocode    ; Jif extended header does not exist\r
+\r
+   ; Set edi -> extended header\r
+   mov   edi, esi\r
+   add   edi, MicrocodeHdr.size\r
+   add   edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]\r
+\r
+   ; Get count of extended structures\r
+   mov   ecx, dword [edi + ExtSigHdr.ExtSigHdrCount]\r
+\r
+   ; Move pointer to first signature structure\r
+   add   edi, ExtSigHdr.size\r
+\r
+CheckExtSig:\r
+   ; Check if extended signature and platform ID match\r
+   cmp   dword [edi + ExtSig.ExtSigProcessor], ebx\r
+   jne   LoadMicrocodeDefault2\r
+   test  dword [edi + ExtSig.ExtSigFlags], edx\r
+   jnz   LoadCheck      ; Jif signature and platform ID match\r
+LoadMicrocodeDefault2:\r
+   ; Check if any more extended signatures exist\r
+   add   edi, ExtSig.size\r
+   loop  CheckExtSig\r
+\r
+NextMicrocode:\r
+   ; Advance just after end of this microcode\r
+   xor   rax, rax\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax\r
+   je    LoadMicrocodeDefault3\r
+   add   esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]\r
+   jmp   CheckAddress\r
+LoadMicrocodeDefault3:\r
+   add   esi, dword  2048\r
+   jmp   CheckAddress\r
+\r
+AdvanceFixedSize:\r
+   ; Advance by 4X dwords\r
+   add   esi, dword  1024\r
+\r
+CheckAddress:\r
+   ; Check UPD header revision\r
+   cmp   byte [rsp + LoadMicrocodeParamsFsp24.FspUpdHeaderRevision], 2\r
+   jb    ParamError\r
+   cmp   byte [rsp + LoadMicrocodeParamsFsp24.FsptArchRevision], 2\r
+   jne   ParamError\r
+\r
+   ; UPD structure is compliant with FSP spec 2.4\r
+   ; Is automatic size detection ?\r
+   mov   rax, qword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeSize]\r
+   cmp   rax, 0ffffffffffffffffh\r
+   jz    LoadMicrocodeDefault4\r
+\r
+   ; Address >= microcode region address + microcode region size?\r
+   add   rax, qword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr]\r
+   cmp   rsi, rax\r
+   jae   Done        ;Jif address is outside of microcode region\r
+   jmp   CheckMainHeader\r
+\r
+LoadMicrocodeDefault4:\r
+   ; Is valid Microcode start point ?\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh\r
+   jz    Done\r
+\r
+LoadCheck:\r
+   ; Get the revision of the current microcode update loaded\r
+   mov   ecx, MSR_IA32_BIOS_SIGN_ID\r
+   xor   eax, eax               ; Clear EAX\r
+   xor   edx, edx               ; Clear EDX\r
+   wrmsr                        ; Load 0 to MSR at 8Bh\r
+\r
+   mov   eax, 1\r
+   cpuid\r
+   mov   ecx, MSR_IA32_BIOS_SIGN_ID\r
+   rdmsr                        ; Get current microcode signature\r
+\r
+   ; Verify this microcode update is not already loaded\r
+   cmp   dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx\r
+   je    Continue\r
+\r
+LoadMicrocode:\r
+   ; EAX contains the linear address of the start of the Update Data\r
+   ; EDX contains zero\r
+   ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)\r
+   ; Start microcode load with wrmsr\r
+   mov   eax, esi\r
+   add   eax, MicrocodeHdr.size\r
+   xor   edx, edx\r
+   mov   ecx, MSR_IA32_BIOS_UPDT_TRIG\r
+   wrmsr\r
+   mov   eax, 1\r
+   cpuid\r
+\r
+Continue:\r
+   jmp   NextMicrocode\r
+\r
+Done:\r
+   mov   eax, 1\r
+   cpuid\r
+   mov   ecx, MSR_IA32_BIOS_SIGN_ID\r
+   rdmsr                         ; Get current microcode signature\r
+   xor   eax, eax\r
+   cmp   edx, 0\r
+   jnz   Exit2\r
+   mov   eax, 0800000000000000Eh\r
+\r
+Exit2:\r
+   jmp   rbp\r
+\r
+\r
+global ASM_PFX(EstablishStackFsp)\r
+ASM_PFX(EstablishStackFsp):\r
+  ;\r
+  ; Save parameter pointer in rdx\r
+  ;\r
+  mov       rdx, qword [rsp + 8]\r
+\r
+  ;\r
+  ; Enable FSP STACK\r
+  ;\r
+  mov       rax, ASM_PFX(PcdGet32 (PcdTemporaryRamBase))\r
+  mov       esp, DWORD[rax]\r
+  mov       rax, ASM_PFX(PcdGet32 (PcdTemporaryRamSize))\r
+  add       esp, DWORD[rax]\r
+\r
+  sub       esp, 4\r
+  mov       dword[esp], DATA_LEN_OF_MCUD ; Size of the data region\r
+  sub       esp, 4\r
+  mov       dword[esp], 4455434Dh        ; Signature of the  data region 'MCUD'\r
+\r
+  ; check UPD structure revision (rdx + 8)\r
+  cmp       byte [rdx + LoadMicrocodeParamsFsp24.FspUpdHeaderRevision], 2\r
+  jb        ParamError1\r
+  cmp       byte [rdx + LoadMicrocodeParamsFsp24.FsptArchRevision], 2\r
+  je        Fsp24UpdHeader\r
+\r
+ParamError1:\r
+  mov       rax, 08000000000000002h\r
+  jmp       EstablishStackFspExit\r
+\r
+Fsp24UpdHeader:\r
+  ; UPD structure is compliant with FSP spec 2.4\r
+  xor       rax, rax\r
+  mov       rax, qword [rdx + LoadMicrocodeParamsFsp24.CodeRegionSize]     ; Code size       sizeof(FSPT_UPD_COMMON) + 18h\r
+  sub       rsp, 8\r
+  mov       qword[rsp], rax\r
+  mov       rax, qword [rdx + LoadMicrocodeParamsFsp24.CodeRegionBase]     ; Code base       sizeof(FSPT_UPD_COMMON) + 10h\r
+  sub       rsp, 8\r
+  mov       qword[rsp], rax\r
+  mov       rax, qword [rdx + LoadMicrocodeParamsFsp24.MicrocodeCodeSize]  ; Microcode size  sizeof(FSPT_UPD_COMMON) + 8h\r
+  sub       rsp, 8\r
+  mov       qword[rsp], rax\r
+  mov       rax, qword [rdx + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr]  ; Microcode base  sizeof(FSPT_UPD_COMMON) + 0h\r
+  sub       rsp, 8\r
+  mov       qword[rsp], rax\r
+\r
+ContinueAfterUpdPush:\r
+  ;\r
+  ; Save API entry/exit timestamp into stack\r
+  ;\r
+  sub       esp, 4\r
+  mov       dword[esp], DATA_LEN_OF_PER0 ; Size of the data region\r
+  sub       esp, 4\r
+  mov       dword[esp], 30524550h        ; Signature of the  data region 'PER0'\r
+  rdtsc\r
+  sub       esp, 4\r
+  mov       dword[esp], edx\r
+  sub       esp, 4\r
+  mov       dword[esp], eax\r
+  LOAD_TS   rax\r
+  push      rax\r
+\r
+  ;\r
+  ; Terminator for the data on stack\r
+  ;\r
+  push      0\r
+\r
+  ;\r
+  ; Set ECX/EDX to the BootLoader temporary memory range\r
+  ;\r
+  mov       rcx, ASM_PFX(PcdGet32 (PcdTemporaryRamBase))\r
+  mov       edx, [ecx]\r
+  mov       rcx, ASM_PFX(PcdGet32 (PcdTemporaryRamSize))\r
+  add       edx, [ecx]\r
+  mov       rcx, ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))\r
+  sub       edx, [ecx]\r
+  mov       rcx, ASM_PFX(PcdGet32 (PcdTemporaryRamBase))\r
+  mov       ecx, [ecx]\r
+\r
+  cmp       ecx, edx                 ; If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error.\r
+  jb        EstablishStackFspSuccess\r
+  mov       rax, 08000000000000003h  ; EFI_UNSUPPORTED\r
+  jmp       EstablishStackFspExit\r
+EstablishStackFspSuccess:\r
+  xor       rax, rax\r
+\r
+EstablishStackFspExit:\r
+  RET_YMM\r
+\r
+;----------------------------------------------------------------------------\r
+; TempRamInit API\r
+;\r
+; This FSP API will load the microcode update, enable code caching for the\r
+; region specified by the boot loader and also setup a temporary stack to be\r
+; used till main memory is initialized.\r
+;\r
+;----------------------------------------------------------------------------\r
+global ASM_PFX(TempRamInitApi)\r
+ASM_PFX(TempRamInitApi):\r
+  ;\r
+  ; Ensure both SSE and AVX are enabled\r
+  ;\r
+  ENABLE_SSE\r
+  ENABLE_AVX\r
+\r
+  ;\r
+  ; Save RBP, RBX, RSI, RDI and RSP in YMM7, YMM8 and YMM6\r
+  ;\r
+  SAVE_REGS\r
+\r
+  ;\r
+  ; Save BFV address in YMM9\r
+  ;\r
+  SAVE_BFV  rbp\r
+\r
+  ;\r
+  ; Save timestamp into YMM6\r
+  ;\r
+  rdtsc\r
+  shl       rdx, 32\r
+  or        rax, rdx\r
+  SAVE_TS   rax\r
+\r
+  ;\r
+  ; Check Parameter\r
+  ;\r
+  mov       rax, qword [rsp + 8]\r
+  cmp       rax, 0\r
+  mov       rax, 08000000000000002h\r
+  jz        TempRamInitExit\r
+\r
+  ;\r
+  ; Sec Platform Init\r
+  ;\r
+  CALL_YMM  ASM_PFX(SecPlatformInit)\r
+  cmp       eax, 0\r
+  jnz       TempRamInitExit\r
+\r
+  ; Load microcode\r
+  LOAD_RSP\r
+  CALL_YMM  ASM_PFX(LoadMicrocodeDefault)\r
+  SAVE_UCODE_STATUS rax             ; Save microcode return status in SLOT 0 in YMM9 (upper 128bits).\r
+  ; @note If return value rax is not 0, microcode did not load, but continue and attempt to boot.\r
+\r
+  ; Call Sec CAR Init\r
+  LOAD_RSP\r
+  CALL_YMM  ASM_PFX(SecCarInit)\r
+  cmp       rax, 0\r
+  jnz       TempRamInitExit\r
+\r
+  LOAD_RSP\r
+  CALL_YMM  ASM_PFX(EstablishStackFsp)\r
+  cmp       rax, 0\r
+  jnz       TempRamInitExit\r
+\r
+  LOAD_UCODE_STATUS rax             ; Restore microcode status if no CAR init error from SLOT 0 in YMM9 (upper 128bits).\r
+\r
+TempRamInitExit:\r
+  mov       bl, al                  ; save al data in bl\r
+  mov       al, 07Fh                ; API exit postcode 7f\r
+  out       080h, al\r
+  mov       al, bl                  ; restore al data from bl\r
+\r
+  ;\r
+  ; Load RBP, RBX, RSI, RDI and RSP from YMM7, YMM8 and YMM6\r
+  ;\r
+  LOAD_REGS\r
+  LOAD_BFV  rbp\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/FspHelper.nasm b/IntelFsp2Pkg/FspSecCore/X64/FspHelper.nasm
new file mode 100644 (file)
index 0000000..122fa1d
--- /dev/null
@@ -0,0 +1,34 @@
+;; @file\r
+;  Provide FSP helper function.\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;;\r
+    DEFAULT  REL\r
+    SECTION .text\r
+\r
+global ASM_PFX(AsmGetFspBaseAddress)\r
+ASM_PFX(AsmGetFspBaseAddress):\r
+   call  ASM_PFX(AsmGetFspInfoHeader)\r
+   add   rax, 0x1C\r
+   mov   eax, [rax]\r
+   ret\r
+\r
+global ASM_PFX(AsmGetFspInfoHeader)\r
+ASM_PFX(AsmGetFspInfoHeader):\r
+   lea   rax, [ASM_PFX(AsmGetFspInfoHeader)]\r
+   DB    0x48, 0x2d               ; sub rax, 0x????????\r
+global ASM_PFX(FspInfoHeaderRelativeOff)\r
+ASM_PFX(FspInfoHeaderRelativeOff):\r
+   DD    0x12345678               ; This value must be patched by the build script\r
+   and   rax, 0xffffffff\r
+   ret\r
+\r
+global ASM_PFX(AsmGetFspInfoHeaderNoStack)\r
+ASM_PFX(AsmGetFspInfoHeaderNoStack):\r
+   lea   rax, [ASM_PFX(AsmGetFspInfoHeader)]\r
+   lea   rcx, [ASM_PFX(FspInfoHeaderRelativeOff)]\r
+   mov   ecx, [rcx]\r
+   sub   rax, rcx\r
+   and   rax, 0xffffffff\r
+   jmp   rdi\r
diff --git a/IntelFsp2Pkg/FspSecCore/X64/MicrocodeLoadNasm.inc b/IntelFsp2Pkg/FspSecCore/X64/MicrocodeLoadNasm.inc
new file mode 100644 (file)
index 0000000..4ec5070
--- /dev/null
@@ -0,0 +1,11 @@
+;; @file\r
+;\r
+;@copyright\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;;\r
+\r
+MSR_IA32_PLATFORM_ID        equ     000000017h\r
+MSR_IA32_BIOS_UPDT_TRIG     equ     000000079h\r
+MSR_IA32_BIOS_SIGN_ID       equ     00000008bh\r
+\r
diff --git a/IntelFsp2Pkg/FspSecCore/X64/ReadRsp.nasm b/IntelFsp2Pkg/FspSecCore/X64/ReadRsp.nasm
new file mode 100644 (file)
index 0000000..af82509
--- /dev/null
@@ -0,0 +1,22 @@
+;; @file\r
+;  Provide read RSP function\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;;\r
+;------------------------------------------------------------------------------\r
+\r
+    SECTION .text\r
+\r
+;------------------------------------------------------------------------------\r
+; UINTN\r
+; EFIAPI\r
+; AsmReadStackPointer (\r
+;   VOID\r
+;   );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(AsmReadStackPointer)\r
+ASM_PFX(AsmReadStackPointer):\r
+    mov     rax, rsp\r
+    ret\r
+\r
diff --git a/IntelFsp2Pkg/FspSecCore/X64/Stack.nasm b/IntelFsp2Pkg/FspSecCore/X64/Stack.nasm
new file mode 100644 (file)
index 0000000..0af7f54
--- /dev/null
@@ -0,0 +1,73 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+; Abstract:\r
+;\r
+;   Switch the stack from temporary memory to permanent memory.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+    SECTION .text\r
+\r
+;------------------------------------------------------------------------------\r
+; VOID\r
+; EFIAPI\r
+; SecSwitchStack (\r
+;   UINT64   TemporaryMemoryBase,\r
+;   UINT64   PermanentMemoryBase\r
+;   );\r
+;------------------------------------------------------------------------------\r
+global ASM_PFX(SecSwitchStack)\r
+ASM_PFX(SecSwitchStack):\r
+    ;\r
+    ; Save four register: rax, rbx, rcx, rdx\r
+    ;\r
+    push  rax\r
+    push  rbx\r
+    push  rcx\r
+    push  rdx\r
+\r
+    ;\r
+    ; !!CAUTION!! this function address's is pushed into stack after\r
+    ; migration of whole temporary memory, so need save it to permanent\r
+    ; memory at first!\r
+    ;\r
+\r
+    mov   rbx, rcx                 ; Save the first parameter\r
+    mov   rcx, rdx                 ; Save the second parameter\r
+\r
+    ;\r
+    ; Save this function's return address into permanent memory at first.\r
+    ; Then, Fixup the esp point to permanent memory\r
+    ;\r
+    mov   rax, rsp\r
+    sub   rax, rbx\r
+    add   rax, rcx\r
+    mov   rdx, qword [rsp]         ; copy pushed register's value to permanent memory\r
+    mov   qword [rax], rdx\r
+    mov   rdx, qword [rsp + 8]\r
+    mov   qword [rax + 8], rdx\r
+    mov   rdx, qword [rsp + 16]\r
+    mov   qword [rax + 16], rdx\r
+    mov   rdx, qword [rsp + 24]\r
+    mov   qword [rax + 24], rdx\r
+    mov   rdx, qword [rsp + 32]    ; Update this function's return address into permanent memory\r
+    mov   qword [rax + 32], rdx\r
+    mov   rsp, rax                 ; From now, rsp is pointed to permanent memory\r
+\r
+    ;\r
+    ; Fixup the rbp point to permanent memory\r
+    ;\r
+    mov   rax, rbp\r
+    sub   rax, rbx\r
+    add   rax, rcx\r
+    mov   rbp, rax                 ; From now, rbp is pointed to permanent memory\r
+\r
+    pop   rdx\r
+    pop   rcx\r
+    pop   rbx\r
+    pop   rax\r
+    ret\r
+\r
index e5a9d7a2b4bcd8b074b39df8cfee03073b9097a3..c660defac367506b7f28a3ef1a79debf06fbcad6 100644 (file)
@@ -2,11 +2,13 @@
   Intel FSP Header File definition from Intel Firmware Support Package External\r
   Architecture Specification v2.0 and above.\r
 \r
-  Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
+#include <Base.h>\r
+\r
 #ifndef __FSP_HEADER_FILE_H__\r
 #define __FSP_HEADER_FILE_H__\r
 \r
 \r
 #define FSP_INFO_HEADER_SIGNATURE  SIGNATURE_32 ('F', 'S', 'P', 'H')\r
 \r
+#define IMAGE_ATTRIBUTE_GRAPHICS_SUPPORT      BIT0\r
+#define IMAGE_ATTRIBUTE_DISPATCH_MODE_SUPPORT BIT1\r
+#define IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT    BIT2\r
+#define FSP_IA32                              0\r
+#define FSP_X64                               1\r
+\r
 #pragma pack(1)\r
 \r
 ///\r
@@ -49,7 +57,7 @@ typedef struct {
   UINT8     SpecVersion;\r
   ///\r
   /// Byte 0x0B: Revision of the FSP Information Header.\r
-  ///            The Current value for this field is 0x6.\r
+  ///            The Current value for this field is 0x7.\r
   ///\r
   UINT8     HeaderRevision;\r
   ///\r
@@ -82,6 +90,10 @@ typedef struct {
   UINT32    ImageBase;\r
   ///\r
   /// Byte 0x20: Attribute for the FSP binary.\r
+  ///   Bit 0: Graphics Support - Set to 1 when FSP supports enabling Graphics Display.\r
+  ///   Bit 1: Dispatch Mode Support - Set to 1 when FSP supports the optional Dispatch Mode API defined in Section 7.2 and 9. This bit is only valid if FSP HeaderRevision is >= 4.\r
+  ///   Bit 2: 64-bit mode support - Set to 1 to indicate FSP supports 64-bit long mode interfaces. Set to 0 to indicate FSP supports 32-bit mode interfaces. This bit is only valid if FSP HeaderRevision is >= 7.\r
+  ///   Bits 15:3 - Reserved\r
   ///\r
   UINT16    ImageAttribute;\r
   ///\r
diff --git a/IntelFsp2Pkg/Include/SaveRestoreSseAvxNasm.inc b/IntelFsp2Pkg/Include/SaveRestoreSseAvxNasm.inc
new file mode 100644 (file)
index 0000000..e8bd916
--- /dev/null
@@ -0,0 +1,284 @@
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+; Abstract:\r
+;\r
+;   Provide macro for register save/restore using SSE registers\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+;\r
+; Define SSE and AVX instruction set\r
+;\r
+;\r
+; Define SSE macros using SSE 4.1 instructions\r
+; args 1:XMM, 2:IDX, 3:REG\r
+;\r
+%macro SXMMN        3\r
+            pinsrq  %1, %3, (%2 & 3)\r
+            %endmacro\r
+\r
+;\r
+; args 1:XMM, 2:REG, 3:IDX\r
+;\r
+%macro LXMMN        3\r
+            pextrq  %2, %1, (%3 & 3)\r
+            %endmacro\r
+\r
+;\r
+; Define AVX macros using AVX instructions\r
+; Save XMM to YMM\r
+; args 1:YMM, 2:IDX (0 - lower 128bits, 1 - upper 128bits), 3:XMM\r
+;\r
+%macro SYMMN        3\r
+            vinsertf128  %1, %1, %3, %2\r
+            %endmacro\r
+\r
+;\r
+; Restore XMM from YMM\r
+; args 1:YMM, 2:XMM, 3:IDX (0 - lower 128bits, 1 - upper 128bits)\r
+;\r
+%macro LYMMN        3\r
+            vextractf128  %2, %1, %3\r
+            %endmacro\r
+\r
+;\r
+; Upper half of YMM7 to save RBP and RBX. Upper half of YMM8 to save RSI and RDI.\r
+; Modified: XMM5, YMM6, YMM7 and YMM8\r
+;\r
+%macro SAVE_REGS    0\r
+            SXMMN   xmm5, 0, rbp\r
+            SXMMN   xmm5, 1, rbx\r
+            SYMMN   ymm7, 1, xmm5\r
+            SXMMN   xmm5, 0, rsi\r
+            SXMMN   xmm5, 1, rdi\r
+            SYMMN   ymm8, 1, xmm5\r
+            SAVE_RSP\r
+            %endmacro\r
+\r
+;\r
+; Upper half of YMM7 to restore RBP and RBX. Upper half of YMM8 to restore RSI and RDI.\r
+; Modified: XMM5, RBP, RBX, RSI, RDI and RSP\r
+;\r
+%macro LOAD_REGS    0\r
+            LYMMN   ymm7, xmm5, 1\r
+            LXMMN   xmm5, rbp, 0\r
+            LXMMN   xmm5, rbx, 1\r
+            LYMMN   ymm8, xmm5, 1\r
+            LXMMN   xmm5, rsi, 0\r
+            LXMMN   xmm5, rdi, 1\r
+            LOAD_RSP\r
+            %endmacro\r
+;\r
+; Restore RBP from YMM7[128:191]\r
+; Modified: XMM5 and RBP\r
+;\r
+%macro LOAD_RBP     0\r
+            LYMMN   ymm7, xmm5, 1\r
+            movq    rbp,  xmm5\r
+            %endmacro\r
+\r
+;\r
+; Restore RBX from YMM7[192:255]\r
+; Modified: XMM5 and RBX\r
+;\r
+%macro LOAD_RBX     0\r
+            LYMMN   ymm7, xmm5, 1\r
+            LXMMN   xmm5, rbx, 1\r
+            %endmacro\r
+\r
+;\r
+; Upper half of YMM6 to save/restore Time Stamp, RSP\r
+;\r
+;\r
+; Save Time Stamp to YMM6[192:255]\r
+; arg 1:general purpose register which holds time stamp\r
+; Modified: XMM5 and YMM6\r
+;\r
+%macro SAVE_TS      1\r
+            LYMMN   ymm6, xmm5, 1\r
+            SXMMN   xmm5, 1, %1\r
+            SYMMN   ymm6, 1, xmm5\r
+            %endmacro\r
+\r
+;\r
+; Restore Time Stamp from YMM6[192:255]\r
+; arg 1:general purpose register where to save time stamp\r
+; Modified: XMM5 and %1\r
+;\r
+%macro LOAD_TS      1\r
+            LYMMN   ymm6, xmm5, 1\r
+            LXMMN   xmm5, %1, 1\r
+            %endmacro\r
+\r
+;\r
+; Save RSP to YMM6[128:191]\r
+; Modified: XMM5 and YMM6\r
+;\r
+%macro SAVE_RSP     0\r
+            LYMMN   ymm6, xmm5, 1\r
+            SXMMN   xmm5, 0, rsp\r
+            SYMMN   ymm6, 1, xmm5\r
+            %endmacro\r
+\r
+;\r
+; Restore RSP from YMM6[128:191]\r
+; Modified: XMM5 and RSP\r
+;\r
+%macro LOAD_RSP     0\r
+            LYMMN   ymm6, xmm5, 1\r
+            movq    rsp,  xmm5\r
+            %endmacro\r
+\r
+;\r
+; Upper half of YMM9 to save/restore UCODE status, BFV address\r
+;\r
+;\r
+; Save uCode status to YMM9[192:255]\r
+; arg 1:general purpose register which holds uCode status\r
+; Modified: XMM5 and YMM9\r
+;\r
+%macro SAVE_UCODE_STATUS     1\r
+            LYMMN   ymm9, xmm5, 1\r
+            SXMMN   xmm5, 0, %1\r
+            SYMMN   ymm9, 1, xmm5\r
+            %endmacro\r
+\r
+;\r
+; Restore uCode status from YMM9[192:255]\r
+; arg 1:general purpose register where to save uCode status\r
+; Modified: XMM5 and %1\r
+;\r
+%macro LOAD_UCODE_STATUS     1\r
+            LYMMN   ymm9, xmm5, 1\r
+            movq    %1,  xmm5\r
+            %endmacro\r
+\r
+;\r
+; Save BFV address to YMM9[128:191]\r
+; arg 1:general purpose register which holds BFV address\r
+; Modified: XMM5 and YMM9\r
+;\r
+%macro SAVE_BFV     1\r
+            LYMMN   ymm9, xmm5, 1\r
+            SXMMN   xmm5, 1, %1\r
+            SYMMN   ymm9, 1, xmm5\r
+            %endmacro\r
+\r
+;\r
+; Restore BFV address from YMM9[128:191]\r
+; arg 1:general purpose register where to save BFV address\r
+; Modified: XMM5 and %1\r
+;\r
+%macro LOAD_BFV     1\r
+            LYMMN   ymm9, xmm5, 1\r
+            LXMMN   xmm5, %1, 1\r
+            %endmacro\r
+\r
+;\r
+; YMM7[128:191] for calling stack\r
+; arg 1:Entry\r
+; Modified: RSI, XMM5, YMM7\r
+;\r
+%macro CALL_YMM     1\r
+            mov     rsi, %%ReturnAddress\r
+            LYMMN   ymm7, xmm5, 1\r
+            SXMMN   xmm5, 0, rsi\r
+            SYMMN   ymm7, 1, xmm5\r
+            mov     rsi,  %1\r
+            jmp     rsi\r
+%%ReturnAddress:\r
+            %endmacro\r
+;\r
+; Restore RIP from YMM7[128:191]\r
+; Modified: RSI, XMM5\r
+;\r
+%macro RET_YMM      0\r
+            LYMMN   ymm7, xmm5, 1\r
+            movq    rsi, xmm5\r
+            jmp     rsi\r
+            %endmacro\r
+\r
+%macro ENABLE_SSE   0\r
+            ;\r
+            ; Initialize floating point units\r
+            ;\r
+            jmp     NextAddress\r
+align 4\r
+            ;\r
+            ; Float control word initial value:\r
+            ; all exceptions masked, double-precision, round-to-nearest\r
+            ;\r
+FpuControlWord       DW      027Fh\r
+            ;\r
+            ; Multimedia-extensions control word:\r
+            ; all exceptions masked, round-to-nearest, flush to zero for masked underflow\r
+            ;\r
+MmxControlWord       DQ      01F80h\r
+SseError:\r
+            ;\r
+            ; Processor has to support SSE\r
+            ;\r
+            jmp     SseError\r
+NextAddress:\r
+            finit\r
+            mov rax, FpuControlWord\r
+            fldcw [rax]\r
+\r
+            ;\r
+            ; Use CpuId instruction (CPUID.01H:EDX.SSE[bit 25] = 1) to test\r
+            ; whether the processor supports SSE instruction.\r
+            ;\r
+            mov     rax, 1\r
+            cpuid\r
+            bt      rdx, 25\r
+            jnc     SseError\r
+\r
+            ;\r
+            ; SSE 4.1 support\r
+            ;\r
+            bt      ecx, 19\r
+            jnc     SseError\r
+\r
+            ;\r
+            ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+            ;\r
+            mov     rax, cr4\r
+            or      rax, 00000600h\r
+            mov     cr4, rax\r
+\r
+            ;\r
+            ; The processor should support SSE instruction and we can use\r
+            ; ldmxcsr instruction\r
+            ;\r
+            mov  rax, MmxControlWord\r
+            ldmxcsr [rax]\r
+            %endmacro\r
+\r
+%macro ENABLE_AVX   0\r
+            mov     eax, 1\r
+            cpuid\r
+            and     ecx, 10000000h\r
+            cmp     ecx, 10000000h ; check AVX feature flag\r
+            je      EnableAvx\r
+AvxError:\r
+            ;\r
+            ; Processor has to support AVX\r
+            ;\r
+            jmp     AvxError\r
+EnableAvx:\r
+            ;\r
+            ; Set OSXSAVE bit (bit #18) to enable xgetbv/xsetbv instruction\r
+            ;\r
+            mov     rax, cr4\r
+            or      rax, 00040000h\r
+            mov     cr4, rax\r
+\r
+            mov     rcx, 0         ; index 0\r
+            xgetbv                 ; result in edx:eax\r
+            or      eax, 00000006h ; Set XCR0 bit #1 and bit #2 to enable SSE state and AVX state\r
+            xsetbv\r
+            %endmacro\r
+\r
index cd10b63c95d35d1debbf3a718df835bab8d014bc..67e08a9e7eb4cb91702266baf5723171bf7e0752 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -38,7 +38,8 @@ typedef struct {
 } CONTEXT_STACK;\r
 \r
 //\r
-//   API return address           +0xB0\r
+//   API return address           +0xB8\r
+//   Reserved                     +0xB0\r
 //   push    API Parameter2       +0xA8\r
 //   push    API Parameter1       +0xA0\r
 //   push    FspInfoHeader        +0x98\r
@@ -54,6 +55,7 @@ typedef struct {
   UINT32    Flags[2];\r
   UINT64    FspInfoHeader;\r
   UINT64    ApiParam[2];\r
+  UINT64    Reserved;       // The reserved QWORD is needed for stack alignment in X64.\r
   UINT64    ApiRet;         // 64bit stack format is different from the 32bit one due to x64 calling convention\r
 } CONTEXT_STACK_64;\r
 \r
index bd36fe4b8b867868c015faa4dc10f85b9c351a94..1ea1220608ef51a91c33ad2cc341a48b74e2dd56 100644 (file)
@@ -47,7 +47,8 @@ ASM_PFX(Loader2PeiSwitchStack):
 ;------------------------------------------------------------------------------\r
 global ASM_PFX(FspSwitchStack)\r
 ASM_PFX(FspSwitchStack):\r
-    ; Save current contexts\r
+    ; Save current contexts. The format must align with CONTEXT_STACK_64.\r
+    push    rdx     ; Reserved QWORD for stack alignment\r
     push    rdx     ; ApiParam2\r
     push    rcx     ; ApiParam1\r
     push    rax     ; FspInfoHeader\r
@@ -67,6 +68,6 @@ ASM_PFX(FspSwitchStack):
     add     rsp, 16\r
     POPA_64\r
     popfq\r
-    add     rsp, 24 ; FspInfoHeader + ApiParam[2]\r
+    add     rsp, 32 ; FspInfoHeader + ApiParam[2] + Reserved QWORD\r
     ret\r
 \r