IntelFsp2WrapperPkg: SecFspWrapperPlatformSecLibSample support for X64

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3893
1.Added SecFspWrapperPlatformSecLibSample support for X64.
2.Adopted FSPT_ARCH2_UPD in SecFspWrapperPlatformSecLibSample.
3.Moved Fsp.h up one level to be shared across IA32 and X64.

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>
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Fsp.h
similarity index 100%
rename from IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Fsp.h
rename to IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Fsp.h
diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
index d7394cf..eb5b120 100644
--- a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/Ia32/Stack.nasm
@@ -1,6 +1,6 @@
 ;------------------------------------------------------------------------------

 ;

-; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>

+; Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>

 ; SPDX-License-Identifier: BSD-2-Clause-Patent

 ;

 ; Abstract:

@@ -22,7 +22,7 @@
 global ASM_PFX(SecSwitchStack)

 ASM_PFX(SecSwitchStack):

     ;

-    ; Save three register: eax, ebx, ecx

+    ; Save four register: eax, ebx, ecx, edx

     ;

     push  eax

     push  ebx

@@ -55,7 +55,7 @@
     mov   dword [eax + 12], edx

     mov   edx, dword [esp + 16]    ; Update this function's return address into permanent memory

     mov   dword [eax + 16], edx

-    mov   esp, eax                     ; From now, esp is pointed to permanent memory

+    mov   esp, eax                 ; From now, esp is pointed to permanent memory

 

     ;

     ; Fixup the ebp point to permanent memory

@@ -63,7 +63,7 @@
     mov   eax, ebp

     sub   eax, ebx

     add   eax, ecx

-    mov   ebp, eax                ; From now, ebp is pointed to permanent memory

+    mov   ebp, eax                 ; From now, ebp is pointed to permanent memory

 

     pop   edx

     pop   ecx

diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
index 027b127..28a8602 100644
--- a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecFspWrapperPlatformSecLibSample.inf
@@ -1,7 +1,7 @@
 ## @file

 #  Sample to provide FSP wrapper platform sec related function.

 #

-#  Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>

+#  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>

 #

 #  SPDX-License-Identifier: BSD-2-Clause-Patent

 #

@@ -39,13 +39,18 @@
   SecGetPerformance.c

   SecTempRamDone.c

   PlatformInit.c

+  Fsp.h

 

 [Sources.IA32]

-  Ia32/Fsp.h

   Ia32/SecEntry.nasm

   Ia32/PeiCoreEntry.nasm

   Ia32/Stack.nasm

 

+[Sources.X64]

+  X64/SecEntry.nasm

+  X64/PeiCoreEntry.nasm

+  X64/Stack.nasm

+

 ################################################################################

 #

 # Package Dependency Section - list of Package files that are required for

diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
index 03616cb..d2acb2f 100644
--- a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/SecRamInitData.c
@@ -1,7 +1,7 @@
 /** @file

   Sample to provide TempRamInitParams data.

 

-  Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>

+  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>

   SPDX-License-Identifier: BSD-2-Clause-Patent

 

 **/

@@ -10,18 +10,20 @@
 #include <FspEas.h>

 

 typedef struct {

-  UINT32    MicrocodeRegionBase;

-  UINT32    MicrocodeRegionSize;

-  UINT32    CodeRegionBase;

-  UINT32    CodeRegionSize;

+  EFI_PHYSICAL_ADDRESS  MicrocodeRegionBase;

+  UINT64                MicrocodeRegionSize;

+  EFI_PHYSICAL_ADDRESS  CodeRegionBase;

+  UINT64                CodeRegionSize;

 } FSPT_CORE_UPD;

 

 typedef struct {

   FSP_UPD_HEADER    FspUpdHeader;

   //

-  // If platform does not support FSP spec 2.2 remove FSPT_ARCH_UPD structure.

+  // If FSP spec version < 2.2, remove FSPT_ARCH_UPD structure.

+  // Else If FSP spec version >= 2.2 and FSP spec version < 2.4, use FSPT_ARCH_UPD structure.

+  // Else, use FSPT_ARCH2_UPD structure.

   //

-  FSPT_ARCH_UPD     FsptArchUpd;

+  FSPT_ARCH2_UPD    FsptArchUpd;

   FSPT_CORE_UPD     FsptCoreUpd;

 } FSPT_UPD_CORE_DATA;

 

