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,310 +15,438 @@
# #
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#.INCLUDE "UcodeLoad.inc" #.INCLUDE "UcodeLoadGcc.inc" - begin
# .equ MSR_IA32_PLATFORM_ID, 0x00000017
# Following are fixed PCDs .equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079
# .equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b
.equ MSR_IA32_PLATFORM_ID, 0x000000017 Ucode:
.equ MSR_IA32_BIOS_UPDT_TRIG, 0x000000079 .equ UcodeVersion, 0x0000
.equ MSR_IA32_BIOS_SIGN_ID, 0x00000008b .equ UcodeRevision, 0x0004
.equ UcodeDate, 0x0008
.equ UcodeProcessor, 0x000C
.equ UcodeChecksum, 0x0010
.equ UcodeLoader, 0x0014
.equ UcodeRsvd, 0x0018
UcodeEnd:
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase) UcodeHdr:
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) .equ UcodeHdrVersion, 0x0000
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize) .equ UcodeHdrRevision, 0x0004
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize) .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:
# Following functions will be provided in C .equ ExtSigHdrCount, 0x0000
# .equ ExtSigHdrChecksum, 0x0004
#EXTERNDEF SecStartup:PROC .equ rsvd, 0x0008
#EXTERNDEF FspApiCallingCheck:PROC ExtSigHdrEnd:
.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr
# ExtSig:
# Following functions will be provided in PlatformSecLib .equ ExtSigProcessor, 0x0000
# .equ ExtSigFlags, 0x0004
#EXTERNDEF GetFspBaseAddress:PROC .equ ExtSigChecksum, 0x0008
#EXTERNDEF GetBootFirmwareVolumeOffset:PROC ExtSigEnd:
#EXTERNDEF PlatformTempRamInit:PROC .equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig
#EXTERNDEF Pei2LoaderSwitchStack:PROC
#EXTERN FspSelfCheck(FspSelfCheckDflt):PROC
#EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC
# LoadUcodeParams:
# Define the data length that we saved on the stack top .equ LoadUcodeParamsUcodeCodeAddr, 0x0000
# .equ LoadUcodeParamsUcodeCodeSize, 0x0004
.equ DATA_LEN_OF_PER0, 0x018 LoadUcodeParamsEnd:
.equ DATA_LEN_OF_MCUD, 0x018
.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
# #.INCLUDE "UcodeLoadGcc.inc" - end
# Define SSE macros
# #.INCLUDE "SaveRestoreSseGcc.inc" - begin
.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 .macro SAVE_REGS
movd %ebp, %xmm7 pinsrw $0x00, %ebp, %xmm7
pshufd $0x93, %xmm7, %xmm7 ror $0x10, %ebp
movd %ebx, %xmm6 pinsrw $0x01, %ebp, %xmm7
por %xmm6, %xmm7 ror $0x10, %ebp
pshufd $0x93, %xmm7, %xmm7 #
movd %esi,%xmm6 pinsrw $0x02, %ebx, %xmm7
por %xmm6, %xmm7 ror $0x10, %ebx
pshufd $0x93, %xmm7, %xmm7 pinsrw $0x03, %ebx, %xmm7
movd %edi, %xmm6 ror $0x10, %ebx
por %xmm6, %xmm7 #
movd %esp, %xmm6 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 .endm
.macro LOAD_REGS .macro LOAD_REGS
movd %xmm6, %esp pshufd $0xe4, %xmm7, %xmm7
movd %xmm7, %edi movd %xmm7, %ebp
pshufd $0x39,%xmm7, %xmm7 pshufd $0xe4, %xmm7, %xmm7
movd %xmm7, %esi #
pshufd $0x39,%xmm7, %xmm7
movd %xmm7, %ebx
pshufd $0x39, %xmm7, %xmm7 pshufd $0x39, %xmm7, %xmm7
movd %xmm7, %ebp 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 .endm
.macro LOAD_ESP .macro LOAD_ESP
movd %xmm6, %esp movd %xmm6, %esp
.endm .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
#
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)
ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)
#
# Following functions will be provided in C
#
ASM_GLOBAL ASM_PFX(FspImageSizeOffset)
ASM_GLOBAL ASM_PFX(SecStartup)
ASM_GLOBAL ASM_PFX(FspApiCallingCheck)
#
# Following functions will be provided in PlatformSecLib
#
ASM_GLOBAL ASM_PFX(GetBootFirmwareVolumeOffset)
ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)
#
# 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)
#------------------------------------------------------------------------------
# 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_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:
PlatformBasicInitDfltExit:
jmp *%ebp jmp *%ebp
#PlatformBasicInitDflt ENDP
#------------------------------------------------------------------------------
# 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 #
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 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 NextMicrocode
add 0x24(%esi) , %esi #(%esi).ucode_hdr.total_size cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax
jmp check_address je NextMicrocode
L10:
addl $0x800, %esi
jmp check_address
advance_fixed_size: #
# Then verify total size - sizeof header > data size
#
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 $UcodeHdrLength, %edi #add edi, sizeof ucode_hdr
addl UcodeHdrDataSize(%esi), %edi #add edi, [esi].ucode_hdr.data_size
#
# Get count of extended structures
#
movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count
#
# Move pointer to first signature structure
#
addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr
CheckExtSig:
#
# Check if extended signature and platform ID match
#
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 $ExtSigLength, %edi #add edi, sizeof ext_sig
loop CheckExtSig
NextMicrocode:
#
# Advance just after end of this microcode
#
xorl %eax, %eax
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
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 cmpl %eax, %esi
jae done #Jif address is outside of ucode region jae Done #Jif address is outside of ucode region
jmp check_main_header jmp CheckMainHeader
load_check: 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 #
xorl %eax, %eax # Clear EAX movl $MSR_IA32_BIOS_SIGN_ID, %ecx
xorl %edx, %edx # Clear EDX xorl %eax, %eax # Clear EAX
wrmsr # Load 0 to MSR at 8Bh xorl %edx, %edx # Clear EDX
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
xorl %edx, %edx addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr
mov MSR_IA32_BIOS_UPDT_TRIG,%ecx xorl %edx, %edx
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,102 +472,103 @@ 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
# #
# Save parameter pointer in edx # Save parameter pointer in edx
# #
movl 4(%esp), %edx movl 4(%esp), %edx
# #
# Enable FSP STACK # Enable FSP STACK
# #
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
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 4(%edx) # Microcode size
pushl 8(%edx) # Code base pushl (%edx) # Microcode base
cmpl $0, %edx # Is parameter pointer valid ? pushl 12(%edx) # Code size
jz InvalidMicrocodeRegion pushl 8(%edx) # Code base
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 # 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
# #
movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx
movl %ecx, %edx movl %ecx, %edx
addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx
subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx
xorl %eax, %eax xorl %eax, %eax
NemInitExit: NemInitExit:
# #
@ -447,7 +576,7 @@ NemInitExit:
# #
LOAD_REGS LOAD_REGS
ret ret
#TempRamInitApi ENDP
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# FspInit API # FspInit API
@ -463,60 +592,53 @@ 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)
# #
# Setup new FSP stack # Setup new FSP stack
# #
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