mirror of https://github.com/acidanthera/audk.git
Updated FspApiEntry.asm/.s to auto detect the size of the MCU region.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" <jiewen.yao@intel.com> Reviewed-by: "Rangarajan, Ravi P" <ravi.p.rangarajan@intel.com> Reviewed-by: "Ma, Maurice" <maurice.ma@intel.com> Reviewed-by: "Mudusuru, Giri P" <giri.p.mudusuru@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16478 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
54190e8366
commit
975f1c6417
|
@ -214,16 +214,21 @@ advance_fixed_size:
|
|||
|
||||
check_address:
|
||||
; Is valid Microcode start point ?
|
||||
cmp dword ptr [esi], 0ffffffffh
|
||||
cmp dword ptr [esi].ucode_hdr.version, 0ffffffffh
|
||||
jz done
|
||||
|
||||
; Is automatic size detection ?
|
||||
mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size
|
||||
cmp eax, 0ffffffffh
|
||||
jz @f
|
||||
|
||||
; 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
|
||||
add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
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
|
||||
|
|
|
@ -15,37 +15,166 @@
|
|||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#.INCLUDE "UcodeLoad.inc"
|
||||
#.INCLUDE "UcodeLoadGcc.inc" - begin
|
||||
|
||||
.equ MSR_IA32_PLATFORM_ID, 0x00000017
|
||||
.equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079
|
||||
.equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b
|
||||
|
||||
Ucode:
|
||||
.equ UcodeVersion, 0x0000
|
||||
.equ UcodeRevision, 0x0004
|
||||
.equ UcodeDate, 0x0008
|
||||
.equ UcodeProcessor, 0x000C
|
||||
.equ UcodeChecksum, 0x0010
|
||||
.equ UcodeLoader, 0x0014
|
||||
.equ UcodeRsvd, 0x0018
|
||||
UcodeEnd:
|
||||
|
||||
UcodeHdr:
|
||||
.equ UcodeHdrVersion, 0x0000
|
||||
.equ UcodeHdrRevision, 0x0004
|
||||
.equ UcodeHdrDate, 0x0008
|
||||
.equ UcodeHdrProcessor, 0x000c
|
||||
.equ UcodeHdrChecksum, 0x0010
|
||||
.equ UcodeHdrLoader, 0x0014
|
||||
.equ UcodeHdrFlags, 0x0018
|
||||
.equ UcodeHdrDataSize, 0x001C
|
||||
.equ UcodeHdrTotalSize, 0x0020
|
||||
.equ UcodeHdrRsvd, 0x0024
|
||||
UcodeHdrEnd:
|
||||
.equ UcodeHdrLength, 0x0030 # UcodeHdrLength = UcodeHdrEnd - UcodeHdr
|
||||
|
||||
|
||||
ExtSigHdr:
|
||||
.equ ExtSigHdrCount, 0x0000
|
||||
.equ ExtSigHdrChecksum, 0x0004
|
||||
.equ rsvd, 0x0008
|
||||
ExtSigHdrEnd:
|
||||
.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr
|
||||
|
||||
ExtSig:
|
||||
.equ ExtSigProcessor, 0x0000
|
||||
.equ ExtSigFlags, 0x0004
|
||||
.equ ExtSigChecksum, 0x0008
|
||||
ExtSigEnd:
|
||||
.equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig
|
||||
|
||||
LoadUcodeParams:
|
||||
.equ LoadUcodeParamsUcodeCodeAddr, 0x0000
|
||||
.equ LoadUcodeParamsUcodeCodeSize, 0x0004
|
||||
LoadUcodeParamsEnd:
|
||||
|
||||
#.INCLUDE "UcodeLoadGcc.inc" - end
|
||||
|
||||
#.INCLUDE "SaveRestoreSseGcc.inc" - begin
|
||||
|
||||
.macro SAVE_REGS
|
||||
pinsrw $0x00, %ebp, %xmm7
|
||||
ror $0x10, %ebp
|
||||
pinsrw $0x01, %ebp, %xmm7
|
||||
ror $0x10, %ebp
|
||||
#
|
||||
pinsrw $0x02, %ebx, %xmm7
|
||||
ror $0x10, %ebx
|
||||
pinsrw $0x03, %ebx, %xmm7
|
||||
ror $0x10, %ebx
|
||||
#
|
||||
pinsrw $0x04, %esi, %xmm7
|
||||
ror $0x10, %esi
|
||||
pinsrw $0x05, %esi, %xmm7
|
||||
ror $0x10, %esi
|
||||
#
|
||||
pinsrw $0x06, %edi, %xmm7
|
||||
ror $0x10, %edi
|
||||
pinsrw $0x07, %edi, %xmm7
|
||||
ror $0x10, %edi
|
||||
#
|
||||
pinsrw $0x00, %esp, %xmm6
|
||||
ror $0x10, %esp
|
||||
pinsrw $0x01, %esp, %xmm6
|
||||
ror $0x10, %esp
|
||||
.endm
|
||||
|
||||
.macro LOAD_REGS
|
||||
pshufd $0xe4, %xmm7, %xmm7
|
||||
movd %xmm7, %ebp
|
||||
pshufd $0xe4, %xmm7, %xmm7
|
||||
#
|
||||
pshufd $0x39, %xmm7, %xmm7
|
||||
movd %xmm7, %ebx
|
||||
pshufd $0x93, %xmm7, %xmm7
|
||||
#
|
||||
pshufd $0x4e, %xmm7, %xmm7
|
||||
movd %xmm7, %esi
|
||||
pshufd $0x4e, %xmm7, %xmm7
|
||||
#
|
||||
pshufd $0x93, %xmm7, %xmm7
|
||||
movd %xmm7, %edi
|
||||
pshufd $0x39, %xmm7, %xmm7
|
||||
#
|
||||
movd %xmm6, %esp
|
||||
.endm
|
||||
|
||||
.macro LOAD_EAX
|
||||
pshufd $0x39, %xmm6, %xmm6
|
||||
movd %xmm6, %eax
|
||||
pshufd $0x93, %xmm6, %xmm6
|
||||
.endm
|
||||
|
||||
.macro LOAD_EDX
|
||||
pshufd $0xe4, %xmm6, %xmm6
|
||||
movd %xmm6, %edx
|
||||
pshufd $0xe4, %xmm6, %xmm6
|
||||
.endm
|
||||
|
||||
.macro SAVE_EAX
|
||||
pinsrw $0x02, %eax, %xmm6
|
||||
ror $0x10, %eax
|
||||
pinsrw $0x03, %eax, %xmm6
|
||||
ror $0x10, %eax
|
||||
.endm
|
||||
|
||||
.macro SAVE_EDX
|
||||
pinsrw $0x04, %edx, %xmm6
|
||||
ror $0x10, %edx
|
||||
pinsrw $0x05, %edx, %xmm6
|
||||
ror $0x10, %edx
|
||||
.endm
|
||||
|
||||
.macro LOAD_ESP
|
||||
movd %xmm6, %esp
|
||||
.endm
|
||||
|
||||
.macro ENABLE_SSE
|
||||
movl %cr4, %eax
|
||||
orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
|
||||
movl %eax,%cr4
|
||||
.endm
|
||||
|
||||
#.INCLUDE "SaveRestoreSseGcc.inc" - end
|
||||
|
||||
|
||||
#
|
||||
# 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
|
||||
ASM_GLOBAL ASM_PFX(FspImageSizeOffset)
|
||||
ASM_GLOBAL ASM_PFX(SecStartup)
|
||||
ASM_GLOBAL ASM_PFX(FspApiCallingCheck)
|
||||
|
||||
#
|
||||
# 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
|
||||
ASM_GLOBAL ASM_PFX(GetBootFirmwareVolumeOffset)
|
||||
ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
|
||||
|
||||
|
||||
#
|
||||
# Define the data length that we saved on the stack top
|
||||
|
@ -54,271 +183,270 @@ ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize)
|
|||
.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
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 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.
|
||||
#------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
FspSelfCheckDfltExit:
|
||||
jmp *%ebp
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 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.
|
||||
#------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
PlatformBasicInitDfltExit:
|
||||
jmp *%ebp
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# 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
|
||||
#------------------------------------------------------------------------------
|
||||
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
|
||||
cmpl $0x00, %esp
|
||||
jz ParamError
|
||||
movl (%esp), %eax #dword ptr [] Parameter pointer
|
||||
cmpl $0, %eax
|
||||
jz paramerror
|
||||
cmpl $0x00, %eax
|
||||
jz ParamError
|
||||
movl %eax, %esp
|
||||
movl (%esp), %esi #LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
cmpl $0, %esi
|
||||
jnz L0
|
||||
movl LoadUcodeParamsUcodeCodeAddr(%esp), %esi #mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
cmpl $0x00, %esi
|
||||
jnz CheckMainHeader
|
||||
|
||||
paramerror:
|
||||
ParamError:
|
||||
movl $0x080000002, %eax
|
||||
jmp exit4
|
||||
jmp LoadUcodeExit
|
||||
|
||||
movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
|
||||
check_main_header:
|
||||
CheckMainHeader:
|
||||
#
|
||||
# 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
|
||||
#
|
||||
movl $0x01, %eax
|
||||
cpuid
|
||||
movl %eax, %ebx
|
||||
movl MSR_IA32_PLATFORM_ID, %ecx
|
||||
movl $MSR_IA32_PLATFORM_ID, %ecx
|
||||
rdmsr
|
||||
movl %edx, %ecx
|
||||
#--------------------------------------------------------------------------------------------------------------------
|
||||
shrl $18, %ecx #($50-$32)
|
||||
andl $0x7, %ecx
|
||||
movl $1, %edx
|
||||
shrl $0x12, %ecx #($50-$32)
|
||||
andl $0x07, %ecx
|
||||
movl $0x01, %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
|
||||
#
|
||||
movl $0x01, %eax
|
||||
cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax
|
||||
jne AdvanceFixedSize
|
||||
cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax
|
||||
jne AdvanceFixedSize
|
||||
|
||||
#
|
||||
# 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
|
||||
#
|
||||
cmpl UcodeHdrProcessor(%esi), %ebx #cmp ebx, [esi].ucode_hdr.processor
|
||||
jne LoadUcodeL0
|
||||
testl UcodeHdrFlags(%esi), %edx #test edx, [esi].ucode_hdr.flags
|
||||
jnz LoadCheck #Jif signature and platform ID match
|
||||
|
||||
L0:
|
||||
LoadUcodeL0:
|
||||
#
|
||||
# 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
|
||||
cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax
|
||||
je NextMicrocode
|
||||
cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax
|
||||
je NextMicrocode
|
||||
|
||||
#
|
||||
# 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
|
||||
#
|
||||
movl UcodeHdrTotalSize(%esi), %ecx #mov ecx, [esi].ucode_hdr.total_size
|
||||
subl $UcodeHdrLength, %ecx #sub ecx, sizeof ucode_hdr
|
||||
cmpl UcodeHdrDataSize(%esi), %ecx #cmp ecx, [esi].ucode_hdr.data_size
|
||||
jle NextMicrocode
|
||||
|
||||
#
|
||||
# Set edi -> extended header
|
||||
movl %esi , %edi
|
||||
addl $0x30 , %edi #sizeof ucode_hdr = 48
|
||||
addl 0x20(%esi), %edi #%esi.ucode_hdr.data_size
|
||||
#
|
||||
movl %esi, %edi
|
||||
addl $UcodeHdrLength, %edi #add edi, sizeof ucode_hdr
|
||||
addl UcodeHdrDataSize(%esi), %edi #add edi, [esi].ucode_hdr.data_size
|
||||
|
||||
#
|
||||
# Get count of extended structures
|
||||
movl (%edi), %ecx #(%edi).ext_sig_hdr.count
|
||||
#
|
||||
movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count
|
||||
|
||||
#
|
||||
# Move pointer to first signature structure
|
||||
addl $0x20, %edi # sizeof ext_sig_hdr = 20
|
||||
#
|
||||
addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr
|
||||
|
||||
check_ext_sig:
|
||||
CheckExtSig:
|
||||
#
|
||||
# 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:
|
||||
#
|
||||
cmpl %ebx, ExtSigProcessor(%edi) #cmp [edi].ext_sig.processor, ebx
|
||||
jne LoadUcodeL1
|
||||
test %edx, ExtSigFlags(%edi) #test [edi].ext_sig.flags, edx
|
||||
jnz LoadCheck # Jif signature and platform ID match
|
||||
LoadUcodeL1:
|
||||
#
|
||||
# Check if any more extended signatures exist
|
||||
addl $0xc, %edi #sizeof ext_sig = 12
|
||||
loop check_ext_sig
|
||||
#
|
||||
addl $ExtSigLength, %edi #add edi, sizeof ext_sig
|
||||
loop CheckExtSig
|
||||
|
||||
next_microcode:
|
||||
NextMicrocode:
|
||||
#
|
||||
# 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
|
||||
cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax
|
||||
je LoadUcodeL2
|
||||
addl UcodeHdrTotalSize(%esi), %esi #add esi, [esi].ucode_hdr.total_size
|
||||
jmp CheckAddress
|
||||
LoadUcodeL2:
|
||||
addl $0x800, %esi #add esi, dword ptr 2048
|
||||
jmp CheckAddress
|
||||
|
||||
advance_fixed_size:
|
||||
AdvanceFixedSize:
|
||||
#
|
||||
# Advance by 4X dwords
|
||||
addl $0x400, %esi
|
||||
#
|
||||
addl $0x400, %esi #add esi, dword ptr 1024
|
||||
|
||||
check_address:
|
||||
CheckAddress:
|
||||
#
|
||||
# Is valid Microcode start point ?
|
||||
cmp $0x0ffffffff , %esi
|
||||
jz done
|
||||
#
|
||||
cmpl $0x0ffffffff, UcodeHdrVersion(%esi)
|
||||
|
||||
#
|
||||
# Is automatic size detection ?
|
||||
#
|
||||
movl LoadUcodeParamsUcodeCodeSize(%esp), %eax
|
||||
cmpl $0x0ffffffff, %eax
|
||||
jz LoadUcodeL3
|
||||
#
|
||||
# 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
|
||||
#
|
||||
addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
|
||||
|
||||
load_check:
|
||||
cmpl %eax, %esi
|
||||
jae Done #Jif address is outside of ucode region
|
||||
jmp CheckMainHeader
|
||||
|
||||
LoadUcodeL3:
|
||||
LoadCheck:
|
||||
#
|
||||
# Get the revision of the current microcode update loaded
|
||||
movl MSR_IA32_BIOS_SIGN_ID, %ecx
|
||||
#
|
||||
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
|
||||
movl $0x01, %eax
|
||||
cpuid
|
||||
movl MSR_IA32_BIOS_SIGN_ID, %ecx
|
||||
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
|
||||
#
|
||||
cmpl %edx, UcodeHdrRevision(%esi) #cmp [esi].ucode_hdr.revision, edx
|
||||
je Continue
|
||||
|
||||
load_microcode:
|
||||
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 %esi, %eax
|
||||
add $0x30, %eax #sizeof ucode_hdr = 48
|
||||
#
|
||||
movl %esi, %eax
|
||||
addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr
|
||||
xorl %edx, %edx
|
||||
mov MSR_IA32_BIOS_UPDT_TRIG,%ecx
|
||||
movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx
|
||||
wrmsr
|
||||
mov $1, %eax
|
||||
movl $0x01, %eax
|
||||
cpuid
|
||||
|
||||
continue:
|
||||
jmp next_microcode
|
||||
Continue:
|
||||
jmp NextMicrocode
|
||||
|
||||
done:
|
||||
mov $1, %eax
|
||||
Done:
|
||||
movl $0x01, %eax
|
||||
cpuid
|
||||
mov MSR_IA32_BIOS_SIGN_ID, %ecx
|
||||
movl $MSR_IA32_BIOS_SIGN_ID, %ecx
|
||||
rdmsr # Get current microcode signature
|
||||
xorl %eax, %eax
|
||||
cmp $0 , %edx
|
||||
jnz exit4
|
||||
mov $0x08000000E, %eax
|
||||
cmpl $0x00, %edx
|
||||
jnz LoadUcodeExit
|
||||
movl $0x08000000E, %eax
|
||||
|
||||
exit4:
|
||||
LoadUcodeExit:
|
||||
jmp *%ebp
|
||||
|
||||
#LoadUcode ENDP
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# TempRamInit API
|
||||
|
@ -344,47 +472,56 @@ ASM_PFX(TempRamInitApi):
|
|||
# Save timestamp into XMM4 & XMM5
|
||||
#
|
||||
rdtsc
|
||||
movd %edx, %xmm4
|
||||
movd %eax, %xmm5
|
||||
SAVE_EAX
|
||||
SAVE_EDX
|
||||
|
||||
#
|
||||
# Check Parameter
|
||||
#
|
||||
movl 4(%esp), %eax
|
||||
cmpl $0x00, %eax
|
||||
movl $0x80000002, %eax
|
||||
jz NemInitExit
|
||||
|
||||
#
|
||||
# CPUID/DeviceID check
|
||||
#
|
||||
movl L11, %eax
|
||||
jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed.
|
||||
L11:
|
||||
cmpl $0, %eax
|
||||
movl $TempRamInitApiL0, %eax
|
||||
jmp ASM_PFX(FspSelfCheckDflt) # Note: ESP can not be changed.
|
||||
TempRamInitApiL0:
|
||||
cmpl $0x00, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
# Platform Basic Init.
|
||||
#
|
||||
movl L1, %eax
|
||||
movl $TempRamInitApiL1, %eax
|
||||
jmp ASM_PFX(PlatformBasicInitDflt)
|
||||
L1:
|
||||
cmp $0, %eax
|
||||
TempRamInitApiL1:
|
||||
cmpl $0x00, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
# Load microcode
|
||||
#
|
||||
movl L2, %eax
|
||||
addl $4, %esp
|
||||
movl $TempRamInitApiL2, %eax
|
||||
addl $0x04, %esp
|
||||
jmp LoadUcode
|
||||
L2:
|
||||
|
||||
TempRamInitApiL2:
|
||||
LOAD_ESP
|
||||
cmpl $0, %eax
|
||||
cmpl $0x00, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
# Call platform NEM init
|
||||
#-------------------------------------------------------------------------------------------------------------------------
|
||||
movl L3, %eax
|
||||
addl $4, %esp
|
||||
#
|
||||
movl $TempRamInitApiL3, %eax
|
||||
addl $0x04, %esp
|
||||
jmp ASM_PFX(PlatformTempRamInit)
|
||||
L3:
|
||||
subl $4, %esp
|
||||
cmpl $0, %eax
|
||||
TempRamInitApiL3:
|
||||
subl $0x04, %esp
|
||||
cmpl $0x00, %eax
|
||||
jnz NemInitExit
|
||||
|
||||
#
|
||||
|
@ -399,37 +536,29 @@ L3:
|
|||
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 $0x4455434D # Signature of the data region 'MCUD'
|
||||
pushl 4(%edx) # Microcode size
|
||||
pushl (%edx) # Microcode base
|
||||
jmp L4
|
||||
pushl 12(%edx) # Code size
|
||||
pushl 8(%edx) # Code base
|
||||
|
||||
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
|
||||
pushl $DATA_LEN_OF_PER0 # Size of the data region
|
||||
pushl $0x30524550 # Signature of the data region 'PER0'
|
||||
rdtsc
|
||||
pushl %edx
|
||||
pushl %eax
|
||||
LOAD_EAX
|
||||
LOAD_EDX
|
||||
pushl %edx
|
||||
pushl %eax
|
||||
|
||||
#
|
||||
# Terminator for the data on stack
|
||||
#
|
||||
pushl $0
|
||||
pushl $0x00
|
||||
|
||||
#
|
||||
# Set ECX/EDX to the bootloader temporary memory range
|
||||
|
@ -447,7 +576,7 @@ NemInitExit:
|
|||
#
|
||||
LOAD_REGS
|
||||
ret
|
||||
#TempRamInitApi ENDP
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# FspInit API
|
||||
|
@ -463,48 +592,43 @@ ASM_PFX(FspInitApi):
|
|||
# Stack must be ready
|
||||
#
|
||||
pushl $0x087654321
|
||||
pop %eax
|
||||
popl %eax
|
||||
cmpl $0x087654321, %eax
|
||||
jz L5
|
||||
jz FspInitApiL0
|
||||
movl $0x080000003, %eax
|
||||
jmp exit3
|
||||
jmp FspInitApiexit
|
||||
|
||||
L5:
|
||||
FspInitApiL0:
|
||||
#
|
||||
# Additional check
|
||||
#
|
||||
pusha
|
||||
pushl $1
|
||||
pushl $0x01
|
||||
call ASM_PFX(FspApiCallingCheck)
|
||||
addl $4, %esp
|
||||
addl $0x04, %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
|
||||
cmpl $0x00, %eax
|
||||
jz FspInitApiL1
|
||||
jmp FspInitApiexit
|
||||
|
||||
FspInitApiL1:
|
||||
#
|
||||
# Store the address in FSP which will return control to the BL
|
||||
#
|
||||
pushl $exit3
|
||||
pushl $FspInitApiexit
|
||||
|
||||
#
|
||||
# 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
|
||||
#
|
||||
subl $0x08, %esp
|
||||
sidt (%esp)
|
||||
|
||||
#
|
||||
|
@ -512,11 +636,9 @@ L6:
|
|||
#
|
||||
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
|
||||
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
|
||||
subl $(DATA_LEN_AT_STACK_TOP + 0x40), %esp
|
||||
|
||||
#
|
||||
# Save the bootloader's stack pointer
|
||||
#
|
||||
pushl %eax
|
||||
|
@ -525,10 +647,11 @@ L6:
|
|||
# Pass entry point of the PEI core
|
||||
#
|
||||
call ASM_PFX(GetFspBaseAddress)
|
||||
movl %eax, %edi
|
||||
addl ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi
|
||||
movl ASM_PFX(FspImageSizeOffset), %edi
|
||||
movl (%eax, %edi), %edi
|
||||
addl %eax, %edi
|
||||
subl $0x20, %edi
|
||||
addl %ds:(%edi), %eax
|
||||
addl (%edi), %eax
|
||||
pushl %eax
|
||||
|
||||
#
|
||||
|
@ -558,10 +681,9 @@ L6:
|
|||
#
|
||||
call ASM_PFX(SecStartup)
|
||||
|
||||
exit3:
|
||||
FspInitApiexit:
|
||||
ret
|
||||
|
||||
# FspInitApi ENDP
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# NotifyPhase API
|
||||
|
@ -576,36 +698,35 @@ ASM_PFX(NotifyPhaseApi):
|
|||
# Stack must be ready
|
||||
#
|
||||
pushl $0x0087654321
|
||||
pop %eax
|
||||
popl %eax
|
||||
cmpl $0x087654321, %eax
|
||||
jz L7
|
||||
jz NotifyPhaseApiL0
|
||||
movl $0x080000003, %eax
|
||||
jmp err_exit
|
||||
jmp NotifyPhaseApiErrExit
|
||||
|
||||
L7:
|
||||
NotifyPhaseApiL0:
|
||||
#
|
||||
# Verify the calling condition
|
||||
#
|
||||
pusha
|
||||
pushl $2
|
||||
pushl $0x02
|
||||
call ASM_PFX(FspApiCallingCheck)
|
||||
add $4, %esp
|
||||
mov %eax, 28(%esp)
|
||||
addl $0x04, %esp
|
||||
movl %eax, 28(%esp)
|
||||
popa
|
||||
|
||||
cmpl $0, %eax
|
||||
jz L8
|
||||
cmpl $0x00, %eax
|
||||
jz NotifyPhaseApiL1
|
||||
|
||||
#
|
||||
# Error return
|
||||
#
|
||||
err_exit:
|
||||
NotifyPhaseApiErrExit:
|
||||
ret
|
||||
|
||||
L8:
|
||||
NotifyPhaseApiL1:
|
||||
jmp ASM_PFX(Pei2LoaderSwitchStack)
|
||||
|
||||
#NotifyPhaseApi ENDP
|
||||
|
||||
|
||||
#END
|
||||
|
|
Loading…
Reference in New Issue