@@ -36,10 +38,12 @@
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }

   },

   //

-  // If platform does not support FSP spec 2.2 remove FSPT_ARCH_UPD structure.

+  // If FSP spec version < 2.2, remove FSPT_ARCH_UPD structure.

+  // Else If FSP spec version >= 2.2 and FSP spec version < 2.4, use FSPT_ARCH_UPD structure.

+  // Else, use FSPT_ARCH2_UPD structure.

   //

   {

-    0x01,

+    0x02,

     {

       0x00, 0x00, 0x00

     },

@@ -47,7 +51,7 @@
     0x00000000,

     {

       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00

     }

   },

   {

diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
new file mode 100644
index 0000000..0c0766a
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/PeiCoreEntry.nasm
@@ -0,0 +1,149 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>

+; SPDX-License-Identifier: BSD-2-Clause-Patent

+;

+; Module Name:

+;

+;  PeiCoreEntry.nasm

+;

+; Abstract:

+;

+;   Find and call SecStartup

+;

+;------------------------------------------------------------------------------

+

+SECTION .text

+

+%include    "PushPopRegsNasm.inc"

+

+extern ASM_PFX(SecStartup)

+extern ASM_PFX(PlatformInit)

+

+;

+; args 1:XMM, 2:REG, 3:IDX

+;

+%macro LXMMN        3

+            pextrq  %2, %1, (%3 & 3)

+            %endmacro

+

+;

+; args 1:YMM, 2:XMM, 3:IDX (0 - lower 128bits, 1 - upper 128bits)

+;

+%macro LYMMN        3

+            vextractf128  %2, %1, %3

+            %endmacro

+

+%macro LOAD_TS      1

+            LYMMN   ymm6, xmm5, 1

+            LXMMN   xmm5, %1, 1

+            %endmacro

+

+global ASM_PFX(CallPeiCoreEntryPoint)

+ASM_PFX(CallPeiCoreEntryPoint):

+  ;

+  ; Per X64 calling convention, make sure RSP is 16-byte aligned.

+  ;

+  mov     rax, rsp

+  and     rax, 0fh

+  sub     rsp, rax

+

+  ;

+  ; Platform init

+  ;

+  PUSHA_64

+  sub     rsp, 20h

+  call    ASM_PFX(PlatformInit)

+  add     rsp, 20h

+  POPA_64

+

+  ;

+  ; Set stack top pointer

+  ;

+  mov     rsp, r8

+

+  ;

+  ; Push the hob list pointer

+  ;

+  push    rcx

+

+  ;

+  ; RBP holds start of BFV passed from Vtf0. Save it to r10.

+  ;

+  mov     r10, rbp

+

+  ;

+  ; Save the value

+  ;   RDX: start of range

+  ;   r8: end of range

+  ;

+  mov     rbp, rsp

+  push    rdx

+  push    r8

+  mov     r14, rdx

+  mov     r15, r8

+

+  ;

+  ; Push processor count to stack first, then BIST status (AP then BSP)

+  ;

+  mov     eax, 1

+  cpuid

+  shr     ebx, 16

+  and     ebx, 0000000FFh

+  cmp     bl, 1

+  jae     PushProcessorCount

+

+  ;

+  ; Some processors report 0 logical processors.  Effectively 0 = 1.

+  ; So we fix up the processor count

+  ;

+  inc     ebx

+

+PushProcessorCount:

+  sub     rsp, 4

+  mov     rdi, rsp

+  mov     DWORD [rdi], ebx

+

+  ;

+  ; We need to implement a long-term solution for BIST capture.  For now, we just copy BSP BIST

+  ; for all processor threads

+  ;

+  xor     ecx, ecx

+  mov     cl, bl

+PushBist:

+  sub     rsp, 4

+  mov     rdi, rsp

+  movd    eax, mm0

+  mov     DWORD [rdi], eax

+  loop    PushBist

+

+  ; Save Time-Stamp Counter

+  LOAD_TS rax

+  push    rax

+

+  ;

+  ; Pass entry point of the PEI core

+  ;

+  mov     rdi, 0FFFFFFE0h

+  mov     edi, DWORD [rdi]

+  mov     r9, rdi

+

+  ;

+  ; Pass BFV into the PEI Core

+  ;

+  mov     r8, r10

+

+  ;

+  ; Pass stack size into the PEI Core

+  ;

+  mov     rcx, r15  ; Start of TempRam

+  mov     rdx, r14  ; End of TempRam

+

+  sub     rcx, rdx  ; Size of TempRam

+

+  ;

+  ; Pass Control into the PEI Core

+  ;

+  sub     rsp, 20h

+  call ASM_PFX(SecStartup)

+

diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm
new file mode 100644
index 0000000..dbbf633
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/SecEntry.nasm
@@ -0,0 +1,171 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>

+; SPDX-License-Identifier: BSD-2-Clause-Patent

+;

+; Module Name:

+;

+;  SecEntry.asm

+;

+; Abstract:

+;

+;  This is the code that calls TempRamInit API from FSP binary and passes

+;  control into PEI core.

+;

+;------------------------------------------------------------------------------

+

+#include "Fsp.h"

+

+IA32_CR4_OSFXSR           equ        200h

+IA32_CR4_OSXMMEXCPT       equ        400h

+IA32_CR0_MP               equ        2h

+

+IA32_CPUID_SSE2           equ        02000000h

+IA32_CPUID_SSE2_B         equ        26

+

+SECTION .text

+

+extern   ASM_PFX(CallPeiCoreEntryPoint)

+extern   ASM_PFX(FsptUpdDataPtr)

+

+; Pcds

+extern   ASM_PFX(PcdGet32 (PcdFsptBaseAddress))

+

+;----------------------------------------------------------------------------

+;

+; Procedure:    _ModuleEntryPoint

+;

+; Input:        None

+;

+; Output:       None

+;

+; Destroys:     Assume all registers

+;

+; Description:

+;

+;  Call TempRamInit API from FSP binary. After TempRamInit done, pass

+;  control into PEI core.

+;

+; Return:       None

+;

+;  MMX Usage:

+;              MM0 = BIST State

+;

+;----------------------------------------------------------------------------

+

+BITS 64

+align 16

+global ASM_PFX(ModuleEntryPoint)

+ASM_PFX(ModuleEntryPoint):

+  fninit                                ; clear any pending Floating point exceptions

+  ;

+  ; Store the BIST value in mm0

+  ;

+  movd    mm0, eax

+

+  ; Find the fsp info header

+  mov     rax, ASM_PFX(PcdGet32 (PcdFsptBaseAddress))

+  mov     edi, [eax]

+

+  mov     eax, dword [edi + FVH_SIGINATURE_OFFSET]

+  cmp     eax, FVH_SIGINATURE_VALID_VALUE

+  jnz     FspHeaderNotFound

+

+  xor     eax, eax

+  mov     ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]

