mirror of https://github.com/acidanthera/audk.git
IntelFsp2Pkg: FspSecCore support for X64
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>
This commit is contained in:
parent
d40965b987
commit
00aa71ce20
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Sec Core for FSP to support MultiPhase (SeparatePhase) SiInitialization.
|
||||
#
|
||||
# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2020 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
|
@ -17,7 +17,7 @@
|
|||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
|
@ -30,6 +30,12 @@
|
|||
Ia32/FspApiEntryCommon.nasm
|
||||
Ia32/FspHelper.nasm
|
||||
|
||||
[Sources.X64]
|
||||
X64/Stack.nasm
|
||||
X64/Fsp22ApiEntryS.nasm
|
||||
X64/FspApiEntryCommon.nasm
|
||||
X64/FspHelper.nasm
|
||||
|
||||
[Binaries.Ia32]
|
||||
RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Sec Core for FSP
|
||||
#
|
||||
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
|
@ -17,7 +17,7 @@
|
|||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
|
@ -34,6 +34,13 @@
|
|||
Ia32/FspHelper.nasm
|
||||
Ia32/ReadEsp.nasm
|
||||
|
||||
[Sources.X64]
|
||||
X64/Stack.nasm
|
||||
X64/FspApiEntryM.nasm
|
||||
X64/FspApiEntryCommon.nasm
|
||||
X64/FspHelper.nasm
|
||||
X64/ReadRsp.nasm
|
||||
|
||||
[Binaries.Ia32]
|
||||
RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Sec Core for FSP
|
||||
#
|
||||
# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
|
@ -17,7 +17,7 @@
|
|||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
|
@ -30,6 +30,12 @@
|
|||
Ia32/FspApiEntryCommon.nasm
|
||||
Ia32/FspHelper.nasm
|
||||
|
||||
[Sources.X64]
|
||||
X64/Stack.nasm
|
||||
X64/FspApiEntryS.nasm
|
||||
X64/FspApiEntryCommon.nasm
|
||||
X64/FspHelper.nasm
|
||||
|
||||
[Binaries.Ia32]
|
||||
RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Sec Core for FSP
|
||||
#
|
||||
# Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
|
@ -17,17 +17,19 @@
|
|||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
|
||||
|
||||
[Sources.IA32]
|
||||
Ia32/Stack.nasm
|
||||
Ia32/FspApiEntryT.nasm
|
||||
Ia32/FspHelper.nasm
|
||||
|
||||
[Sources.X64]
|
||||
X64/Stack.nasm
|
||||
X64/FspApiEntryT.nasm
|
||||
X64/FspHelper.nasm
|
||||
|
||||
[Binaries.Ia32]
|
||||
RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
;; @file
|
||||
; Provide FSP API entry points.
|
||||
;
|
||||
; Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
|
||||
; Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
|
||||
SECTION .text
|
||||
|
||||
STACK_SAVED_EAX_OFFSET EQU 4 * 7 ; size of a general purpose register * eax index
|
||||
|
||||
;
|
||||
; Following functions will be provided in C
|
||||
;
|
||||
|
@ -52,7 +54,7 @@ FspApiCommon1:
|
|||
add esp, 8
|
||||
cmp eax, 0
|
||||
jz FspApiCommon2
|
||||
mov dword [esp + (4 * 7)], eax
|
||||
mov dword [esp + STACK_SAVED_EAX_OFFSET], eax
|
||||
popad
|
||||
exit:
|
||||
ret
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
;; @file
|
||||
; Provide FSP API entry points.
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
|
||||
SECTION .text
|
||||
|
||||
;
|
||||
; Following functions will be provided in C
|
||||
;
|
||||
extern ASM_PFX(FspApiCommon)
|
||||
extern ASM_PFX(FspMultiPhaseSiInitApiHandler)
|
||||
|
||||
STACK_SAVED_RAX_OFFSET EQU 8 * 7 ; size of a general purpose register * rax index
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; NotifyPhase API
|
||||
;
|
||||
; This FSP API will notify the FSP about the different phases in the boot
|
||||
; process
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(NotifyPhaseApi)
|
||||
ASM_PFX(NotifyPhaseApi):
|
||||
mov eax, 2 ; FSP_API_INDEX.NotifyPhaseApiIndex
|
||||
jmp ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspSiliconInit API
|
||||
;
|
||||
; This FSP API initializes the CPU and the chipset including the IO
|
||||
; controllers in the chipset to enable normal operation of these devices.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(FspSiliconInitApi)
|
||||
ASM_PFX(FspSiliconInitApi):
|
||||
mov eax, 5 ; FSP_API_INDEX.FspSiliconInitApiIndex
|
||||
jmp ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspMultiPhaseSiInitApi API
|
||||
;
|
||||
; This FSP API provides multi-phase silicon initialization, which brings greater
|
||||
; modularity beyond the existing FspSiliconInit() API.
|
||||
; Increased modularity is achieved by adding an extra API to FSP-S.
|
||||
; This allows the bootloader to add board specific initialization steps throughout
|
||||
; the SiliconInit flow as needed.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
%include "PushPopRegsNasm.inc"
|
||||
|
||||
global ASM_PFX(FspMultiPhaseSiInitApi)
|
||||
ASM_PFX(FspMultiPhaseSiInitApi):
|
||||
mov eax, 6 ; FSP_API_INDEX.FspMultiPhaseSiInitApiIndex
|
||||
jmp ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspApiCommonContinue API
|
||||
;
|
||||
; This is the FSP API common entry point to resume the FSP execution
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(FspApiCommonContinue)
|
||||
ASM_PFX(FspApiCommonContinue):
|
||||
;
|
||||
; Handle FspMultiPhaseSiInitApiIndex API
|
||||
;
|
||||
cmp eax, 6
|
||||
jnz NotMultiPhaseSiInitApi
|
||||
|
||||
PUSHA_64
|
||||
mov rdx, rcx ; move ApiParam to rdx
|
||||
mov rcx, rax ; move ApiIdx to rcx
|
||||
call ASM_PFX(FspMultiPhaseSiInitApiHandler)
|
||||
mov qword [rsp + STACK_SAVED_RAX_OFFSET], rax
|
||||
POPA_64
|
||||
ret
|
||||
|
||||
NotMultiPhaseSiInitApi:
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; TempRamInit API
|
||||
;
|
||||
; Empty function for WHOLEARCHIVE build option
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(TempRamInitApi)
|
||||
ASM_PFX(TempRamInitApi):
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Module Entrypoint API
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(_ModuleEntryPoint)
|
||||
ASM_PFX(_ModuleEntryPoint):
|
||||
jmp $
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
;; @file
|
||||
; Provide FSP API entry points.
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
|
||||
SECTION .text
|
||||
|
||||
%include "PushPopRegsNasm.inc"
|
||||
|
||||
STACK_SAVED_RAX_OFFSET EQU 8 * 7 ; size of a general purpose register * rax index
|
||||
|
||||
;
|
||||
; Following functions will be provided in C
|
||||
;
|
||||
extern ASM_PFX(Loader2PeiSwitchStack)
|
||||
extern ASM_PFX(FspApiCallingCheck)
|
||||
|
||||
;
|
||||
; Following functions will be provided in ASM
|
||||
;
|
||||
extern ASM_PFX(FspApiCommonContinue)
|
||||
extern ASM_PFX(AsmGetFspInfoHeader)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspApiCommon API
|
||||
;
|
||||
; This is the FSP API common entry point to resume the FSP execution
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(FspApiCommon)
|
||||
ASM_PFX(FspApiCommon):
|
||||
;
|
||||
; RAX holds the API index
|
||||
;
|
||||
|
||||
;
|
||||
; Stack must be ready
|
||||
;
|
||||
push rax
|
||||
add rsp, 8
|
||||
cmp rax, [rsp - 8]
|
||||
jz FspApiCommon1
|
||||
mov rax, 08000000000000003h
|
||||
jmp exit
|
||||
|
||||
FspApiCommon1:
|
||||
;
|
||||
; Verify the calling condition
|
||||
;
|
||||
PUSHA_64
|
||||
mov rdx, rcx ; move ApiParam to rdx
|
||||
mov rcx, rax ; move ApiIdx to rcx
|
||||
call ASM_PFX(FspApiCallingCheck)
|
||||
cmp rax, 0
|
||||
jz FspApiCommon2
|
||||
mov [rsp + STACK_SAVED_RAX_OFFSET], rax
|
||||
POPA_64
|
||||
exit:
|
||||
ret
|
||||
|
||||
FspApiCommon2:
|
||||
POPA_64
|
||||
cmp rax, 3 ; FspMemoryInit API
|
||||
jz FspApiCommon3
|
||||
|
||||
cmp rax, 6 ; FspMultiPhaseSiInitApiIndex API
|
||||
jz FspApiCommon3
|
||||
|
||||
call ASM_PFX(AsmGetFspInfoHeader)
|
||||
jmp ASM_PFX(Loader2PeiSwitchStack)
|
||||
|
||||
FspApiCommon3:
|
||||
jmp ASM_PFX(FspApiCommonContinue)
|
||||
|
|
@ -0,0 +1,271 @@
|
|||
;; @file
|
||||
; Provide FSP API entry points.
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
|
||||
SECTION .text
|
||||
|
||||
%include "PushPopRegsNasm.inc"
|
||||
|
||||
;
|
||||
; Following are fixed PCDs
|
||||
;
|
||||
extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
|
||||
|
||||
struc FSPM_UPD_COMMON_FSP24
|
||||
; FSP_UPD_HEADER {
|
||||
.FspUpdHeader: resd 8
|
||||
; }
|
||||
; FSPM_ARCH2_UPD {
|
||||
.Revision: resb 1
|
||||
.Reserved: resb 3
|
||||
.Length resd 1
|
||||
.StackBase: resq 1
|
||||
.StackSize: resq 1
|
||||
.BootLoaderTolumSize: resd 1
|
||||
.BootMode: resd 1
|
||||
.FspEventHandler resq 1
|
||||
.Reserved1: resb 24
|
||||
; }
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
;
|
||||
; Following functions will be provided in C
|
||||
;
|
||||
extern ASM_PFX(SecStartup)
|
||||
extern ASM_PFX(FspApiCommon)
|
||||
|
||||
;
|
||||
; Following functions will be provided in PlatformSecLib
|
||||
;
|
||||
extern ASM_PFX(AsmGetFspBaseAddress)
|
||||
extern ASM_PFX(AsmGetFspInfoHeader)
|
||||
|
||||
FSP_HEADER_IMGBASE_OFFSET EQU 1Ch
|
||||
FSP_HEADER_CFGREG_OFFSET EQU 24h
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspMemoryInit API
|
||||
;
|
||||
; This FSP API is called after TempRamInit and initializes the memory.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(FspMemoryInitApi)
|
||||
ASM_PFX(FspMemoryInitApi):
|
||||
mov eax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex
|
||||
jmp ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; TempRamExitApi API
|
||||
;
|
||||
; This API tears down temporary RAM
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(TempRamExitApi)
|
||||
ASM_PFX(TempRamExitApi):
|
||||
mov eax, 4 ; FSP_API_INDEX.TempRamExitApiIndex
|
||||
jmp ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspApiCommonContinue API
|
||||
;
|
||||
; This is the FSP API common entry point to resume the FSP execution
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(FspApiCommonContinue)
|
||||
ASM_PFX(FspApiCommonContinue):
|
||||
;
|
||||
; RAX holds the API index
|
||||
; Push RDX and RCX to form CONTEXT_STACK_64
|
||||
;
|
||||
push rdx ; Push a QWORD data for stack alignment
|
||||
push rdx ; Push API Parameter2 on stack
|
||||
push rcx ; Push API Parameter1 on stack
|
||||
|
||||
;
|
||||
; FspMemoryInit API setup the initial stack frame
|
||||
;
|
||||
|
||||
;
|
||||
; Place holder to store the FspInfoHeader pointer
|
||||
;
|
||||
push rax
|
||||
|
||||
;
|
||||
; Update the FspInfoHeader pointer
|
||||
;
|
||||
push rax
|
||||
call ASM_PFX(AsmGetFspInfoHeader)
|
||||
mov [rsp + 8], rax
|
||||
pop rax
|
||||
|
||||
;
|
||||
; Create a Task Frame in the stack for the Boot Loader
|
||||
;
|
||||
pushfq
|
||||
cli
|
||||
PUSHA_64
|
||||
|
||||
; Reserve 16 bytes for IDT save/restore
|
||||
sub rsp, 16
|
||||
sidt [rsp]
|
||||
|
||||
; Get Stackbase and StackSize from FSPM_UPD Param
|
||||
mov rdx, rcx ; Put FSPM_UPD Param to rdx
|
||||
cmp rdx, 0
|
||||
jnz FspStackSetup
|
||||
|
||||
; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null
|
||||
xchg rbx, rax
|
||||
call ASM_PFX(AsmGetFspInfoHeader)
|
||||
mov edx, [rax + FSP_HEADER_IMGBASE_OFFSET]
|
||||
add edx, [rax + FSP_HEADER_CFGREG_OFFSET]
|
||||
xchg rbx, rax
|
||||
|
||||
FspStackSetup:
|
||||
mov cl, [rdx + FSPM_UPD_COMMON_FSP24.Revision]
|
||||
cmp cl, 3
|
||||
jae FspmUpdCommonFsp24
|
||||
|
||||
mov rax, 08000000000000002h ; RETURN_INVALID_PARAMETER
|
||||
sub rsp, 0b8h
|
||||
ret
|
||||
|
||||
FspmUpdCommonFsp24:
|
||||
;
|
||||
; StackBase = temp memory base, StackSize = temp memory size
|
||||
;
|
||||
mov rdi, [rdx + FSPM_UPD_COMMON_FSP24.StackBase]
|
||||
mov ecx, [rdx + FSPM_UPD_COMMON_FSP24.StackSize]
|
||||
|
||||
;
|
||||
; Keep using bootloader stack if heap size % is 0
|
||||
;
|
||||
mov rbx, ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
|
||||
mov bl, BYTE [rbx]
|
||||
cmp bl, 0
|
||||
jz SkipStackSwitch
|
||||
|
||||
;
|
||||
; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0
|
||||
;
|
||||
add rdi, rcx
|
||||
;
|
||||
; Switch to new FSP stack
|
||||
;
|
||||
xchg rdi, rsp ; Exchange rdi and rsp, rdi will be assigned to the current rsp pointer and rsp will be Stack base + Stack size
|
||||
|
||||
SkipStackSwitch:
|
||||
;
|
||||
; If heap size % is 0:
|
||||
; EDI is FSPM_UPD_COMMON_FSP24.StackBase and will hold ESP later (boot loader stack pointer)
|
||||
; ECX is FSPM_UPD_COMMON_FSP24.StackSize
|
||||
; ESP is boot loader stack pointer (no stack switch)
|
||||
; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON_FSP24.StackBase later)
|
||||
;
|
||||
; If heap size % is not 0
|
||||
; EDI is boot loader stack pointer
|
||||
; ECX is FSPM_UPD_COMMON_FSP24.StackSize
|
||||
; ESP is new stack (FSPM_UPD_COMMON_FSP24.StackBase + FSPM_UPD_COMMON_FSP24.StackSize)
|
||||
; BL is NOT 0 to indicate stack has switched
|
||||
;
|
||||
cmp bl, 0
|
||||
jnz StackHasBeenSwitched
|
||||
|
||||
mov rbx, rdi ; Put FSPM_UPD_COMMON_FSP24.StackBase to rbx as temp memory base
|
||||
mov rdi, rsp ; Put boot loader stack pointer to rdi
|
||||
jmp StackSetupDone
|
||||
|
||||
StackHasBeenSwitched:
|
||||
mov rbx, rsp ; Put Stack base + Stack size in ebx
|
||||
sub rbx, rcx ; Stack base + Stack size - Stack size as temp memory base
|
||||
|
||||
StackSetupDone:
|
||||
|
||||
;
|
||||
; Per X64 calling convention, make sure RSP is 16-byte aligned.
|
||||
;
|
||||
mov rdx, rsp
|
||||
and rdx, 0fh
|
||||
sub rsp, rdx
|
||||
|
||||
;
|
||||
; Pass the API Idx to SecStartup
|
||||
;
|
||||
push rax
|
||||
|
||||
;
|
||||
; Pass the BootLoader stack to SecStartup
|
||||
;
|
||||
push rdi
|
||||
|
||||
;
|
||||
; Pass BFV into the PEI Core
|
||||
; It uses relative address to calculate the actual boot FV base
|
||||
; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and
|
||||
; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,
|
||||
; they are different. The code below can handle both cases.
|
||||
;
|
||||
call ASM_PFX(AsmGetFspBaseAddress)
|
||||
mov r8, rax
|
||||
|
||||
;
|
||||
; Pass entry point of the PEI core
|
||||
;
|
||||
call ASM_PFX(AsmGetPeiCoreOffset)
|
||||
lea r9, [r8 + rax]
|
||||
|
||||
;
|
||||
; Pass stack base and size into the PEI Core
|
||||
;
|
||||
mov rcx, rcx
|
||||
mov rdx, rbx
|
||||
|
||||
;
|
||||
; Pass Control into the PEI Core
|
||||
; RCX = SizeOfRam, RDX = TempRamBase, R8 = BFV, R9 = PeiCoreEntry, Last 1 Stack = BL stack, Last 2 Stack = API index
|
||||
; According to X64 calling convention, caller has to allocate 32 bytes as a shadow store on call stack right before
|
||||
; calling the function.
|
||||
;
|
||||
sub rsp, 20h
|
||||
call ASM_PFX(SecStartup)
|
||||
add rsp, 20h
|
||||
exit:
|
||||
ret
|
||||
|
||||
global ASM_PFX(FspPeiCoreEntryOff)
|
||||
ASM_PFX(FspPeiCoreEntryOff):
|
||||
;
|
||||
; This value will be patched by the build script
|
||||
;
|
||||
DD 0x12345678
|
||||
|
||||
global ASM_PFX(AsmGetPeiCoreOffset)
|
||||
ASM_PFX(AsmGetPeiCoreOffset):
|
||||
push rbx
|
||||
mov rbx, ASM_PFX(FspPeiCoreEntryOff)
|
||||
mov eax, dword[ebx]
|
||||
pop rbx
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; TempRamInit API
|
||||
;
|
||||
; Empty function for WHOLEARCHIVE build option
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(TempRamInitApi)
|
||||
ASM_PFX(TempRamInitApi):
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Module Entrypoint API
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(_ModuleEntryPoint)
|
||||
ASM_PFX(_ModuleEntryPoint):
|
||||
jmp $
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
;; @file
|
||||
; Provide FSP API entry points.
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
|
||||
SECTION .text
|
||||
|
||||
;
|
||||
; Following functions will be provided in C
|
||||
;
|
||||
extern ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; NotifyPhase API
|
||||
;
|
||||
; This FSP API will notify the FSP about the different phases in the boot
|
||||
; process
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(NotifyPhaseApi)
|
||||
ASM_PFX(NotifyPhaseApi):
|
||||
mov eax, 2 ; FSP_API_INDEX.NotifyPhaseApiIndex
|
||||
jmp ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspSiliconInit API
|
||||
;
|
||||
; This FSP API initializes the CPU and the chipset including the IO
|
||||
; controllers in the chipset to enable normal operation of these devices.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(FspSiliconInitApi)
|
||||
ASM_PFX(FspSiliconInitApi):
|
||||
mov eax, 5 ; FSP_API_INDEX.FspSiliconInitApiIndex
|
||||
jmp ASM_PFX(FspApiCommon)
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspApiCommonContinue API
|
||||
;
|
||||
; This is the FSP API common entry point to resume the FSP execution
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(FspApiCommonContinue)
|
||||
ASM_PFX(FspApiCommonContinue):
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; TempRamInit API
|
||||
;
|
||||
; Empty function for WHOLEARCHIVE build option
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(TempRamInitApi)
|
||||
ASM_PFX(TempRamInitApi):
|
||||
jmp $
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Module Entrypoint API
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(_ModuleEntryPoint)
|
||||
ASM_PFX(_ModuleEntryPoint):
|
||||
jmp $
|
||||
|
|
@ -0,0 +1,495 @@
|
|||
;; @file
|
||||
; Provide FSP API entry points.
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
|
||||
SECTION .text
|
||||
|
||||
%include "SaveRestoreSseAvxNasm.inc"
|
||||
%include "MicrocodeLoadNasm.inc"
|
||||
|
||||
;
|
||||
; Following are fixed PCDs
|
||||
;
|
||||
extern ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
|
||||
extern ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
|
||||
extern ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))
|
||||
|
||||
;
|
||||
; Following functions will be provided in PlatformSecLib
|
||||
;
|
||||
extern ASM_PFX(AsmGetFspBaseAddress)
|
||||
extern ASM_PFX(AsmGetFspInfoHeader)
|
||||
;extern ASM_PFX(LoadMicrocode) ; @todo: needs a weak implementation
|
||||
extern ASM_PFX(SecPlatformInit) ; @todo: needs a weak implementation
|
||||
extern ASM_PFX(SecCarInit)
|
||||
|
||||
;
|
||||
; Define the data length that we saved on the stack top
|
||||
;
|
||||
DATA_LEN_OF_PER0 EQU 18h
|
||||
DATA_LEN_OF_MCUD EQU 18h
|
||||
DATA_LEN_AT_STACK_TOP EQU (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
|
||||
|
||||
;
|
||||
; @todo: These structures are moved from MicrocodeLoadNasm.inc to avoid
|
||||
; build error. This needs to be fixed later on.
|
||||
;
|
||||
struc MicrocodeHdr
|
||||
.MicrocodeHdrVersion: resd 1
|
||||
.MicrocodeHdrRevision: resd 1
|
||||
.MicrocodeHdrDate: resd 1
|
||||
.MicrocodeHdrProcessor: resd 1
|
||||
.MicrocodeHdrChecksum: resd 1
|
||||
.MicrocodeHdrLoader: resd 1
|
||||
.MicrocodeHdrFlags: resd 1
|
||||
.MicrocodeHdrDataSize: resd 1
|
||||
.MicrocodeHdrTotalSize: resd 1
|
||||
.MicrocodeHdrRsvd: resd 3
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
struc ExtSigHdr
|
||||
.ExtSigHdrCount: resd 1
|
||||
.ExtSigHdrChecksum: resd 1
|
||||
.ExtSigHdrRsvd: resd 3
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
struc ExtSig
|
||||
.ExtSigProcessor: resd 1
|
||||
.ExtSigFlags: resd 1
|
||||
.ExtSigChecksum: resd 1
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
struc LoadMicrocodeParamsFsp24
|
||||
; FSP_UPD_HEADER {
|
||||
.FspUpdHeaderSignature: resd 2
|
||||
.FspUpdHeaderRevision: resb 1
|
||||
.FspUpdHeaderReserved: resb 23
|
||||
; }
|
||||
; FSPT_ARCH2_UPD {
|
||||
.FsptArchRevision: resb 1
|
||||
.FsptArchReserved: resb 3
|
||||
.FsptArchLength: resd 1
|
||||
.FspDebugHandler resq 1
|
||||
.FsptArchUpd: resd 4
|
||||
; }
|
||||
; FSPT_CORE_UPD {
|
||||
.MicrocodeCodeAddr: resq 1
|
||||
.MicrocodeCodeSize: resq 1
|
||||
.CodeRegionBase: resq 1
|
||||
.CodeRegionSize: resq 1
|
||||
; }
|
||||
.size:
|
||||
endstruc
|
||||
|
||||
;
|
||||
; @todo: The strong/weak implementation does not work.
|
||||
; This needs to be reviewed later.
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
;;global ASM_PFX(SecPlatformInitDefault)
|
||||
;ASM_PFX(SecPlatformInitDefault):
|
||||
; ; Inputs:
|
||||
; ; ymm7 -> Return address
|
||||
; ; Outputs:
|
||||
; ; rax -> 0 - Successful, Non-zero - Failed.
|
||||
; ; Register Usage:
|
||||
; ; rax is cleared and rbp is used for return address.
|
||||
; ; All others reserved.
|
||||
;
|
||||
; ; Save return address to RBP
|
||||
; LOAD_RBP
|
||||
;
|
||||
; xor rax, rax
|
||||
;Exit1:
|
||||
; jmp rbp
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(LoadMicrocodeDefault)
|
||||
ASM_PFX(LoadMicrocodeDefault):
|
||||
; Inputs:
|
||||
; rsp -> LoadMicrocodeParams pointer
|
||||
; Register Usage:
|
||||
; rsp Preserved
|
||||
; All others destroyed
|
||||
; Assumptions:
|
||||
; No memory available, stack is hard-coded and used for return address
|
||||
; Executed by SBSP and NBSP
|
||||
; Beginning of microcode update region starts on paragraph boundary
|
||||
|
||||
;
|
||||
; Save return address to RBP
|
||||
;
|
||||
LOAD_RBP
|
||||
|
||||
cmp rsp, 0
|
||||
jz ParamError
|
||||
mov eax, dword [rsp + 8] ; Parameter pointer
|
||||
cmp eax, 0
|
||||
jz ParamError
|
||||
mov esp, eax
|
||||
|
||||
; skip loading Microcode if the MicrocodeCodeSize is zero
|
||||
; and report error if size is less than 2k
|
||||
; first check UPD header revision
|
||||
cmp byte [rsp + LoadMicrocodeParamsFsp24.FspUpdHeaderRevision], 2
|
||||
jb ParamError
|
||||
cmp byte [rsp + LoadMicrocodeParamsFsp24.FsptArchRevision], 2
|
||||
jne ParamError
|
||||
|
||||
; UPD structure is compliant with FSP spec 2.4
|
||||
mov eax, dword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeSize]
|
||||
cmp eax, 0
|
||||
jz Exit2
|
||||
cmp eax, 0800h
|
||||
jl ParamError
|
||||
|
||||
mov esi, dword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr]
|
||||
cmp esi, 0
|
||||
jnz CheckMainHeader
|
||||
|
||||
ParamError:
|
||||
mov rax, 08000000000000002h
|
||||
jmp Exit2
|
||||
|
||||
CheckMainHeader:
|
||||
; Get processor signature and platform ID from the installed processor
|
||||
; and save into registers for later use
|
||||
; ebx = processor signature
|
||||
; edx = platform ID
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov ebx, eax
|
||||
mov ecx, MSR_IA32_PLATFORM_ID
|
||||
rdmsr
|
||||
mov ecx, edx
|
||||
shr ecx, 50-32 ; shift (50d-32d=18d=0x12) bits
|
||||
and ecx, 7h ; platform id at bit[52..50]
|
||||
mov edx, 1
|
||||
shl edx, cl
|
||||
|
||||
; Current register usage
|
||||
; esp -> stack with parameters
|
||||
; esi -> microcode update to check
|
||||
; ebx = processor signature
|
||||
; edx = platform ID
|
||||
|
||||
; Check for valid microcode header
|
||||
; Minimal test checking for header version and loader version as 1
|
||||
mov eax, dword 1
|
||||
cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], eax
|
||||
jne AdvanceFixedSize
|
||||
cmp dword [esi + MicrocodeHdr.MicrocodeHdrLoader], eax
|
||||
jne AdvanceFixedSize
|
||||
|
||||
; Check if signature and plaform ID match
|
||||
cmp ebx, dword [esi + MicrocodeHdr.MicrocodeHdrProcessor]
|
||||
jne LoadMicrocodeDefault1
|
||||
test edx, dword [esi + MicrocodeHdr.MicrocodeHdrFlags ]
|
||||
jnz LoadCheck ; Jif signature and platform ID match
|
||||
|
||||
LoadMicrocodeDefault1:
|
||||
; Check if extended header exists
|
||||
; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
|
||||
xor rax, rax
|
||||
cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
|
||||
je NextMicrocode
|
||||
cmp dword [esi + MicrocodeHdr.MicrocodeHdrDataSize], eax
|
||||
je NextMicrocode
|
||||
|
||||
; Then verify total size - sizeof header > data size
|
||||
mov ecx, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
|
||||
sub ecx, MicrocodeHdr.size
|
||||
cmp ecx, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
|
||||
jng NextMicrocode ; Jif extended header does not exist
|
||||
|
||||
; Set edi -> extended header
|
||||
mov edi, esi
|
||||
add edi, MicrocodeHdr.size
|
||||
add edi, dword [esi + MicrocodeHdr.MicrocodeHdrDataSize]
|
||||
|
||||
; Get count of extended structures
|
||||
mov ecx, dword [edi + ExtSigHdr.ExtSigHdrCount]
|
||||
|
||||
; Move pointer to first signature structure
|
||||
add edi, ExtSigHdr.size
|
||||
|
||||
CheckExtSig:
|
||||
; Check if extended signature and platform ID match
|
||||
cmp dword [edi + ExtSig.ExtSigProcessor], ebx
|
||||
jne LoadMicrocodeDefault2
|
||||
test dword [edi + ExtSig.ExtSigFlags], edx
|
||||
jnz LoadCheck ; Jif signature and platform ID match
|
||||
LoadMicrocodeDefault2:
|
||||
; Check if any more extended signatures exist
|
||||
add edi, ExtSig.size
|
||||
loop CheckExtSig
|
||||
|
||||
NextMicrocode:
|
||||
; Advance just after end of this microcode
|
||||
xor rax, rax
|
||||
cmp dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize], eax
|
||||
je LoadMicrocodeDefault3
|
||||
add esi, dword [esi + MicrocodeHdr.MicrocodeHdrTotalSize]
|
||||
jmp CheckAddress
|
||||
LoadMicrocodeDefault3:
|
||||
add esi, dword 2048
|
||||
jmp CheckAddress
|
||||
|
||||
AdvanceFixedSize:
|
||||
; Advance by 4X dwords
|
||||
add esi, dword 1024
|
||||
|
||||
CheckAddress:
|
||||
; Check UPD header revision
|
||||
cmp byte [rsp + LoadMicrocodeParamsFsp24.FspUpdHeaderRevision], 2
|
||||
jb ParamError
|
||||
cmp byte [rsp + LoadMicrocodeParamsFsp24.FsptArchRevision], 2
|
||||
jne ParamError
|
||||
|
||||
; UPD structure is compliant with FSP spec 2.4
|
||||
; Is automatic size detection ?
|
||||
mov rax, qword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeSize]
|
||||
cmp rax, 0ffffffffffffffffh
|
||||
jz LoadMicrocodeDefault4
|
||||
|
||||
; Address >= microcode region address + microcode region size?
|
||||
add rax, qword [rsp + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr]
|
||||
cmp rsi, rax
|
||||
jae Done ;Jif address is outside of microcode region
|
||||
jmp CheckMainHeader
|
||||
|
||||
LoadMicrocodeDefault4:
|
||||
; Is valid Microcode start point ?
|
||||
cmp dword [esi + MicrocodeHdr.MicrocodeHdrVersion], 0ffffffffh
|
||||
jz Done
|
||||
|
||||
LoadCheck:
|
||||
; Get the revision of the current microcode update loaded
|
||||
mov ecx, MSR_IA32_BIOS_SIGN_ID
|
||||
xor eax, eax ; Clear EAX
|
||||
xor edx, edx ; Clear EDX
|
||||
wrmsr ; Load 0 to MSR at 8Bh
|
||||
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov ecx, MSR_IA32_BIOS_SIGN_ID
|
||||
rdmsr ; Get current microcode signature
|
||||
|
||||
; Verify this microcode update is not already loaded
|
||||
cmp dword [esi + MicrocodeHdr.MicrocodeHdrRevision], edx
|
||||
je Continue
|
||||
|
||||
LoadMicrocode:
|
||||
; EAX contains the linear address of the start of the Update Data
|
||||
; EDX contains zero
|
||||
; ECX contains 79h (IA32_BIOS_UPDT_TRIG)
|
||||
; Start microcode load with wrmsr
|
||||
mov eax, esi
|
||||
add eax, MicrocodeHdr.size
|
||||
xor edx, edx
|
||||
mov ecx, MSR_IA32_BIOS_UPDT_TRIG
|
||||
wrmsr
|
||||
mov eax, 1
|
||||
cpuid
|
||||
|
||||
Continue:
|
||||
jmp NextMicrocode
|
||||
|
||||
Done:
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov ecx, MSR_IA32_BIOS_SIGN_ID
|
||||
rdmsr ; Get current microcode signature
|
||||
xor eax, eax
|
||||
cmp edx, 0
|
||||
jnz Exit2
|
||||
mov eax, 0800000000000000Eh
|
||||
|
||||
Exit2:
|
||||
jmp rbp
|
||||
|
||||
|
||||
global ASM_PFX(EstablishStackFsp)
|
||||
ASM_PFX(EstablishStackFsp):
|
||||
;
|
||||
; Save parameter pointer in rdx
|
||||
;
|
||||
mov rdx, qword [rsp + 8]
|
||||
|
||||
;
|
||||
; Enable FSP STACK
|
||||
;
|
||||
mov rax, ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
|
||||
mov esp, DWORD[rax]
|
||||
mov rax, ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
|
||||
add esp, DWORD[rax]
|
||||
|
||||
sub esp, 4
|
||||
mov dword[esp], DATA_LEN_OF_MCUD ; Size of the data region
|
||||
sub esp, 4
|
||||
mov dword[esp], 4455434Dh ; Signature of the data region 'MCUD'
|
||||
|
||||
; check UPD structure revision (rdx + 8)
|
||||
cmp byte [rdx + LoadMicrocodeParamsFsp24.FspUpdHeaderRevision], 2
|
||||
jb ParamError1
|
||||
cmp byte [rdx + LoadMicrocodeParamsFsp24.FsptArchRevision], 2
|
||||
je Fsp24UpdHeader
|
||||
|
||||
ParamError1:
|
||||
mov rax, 08000000000000002h
|
||||
jmp EstablishStackFspExit
|
||||
|
||||
Fsp24UpdHeader:
|
||||
; UPD structure is compliant with FSP spec 2.4
|
||||
xor rax, rax
|
||||
mov rax, qword [rdx + LoadMicrocodeParamsFsp24.CodeRegionSize] ; Code size sizeof(FSPT_UPD_COMMON) + 18h
|
||||
sub rsp, 8
|
||||
mov qword[rsp], rax
|
||||
mov rax, qword [rdx + LoadMicrocodeParamsFsp24.CodeRegionBase] ; Code base sizeof(FSPT_UPD_COMMON) + 10h
|
||||
sub rsp, 8
|
||||
mov qword[rsp], rax
|
||||
mov rax, qword [rdx + LoadMicrocodeParamsFsp24.MicrocodeCodeSize] ; Microcode size sizeof(FSPT_UPD_COMMON) + 8h
|
||||
sub rsp, 8
|
||||
mov qword[rsp], rax
|
||||
mov rax, qword [rdx + LoadMicrocodeParamsFsp24.MicrocodeCodeAddr] ; Microcode base sizeof(FSPT_UPD_COMMON) + 0h
|
||||
sub rsp, 8
|
||||
mov qword[rsp], rax
|
||||
|
||||
ContinueAfterUpdPush:
|
||||
;
|
||||
; Save API entry/exit timestamp into stack
|
||||
;
|
||||
sub esp, 4
|
||||
mov dword[esp], DATA_LEN_OF_PER0 ; Size of the data region
|
||||
sub esp, 4
|
||||
mov dword[esp], 30524550h ; Signature of the data region 'PER0'
|
||||
rdtsc
|
||||
sub esp, 4
|
||||
mov dword[esp], edx
|
||||
sub esp, 4
|
||||
mov dword[esp], eax
|
||||
LOAD_TS rax
|
||||
push rax
|
||||
|
||||
;
|
||||
; Terminator for the data on stack
|
||||
;
|
||||
push 0
|
||||
|
||||
;
|
||||
; Set ECX/EDX to the BootLoader temporary memory range
|
||||
;
|
||||
mov rcx, ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
|
||||
mov edx, [ecx]
|
||||
mov rcx, ASM_PFX(PcdGet32 (PcdTemporaryRamSize))
|
||||
add edx, [ecx]
|
||||
mov rcx, ASM_PFX(PcdGet32 (PcdFspReservedBufferSize))
|
||||
sub edx, [ecx]
|
||||
mov rcx, ASM_PFX(PcdGet32 (PcdTemporaryRamBase))
|
||||
mov ecx, [ecx]
|
||||
|
||||
cmp ecx, edx ; If PcdFspReservedBufferSize >= PcdTemporaryRamSize, then error.
|
||||
jb EstablishStackFspSuccess
|
||||
mov rax, 08000000000000003h ; EFI_UNSUPPORTED
|
||||
jmp EstablishStackFspExit
|
||||
EstablishStackFspSuccess:
|
||||
xor rax, rax
|
||||
|
||||
EstablishStackFspExit:
|
||||
RET_YMM
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; TempRamInit API
|
||||
;
|
||||
; This FSP API will load the microcode update, enable code caching for the
|
||||
; region specified by the boot loader and also setup a temporary stack to be
|
||||
; used till main memory is initialized.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(TempRamInitApi)
|
||||
ASM_PFX(TempRamInitApi):
|
||||
;
|
||||
; Ensure both SSE and AVX are enabled
|
||||
;
|
||||
ENABLE_SSE
|
||||
ENABLE_AVX
|
||||
|
||||
;
|
||||
; Save RBP, RBX, RSI, RDI and RSP in YMM7, YMM8 and YMM6
|
||||
;
|
||||
SAVE_REGS
|
||||
|
||||
;
|
||||
; Save BFV address in YMM9
|
||||
;
|
||||
SAVE_BFV rbp
|
||||
|
||||
;
|
||||
; Save timestamp into YMM6
|
||||
;
|
||||
rdtsc
|
||||
shl rdx, 32
|
||||
or rax, rdx
|
||||
SAVE_TS rax
|
||||
|
||||
;
|
||||
; Check Parameter
|
||||
;
|
||||
mov rax, qword [rsp + 8]
|
||||
cmp rax, 0
|
||||
mov rax, 08000000000000002h
|
||||
jz TempRamInitExit
|
||||
|
||||
;
|
||||
; Sec Platform Init
|
||||
;
|
||||
CALL_YMM ASM_PFX(SecPlatformInit)
|
||||
cmp eax, 0
|
||||
jnz TempRamInitExit
|
||||
|
||||
; Load microcode
|
||||
LOAD_RSP
|
||||
CALL_YMM ASM_PFX(LoadMicrocodeDefault)
|
||||
SAVE_UCODE_STATUS rax ; Save microcode return status in SLOT 0 in YMM9 (upper 128bits).
|
||||
; @note If return value rax is not 0, microcode did not load, but continue and attempt to boot.
|
||||
|
||||
; Call Sec CAR Init
|
||||
LOAD_RSP
|
||||
CALL_YMM ASM_PFX(SecCarInit)
|
||||
cmp rax, 0
|
||||
jnz TempRamInitExit
|
||||
|
||||
LOAD_RSP
|
||||
CALL_YMM ASM_PFX(EstablishStackFsp)
|
||||
cmp rax, 0
|
||||
jnz TempRamInitExit
|
||||
|
||||
LOAD_UCODE_STATUS rax ; Restore microcode status if no CAR init error from SLOT 0 in YMM9 (upper 128bits).
|
||||
|
||||
TempRamInitExit:
|
||||
mov bl, al ; save al data in bl
|
||||
mov al, 07Fh ; API exit postcode 7f
|
||||
out 080h, al
|
||||
mov al, bl ; restore al data from bl
|
||||
|
||||
;
|
||||
; Load RBP, RBX, RSI, RDI and RSP from YMM7, YMM8 and YMM6
|
||||
;
|
||||
LOAD_REGS
|
||||
LOAD_BFV rbp
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Module Entrypoint API
|
||||
;----------------------------------------------------------------------------
|
||||
global ASM_PFX(_ModuleEntryPoint)
|
||||
ASM_PFX(_ModuleEntryPoint):
|
||||
jmp $
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
;; @file
|
||||
; Provide FSP helper function.
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
DEFAULT REL
|
||||
SECTION .text
|
||||
|
||||
global ASM_PFX(AsmGetFspBaseAddress)
|
||||
ASM_PFX(AsmGetFspBaseAddress):
|
||||
call ASM_PFX(AsmGetFspInfoHeader)
|
||||
add rax, 0x1C
|
||||
mov eax, [rax]
|
||||
ret
|
||||
|
||||
global ASM_PFX(AsmGetFspInfoHeader)
|
||||
ASM_PFX(AsmGetFspInfoHeader):
|
||||
lea rax, [ASM_PFX(AsmGetFspInfoHeader)]
|
||||
DB 0x48, 0x2d ; sub rax, 0x????????
|
||||
global ASM_PFX(FspInfoHeaderRelativeOff)
|
||||
ASM_PFX(FspInfoHeaderRelativeOff):
|
||||
DD 0x12345678 ; This value must be patched by the build script
|
||||
and rax, 0xffffffff
|
||||
ret
|
||||
|
||||
global ASM_PFX(AsmGetFspInfoHeaderNoStack)
|
||||
ASM_PFX(AsmGetFspInfoHeaderNoStack):
|
||||
lea rax, [ASM_PFX(AsmGetFspInfoHeader)]
|
||||
lea rcx, [ASM_PFX(FspInfoHeaderRelativeOff)]
|
||||
mov ecx, [rcx]
|
||||
sub rax, rcx
|
||||
and rax, 0xffffffff
|
||||
jmp rdi
|
|
@ -0,0 +1,11 @@
|
|||
;; @file
|
||||
;
|
||||
;@copyright
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
|
||||
MSR_IA32_PLATFORM_ID equ 000000017h
|
||||
MSR_IA32_BIOS_UPDT_TRIG equ 000000079h
|
||||
MSR_IA32_BIOS_SIGN_ID equ 00000008bh
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
;; @file
|
||||
; Provide read RSP function
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
SECTION .text
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; UINTN
|
||||
; EFIAPI
|
||||
; AsmReadStackPointer (
|
||||
; VOID
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(AsmReadStackPointer)
|
||||
ASM_PFX(AsmReadStackPointer):
|
||||
mov rax, rsp
|
||||
ret
|
||||
|
|
@ -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 (
|
||||
; UINT64 TemporaryMemoryBase,
|
||||
; UINT64 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
|
||||
|
|
@ -2,11 +2,13 @@
|
|||
Intel FSP Header File definition from Intel Firmware Support Package External
|
||||
Architecture Specification v2.0 and above.
|
||||
|
||||
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
|
||||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
|
||||
#ifndef __FSP_HEADER_FILE_H__
|
||||
#define __FSP_HEADER_FILE_H__
|
||||
|
||||
|
@ -24,6 +26,12 @@
|
|||
|
||||
#define FSP_INFO_HEADER_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'H')
|
||||
|
||||
#define IMAGE_ATTRIBUTE_GRAPHICS_SUPPORT BIT0
|
||||
#define IMAGE_ATTRIBUTE_DISPATCH_MODE_SUPPORT BIT1
|
||||
#define IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT BIT2
|
||||
#define FSP_IA32 0
|
||||
#define FSP_X64 1
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
///
|
||||
|
@ -49,7 +57,7 @@ typedef struct {
|
|||
UINT8 SpecVersion;
|
||||
///
|
||||
/// Byte 0x0B: Revision of the FSP Information Header.
|
||||
/// The Current value for this field is 0x6.
|
||||
/// The Current value for this field is 0x7.
|
||||
///
|
||||
UINT8 HeaderRevision;
|
||||
///
|
||||
|
@ -82,6 +90,10 @@ typedef struct {
|
|||
UINT32 ImageBase;
|
||||
///
|
||||
/// Byte 0x20: Attribute for the FSP binary.
|
||||
/// Bit 0: Graphics Support - Set to 1 when FSP supports enabling Graphics Display.
|
||||
/// 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.
|
||||
/// 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.
|
||||
/// Bits 15:3 - Reserved
|
||||
///
|
||||
UINT16 ImageAttribute;
|
||||
///
|
||||
|
|
|
@ -0,0 +1,284 @@
|
|||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
|
||||
; SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Provide macro for register save/restore using SSE registers
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;
|
||||
; Define SSE and AVX instruction set
|
||||
;
|
||||
;
|
||||
; Define SSE macros using SSE 4.1 instructions
|
||||
; args 1:XMM, 2:IDX, 3:REG
|
||||
;
|
||||
%macro SXMMN 3
|
||||
pinsrq %1, %3, (%2 & 3)
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; args 1:XMM, 2:REG, 3:IDX
|
||||
;
|
||||
%macro LXMMN 3
|
||||
pextrq %2, %1, (%3 & 3)
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Define AVX macros using AVX instructions
|
||||
; Save XMM to YMM
|
||||
; args 1:YMM, 2:IDX (0 - lower 128bits, 1 - upper 128bits), 3:XMM
|
||||
;
|
||||
%macro SYMMN 3
|
||||
vinsertf128 %1, %1, %3, %2
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Restore XMM from YMM
|
||||
; args 1:YMM, 2:XMM, 3:IDX (0 - lower 128bits, 1 - upper 128bits)
|
||||
;
|
||||
%macro LYMMN 3
|
||||
vextractf128 %2, %1, %3
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Upper half of YMM7 to save RBP and RBX. Upper half of YMM8 to save RSI and RDI.
|
||||
; Modified: XMM5, YMM6, YMM7 and YMM8
|
||||
;
|
||||
%macro SAVE_REGS 0
|
||||
SXMMN xmm5, 0, rbp
|
||||
SXMMN xmm5, 1, rbx
|
||||
SYMMN ymm7, 1, xmm5
|
||||
SXMMN xmm5, 0, rsi
|
||||
SXMMN xmm5, 1, rdi
|
||||
SYMMN ymm8, 1, xmm5
|
||||
SAVE_RSP
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Upper half of YMM7 to restore RBP and RBX. Upper half of YMM8 to restore RSI and RDI.
|
||||
; Modified: XMM5, RBP, RBX, RSI, RDI and RSP
|
||||
;
|
||||
%macro LOAD_REGS 0
|
||||
LYMMN ymm7, xmm5, 1
|
||||
LXMMN xmm5, rbp, 0
|
||||
LXMMN xmm5, rbx, 1
|
||||
LYMMN ymm8, xmm5, 1
|
||||
LXMMN xmm5, rsi, 0
|
||||
LXMMN xmm5, rdi, 1
|
||||
LOAD_RSP
|
||||
%endmacro
|
||||
;
|
||||
; Restore RBP from YMM7[128:191]
|
||||
; Modified: XMM5 and RBP
|
||||
;
|
||||
%macro LOAD_RBP 0
|
||||
LYMMN ymm7, xmm5, 1
|
||||
movq rbp, xmm5
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Restore RBX from YMM7[192:255]
|
||||
; Modified: XMM5 and RBX
|
||||
;
|
||||
%macro LOAD_RBX 0
|
||||
LYMMN ymm7, xmm5, 1
|
||||
LXMMN xmm5, rbx, 1
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Upper half of YMM6 to save/restore Time Stamp, RSP
|
||||
;
|
||||
;
|
||||
; Save Time Stamp to YMM6[192:255]
|
||||
; arg 1:general purpose register which holds time stamp
|
||||
; Modified: XMM5 and YMM6
|
||||
;
|
||||
%macro SAVE_TS 1
|
||||
LYMMN ymm6, xmm5, 1
|
||||
SXMMN xmm5, 1, %1
|
||||
SYMMN ymm6, 1, xmm5
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Restore Time Stamp from YMM6[192:255]
|
||||
; arg 1:general purpose register where to save time stamp
|
||||
; Modified: XMM5 and %1
|
||||
;
|
||||
%macro LOAD_TS 1
|
||||
LYMMN ymm6, xmm5, 1
|
||||
LXMMN xmm5, %1, 1
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Save RSP to YMM6[128:191]
|
||||
; Modified: XMM5 and YMM6
|
||||
;
|
||||
%macro SAVE_RSP 0
|
||||
LYMMN ymm6, xmm5, 1
|
||||
SXMMN xmm5, 0, rsp
|
||||
SYMMN ymm6, 1, xmm5
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Restore RSP from YMM6[128:191]
|
||||
; Modified: XMM5 and RSP
|
||||
;
|
||||
%macro LOAD_RSP 0
|
||||
LYMMN ymm6, xmm5, 1
|
||||
movq rsp, xmm5
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Upper half of YMM9 to save/restore UCODE status, BFV address
|
||||
;
|
||||
;
|
||||
; Save uCode status to YMM9[192:255]
|
||||
; arg 1:general purpose register which holds uCode status
|
||||
; Modified: XMM5 and YMM9
|
||||
;
|
||||
%macro SAVE_UCODE_STATUS 1
|
||||
LYMMN ymm9, xmm5, 1
|
||||
SXMMN xmm5, 0, %1
|
||||
SYMMN ymm9, 1, xmm5
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Restore uCode status from YMM9[192:255]
|
||||
; arg 1:general purpose register where to save uCode status
|
||||
; Modified: XMM5 and %1
|
||||
;
|
||||
%macro LOAD_UCODE_STATUS 1
|
||||
LYMMN ymm9, xmm5, 1
|
||||
movq %1, xmm5
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Save BFV address to YMM9[128:191]
|
||||
; arg 1:general purpose register which holds BFV address
|
||||
; Modified: XMM5 and YMM9
|
||||
;
|
||||
%macro SAVE_BFV 1
|
||||
LYMMN ymm9, xmm5, 1
|
||||
SXMMN xmm5, 1, %1
|
||||
SYMMN ymm9, 1, xmm5
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; Restore BFV address from YMM9[128:191]
|
||||
; arg 1:general purpose register where to save BFV address
|
||||
; Modified: XMM5 and %1
|
||||
;
|
||||
%macro LOAD_BFV 1
|
||||
LYMMN ymm9, xmm5, 1
|
||||
LXMMN xmm5, %1, 1
|
||||
%endmacro
|
||||
|
||||
;
|
||||
; YMM7[128:191] for calling stack
|
||||
; arg 1:Entry
|
||||
; Modified: RSI, XMM5, YMM7
|
||||
;
|
||||
%macro CALL_YMM 1
|
||||
mov rsi, %%ReturnAddress
|
||||
LYMMN ymm7, xmm5, 1
|
||||
SXMMN xmm5, 0, rsi
|
||||
SYMMN ymm7, 1, xmm5
|
||||
mov rsi, %1
|
||||
jmp rsi
|
||||
%%ReturnAddress:
|
||||
%endmacro
|
||||
;
|
||||
; Restore RIP from YMM7[128:191]
|
||||
; Modified: RSI, XMM5
|
||||
;
|
||||
%macro RET_YMM 0
|
||||
LYMMN ymm7, xmm5, 1
|
||||
movq rsi, xmm5
|
||||
jmp rsi
|
||||
%endmacro
|
||||
|
||||
%macro ENABLE_SSE 0
|
||||
;
|
||||
; Initialize floating point units
|
||||
;
|
||||
jmp NextAddress
|
||||
align 4
|
||||
;
|
||||
; Float control word initial value:
|
||||
; all exceptions masked, double-precision, round-to-nearest
|
||||
;
|
||||
FpuControlWord DW 027Fh
|
||||
;
|
||||
; Multimedia-extensions control word:
|
||||
; all exceptions masked, round-to-nearest, flush to zero for masked underflow
|
||||
;
|
||||
MmxControlWord DQ 01F80h
|
||||
SseError:
|
||||
;
|
||||
; Processor has to support SSE
|
||||
;
|
||||
jmp SseError
|
||||
NextAddress:
|
||||
finit
|
||||
mov rax, FpuControlWord
|
||||
fldcw [rax]
|
||||
|
||||
;
|
||||
; Use CpuId instruction (CPUID.01H:EDX.SSE[bit 25] = 1) to test
|
||||
; whether the processor supports SSE instruction.
|
||||
;
|
||||
mov rax, 1
|
||||
cpuid
|
||||
bt rdx, 25
|
||||
jnc SseError
|
||||
|
||||
;
|
||||
; SSE 4.1 support
|
||||
;
|
||||
bt ecx, 19
|
||||
jnc SseError
|
||||
|
||||
;
|
||||
; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
|
||||
;
|
||||
mov rax, cr4
|
||||
or rax, 00000600h
|
||||
mov cr4, rax
|
||||
|
||||
;
|
||||
; The processor should support SSE instruction and we can use
|
||||
; ldmxcsr instruction
|
||||
;
|
||||
mov rax, MmxControlWord
|
||||
ldmxcsr [rax]
|
||||
%endmacro
|
||||
|
||||
%macro ENABLE_AVX 0
|
||||
mov eax, 1
|
||||
cpuid
|
||||
and ecx, 10000000h
|
||||
cmp ecx, 10000000h ; check AVX feature flag
|
||||
je EnableAvx
|
||||
AvxError:
|
||||
;
|
||||
; Processor has to support AVX
|
||||
;
|
||||
jmp AvxError
|
||||
EnableAvx:
|
||||
;
|
||||
; Set OSXSAVE bit (bit #18) to enable xgetbv/xsetbv instruction
|
||||
;
|
||||
mov rax, cr4
|
||||
or rax, 00040000h
|
||||
mov cr4, rax
|
||||
|
||||
mov rcx, 0 ; index 0
|
||||
xgetbv ; result in edx:eax
|
||||
or eax, 00000006h ; Set XCR0 bit #1 and bit #2 to enable SSE state and AVX state
|
||||
xsetbv
|
||||
%endmacro
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/** @file
|
||||
|
||||
Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
@ -38,7 +38,8 @@ typedef struct {
|
|||
} CONTEXT_STACK;
|
||||
|
||||
//
|
||||
// API return address +0xB0
|
||||
// API return address +0xB8
|
||||
// Reserved +0xB0
|
||||
// push API Parameter2 +0xA8
|
||||
// push API Parameter1 +0xA0
|
||||
// push FspInfoHeader +0x98
|
||||
|
@ -54,6 +55,7 @@ typedef struct {
|
|||
UINT32 Flags[2];
|
||||
UINT64 FspInfoHeader;
|
||||
UINT64 ApiParam[2];
|
||||
UINT64 Reserved; // The reserved QWORD is needed for stack alignment in X64.
|
||||
UINT64 ApiRet; // 64bit stack format is different from the 32bit one due to x64 calling convention
|
||||
} CONTEXT_STACK_64;
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ ASM_PFX(Loader2PeiSwitchStack):
|
|||
;------------------------------------------------------------------------------
|
||||
global ASM_PFX(FspSwitchStack)
|
||||
ASM_PFX(FspSwitchStack):
|
||||
; Save current contexts
|
||||
; Save current contexts. The format must align with CONTEXT_STACK_64.
|
||||
push rdx ; Reserved QWORD for stack alignment
|
||||
push rdx ; ApiParam2
|
||||
push rcx ; ApiParam1
|
||||
push rax ; FspInfoHeader
|
||||
|
@ -67,6 +68,6 @@ ASM_PFX(FspSwitchStack):
|
|||
add rsp, 16
|
||||
POPA_64
|
||||
popfq
|
||||
add rsp, 24 ; FspInfoHeader + ApiParam[2]
|
||||
add rsp, 32 ; FspInfoHeader + ApiParam[2] + Reserved QWORD
|
||||
ret
|
||||
|
||||
|
|
Loading…
Reference in New Issue