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:
Yao, Jiewen 2014-12-06 00:29:04 +00:00 committed by jyao1
parent 54190e8366
commit 975f1c6417
2 changed files with 444 additions and 318 deletions

View File

@ -214,16 +214,21 @@ advance_fixed_size:
check_address: check_address:
; Is valid Microcode start point ? ; Is valid Microcode start point ?
cmp dword ptr [esi], 0ffffffffh cmp dword ptr [esi].ucode_hdr.version, 0ffffffffh
jz done 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? ; Address >= microcode region address + microcode region size?
mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size
cmp esi, eax cmp esi, eax
jae done ;Jif address is outside of ucode region jae done ;Jif address is outside of ucode region
jmp check_main_header jmp check_main_header
@@:
load_check: load_check:
; Get the revision of the current microcode update loaded ; Get the revision of the current microcode update loaded
mov ecx, MSR_IA32_BIOS_SIGN_ID mov ecx, MSR_IA32_BIOS_SIGN_ID

View File

@ -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 # 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_PcdTemporaryRamBase)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize) ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize)
# #
# Following functions will be provided in C # Following functions will be provided in C
# #
#EXTERNDEF SecStartup:PROC ASM_GLOBAL ASM_PFX(FspImageSizeOffset)
#EXTERNDEF FspApiCallingCheck:PROC ASM_GLOBAL ASM_PFX(SecStartup)
ASM_GLOBAL ASM_PFX(FspApiCallingCheck)
# #
# Following functions will be provided in PlatformSecLib # Following functions will be provided in PlatformSecLib
# #
#EXTERNDEF GetFspBaseAddress:PROC ASM_GLOBAL ASM_PFX(GetBootFirmwareVolumeOffset)
#EXTERNDEF GetBootFirmwareVolumeOffset:PROC ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
#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 # 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_OF_MCUD, 0x018
.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4) .equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
# #------------------------------------------------------------------------------
# Define SSE macros # FspSelfCheckDflt
# # Inputs:
.macro ENABLE_SSE # eax -> Return address
movl %cr4, %eax # Outputs:
orl $0x00000600,%eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) # eax -> 0 - Successful, Non-zero - Failed.
movl %eax,%cr4 # Register Usage:
.endm # eax is cleared and ebp is used for return address.
# All others reserved.
.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_GLOBAL ASM_PFX(FspSelfCheckDflt)
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 # Save return address to EBP
#
movl %eax, %ebp movl %eax, %ebp
xorl %eax, %eax 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_GLOBAL ASM_PFX(PlatformBasicInitDflt)
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 # Save return address to EBP
#
movl %eax, %ebp movl %eax, %ebp
xorl %eax, %eax 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_GLOBAL ASM_PFX(LoadUcode)
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 # Save return address to EBP
#
movl %eax, %ebp movl %eax, %ebp
cmpl $0, %esp cmpl $0x00, %esp
jz paramerror jz ParamError
movl (%esp), %eax #dword ptr [] Parameter pointer movl (%esp), %eax #dword ptr [] Parameter pointer
cmpl $0, %eax cmpl $0x00, %eax
jz paramerror jz ParamError
movl %eax, %esp movl %eax, %esp
movl (%esp), %esi #LOAD_UCODE_PARAMS.ucode_code_addr movl LoadUcodeParamsUcodeCodeAddr(%esp), %esi #mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
cmpl $0, %esi cmpl $0x00, %esi
jnz L0 jnz CheckMainHeader
paramerror: ParamError:
movl $0x080000002, %eax movl $0x080000002, %eax
jmp exit4 jmp LoadUcodeExit
movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr CheckMainHeader:
#
check_main_header:
# Get processor signature and platform ID from the installed processor # Get processor signature and platform ID from the installed processor
# and save into registers for later use # and save into registers for later use
# ebx = processor signature # ebx = processor signature
# edx = platform ID # edx = platform ID
movl $1, %eax #
movl $0x01, %eax
cpuid cpuid
movl %eax, %ebx movl %eax, %ebx
movl MSR_IA32_PLATFORM_ID, %ecx movl $MSR_IA32_PLATFORM_ID, %ecx
rdmsr rdmsr
movl %edx, %ecx movl %edx, %ecx
#-------------------------------------------------------------------------------------------------------------------- shrl $0x12, %ecx #($50-$32)
shrl $18, %ecx #($50-$32) andl $0x07, %ecx
andl $0x7, %ecx movl $0x01, %edx
movl $1, %edx
shll %cl,%edx shll %cl,%edx
#
# Current register usage # Current register usage
# esp -> stack with paramters # esp -> stack with paramters
# esi -> microcode update to check # esi -> microcode update to check
# ebx = processor signature # ebx = processor signature
# edx = platform ID # edx = platform ID
#
#
# Check for valid microcode header # Check for valid microcode header
# Minimal test checking for header version and loader version as 1 # Minimal test checking for header version and loader version as 1
movl $1, %eax #
cmpl %eax, (%esi) #.ucode_hdr.version movl $0x01, %eax
jne advance_fixed_size cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax
cmpl %eax, 0x18(%esi) #.ucode_hdr.loader jne AdvanceFixedSize
jne advance_fixed_size cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax
jne AdvanceFixedSize
#
# Check if signature and plaform ID match # Check if signature and plaform ID match
#-------------------------------------------------------------------------------------------------------------------------- #
cmpl 0x10(%esi), %ebx #(%esi).ucode_hdr.processor cmpl UcodeHdrProcessor(%esi), %ebx #cmp ebx, [esi].ucode_hdr.processor
jne L0 jne LoadUcodeL0
testl 0x1c(%esi) , %edx #(%esi).ucode_hdr.flags testl UcodeHdrFlags(%esi), %edx #test edx, [esi].ucode_hdr.flags
jnz load_check # Jif signature and platform ID match jnz LoadCheck #Jif signature and platform ID match
L0: LoadUcodeL0:
#
# Check if extended header exists # Check if extended header exists
# First check if total_size and data_size are valid # First check if total_size and data_size are valid
#
xorl %eax, %eax xorl %eax, %eax
cmpl %eax,0x24(%esi) #(%esi).ucode_hdr.total_size cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax
je next_microcode je NextMicrocode
cmpl %eax,0x20(%esi) #(%esi) .ucode_hdr.data_size cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax
je next_microcode je NextMicrocode
#
# Then verify total size - sizeof header > data size # Then verify total size - sizeof header > data size
movl 0x24(%esi), %ecx #(%esi).ucode_hdr.total_size #
subl $0x30, %ecx #sizeof ucode_hdr = 48 movl UcodeHdrTotalSize(%esi), %ecx #mov ecx, [esi].ucode_hdr.total_size
cmpl 0x20(%esi), %ecx #(%esi).ucode_hdr.data_size subl $UcodeHdrLength, %ecx #sub ecx, sizeof ucode_hdr
jz load_check cmpl UcodeHdrDataSize(%esi), %ecx #cmp ecx, [esi].ucode_hdr.data_size
jb next_microcode # Jif extended header does not exist jle NextMicrocode
# 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 # Set edi -> extended header
movl %esi , %edi #
addl $0x30 , %edi #sizeof ucode_hdr = 48 movl %esi, %edi
addl 0x20(%esi), %edi #%esi.ucode_hdr.data_size addl $UcodeHdrLength, %edi #add edi, sizeof ucode_hdr
addl UcodeHdrDataSize(%esi), %edi #add edi, [esi].ucode_hdr.data_size
#
# Get count of extended structures # 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 # 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 # Check if extended signature and platform ID match
cmpl %ebx, (%edi) #[edi].ext_sig.processor #
jne L1 cmpl %ebx, ExtSigProcessor(%edi) #cmp [edi].ext_sig.processor, ebx
test %edx, 4(%edi) #[edi].ext_sig.flags jne LoadUcodeL1
jnz load_check # Jif signature and platform ID match test %edx, ExtSigFlags(%edi) #test [edi].ext_sig.flags, edx
L9: jnz LoadCheck # Jif signature and platform ID match
LoadUcodeL1:
#
# Check if any more extended signatures exist # 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 # Advance just after end of this microcode
#
xorl %eax, %eax xorl %eax, %eax
cmpl %eax, 0x24(%esi) #(%esi).ucode_hdr.total_size cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax
je L2 je LoadUcodeL2
add 0x24(%esi) , %esi #(%esi).ucode_hdr.total_size addl UcodeHdrTotalSize(%esi), %esi #add esi, [esi].ucode_hdr.total_size
jmp check_address jmp CheckAddress
L10: LoadUcodeL2:
addl $0x800, %esi addl $0x800, %esi #add esi, dword ptr 2048
jmp check_address jmp CheckAddress
advance_fixed_size: AdvanceFixedSize:
#
# Advance by 4X dwords # Advance by 4X dwords
addl $0x400, %esi #
addl $0x400, %esi #add esi, dword ptr 1024
check_address: CheckAddress:
#
# Is valid Microcode start point ? # 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? # 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 addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
cmpl %eax, %esi
jae done #Jif address is outside of ucode region
jmp check_main_header
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 # 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 %eax, %eax # Clear EAX
xorl %edx, %edx # Clear EDX xorl %edx, %edx # Clear EDX
wrmsr # Load 0 to MSR at 8Bh wrmsr # Load 0 to MSR at 8Bh
movl $1, %eax movl $0x01, %eax
cpuid cpuid
movl MSR_IA32_BIOS_SIGN_ID, %ecx movl $MSR_IA32_BIOS_SIGN_ID, %ecx
rdmsr # Get current microcode signature rdmsr # Get current microcode signature
#
# Verify this microcode update is not already loaded # 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 # EAX contains the linear address of the start of the Update Data
# EDX contains zero # EDX contains zero
# ECX contains 79h (IA32_BIOS_UPDT_TRIG) # ECX contains 79h (IA32_BIOS_UPDT_TRIG)
# Start microcode load with wrmsr # 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 xorl %edx, %edx
mov MSR_IA32_BIOS_UPDT_TRIG,%ecx movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx
wrmsr wrmsr
mov $1, %eax movl $0x01, %eax
cpuid cpuid
continue: Continue:
jmp next_microcode jmp NextMicrocode
done: Done:
mov $1, %eax movl $0x01, %eax
cpuid cpuid
mov MSR_IA32_BIOS_SIGN_ID, %ecx movl $MSR_IA32_BIOS_SIGN_ID, %ecx
rdmsr # Get current microcode signature rdmsr # Get current microcode signature
xorl %eax, %eax xorl %eax, %eax
cmp $0 , %edx cmpl $0x00, %edx
jnz exit4 jnz LoadUcodeExit
mov $0x08000000E, %eax movl $0x08000000E, %eax
exit4: LoadUcodeExit:
jmp *%ebp jmp *%ebp
#LoadUcode ENDP
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# TempRamInit API # TempRamInit API
@ -344,47 +472,56 @@ ASM_PFX(TempRamInitApi):
# Save timestamp into XMM4 & XMM5 # Save timestamp into XMM4 & XMM5
# #
rdtsc rdtsc
movd %edx, %xmm4 SAVE_EAX
movd %eax, %xmm5 SAVE_EDX
#
# Check Parameter
#
movl 4(%esp), %eax
cmpl $0x00, %eax
movl $0x80000002, %eax
jz NemInitExit
# #
# CPUID/DeviceID check # CPUID/DeviceID check
# #
movl L11, %eax movl $TempRamInitApiL0, %eax
jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed. jmp ASM_PFX(FspSelfCheckDflt) # Note: ESP can not be changed.
L11: TempRamInitApiL0:
cmpl $0, %eax cmpl $0x00, %eax
jnz NemInitExit jnz NemInitExit
# #
# Platform Basic Init. # Platform Basic Init.
# #
movl L1, %eax movl $TempRamInitApiL1, %eax
jmp ASM_PFX(PlatformBasicInitDflt) jmp ASM_PFX(PlatformBasicInitDflt)
L1: TempRamInitApiL1:
cmp $0, %eax cmpl $0x00, %eax
jnz NemInitExit jnz NemInitExit
# #
# Load microcode # Load microcode
# #
movl L2, %eax movl $TempRamInitApiL2, %eax
addl $4, %esp addl $0x04, %esp
jmp LoadUcode jmp LoadUcode
L2:
TempRamInitApiL2:
LOAD_ESP LOAD_ESP
cmpl $0, %eax cmpl $0x00, %eax
jnz NemInitExit jnz NemInitExit
# #
# Call platform NEM init # Call platform NEM init
#------------------------------------------------------------------------------------------------------------------------- #
movl L3, %eax movl $TempRamInitApiL3, %eax
addl $4, %esp addl $0x04, %esp
jmp ASM_PFX(PlatformTempRamInit) jmp ASM_PFX(PlatformTempRamInit)
L3: TempRamInitApiL3:
subl $4, %esp subl $0x04, %esp
cmpl $0, %eax cmpl $0x00, %eax
jnz NemInitExit jnz NemInitExit
# #
@ -399,37 +536,29 @@ L3:
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
pushl $DATA_LEN_OF_MCUD # Size of the data region pushl $DATA_LEN_OF_MCUD # Size of the data region
pushl 0x4455434D # Signature of the data region 'MCUD' 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 4(%edx) # Microcode size
pushl (%edx) # Microcode base 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 # Save API entry/exit timestamp into stack
# #
pushl DATA_LEN_OF_PER0 # Size of the data region pushl $DATA_LEN_OF_PER0 # Size of the data region
pushl 0x30524550 # Signature of the data region 'PER0' pushl $0x30524550 # Signature of the data region 'PER0'
movd %xmm4, %eax
pushl %eax
movd %xmm5, %eax
pushl %eax
rdtsc rdtsc
pushl %edx pushl %edx
pushl %eax pushl %eax
LOAD_EAX
LOAD_EDX
pushl %edx
pushl %eax
# #
# Terminator for the data on stack # Terminator for the data on stack
# #
pushl $0 pushl $0x00
# #
# Set ECX/EDX to the bootloader temporary memory range # Set ECX/EDX to the bootloader temporary memory range
@ -447,7 +576,7 @@ NemInitExit:
# #
LOAD_REGS LOAD_REGS
ret ret
#TempRamInitApi ENDP
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# FspInit API # FspInit API
@ -463,48 +592,43 @@ ASM_PFX(FspInitApi):
# Stack must be ready # Stack must be ready
# #
pushl $0x087654321 pushl $0x087654321
pop %eax popl %eax
cmpl $0x087654321, %eax cmpl $0x087654321, %eax
jz L5 jz FspInitApiL0
movl $0x080000003, %eax movl $0x080000003, %eax
jmp exit3 jmp FspInitApiexit
L5: FspInitApiL0:
# #
# Additional check # Additional check
# #
pusha pusha
pushl $1 pushl $0x01
call ASM_PFX(FspApiCallingCheck) call ASM_PFX(FspApiCallingCheck)
addl $4, %esp addl $0x04, %esp
movl %eax, 28(%esp) movl %eax, 28(%esp)
popa popa
cmpl $0 , %eax cmpl $0x00, %eax
jz L6 jz FspInitApiL1
jmp exit3 jmp FspInitApiexit
L6:
#
# Save the Platform Data Pointer in EDI
#
movl 4(%esp), %edi
FspInitApiL1:
# #
# Store the address in FSP which will return control to the BL # 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 # Create a Task Frame in the stack for the Boot Loader
# #
pushfl
pushfl # 2 pushf for 4 byte alignment pushfl # 2 pushf for 4 byte alignment
cli cli
pushal pushal
#
# Reserve 8 bytes for IDT save/restore # Reserve 8 bytes for IDT save/restore
pushl $0 #
pushl $0 subl $0x08, %esp
sidt (%esp) sidt (%esp)
# #
@ -512,11 +636,9 @@ L6:
# #
movl %esp, %eax movl %esp, %eax
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) , %esp addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp
subl DATA_LEN_AT_STACK_TOP, %esp subl $(DATA_LEN_AT_STACK_TOP + 0x40), %esp
addl $0x0FFFFFFC0, %esp
#
# Save the bootloader's stack pointer # Save the bootloader's stack pointer
# #
pushl %eax pushl %eax
@ -525,10 +647,11 @@ L6:
# Pass entry point of the PEI core # Pass entry point of the PEI core
# #
call ASM_PFX(GetFspBaseAddress) call ASM_PFX(GetFspBaseAddress)
movl %eax, %edi movl ASM_PFX(FspImageSizeOffset), %edi
addl ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi movl (%eax, %edi), %edi
addl %eax, %edi
subl $0x20, %edi subl $0x20, %edi
addl %ds:(%edi), %eax addl (%edi), %eax
pushl %eax pushl %eax
# #
@ -558,10 +681,9 @@ L6:
# #
call ASM_PFX(SecStartup) call ASM_PFX(SecStartup)
exit3: FspInitApiexit:
ret ret
# FspInitApi ENDP
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# NotifyPhase API # NotifyPhase API
@ -576,36 +698,35 @@ ASM_PFX(NotifyPhaseApi):
# Stack must be ready # Stack must be ready
# #
pushl $0x0087654321 pushl $0x0087654321
pop %eax popl %eax
cmpl $0x087654321, %eax cmpl $0x087654321, %eax
jz L7 jz NotifyPhaseApiL0
movl $0x080000003, %eax movl $0x080000003, %eax
jmp err_exit jmp NotifyPhaseApiErrExit
L7: NotifyPhaseApiL0:
# #
# Verify the calling condition # Verify the calling condition
# #
pusha pusha
pushl $2 pushl $0x02
call ASM_PFX(FspApiCallingCheck) call ASM_PFX(FspApiCallingCheck)
add $4, %esp addl $0x04, %esp
mov %eax, 28(%esp) movl %eax, 28(%esp)
popa popa
cmpl $0, %eax cmpl $0x00, %eax
jz L8 jz NotifyPhaseApiL1
# #
# Error return # Error return
# #
err_exit: NotifyPhaseApiErrExit:
ret ret
L8: NotifyPhaseApiL1:
jmp ASM_PFX(Pei2LoaderSwitchStack) jmp ASM_PFX(Pei2LoaderSwitchStack)
#NotifyPhaseApi ENDP
#END #END