+  cmp     ax, 0

+  jnz     FspFvExtHeaderExist

+

+  xor     eax, eax

+  mov     ax, word [edi + FVH_HEADER_LENGTH_OFFSET]     ; Bypass Fv Header

+  add     edi, eax

+  jmp     FspCheckFfsHeader

+

+FspFvExtHeaderExist:

+  add     edi, eax

+  mov     eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET]  ; Bypass Ext Fv Header

+  add     edi, eax

+

+  ; Round up to 8 byte alignment

+  mov     eax, edi

+  and     al,  07h

+  jz      FspCheckFfsHeader

+

+  and     edi, 0FFFFFFF8h

+  add     edi, 08h

+

+FspCheckFfsHeader:

+  ; Check the ffs guid

+  mov     eax, dword [edi]

+  cmp     eax, FSP_HEADER_GUID_DWORD1

+  jnz     FspHeaderNotFound

+

+  mov     eax, dword [edi + 4]

+  cmp     eax, FSP_HEADER_GUID_DWORD2

+  jnz     FspHeaderNotFound

+

+  mov     eax, dword [edi + 8]

+  cmp     eax, FSP_HEADER_GUID_DWORD3

+  jnz     FspHeaderNotFound

+

+  mov     eax, dword [edi + 0Ch]

+  cmp     eax, FSP_HEADER_GUID_DWORD4

+  jnz     FspHeaderNotFound

+

+  add     edi, FFS_HEADER_SIZE_VALUE         ; Bypass the ffs header

+

+  ; Check the section type as raw section

