--- /dev/null
+/** @file\r
+ Fsp related definitions\r
+\r
+ Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __FSP_H__\r
+#define __FSP_H__\r
+\r
+//\r
+// Fv Header\r
+//\r
+#define FVH_FV_LENGTH_OFFSET 0x20\r
+#define FVH_SIGINATURE_OFFSET 0x28\r
+#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH\r
+#define FVH_HEADER_LENGTH_OFFSET 0x30\r
+#define FVH_EXTHEADER_OFFSET_OFFSET 0x34\r
+#define FVH_EXTHEADER_SIZE_OFFSET 0x10\r
+\r
+//\r
+// Ffs Header\r
+//\r
+#define FSP_HEADER_SIGNATURE_OFFSET 0x1C\r
+#define FSP_HEADER_SIGNATURE 0x48505346 ; valid signature:FSPH\r
+#define FSP_HEADER_GUID_DWORD1 0x912740BE\r
+#define FSP_HEADER_GUID_DWORD2 0x47342284\r
+#define FSP_HEADER_GUID_DWORD3 0xB08471B9\r
+#define FSP_HEADER_GUID_DWORD4 0x0C3F3527\r
+#define FFS_HEADER_SIZE_VALUE 0x18\r
+\r
+//\r
+// Section Header\r
+//\r
+#define SECTION_HEADER_TYPE_OFFSET 0x03\r
+#define RAW_SECTION_HEADER_SIZE_VALUE 0x04\r
+\r
+//\r
+// Fsp Header\r
+//\r
+#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C\r
+#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30\r
+\r
+#endif\r
+++ /dev/null
-/** @file\r
- Fsp related definitions\r
-\r
- Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __FSP_H__\r
-#define __FSP_H__\r
-\r
-//\r
-// Fv Header\r
-//\r
-#define FVH_FV_LENGTH_OFFSET 0x20\r
-#define FVH_SIGINATURE_OFFSET 0x28\r
-#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH\r
-#define FVH_HEADER_LENGTH_OFFSET 0x30\r
-#define FVH_EXTHEADER_OFFSET_OFFSET 0x34\r
-#define FVH_EXTHEADER_SIZE_OFFSET 0x10\r
-\r
-//\r
-// Ffs Header\r
-//\r
-#define FSP_HEADER_SIGNATURE_OFFSET 0x1C\r
-#define FSP_HEADER_SIGNATURE 0x48505346 ; valid signature:FSPH\r
-#define FSP_HEADER_GUID_DWORD1 0x912740BE\r
-#define FSP_HEADER_GUID_DWORD2 0x47342284\r
-#define FSP_HEADER_GUID_DWORD3 0xB08471B9\r
-#define FSP_HEADER_GUID_DWORD4 0x0C3F3527\r
-#define FFS_HEADER_SIZE_VALUE 0x18\r
-\r
-//\r
-// Section Header\r
-//\r
-#define SECTION_HEADER_TYPE_OFFSET 0x03\r
-#define RAW_SECTION_HEADER_SIZE_VALUE 0x04\r
-\r
-//\r
-// Fsp Header\r
-//\r
-#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C\r
-#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30\r
-\r
-#endif\r
;------------------------------------------------------------------------------\r
;\r
-; Copyright (c) 2016, 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
; Abstract:\r
global ASM_PFX(SecSwitchStack)\r
ASM_PFX(SecSwitchStack):\r
;\r
- ; Save three register: eax, ebx, ecx\r
+ ; Save four register: eax, ebx, ecx, edx\r
;\r
push eax\r
push ebx\r
mov dword [eax + 12], edx\r
mov edx, dword [esp + 16] ; Update this function's return address into permanent memory\r
mov dword [eax + 16], edx\r
- mov esp, eax ; From now, esp is pointed to permanent memory\r
+ mov esp, eax ; From now, esp is pointed to permanent memory\r
\r
;\r
; Fixup the ebp point to permanent memory\r
mov eax, ebp\r
sub eax, ebx\r
add eax, ecx\r
- mov ebp, eax ; From now, ebp is pointed to permanent memory\r
+ mov ebp, eax ; From now, ebp is pointed to permanent memory\r
\r
pop edx\r
pop ecx\r
## @file\r
# Sample to provide FSP wrapper platform sec related function.\r
#\r
-# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>\r
#\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
SecGetPerformance.c\r
SecTempRamDone.c\r
PlatformInit.c\r
+ Fsp.h\r
\r
[Sources.IA32]\r
- Ia32/Fsp.h\r
Ia32/SecEntry.nasm\r
Ia32/PeiCoreEntry.nasm\r
Ia32/Stack.nasm\r
\r
+[Sources.X64]\r
+ X64/SecEntry.nasm\r
+ X64/PeiCoreEntry.nasm\r
+ X64/Stack.nasm\r
+\r
################################################################################\r
#\r
# Package Dependency Section - list of Package files that are required for\r
/** @file\r
Sample to provide TempRamInitParams data.\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
#include <FspEas.h>\r
\r
typedef struct {\r
- UINT32 MicrocodeRegionBase;\r
- UINT32 MicrocodeRegionSize;\r
- UINT32 CodeRegionBase;\r
- UINT32 CodeRegionSize;\r
+ EFI_PHYSICAL_ADDRESS MicrocodeRegionBase;\r
+ UINT64 MicrocodeRegionSize;\r
+ EFI_PHYSICAL_ADDRESS CodeRegionBase;\r
+ UINT64 CodeRegionSize;\r
} FSPT_CORE_UPD;\r
\r
typedef struct {\r
FSP_UPD_HEADER FspUpdHeader;\r
//\r
- // If platform does not support FSP spec 2.2 remove FSPT_ARCH_UPD structure.\r
+ // If FSP spec version < 2.2, remove FSPT_ARCH_UPD structure.\r
+ // Else If FSP spec version >= 2.2 and FSP spec version < 2.4, use FSPT_ARCH_UPD structure.\r
+ // Else, use FSPT_ARCH2_UPD structure.\r
//\r
- FSPT_ARCH_UPD FsptArchUpd;\r
+ FSPT_ARCH2_UPD FsptArchUpd;\r
FSPT_CORE_UPD FsptCoreUpd;\r
} FSPT_UPD_CORE_DATA;\r
\r
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }\r
},\r
//\r
- // If platform does not support FSP spec 2.2 remove FSPT_ARCH_UPD structure.\r
+ // If FSP spec version < 2.2, remove FSPT_ARCH_UPD structure.\r
+ // Else If FSP spec version >= 2.2 and FSP spec version < 2.4, use FSPT_ARCH_UPD structure.\r
+ // Else, use FSPT_ARCH2_UPD structure.\r
//\r
{\r
- 0x01,\r
+ 0x02,\r
{\r
0x00, 0x00, 0x00\r
},\r
0x00000000,\r
{\r
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
}\r
},\r
{\r
--- /dev/null
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+; Module Name:\r
+;\r
+; PeiCoreEntry.nasm\r
+;\r
+; Abstract:\r
+;\r
+; Find and call SecStartup\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+SECTION .text\r
+\r
+%include "PushPopRegsNasm.inc"\r
+\r
+extern ASM_PFX(SecStartup)\r
+extern ASM_PFX(PlatformInit)\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
+; 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
+%macro LOAD_TS 1\r
+ LYMMN ymm6, xmm5, 1\r
+ LXMMN xmm5, %1, 1\r
+ %endmacro\r
+\r
+global ASM_PFX(CallPeiCoreEntryPoint)\r
+ASM_PFX(CallPeiCoreEntryPoint):\r
+ ;\r
+ ; Per X64 calling convention, make sure RSP is 16-byte aligned.\r
+ ;\r
+ mov rax, rsp\r
+ and rax, 0fh\r
+ sub rsp, rax\r
+\r
+ ;\r
+ ; Platform init\r
+ ;\r
+ PUSHA_64\r
+ sub rsp, 20h\r
+ call ASM_PFX(PlatformInit)\r
+ add rsp, 20h\r
+ POPA_64\r
+\r
+ ;\r
+ ; Set stack top pointer\r
+ ;\r
+ mov rsp, r8\r
+\r
+ ;\r
+ ; Push the hob list pointer\r
+ ;\r
+ push rcx\r
+\r
+ ;\r
+ ; RBP holds start of BFV passed from Vtf0. Save it to r10.\r
+ ;\r
+ mov r10, rbp\r
+\r
+ ;\r
+ ; Save the value\r
+ ; RDX: start of range\r
+ ; r8: end of range\r
+ ;\r
+ mov rbp, rsp\r
+ push rdx\r
+ push r8\r
+ mov r14, rdx\r
+ mov r15, r8\r
+\r
+ ;\r
+ ; Push processor count to stack first, then BIST status (AP then BSP)\r
+ ;\r
+ mov eax, 1\r
+ cpuid\r
+ shr ebx, 16\r
+ and ebx, 0000000FFh\r
+ cmp bl, 1\r
+ jae PushProcessorCount\r
+\r
+ ;\r
+ ; Some processors report 0 logical processors. Effectively 0 = 1.\r
+ ; So we fix up the processor count\r
+ ;\r
+ inc ebx\r
+\r
+PushProcessorCount:\r
+ sub rsp, 4\r
+ mov rdi, rsp\r
+ mov DWORD [rdi], ebx\r
+\r
+ ;\r
+ ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST\r
+ ; for all processor threads\r
+ ;\r
+ xor ecx, ecx\r
+ mov cl, bl\r
+PushBist:\r
+ sub rsp, 4\r
+ mov rdi, rsp\r
+ movd eax, mm0\r
+ mov DWORD [rdi], eax\r
+ loop PushBist\r
+\r
+ ; Save Time-Stamp Counter\r
+ LOAD_TS rax\r
+ push rax\r
+\r
+ ;\r
+ ; Pass entry point of the PEI core\r
+ ;\r
+ mov rdi, 0FFFFFFE0h\r
+ mov edi, DWORD [rdi]\r
+ mov r9, rdi\r
+\r
+ ;\r
+ ; Pass BFV into the PEI Core\r
+ ;\r
+ mov r8, r10\r
+\r
+ ;\r
+ ; Pass stack size into the PEI Core\r
+ ;\r
+ mov rcx, r15 ; Start of TempRam\r
+ mov rdx, r14 ; End of TempRam\r
+\r
+ sub rcx, rdx ; Size of TempRam\r
+\r
+ ;\r
+ ; Pass Control into the PEI Core\r
+ ;\r
+ sub rsp, 20h\r
+ call ASM_PFX(SecStartup)\r
+\r
--- /dev/null
+;------------------------------------------------------------------------------\r
+;\r
+; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+; Module Name:\r
+;\r
+; SecEntry.asm\r
+;\r
+; Abstract:\r
+;\r
+; This is the code that calls TempRamInit API from FSP binary and passes\r
+; control into PEI core.\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+#include "Fsp.h"\r
+\r
+IA32_CR4_OSFXSR equ 200h\r
+IA32_CR4_OSXMMEXCPT equ 400h\r
+IA32_CR0_MP equ 2h\r
+\r
+IA32_CPUID_SSE2 equ 02000000h\r
+IA32_CPUID_SSE2_B equ 26\r
+\r
+SECTION .text\r
+\r
+extern ASM_PFX(CallPeiCoreEntryPoint)\r
+extern ASM_PFX(FsptUpdDataPtr)\r
+\r
+; Pcds\r
+extern ASM_PFX(PcdGet32 (PcdFsptBaseAddress))\r
+\r
+;----------------------------------------------------------------------------\r
+;\r
+; Procedure: _ModuleEntryPoint\r
+;\r
+; Input: None\r
+;\r
+; Output: None\r
+;\r
+; Destroys: Assume all registers\r
+;\r
+; Description:\r
+;\r
+; Call TempRamInit API from FSP binary. After TempRamInit done, pass\r
+; control into PEI core.\r
+;\r
+; Return: None\r
+;\r
+; MMX Usage:\r
+; MM0 = BIST State\r
+;\r
+;----------------------------------------------------------------------------\r
+\r
+BITS 64\r
+align 16\r
+global ASM_PFX(ModuleEntryPoint)\r
+ASM_PFX(ModuleEntryPoint):\r
+ fninit ; clear any pending Floating point exceptions\r
+ ;\r
+ ; Store the BIST value in mm0\r
+ ;\r
+ movd mm0, eax\r
+\r
+ ; Find the fsp info header\r
+ mov rax, ASM_PFX(PcdGet32 (PcdFsptBaseAddress))\r
+ mov edi, [eax]\r
+\r
+ mov eax, dword [edi + FVH_SIGINATURE_OFFSET]\r
+ cmp eax, FVH_SIGINATURE_VALID_VALUE\r
+ jnz FspHeaderNotFound\r
+\r
+ xor eax, eax\r
+ mov ax, word [edi + FVH_EXTHEADER_OFFSET_OFFSET]\r
+ cmp ax, 0\r
+ jnz FspFvExtHeaderExist\r
+\r
+ xor eax, eax\r
+ mov ax, word [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header\r
+ add edi, eax\r
+ jmp FspCheckFfsHeader\r
+\r
+FspFvExtHeaderExist:\r
+ add edi, eax\r
+ mov eax, dword [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header\r
+ add edi, eax\r
+\r
+ ; Round up to 8 byte alignment\r
+ mov eax, edi\r
+ and al, 07h\r
+ jz FspCheckFfsHeader\r
+\r
+ and edi, 0FFFFFFF8h\r
+ add edi, 08h\r
+\r
+FspCheckFfsHeader:\r
+ ; Check the ffs guid\r
+ mov eax, dword [edi]\r
+ cmp eax, FSP_HEADER_GUID_DWORD1\r
+ jnz FspHeaderNotFound\r
+\r
+ mov eax, dword [edi + 4]\r
+ cmp eax, FSP_HEADER_GUID_DWORD2\r
+ jnz FspHeaderNotFound\r
+\r
+ mov eax, dword [edi + 8]\r
+ cmp eax, FSP_HEADER_GUID_DWORD3\r
+ jnz FspHeaderNotFound\r
+\r
+ mov eax, dword [edi + 0Ch]\r
+ cmp eax, FSP_HEADER_GUID_DWORD4\r
+ jnz FspHeaderNotFound\r
+\r
+ add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header\r
+\r
+ ; Check the section type as raw section\r
+ mov al, byte [edi + SECTION_HEADER_TYPE_OFFSET]\r
+ cmp al, 019h\r
+ jnz FspHeaderNotFound\r
+\r
+ add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header\r
+ jmp FspHeaderFound\r
+\r
+FspHeaderNotFound:\r
+ jmp $\r
+\r
+FspHeaderFound:\r
+ ; Get the fsp TempRamInit Api address\r
+ mov eax, dword [edi + FSP_HEADER_IMAGEBASE_OFFSET]\r
+ add eax, dword [edi + FSP_HEADER_TEMPRAMINIT_OFFSET]\r
+\r
+ ; Setup the hardcode stack\r
+ mov rsp, TempRamInitStack\r
+\r
+ ; Call the fsp TempRamInit Api\r
+ jmp rax\r
+\r
+TempRamInitDone:\r
+ cmp rax, 0800000000000000Eh ; Check if EFI_NOT_FOUND returned. Error code for Microcode Update not found.\r
+ je CallSecFspInit ; If microcode not found, don't hang, but continue.\r
+\r
+ cmp rax, 0 ; Check if EFI_SUCCESS returned.\r
+ jnz FspApiFailed\r
+\r
+ ; RDX: start of range\r
+ ; R8: end of range\r
+CallSecFspInit:\r
+\r
+ mov r8, rdx\r
+ mov rdx, rcx\r
+ xor ecx, ecx ; zero - no Hob List Yet\r
+ mov rsp, r8\r
+\r
+ ;\r
+ ; Per X64 calling convention, make sure RSP is 16-byte aligned.\r
+ ;\r
+ mov rax, rsp\r
+ and rax, 0fh\r
+ sub rsp, rax\r
+\r
+ call ASM_PFX(CallPeiCoreEntryPoint)\r
+\r
+FspApiFailed:\r
+ jmp $\r
+\r
+align 10h\r
+TempRamInitStack:\r
+ DQ TempRamInitDone\r
+ DQ ASM_PFX(FsptUpdDataPtr) ; TempRamInitParams\r
+\r
--- /dev/null
+;------------------------------------------------------------------------------\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
+; UINT32 TemporaryMemoryBase,\r
+; UINT32 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