Add IntelFspPkg to support create FSP bin based on EDKII.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed off by: Ravi Rangarajan <ravi.p.rangarajan@intel.com> Reviewed by: Maurice Ma <maurice.ma@intel.com> Reviewed by: Jiewen Yao <jiewen.yao@intel.com> Reviewed by: Giri Mudusuru <giri.p.mudusuru@intel.com> Reviewed by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15705 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
552
IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm
Normal file
552
IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm
Normal file
@@ -0,0 +1,552 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Provide FSP API entry points.
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.586p
|
||||
.model flat,C
|
||||
.code
|
||||
.xmm
|
||||
|
||||
INCLUDE SaveRestoreSse.inc
|
||||
INCLUDE UcodeLoad.inc
|
||||
|
||||
;
|
||||
; Following are fixed PCDs
|
||||
;
|
||||
EXTERN PcdGet32(PcdTemporaryRamBase):DWORD
|
||||
EXTERN PcdGet32(PcdTemporaryRamSize):DWORD
|
||||
EXTERN PcdGet32(PcdFspTemporaryRamSize):DWORD
|
||||
|
||||
;
|
||||
; Following functions will be provided in C
|
||||
;
|
||||
EXTERN FspImageSizeOffset:DWORD
|
||||
EXTERN SecStartup:PROC
|
||||
EXTERN FspApiCallingCheck:PROC
|
||||
|
||||
;
|
||||
; Following functions will be provided in PlatformSecLib
|
||||
;
|
||||
EXTERN GetFspBaseAddress:PROC
|
||||
EXTERN GetBootFirmwareVolumeOffset:PROC
|
||||
EXTERN PlatformTempRamInit:PROC
|
||||
EXTERN Pei2LoaderSwitchStack:PROC
|
||||
EXTERN FspSelfCheck(FspSelfCheckDflt):PROC
|
||||
EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC
|
||||
EXTERN LoadUcode(LoadUcodeDflt):PROC
|
||||
|
||||
;
|
||||
; 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)
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
FspSelfCheckDflt PROC NEAR PUBLIC
|
||||
; Inputs:
|
||||
; eax -> Return address
|
||||
; Outputs:
|
||||
; eax -> 0 - Successful, Non-zero - Failed.
|
||||
; Register Usage:
|
||||
; eax is cleared and ebp is used for return address.
|
||||
; All others reserved.
|
||||
|
||||
; Save return address to EBP
|
||||
mov ebp, eax
|
||||
|
||||
xor eax, eax
|
||||
exit:
|
||||
jmp ebp
|
||||
FspSelfCheckDflt ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
PlatformBasicInitDflt PROC NEAR PUBLIC
|
||||
; Inputs:
|
||||
; eax -> Return address
|
||||
; Outputs:
|
||||
; eax -> 0 - Successful, Non-zero - Failed.
|
||||
; Register Usage:
|
||||
; eax is cleared and ebp is used for return address.
|
||||
; All others reserved.
|
||||
|
||||
; Save return address to EBP
|
||||
mov ebp, eax
|
||||
|
||||
xor eax, eax
|
||||
exit:
|
||||
jmp ebp
|
||||
PlatformBasicInitDflt ENDP
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
LoadUcodeDflt PROC NEAR PUBLIC
|
||||
; Inputs:
|
||||
; esp -> LOAD_UCODE_PARAMS pointer
|
||||
; Register Usage:
|
||||
; esp 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 EBP
|
||||
mov ebp, eax
|
||||
|
||||
cmp esp, 0
|
||||
jz paramerror
|
||||
mov eax, dword ptr [esp] ; Parameter pointer
|
||||
cmp eax, 0
|
||||
jz paramerror
|
||||
mov esp, eax
|
||||
mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
cmp esi, 0
|
||||
jnz check_main_header
|
||||
|
||||
paramerror:
|
||||
mov eax, 080000002h
|
||||
jmp exit
|
||||
|
||||
mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
|
||||
check_main_header:
|
||||
; 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
|
||||
and ecx, 7h
|
||||
mov edx, 1
|
||||
shl edx, cl
|
||||
|
||||
; Current register usage
|
||||
; esp -> stack with paramters
|
||||
; 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 ptr 1
|
||||
cmp [esi].ucode_hdr.version, eax
|
||||
jne advance_fixed_size
|
||||
cmp [esi].ucode_hdr.loader, eax
|
||||
jne advance_fixed_size
|
||||
|
||||
; Check if signature and plaform ID match
|
||||
cmp ebx, [esi].ucode_hdr.processor
|
||||
jne @f
|
||||
test edx, [esi].ucode_hdr.flags
|
||||
jnz load_check ; Jif signature and platform ID match
|
||||
|
||||
@@:
|
||||
; Check if extended header exists
|
||||
; First check if total_size and data_size are valid
|
||||
xor eax, eax
|
||||
cmp [esi].ucode_hdr.total_size, eax
|
||||
je next_microcode
|
||||
cmp [esi].ucode_hdr.data_size, eax
|
||||
je next_microcode
|
||||
|
||||
; Then verify total size - sizeof header > data size
|
||||
mov ecx, [esi].ucode_hdr.total_size
|
||||
sub ecx, sizeof ucode_hdr
|
||||
cmp ecx, [esi].ucode_hdr.data_size
|
||||
jng next_microcode ; Jif extended header does not exist
|
||||
|
||||
; Set edi -> extended header
|
||||
mov edi, esi
|
||||
add edi, sizeof ucode_hdr
|
||||
add edi, [esi].ucode_hdr.data_size
|
||||
|
||||
; Get count of extended structures
|
||||
mov ecx, [edi].ext_sig_hdr.count
|
||||
|
||||
; Move pointer to first signature structure
|
||||
add edi, sizeof ext_sig_hdr
|
||||
|
||||
check_ext_sig:
|
||||
; Check if extended signature and platform ID match
|
||||
cmp [edi].ext_sig.processor, ebx
|
||||
jne @f
|
||||
test [edi].ext_sig.flags, edx
|
||||
jnz load_check ; Jif signature and platform ID match
|
||||
@@:
|
||||
; Check if any more extended signatures exist
|
||||
add edi, sizeof ext_sig
|
||||
loop check_ext_sig
|
||||
|
||||
next_microcode:
|
||||
; Advance just after end of this microcode
|
||||
xor eax, eax
|
||||
cmp [esi].ucode_hdr.total_size, eax
|
||||
je @f
|
||||
add esi, [esi].ucode_hdr.total_size
|
||||
jmp check_address
|
||||
@@:
|
||||
add esi, dword ptr 2048
|
||||
jmp check_address
|
||||
|
||||
advance_fixed_size:
|
||||
; Advance by 4X dwords
|
||||
add esi, dword ptr 1024
|
||||
|
||||
check_address:
|
||||
; Is valid Microcode start point ?
|
||||
cmp dword ptr [esi], 0ffffffffh
|
||||
jz done
|
||||
|
||||
; Address >= microcode region address + microcode region size?
|
||||
mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size
|
||||
cmp esi, eax
|
||||
jae done ;Jif address is outside of ucode region
|
||||
jmp check_main_header
|
||||
|
||||
load_check:
|
||||
; 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 [esi].ucode_hdr.revision, edx
|
||||
je continue
|
||||
|
||||
load_microcode:
|
||||
; 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, sizeof ucode_hdr
|
||||
xor edx, edx
|
||||
mov ecx, MSR_IA32_BIOS_UPDT_TRIG
|
||||
wrmsr
|
||||
mov eax, 1
|
||||
cpuid
|
||||
|
||||
continue:
|
||||
jmp next_microcode
|
||||
|
||||
done:
|
||||
mov eax, 1
|
||||
cpuid
|
||||
mov ecx, MSR_IA32_BIOS_SIGN_ID
|
||||
rdmsr ; Get current microcode signature
|
||||
xor eax, eax
|
||||
cmp edx, 0
|
||||
jnz exit
|
||||
mov eax, 08000000Eh
|
||||
|
||||
exit:
|
||||
jmp ebp
|
||||
|
||||
LoadUcodeDflt ENDP
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; 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.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
TempRamInitApi PROC NEAR PUBLIC
|
||||
;
|
||||
; Ensure SSE is enabled
|
||||
;
|
||||
ENABLE_SSE
|
||||
|
||||
;
|
||||
; Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
|
||||
;
|
||||
SAVE_REGS
|
||||
|
||||
;
|
||||
; Save timestamp into XMM4 & XMM5
|
||||
;
|
||||
rdtsc
|
||||
SAVE_EAX
|
||||
SAVE_EDX
|
||||
|
||||
;
|
||||
; Check Parameter
|
||||
;
|
||||
mov eax, dword ptr [esp + 4]
|
||||
cmp eax, 0
|
||||
mov eax, 80000002h
|
||||
jz NemInitExit
|
||||
|
||||
;
|
||||
; CPUID/DeviceID check
|
||||
;
|
||||
mov eax, @F
|
||||
jmp FspSelfCheck ; Note: ESP can not be changed.
|
||||
@@:
|
||||
cmp eax, 0
|
||||
jnz NemInitExit
|
||||
|
||||
;
|
||||
; Platform Basic Init.
|
||||
;
|
||||
mov eax, @F
|
||||
jmp PlatformBasicInit
|
||||
@@:
|
||||
cmp eax, 0
|
||||
jnz NemInitExit
|
||||
|
||||
;
|
||||
; Load microcode
|
||||
;
|
||||
mov eax, @F
|
||||
add esp, 4
|
||||
jmp LoadUcode
|
||||
@@:
|
||||
LOAD_ESP
|
||||
cmp eax, 0
|
||||
jnz NemInitExit
|
||||
|
||||
;
|
||||
; Call platform NEM init
|
||||
;
|
||||
mov eax, @F
|
||||
add esp, 4
|
||||
jmp PlatformTempRamInit
|
||||
@@:
|
||||
LOAD_ESP
|
||||
cmp eax, 0
|
||||
jnz NemInitExit
|
||||
|
||||
;
|
||||
; Save parameter pointer in edx
|
||||
;
|
||||
mov edx, dword ptr [esp + 4]
|
||||
|
||||
;
|
||||
; Enable FSP STACK
|
||||
;
|
||||
mov esp, PcdGet32(PcdTemporaryRamBase)
|
||||
add esp, PcdGet32(PcdTemporaryRamSize)
|
||||
|
||||
push DATA_LEN_OF_MCUD ; Size of the data region
|
||||
push 4455434Dh ; Signature of the data region 'MCUD'
|
||||
push dword ptr [edx + 4] ; Microcode size
|
||||
push dword ptr [edx + 0] ; Microcode base
|
||||
push dword ptr [edx + 12] ; Code size
|
||||
push dword ptr [edx + 8] ; Code base
|
||||
|
||||
;
|
||||
; Save API entry/exit timestamp into stack
|
||||
;
|
||||
push DATA_LEN_OF_PER0 ; Size of the data region
|
||||
push 30524550h ; Signature of the data region 'PER0'
|
||||
rdtsc
|
||||
push edx
|
||||
push eax
|
||||
LOAD_EAX
|
||||
LOAD_EDX
|
||||
push edx
|
||||
push eax
|
||||
|
||||
;
|
||||
; Terminator for the data on stack
|
||||
;
|
||||
push 0
|
||||
|
||||
;
|
||||
; Set ECX/EDX to the bootloader temporary memory range
|
||||
;
|
||||
mov ecx, PcdGet32(PcdTemporaryRamBase)
|
||||
mov edx, ecx
|
||||
add edx, PcdGet32(PcdTemporaryRamSize)
|
||||
sub edx, PcdGet32(PcdFspTemporaryRamSize)
|
||||
|
||||
xor eax, eax
|
||||
|
||||
NemInitExit:
|
||||
;
|
||||
; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
|
||||
;
|
||||
LOAD_REGS
|
||||
ret
|
||||
TempRamInitApi ENDP
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; FspInit API
|
||||
;
|
||||
; This FSP API will perform the processor and chipset initialization.
|
||||
; This API will not return. Instead, it transfers the control to the
|
||||
; ContinuationFunc provided in the parameter.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
FspInitApi PROC NEAR PUBLIC
|
||||
;
|
||||
; Stack must be ready
|
||||
;
|
||||
push 087654321h
|
||||
pop eax
|
||||
cmp eax, 087654321h
|
||||
jz @F
|
||||
mov eax, 080000003h
|
||||
jmp exit
|
||||
|
||||
@@:
|
||||
;
|
||||
; Additional check
|
||||
;
|
||||
pushad
|
||||
push 1
|
||||
call FspApiCallingCheck
|
||||
add esp, 4
|
||||
mov dword ptr [esp + 4 * 7], eax
|
||||
popad
|
||||
cmp eax, 0
|
||||
jz @F
|
||||
jmp exit
|
||||
|
||||
@@:
|
||||
;
|
||||
; Store the address in FSP which will return control to the BL
|
||||
;
|
||||
push offset exit
|
||||
|
||||
;
|
||||
; Create a Task Frame in the stack for the Boot Loader
|
||||
;
|
||||
pushfd ; 2 pushf for 4 byte alignment
|
||||
cli
|
||||
pushad
|
||||
|
||||
; Reserve 8 bytes for IDT save/restore
|
||||
sub esp, 8
|
||||
sidt fword ptr [esp]
|
||||
|
||||
;
|
||||
; Setup new FSP stack
|
||||
;
|
||||
mov eax, esp
|
||||
mov esp, PcdGet32(PcdTemporaryRamBase)
|
||||
add esp, PcdGet32(PcdTemporaryRamSize)
|
||||
sub esp, (DATA_LEN_AT_STACK_TOP + 40h)
|
||||
|
||||
;
|
||||
; Save the bootloader's stack pointer
|
||||
;
|
||||
push eax
|
||||
|
||||
;
|
||||
; Pass entry point of the PEI core
|
||||
;
|
||||
call GetFspBaseAddress
|
||||
mov edi, FspImageSizeOffset
|
||||
mov edi, DWORD PTR [eax + edi]
|
||||
add edi, eax
|
||||
sub edi, 20h
|
||||
add eax, DWORD PTR [edi]
|
||||
push eax
|
||||
|
||||
;
|
||||
; Pass BFV into the PEI Core
|
||||
; It uses relative address to calucate the actual boot FV base
|
||||
; For FSP impleantion with single FV, PcdFlashFvRecoveryBase and
|
||||
; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,
|
||||
; they are different. The code below can handle both cases.
|
||||
;
|
||||
call GetFspBaseAddress
|
||||
mov edi, eax
|
||||
call GetBootFirmwareVolumeOffset
|
||||
add eax, edi
|
||||
push eax
|
||||
|
||||
;
|
||||
; Pass stack base and size into the PEI Core
|
||||
;
|
||||
mov eax, PcdGet32(PcdTemporaryRamBase)
|
||||
add eax, PcdGet32(PcdTemporaryRamSize)
|
||||
sub eax, PcdGet32(PcdFspTemporaryRamSize)
|
||||
push eax
|
||||
push PcdGet32(PcdFspTemporaryRamSize)
|
||||
|
||||
;
|
||||
; Pass Control into the PEI Core
|
||||
;
|
||||
call SecStartup
|
||||
|
||||
exit:
|
||||
ret
|
||||
|
||||
FspInitApi ENDP
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; NotifyPhase API
|
||||
;
|
||||
; This FSP API will notify the FSP about the different phases in the boot
|
||||
; process
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
NotifyPhaseApi PROC C PUBLIC
|
||||
;
|
||||
; Stack must be ready
|
||||
;
|
||||
push 087654321h
|
||||
pop eax
|
||||
cmp eax, 087654321h
|
||||
jz @F
|
||||
mov eax, 080000003h
|
||||
jmp err_exit
|
||||
|
||||
@@:
|
||||
;
|
||||
; Verify the calling condition
|
||||
;
|
||||
pushad
|
||||
push 2
|
||||
call FspApiCallingCheck
|
||||
add esp, 4
|
||||
mov dword ptr [esp + 4 * 7], eax
|
||||
popad
|
||||
|
||||
cmp eax, 0
|
||||
jz @F
|
||||
|
||||
;
|
||||
; Error return
|
||||
;
|
||||
err_exit:
|
||||
ret
|
||||
|
||||
@@:
|
||||
jmp Pei2LoaderSwitchStack
|
||||
|
||||
NotifyPhaseApi ENDP
|
||||
|
||||
|
||||
END
|
611
IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
Normal file
611
IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
Normal file
@@ -0,0 +1,611 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Provide FSP API entry points.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#.INCLUDE "UcodeLoad.inc"
|
||||
|
||||
#
|
||||
# Following are fixed PCDs
|
||||
#
|
||||
|
||||
.equ MSR_IA32_PLATFORM_ID, 0x000000017
|
||||
.equ MSR_IA32_BIOS_UPDT_TRIG, 0x000000079
|
||||
.equ MSR_IA32_BIOS_SIGN_ID, 0x00000008b
|
||||
|
||||
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)
|
||||
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)
|
||||
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
|
||||
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize)
|
||||
|
||||
|
||||
#
|
||||
# Following functions will be provided in C
|
||||
#
|
||||
#EXTERNDEF SecStartup:PROC
|
||||
#EXTERNDEF FspApiCallingCheck:PROC
|
||||
|
||||
#
|
||||
# Following functions will be provided in PlatformSecLib
|
||||
#
|
||||
#EXTERNDEF GetFspBaseAddress:PROC
|
||||
#EXTERNDEF GetBootFirmwareVolumeOffset:PROC
|
||||
#EXTERNDEF PlatformTempRamInit:PROC
|
||||
#EXTERNDEF Pei2LoaderSwitchStack:PROC
|
||||
#EXTERN FspSelfCheck(FspSelfCheckDflt):PROC
|
||||
#EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC
|
||||
|
||||
#
|
||||
# Define the data length that we saved on the stack top
|
||||
#
|
||||
.equ DATA_LEN_OF_PER0, 0x018
|
||||
.equ DATA_LEN_OF_MCUD, 0x018
|
||||
.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
|
||||
|
||||
#
|
||||
# Define SSE macros
|
||||
#
|
||||
.macro ENABLE_SSE
|
||||
movl %cr4, %eax
|
||||
orl $0x00000600,%eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
|
||||
movl %eax,%cr4
|
||||
.endm
|
||||
|
||||
.macro SAVE_REGS
|
||||
movd %ebp, %xmm7
|
||||
pshufd $0x93, %xmm7, %xmm7
|
||||
movd %ebx, %xmm6
|
||||
por %xmm6, %xmm7
|
||||
pshufd $0x93, %xmm7, %xmm7
|
||||
movd %esi,%xmm6
|
||||
por %xmm6, %xmm7
|
||||
pshufd $0x93, %xmm7, %xmm7
|
||||
movd %edi, %xmm6
|
||||
por %xmm6, %xmm7
|
||||
movd %esp, %xmm6
|
||||
.endm
|
||||
|
||||
.macro LOAD_REGS
|
||||
movd %xmm6, %esp
|
||||
movd %xmm7, %edi
|
||||
pshufd $0x39,%xmm7, %xmm7
|
||||
movd %xmm7, %esi
|
||||
pshufd $0x39,%xmm7, %xmm7
|
||||
movd %xmm7, %ebx
|
||||
pshufd $0x39, %xmm7, %xmm7
|
||||
movd %xmm7, %ebp
|
||||
.endm
|
||||
|
||||
.macro LOAD_ESP
|
||||
movd %xmm6, %esp
|
||||
.endm
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(FspSelfCheckDflt)
|
||||
ASM_PFX(FspSelfCheckDflt):
|
||||
# Inputs:
|
||||
# eax -> Return address
|
||||
# Outputs:
|
||||
# eax -> 0 - Successful, Non-zero - Failed.
|
||||
# Register Usage:
|
||||
# eax is cleared and ebp is used for return address.
|
||||
# All others reserved.
|
||||
|
||||
# Save return address to EBP
|
||||
movl %eax, %ebp
|
||||
xorl %eax, %eax
|
||||
exit:
|
||||
jmp *%ebp
|
||||
#FspSelfCheckDflt ENDP
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(PlatformBasicInitDflt)
|
||||
ASM_PFX(PlatformBasicInitDflt):
|
||||
# Inputs:
|
||||
# eax -> Return address
|
||||
# Outputs:
|
||||
# eax -> 0 - Successful, Non-zero - Failed.
|
||||
# Register Usage:
|
||||
# eax is cleared and ebp is used for return address.
|
||||
# All others reserved.
|
||||
|
||||
# Save return address to EBP
|
||||
movl %eax, %ebp
|
||||
xorl %eax, %eax
|
||||
exit2:
|
||||
jmp *%ebp
|
||||
#PlatformBasicInitDflt ENDP
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(LoadUcode)
|
||||
ASM_PFX(LoadUcode):
|
||||
# Inputs:
|
||||
# esp -> LOAD_UCODE_PARAMS pointer
|
||||
# Register Usage:
|
||||
# esp 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 EBP
|
||||
movl %eax, %ebp
|
||||
cmpl $0, %esp
|
||||
jz paramerror
|
||||
movl (%esp), %eax #dword ptr [] Parameter pointer
|
||||
cmpl $0, %eax
|
||||
jz paramerror
|
||||
movl %eax, %esp
|
||||
movl (%esp), %esi #LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
cmpl $0, %esi
|
||||
jnz L0
|
||||
|
||||
paramerror:
|
||||
movl $0x080000002, %eax
|
||||
jmp exit4
|
||||
|
||||
movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
|
||||
check_main_header:
|
||||
# Get processor signature and platform ID from the installed processor
|
||||
# and save into registers for later use
|
||||
# ebx = processor signature
|
||||
# edx = platform ID
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
movl %eax, %ebx
|
||||
movl MSR_IA32_PLATFORM_ID, %ecx
|
||||
rdmsr
|
||||
movl %edx, %ecx
|
||||
#--------------------------------------------------------------------------------------------------------------------
|
||||
shrl $18, %ecx #($50-$32)
|
||||
andl $0x7, %ecx
|
||||
movl $1, %edx
|
||||
shll %cl,%edx
|
||||
|
||||
# Current register usage
|
||||
# esp -> stack with paramters
|
||||
# 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
|
||||
movl $1, %eax
|
||||
cmpl %eax, (%esi) #.ucode_hdr.version
|
||||
jne advance_fixed_size
|
||||
cmpl %eax, 0x18(%esi) #.ucode_hdr.loader
|
||||
jne advance_fixed_size
|
||||
|
||||
# Check if signature and plaform ID match
|
||||
#--------------------------------------------------------------------------------------------------------------------------
|
||||
cmpl 0x10(%esi), %ebx #(%esi).ucode_hdr.processor
|
||||
jne L0
|
||||
testl 0x1c(%esi) , %edx #(%esi).ucode_hdr.flags
|
||||
jnz load_check # Jif signature and platform ID match
|
||||
|
||||
L0:
|
||||
# Check if extended header exists
|
||||
# First check if total_size and data_size are valid
|
||||
xorl %eax, %eax
|
||||
cmpl %eax,0x24(%esi) #(%esi).ucode_hdr.total_size
|
||||
je next_microcode
|
||||
cmpl %eax,0x20(%esi) #(%esi) .ucode_hdr.data_size
|
||||
je next_microcode
|
||||
|
||||
# Then verify total size - sizeof header > data size
|
||||
movl 0x24(%esi), %ecx #(%esi).ucode_hdr.total_size
|
||||
subl $0x30, %ecx #sizeof ucode_hdr = 48
|
||||
cmpl 0x20(%esi), %ecx #(%esi).ucode_hdr.data_size
|
||||
jz load_check
|
||||
jb next_microcode # Jif extended header does not exist
|
||||
|
||||
# Check if total size fits in microcode region
|
||||
movl %esi , %edi
|
||||
addl 0x24(%esi), %edi # (%esi).ucode_hdr.total_size
|
||||
movl (%esp), %ecx # (%esp).LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
addl 4(%esp), %ecx #.LOAD_UCODE_PARAMS.ucode_code_size
|
||||
cmpl %ecx , %edi
|
||||
xorl %eax, %eax
|
||||
ja exit4 # Jif address is outside of ucode region
|
||||
|
||||
# Set edi -> extended header
|
||||
movl %esi , %edi
|
||||
addl $0x30 , %edi #sizeof ucode_hdr = 48
|
||||
addl 0x20(%esi), %edi #%esi.ucode_hdr.data_size
|
||||
|
||||
# Get count of extended structures
|
||||
movl (%edi), %ecx #(%edi).ext_sig_hdr.count
|
||||
|
||||
# Move pointer to first signature structure
|
||||
addl $0x20, %edi # sizeof ext_sig_hdr = 20
|
||||
|
||||
check_ext_sig:
|
||||
# Check if extended signature and platform ID match
|
||||
cmpl %ebx, (%edi) #[edi].ext_sig.processor
|
||||
jne L1
|
||||
test %edx, 4(%edi) #[edi].ext_sig.flags
|
||||
jnz load_check # Jif signature and platform ID match
|
||||
L9:
|
||||
# Check if any more extended signatures exist
|
||||
addl $0xc, %edi #sizeof ext_sig = 12
|
||||
loop check_ext_sig
|
||||
|
||||
next_microcode:
|
||||
# Advance just after end of this microcode
|
||||
xorl %eax, %eax
|
||||
cmpl %eax, 0x24(%esi) #(%esi).ucode_hdr.total_size
|
||||
je L2
|
||||
add 0x24(%esi) , %esi #(%esi).ucode_hdr.total_size
|
||||
jmp check_address
|
||||
L10:
|
||||
addl $0x800, %esi
|
||||
jmp check_address
|
||||
|
||||
advance_fixed_size:
|
||||
# Advance by 4X dwords
|
||||
addl $0x400, %esi
|
||||
|
||||
check_address:
|
||||
# Is valid Microcode start point ?
|
||||
cmp $0x0ffffffff , %esi
|
||||
jz done
|
||||
|
||||
# Address >= microcode region address + microcode region size?
|
||||
movl (%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
addl 4(%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_size
|
||||
cmpl %eax, %esi
|
||||
jae done #Jif address is outside of ucode region
|
||||
jmp check_main_header
|
||||
|
||||
load_check:
|
||||
# Get the revision of the current microcode update loaded
|
||||
movl MSR_IA32_BIOS_SIGN_ID, %ecx
|
||||
xorl %eax, %eax # Clear EAX
|
||||
xorl %edx, %edx # Clear EDX
|
||||
wrmsr # Load 0 to MSR at 8Bh
|
||||
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
movl MSR_IA32_BIOS_SIGN_ID, %ecx
|
||||
rdmsr # Get current microcode signature
|
||||
|
||||
# Verify this microcode update is not already loaded
|
||||
cmpl %edx, 4(%esi) #(%esi).ucode_hdr.revision
|
||||
je continue
|
||||
|
||||
load_microcode:
|
||||
# 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 %esi, %eax
|
||||
add $0x30, %eax #sizeof ucode_hdr = 48
|
||||
xorl %edx, %edx
|
||||
mov MSR_IA32_BIOS_UPDT_TRIG,%ecx
|
||||
wrmsr
|
||||
mov $1, %eax
|
||||
cpuid
|
||||
|
||||
continue:
|
||||
jmp next_microcode
|
||||
|
||||
done:
|
||||
mov $1, %eax
|
||||
cpuid
|
||||
mov MSR_IA32_BIOS_SIGN_ID, %ecx
|
||||
rdmsr # Get current microcode signature
|
||||
xorl %eax, %eax
|
||||
cmp $0 , %edx
|
||||
jnz exit4
|
||||
mov $0x08000000E, %eax
|
||||
|
||||
exit4:
|
||||
jmp *%ebp
|
||||
|
||||
#LoadUcode ENDP
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# 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.
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(TempRamInitApi)
|
||||
ASM_PFX(TempRamInitApi):
|
||||
#
|
||||
# Ensure SSE is enabled
|
||||
#
|
||||
ENABLE_SSE
|
||||
|
||||
#
|
||||
# Save EBP, EBX, ESI, EDI & ESP in XMM7 & XMM6
|
||||
#
|
||||
SAVE_REGS
|
||||
|
||||
#
|
||||
# Save timestamp into XMM4 & XMM5
|
||||
#
|
||||
rdtsc
|
||||
movd %edx, %xmm4
|
||||
movd %eax, %xmm5
|
||||
|
||||
#
|
||||
# CPUID/DeviceID check
|
||||
#
|
||||
movl L11, %eax
|
||||
jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed.
|
||||
L11:
|
||||
cmpl $0, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
# Platform Basic Init.
|
||||
#
|
||||
movl L1, %eax
|
||||
jmp ASM_PFX(PlatformBasicInitDflt)
|
||||
L1:
|
||||
cmp $0, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
# Load microcode
|
||||
#
|
||||
movl L2, %eax
|
||||
addl $4, %esp
|
||||
jmp LoadUcode
|
||||
L2:
|
||||
LOAD_ESP
|
||||
cmpl $0, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
# Call platform NEM init
|
||||
#-------------------------------------------------------------------------------------------------------------------------
|
||||
movl L3, %eax
|
||||
addl $4, %esp
|
||||
jmp ASM_PFX(PlatformTempRamInit)
|
||||
L3:
|
||||
subl $4, %esp
|
||||
cmpl $0, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
# Save parameter pointer in edx
|
||||
#
|
||||
movl 4(%esp), %edx
|
||||
|
||||
#
|
||||
# Enable FSP STACK
|
||||
#
|
||||
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
|
||||
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
|
||||
|
||||
pushl $DATA_LEN_OF_MCUD # Size of the data region
|
||||
pushl 0x4455434D # Signature of the data region 'MCUD'
|
||||
pushl 12(%edx) # Code size
|
||||
pushl 8(%edx) # Code base
|
||||
cmpl $0, %edx # Is parameter pointer valid ?
|
||||
jz InvalidMicrocodeRegion
|
||||
pushl 4(%edx) # Microcode size
|
||||
pushl (%edx) # Microcode base
|
||||
jmp L4
|
||||
|
||||
InvalidMicrocodeRegion:
|
||||
pushl $0 # Microcode size
|
||||
pushl $0 # Microcode base
|
||||
|
||||
L4:
|
||||
#
|
||||
# Save API entry/exit timestamp into stack
|
||||
#
|
||||
pushl DATA_LEN_OF_PER0 # Size of the data region
|
||||
pushl 0x30524550 # Signature of the data region 'PER0'
|
||||
movd %xmm4, %eax
|
||||
pushl %eax
|
||||
movd %xmm5, %eax
|
||||
pushl %eax
|
||||
rdtsc
|
||||
pushl %edx
|
||||
pushl %eax
|
||||
|
||||
#
|
||||
# Terminator for the data on stack
|
||||
#
|
||||
pushl $0
|
||||
|
||||
#
|
||||
# Set ECX/EDX to the bootloader temporary memory range
|
||||
#
|
||||
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx
|
||||
movl %ecx, %edx
|
||||
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx
|
||||
subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx
|
||||
|
||||
xorl %eax, %eax
|
||||
|
||||
NemInitExit:
|
||||
#
|
||||
# Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
|
||||
#
|
||||
LOAD_REGS
|
||||
ret
|
||||
#TempRamInitApi ENDP
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# FspInit API
|
||||
#
|
||||
# This FSP API will perform the processor and chipset initialization.
|
||||
# This API will not return. Instead, it transfers the control to the
|
||||
# ContinuationFunc provided in the parameter.
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(FspInitApi)
|
||||
ASM_PFX(FspInitApi):
|
||||
#
|
||||
# Stack must be ready
|
||||
#
|
||||
pushl $0x087654321
|
||||
pop %eax
|
||||
cmpl $0x087654321, %eax
|
||||
jz L5
|
||||
movl $0x080000003, %eax
|
||||
jmp exit3
|
||||
|
||||
L5:
|
||||
#
|
||||
# Additional check
|
||||
#
|
||||
pusha
|
||||
pushl $1
|
||||
call ASM_PFX(FspApiCallingCheck)
|
||||
addl $4, %esp
|
||||
movl %eax, 28(%esp)
|
||||
popa
|
||||
cmpl $0 , %eax
|
||||
jz L6
|
||||
jmp exit3
|
||||
|
||||
L6:
|
||||
#
|
||||
# Save the Platform Data Pointer in EDI
|
||||
#
|
||||
movl 4(%esp), %edi
|
||||
|
||||
#
|
||||
# Store the address in FSP which will return control to the BL
|
||||
#
|
||||
pushl $exit3
|
||||
|
||||
#
|
||||
# Create a Task Frame in the stack for the Boot Loader
|
||||
#
|
||||
pushfl
|
||||
pushfl # 2 pushf for 4 byte alignment
|
||||
cli
|
||||
pushal
|
||||
|
||||
# Reserve 8 bytes for IDT save/restore
|
||||
pushl $0
|
||||
pushl $0
|
||||
sidt (%esp)
|
||||
|
||||
#
|
||||
# Setup new FSP stack
|
||||
#
|
||||
movl %esp, %eax
|
||||
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
|
||||
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) , %esp
|
||||
subl DATA_LEN_AT_STACK_TOP, %esp
|
||||
addl $0x0FFFFFFC0, %esp
|
||||
|
||||
#
|
||||
# Save the bootloader's stack pointer
|
||||
#
|
||||
pushl %eax
|
||||
|
||||
#
|
||||
# Pass entry point of the PEI core
|
||||
#
|
||||
call ASM_PFX(GetFspBaseAddress)
|
||||
movl %eax, %edi
|
||||
addl ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi
|
||||
subl $0x20, %edi
|
||||
addl %ds:(%edi), %eax
|
||||
pushl %eax
|
||||
|
||||
#
|
||||
# Pass BFV into the PEI Core
|
||||
# It uses relative address to calucate the actual boot FV base
|
||||
# For FSP impleantion with single FV, PcdFlashFvRecoveryBase and
|
||||
# PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,
|
||||
# they are different. The code below can handle both cases.
|
||||
#
|
||||
call ASM_PFX(GetFspBaseAddress)
|
||||
movl %eax , %edi
|
||||
call ASM_PFX(GetBootFirmwareVolumeOffset)
|
||||
addl %edi ,%eax
|
||||
pushl %eax
|
||||
|
||||
#
|
||||
# Pass stack base and size into the PEI Core
|
||||
#
|
||||
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %eax
|
||||
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %eax
|
||||
subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %eax
|
||||
pushl %eax
|
||||
pushl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
|
||||
|
||||
#
|
||||
# Pass Control into the PEI Core
|
||||
#
|
||||
call ASM_PFX(SecStartup)
|
||||
|
||||
exit3:
|
||||
ret
|
||||
|
||||
# FspInitApi ENDP
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# NotifyPhase API
|
||||
#
|
||||
# This FSP API will notify the FSP about the different phases in the boot
|
||||
# process
|
||||
#
|
||||
#----------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(NotifyPhaseApi)
|
||||
ASM_PFX(NotifyPhaseApi):
|
||||
#
|
||||
# Stack must be ready
|
||||
#
|
||||
pushl $0x0087654321
|
||||
pop %eax
|
||||
cmpl $0x087654321, %eax
|
||||
jz L7
|
||||
movl $0x080000003, %eax
|
||||
jmp err_exit
|
||||
|
||||
L7:
|
||||
#
|
||||
# Verify the calling condition
|
||||
#
|
||||
pusha
|
||||
pushl $2
|
||||
call ASM_PFX(FspApiCallingCheck)
|
||||
add $4, %esp
|
||||
mov %eax, 28(%esp)
|
||||
popa
|
||||
|
||||
cmpl $0, %eax
|
||||
jz L8
|
||||
|
||||
#
|
||||
# Error return
|
||||
#
|
||||
err_exit:
|
||||
ret
|
||||
|
||||
L8:
|
||||
jmp ASM_PFX(Pei2LoaderSwitchStack)
|
||||
|
||||
#NotifyPhaseApi ENDP
|
||||
|
||||
|
||||
#END
|
79
IntelFspPkg/FspSecCore/Ia32/InitializeFpu.asm
Normal file
79
IntelFspPkg/FspSecCore/Ia32/InitializeFpu.asm
Normal file
@@ -0,0 +1,79 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.686
|
||||
.model flat,C
|
||||
.const
|
||||
;
|
||||
; Float control word initial value:
|
||||
; all exceptions masked, double-precision, round-to-nearest
|
||||
;
|
||||
mFpuControlWord DW 027Fh
|
||||
;
|
||||
; Multimedia-extensions control word:
|
||||
; all exceptions masked, round-to-nearest, flush to zero for masked underflow
|
||||
;
|
||||
mMmxControlWord DD 01F80h
|
||||
|
||||
.xmm
|
||||
.code
|
||||
|
||||
;
|
||||
; Initializes floating point units for requirement of UEFI specification.
|
||||
;
|
||||
; This function initializes floating-point control word to 0x027F (all exceptions
|
||||
; masked,double-precision, round-to-nearest) and multimedia-extensions control word
|
||||
; (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero
|
||||
; for masked underflow).
|
||||
;
|
||||
InitializeFloatingPointUnits PROC PUBLIC
|
||||
|
||||
push ebx
|
||||
|
||||
;
|
||||
; Initialize floating point units
|
||||
;
|
||||
finit
|
||||
fldcw mFpuControlWord
|
||||
|
||||
;
|
||||
; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test
|
||||
; whether the processor supports SSE instruction.
|
||||
;
|
||||
mov eax, 1
|
||||
cpuid
|
||||
bt edx, 25
|
||||
jnc Done
|
||||
|
||||
;
|
||||
; Set OSFXSR bit 9 in CR4
|
||||
;
|
||||
mov eax, cr4
|
||||
or eax, BIT9
|
||||
mov cr4, eax
|
||||
|
||||
;
|
||||
; The processor should support SSE instruction and we can use
|
||||
; ldmxcsr instruction
|
||||
;
|
||||
ldmxcsr mMmxControlWord
|
||||
Done:
|
||||
pop ebx
|
||||
|
||||
ret
|
||||
|
||||
InitializeFloatingPointUnits ENDP
|
||||
|
||||
END
|
73
IntelFspPkg/FspSecCore/Ia32/InitializeFpu.s
Normal file
73
IntelFspPkg/FspSecCore/Ia32/InitializeFpu.s
Normal file
@@ -0,0 +1,73 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# Float control word initial value:
|
||||
# all exceptions masked, double-precision, round-to-nearest
|
||||
#
|
||||
ASM_PFX(mFpuControlWord): .word 0x027F
|
||||
#
|
||||
# Multimedia-extensions control word:
|
||||
# all exceptions masked, round-to-nearest, flush to zero for masked underflow
|
||||
#
|
||||
ASM_PFX(mMmxControlWord): .long 0x01F80
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Initializes floating point units for requirement of UEFI specification.
|
||||
#
|
||||
# This function initializes floating-point control word to 0x027F (all exceptions
|
||||
# masked,double-precision, round-to-nearest) and multimedia-extensions control word
|
||||
# (if supported) to 0x1F80 (all exceptions masked, round-to-nearest, flush to zero
|
||||
# for masked underflow).
|
||||
#
|
||||
ASM_GLOBAL ASM_PFX(InitializeFloatingPointUnits)
|
||||
ASM_PFX(InitializeFloatingPointUnits):
|
||||
|
||||
pushl %ebx
|
||||
|
||||
#
|
||||
# Initialize floating point units
|
||||
#
|
||||
finit
|
||||
fldcw ASM_PFX(mFpuControlWord)
|
||||
|
||||
#
|
||||
# Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test
|
||||
# whether the processor supports SSE instruction.
|
||||
#
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
btl $25, %edx
|
||||
jnc Done
|
||||
|
||||
#
|
||||
# Set OSFXSR bit 9 in CR4
|
||||
#
|
||||
movl %cr4, %eax
|
||||
or BIT9, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
#
|
||||
# The processor should support SSE instruction and we can use
|
||||
# ldmxcsr instruction
|
||||
#
|
||||
ldmxcsr ASM_PFX(mMmxControlWord)
|
||||
|
||||
Done:
|
||||
popl %ebx
|
||||
|
||||
ret
|
103
IntelFspPkg/FspSecCore/Ia32/ResetVec.asm16
Normal file
103
IntelFspPkg/FspSecCore/Ia32/ResetVec.asm16
Normal file
@@ -0,0 +1,103 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Reset Vector Data structure
|
||||
; This structure is located at 0xFFFFFFC0
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.model tiny
|
||||
.686p
|
||||
.stack 0h
|
||||
.code
|
||||
|
||||
;
|
||||
; The layout of this file is fixed. The build tool makes assumption of the layout.
|
||||
;
|
||||
|
||||
ORG 0h
|
||||
;
|
||||
; Reserved
|
||||
;
|
||||
ReservedData DD 0eeeeeeeeh, 0eeeeeeeeh
|
||||
|
||||
ORG 10h
|
||||
;
|
||||
; This is located at 0xFFFFFFD0h
|
||||
;
|
||||
mov di, "AP"
|
||||
jmp ApStartup
|
||||
|
||||
ORG 20h
|
||||
;
|
||||
; Pointer to the entry point of the PEI core
|
||||
; It is located at 0xFFFFFFE0, and is fixed up by some build tool
|
||||
; So if the value 8..1 appears in the final FD image, tool failure occurs.
|
||||
;
|
||||
PeiCoreEntryPoint DD 12345678h
|
||||
|
||||
;
|
||||
; This is the handler for all kinds of exceptions. Since it's for debugging
|
||||
; purpose only, nothing except a deadloop would be done here. Developers could
|
||||
; analyze the cause of the exception if a debugger had been attached.
|
||||
;
|
||||
InterruptHandler PROC
|
||||
jmp $
|
||||
iret
|
||||
InterruptHandler ENDP
|
||||
|
||||
ORG 30h
|
||||
;
|
||||
; For IA32, the reset vector must be at 0xFFFFFFF0, i.e., 4G-16 byte
|
||||
; Execution starts here upon power-on/platform-reset.
|
||||
;
|
||||
ResetHandler:
|
||||
nop
|
||||
nop
|
||||
|
||||
ApStartup:
|
||||
;
|
||||
; Jmp Rel16 instruction
|
||||
; Use machine code directly in case of the assembler optimization
|
||||
; SEC entry point relatvie address will be fixed up by some build tool.
|
||||
;
|
||||
; Typically, SEC entry point is the function _ModuleEntryPoint() defined in
|
||||
; SecEntry.asm
|
||||
;
|
||||
DB 0e9h
|
||||
DW -3
|
||||
|
||||
|
||||
ORG 38h
|
||||
;
|
||||
; Ap reset vector segment address is at 0xFFFFFFF8
|
||||
; This will be fixed up by some build tool,
|
||||
; so if the value 1..8 appears in the final FD image,
|
||||
; tool failure occurs
|
||||
;
|
||||
ApSegAddress dd 12345678h
|
||||
|
||||
ORG 3ch
|
||||
;
|
||||
; BFV Base is at 0xFFFFFFFC
|
||||
; This will be fixed up by some build tool,
|
||||
; so if the value 1..8 appears in the final FD image,
|
||||
; tool failure occurs.
|
||||
;
|
||||
BfvBase DD 12345678h
|
||||
|
||||
;
|
||||
; Nothing can go here, otherwise the layout of this file would change.
|
||||
;
|
||||
|
||||
END
|
103
IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc
Normal file
103
IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc
Normal file
@@ -0,0 +1,103 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Provide macro for register save/restore using SSE registers
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
;
|
||||
; Define SSE instruction set
|
||||
;
|
||||
IFDEF USE_SSE41_FLAG
|
||||
;
|
||||
; Define SSE macros using SSE 4.1 instructions
|
||||
;
|
||||
SXMMN MACRO XMM, IDX, REG
|
||||
pinsrd XMM, REG, (IDX AND 3)
|
||||
ENDM
|
||||
|
||||
LXMMN MACRO XMM, REG, IDX
|
||||
pextrd REG, XMM, (IDX AND 3)
|
||||
ENDM
|
||||
ELSE
|
||||
;
|
||||
; Define SSE macros using SSE 2 instructions
|
||||
;
|
||||
SXMMN MACRO XMM, IDX, REG
|
||||
pinsrw XMM, REG, (IDX AND 3) * 2
|
||||
ror REG, 16
|
||||
pinsrw XMM, REG, (IDX AND 3) * 2 + 1
|
||||
rol REG, 16
|
||||
ENDM
|
||||
|
||||
LXMMN MACRO XMM, REG, IDX
|
||||
pshufd XMM, XMM, (0E4E4E4h SHR (IDX * 2)) AND 0FFh
|
||||
movd REG, XMM
|
||||
pshufd XMM, XMM, (0E4E4E4h SHR (IDX * 2 + (IDX AND 1) * 4)) AND 0FFh
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
|
||||
SAVE_REGS MACRO
|
||||
SXMMN xmm7, 0, ebp
|
||||
SXMMN xmm7, 1, ebx
|
||||
SXMMN xmm7, 2, esi
|
||||
SXMMN xmm7, 3, edi
|
||||
SAVE_ESP
|
||||
ENDM
|
||||
|
||||
LOAD_REGS MACRO
|
||||
LXMMN xmm7, ebp, 0
|
||||
LXMMN xmm7, ebx, 1
|
||||
LXMMN xmm7, esi, 2
|
||||
LXMMN xmm7, edi, 3
|
||||
LOAD_ESP
|
||||
ENDM
|
||||
|
||||
LOAD_EAX MACRO
|
||||
LXMMN xmm6, eax, 1
|
||||
ENDM
|
||||
|
||||
SAVE_EAX MACRO
|
||||
SXMMN xmm6, 1, eax
|
||||
ENDM
|
||||
|
||||
LOAD_EDX MACRO
|
||||
LXMMN xmm6, edx, 2
|
||||
ENDM
|
||||
|
||||
SAVE_EDX MACRO
|
||||
SXMMN xmm6, 2, edx
|
||||
ENDM
|
||||
|
||||
SAVE_ECX MACRO
|
||||
SXMMN xmm6, 3, ecx
|
||||
ENDM
|
||||
|
||||
LOAD_ECX MACRO
|
||||
LXMMN xmm6, ecx, 3
|
||||
ENDM
|
||||
|
||||
SAVE_ESP MACRO
|
||||
SXMMN xmm6, 0, esp
|
||||
ENDM
|
||||
|
||||
LOAD_ESP MACRO
|
||||
movd esp, xmm6
|
||||
ENDM
|
||||
|
||||
ENABLE_SSE MACRO
|
||||
mov eax, cr4
|
||||
or eax, 00000600h
|
||||
mov cr4, eax
|
||||
ENDM
|
82
IntelFspPkg/FspSecCore/Ia32/Stack.asm
Normal file
82
IntelFspPkg/FspSecCore/Ia32/Stack.asm
Normal file
@@ -0,0 +1,82 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Switch the stack from temporary memory to permenent memory.
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.586p
|
||||
.model flat,C
|
||||
.code
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; EFIAPI
|
||||
; SecSwitchStack (
|
||||
; UINT32 TemporaryMemoryBase,
|
||||
; UINT32 PermenentMemoryBase
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
SecSwitchStack PROC
|
||||
;
|
||||
; Save three register: eax, ebx, ecx
|
||||
;
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
;
|
||||
; !!CAUTION!! this function address's is pushed into stack after
|
||||
; migration of whole temporary memory, so need save it to permenent
|
||||
; memory at first!
|
||||
;
|
||||
|
||||
mov ebx, [esp + 20] ; Save the first parameter
|
||||
mov ecx, [esp + 24] ; Save the second parameter
|
||||
|
||||
;
|
||||
; Save this function's return address into permenent memory at first.
|
||||
; Then, Fixup the esp point to permenent memory
|
||||
;
|
||||
mov eax, esp
|
||||
sub eax, ebx
|
||||
add eax, ecx
|
||||
mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory
|
||||
mov dword ptr [eax], edx
|
||||
mov edx, dword ptr [esp + 4]
|
||||
mov dword ptr [eax + 4], edx
|
||||
mov edx, dword ptr [esp + 8]
|
||||
mov dword ptr [eax + 8], edx
|
||||
mov edx, dword ptr [esp + 12]
|
||||
mov dword ptr [eax + 12], edx
|
||||
mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory
|
||||
mov dword ptr [eax + 16], edx
|
||||
mov esp, eax ; From now, esp is pointed to permenent memory
|
||||
|
||||
;
|
||||
; Fixup the ebp point to permenent memory
|
||||
;
|
||||
mov eax, ebp
|
||||
sub eax, ebx
|
||||
add eax, ecx
|
||||
mov ebp, eax ; From now, ebp is pointed to permenent memory
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
ret
|
||||
SecSwitchStack ENDP
|
||||
|
||||
END
|
88
IntelFspPkg/FspSecCore/Ia32/Stacks.s
Normal file
88
IntelFspPkg/FspSecCore/Ia32/Stacks.s
Normal file
@@ -0,0 +1,88 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Switch the stack from temporary memory to permenent memory.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ASM_GLOBAL ASM_PFX(SecSwitchStack)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# VOID
|
||||
# EFIAPI
|
||||
# SecSwitchStack (
|
||||
# UINT32 TemporaryMemoryBase,
|
||||
# UINT32 PermenentMemoryBase
|
||||
# )
|
||||
#------------------------------------------------------------------------------
|
||||
ASM_GLOBAL ASM_PFX(SecSwitchStack)
|
||||
ASM_PFX(SecSwitchStack):
|
||||
#
|
||||
# Save three register: eax, ebx, ecx
|
||||
#
|
||||
push %eax
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
#
|
||||
# !!CAUTION!! this function address's is pushed into stack after
|
||||
# migration of whole temporary memory, so need save it to permenent
|
||||
# memory at first!
|
||||
#
|
||||
|
||||
movl 20(%esp), %ebx # Save the first parameter
|
||||
movl 24(%esp), %ecx # Save the second parameter
|
||||
|
||||
#
|
||||
# Save this function's return address into permenent memory at first.
|
||||
# Then, Fixup the esp point to permenent memory
|
||||
#
|
||||
|
||||
movl %esp, %eax
|
||||
subl %ebx, %eax
|
||||
addl %ecx, %eax
|
||||
movl (%esp), %edx # copy pushed register's value to permenent memory
|
||||
movl %edx, (%eax)
|
||||
movl 4(%esp), %edx
|
||||
movl %edx, 4(%eax)
|
||||
movl 8(%esp), %edx
|
||||
movl %edx, 8(%eax)
|
||||
movl 12(%esp), %edx
|
||||
movl %edx, 12(%eax)
|
||||
movl 16(%esp), %edx # Update this function's return address into permenent memory
|
||||
movl %edx, 16(%eax)
|
||||
movl %eax, %esp # From now, esp is pointed to permenent memory
|
||||
|
||||
#
|
||||
# Fixup the ebp point to permenent memory
|
||||
#
|
||||
|
||||
movl %ebp, %eax
|
||||
subl %ebx, %eax
|
||||
addl %ecx, %eax
|
||||
movl %eax, %ebp # From now, ebp is pointed to permenent memory
|
||||
|
||||
#
|
||||
# Fixup callee's ebp point for PeiDispatch
|
||||
#
|
||||
movl %ebp, %eax
|
||||
subl %ebx, %eax
|
||||
addl %ecx, %eax
|
||||
movl %eax, %ebp # From now, ebp is pointed to permenent memory
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %eax
|
||||
ret
|
63
IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc
Normal file
63
IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc
Normal file
@@ -0,0 +1,63 @@
|
||||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
MSR_IA32_PLATFORM_ID EQU 000000017h
|
||||
MSR_IA32_BIOS_UPDT_TRIG EQU 000000079h
|
||||
MSR_IA32_BIOS_SIGN_ID EQU 00000008bh
|
||||
|
||||
ucode STRUCT 1t
|
||||
version DWORD ?
|
||||
revision DWORD ?
|
||||
date DWORD ?
|
||||
processor DWORD ?
|
||||
checksum DWORD ?
|
||||
loader DWORD ?
|
||||
rsvd DWORD 6t DUP (?)
|
||||
data DWORD 500t DUP (?)
|
||||
ucode ENDS
|
||||
ucode_t TYPEDEF ucode
|
||||
|
||||
ucode_hdr STRUCT 1t
|
||||
version DWORD ?
|
||||
revision DWORD ?
|
||||
date DWORD ?
|
||||
processor DWORD ?
|
||||
checksum DWORD ?
|
||||
loader DWORD ?
|
||||
flags DWORD ?
|
||||
data_size DWORD ?
|
||||
total_size DWORD ?
|
||||
rsvd DWORD 3t DUP (?)
|
||||
ucode_hdr ENDS
|
||||
ucode_hdr_t TYPEDEF ucode_hdr
|
||||
|
||||
ext_sig_hdr STRUCT 1t
|
||||
count DWORD ?
|
||||
checksum DWORD ?
|
||||
rsvd DWORD 3t DUP (?)
|
||||
ext_sig_hdr ENDS
|
||||
ext_sig_hdr_t TYPEDEF ext_sig_hdr
|
||||
|
||||
ext_sig STRUCT 1t
|
||||
processor DWORD ?
|
||||
flags DWORD ?
|
||||
checksum DWORD ?
|
||||
ext_sig ENDS
|
||||
ext_sig_t TYPEDEF ext_sig
|
||||
|
||||
LOAD_UCODE_PARAMS STRUCT 1t
|
||||
ucode_code_addr DWORD ?
|
||||
ucode_code_size DWORD ?
|
||||
LOAD_UCODE_PARAMS ENDS
|
Reference in New Issue
Block a user