+  mov     al, byte [edi + SECTION_HEADER_TYPE_OFFSET]

+  cmp     al, 019h

+  jnz FspHeaderNotFound

+

+  add     edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header

+  jmp     FspHeaderFound

+

+FspHeaderNotFound:

+  jmp     $

+

+FspHeaderFound:

+  ; Get the fsp TempRamInit Api address

+  mov     eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]

+  add     eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]

+

+  ; Setup the hardcode stack

+  mov     rsp, TempRamInitStack

+

+  ; Call the fsp TempRamInit Api

+  jmp     rax

+

+TempRamInitDone:

+  cmp     rax, 0800000000000000Eh ; Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.

+  je      CallSecFspInit          ; If microcode not found, don't hang, but continue.

+

+  cmp     rax, 0                  ; Check if EFI_SUCCESS returned.

+  jnz     FspApiFailed

+

+  ; RDX: start of range

+  ; R8: end of range

+CallSecFspInit:

+

+  mov     r8,  rdx

+  mov     rdx, rcx

+  xor     ecx, ecx ; zero - no Hob List Yet

+  mov     rsp, r8

+

+  ;

+  ; Per X64 calling convention, make sure RSP is 16-byte aligned.

+  ;

+  mov     rax, rsp

+  and     rax, 0fh

+  sub     rsp, rax

+

+  call    ASM_PFX(CallPeiCoreEntryPoint)

+

+FspApiFailed:

+  jmp     $

+

+align 10h

+TempRamInitStack:

+    DQ  TempRamInitDone

+    DQ  ASM_PFX(FsptUpdDataPtr)         ; TempRamInitParams

+

diff --git a/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/Stack.nasm b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/Stack.nasm
new file mode 100644
index 0000000..64e46ce
--- /dev/null
+++ b/IntelFsp2WrapperPkg/Library/SecFspWrapperPlatformSecLibSample/X64/Stack.nasm
@@ -0,0 +1,73 @@
+;------------------------------------------------------------------------------

+;

+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>

+; SPDX-License-Identifier: BSD-2-Clause-Patent

+;

+; Abstract:

+;

+;   Switch the stack from temporary memory to permanent memory.

+;

+;------------------------------------------------------------------------------

+

+    SECTION .text

+

+;------------------------------------------------------------------------------

+; VOID

+; EFIAPI

+; SecSwitchStack (

+;   UINT32   TemporaryMemoryBase,

+;   UINT32   PermanentMemoryBase

+;   );

+;------------------------------------------------------------------------------

+global ASM_PFX(SecSwitchStack)

+ASM_PFX(SecSwitchStack):

+    ;

+    ; Save four register: rax, rbx, rcx, rdx

+    ;

+    push  rax

+    push  rbx

+    push  rcx

+    push  rdx

+

+    ;

+    ; !!CAUTION!! this function address's is pushed into stack after

+    ; migration of whole temporary memory, so need save it to permanent

+    ; memory at first!

+    ;

+

+    mov   rbx, rcx                 ; Save the first parameter

+    mov   rcx, rdx                 ; Save the second parameter

+

+    ;

+    ; Save this function's return address into permanent memory at first.

+    ; Then, Fixup the esp point to permanent memory

+    ;

+    mov   rax, rsp

+    sub   rax, rbx

+    add   rax, rcx

+    mov   rdx, qword [rsp]         ; copy pushed register's value to permanent memory

+    mov   qword [rax], rdx

+    mov   rdx, qword [rsp + 8]

+    mov   qword [rax + 8], rdx

+    mov   rdx, qword [rsp + 16]

+    mov   qword [rax + 16], rdx

+    mov   rdx, qword [rsp + 24]

+    mov   qword [rax + 24], rdx

+    mov   rdx, qword [rsp + 32]    ; Update this function's return address into permanent memory

+    mov   qword [rax + 32], rdx

+    mov   rsp, rax                 ; From now, rsp is pointed to permanent memory

+

+    ;

+    ; Fixup the rbp point to permanent memory

+    ;

+    mov   rax, rbp

+    sub   rax, rbx

+    add   rax, rcx

+    mov   rbp, rax                 ; From now, rbp is pointed to permanent memory

+

+    pop   rdx

+    pop   rcx

+    pop   rbx

+    pop   rax

+    ret

+