diff options
Diffstat (limited to 'IntelFspPkg/FspSecCore/Ia32')
-rw-r--r-- | IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm | 141 | ||||
-rw-r--r-- | IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s | 278 | ||||
-rw-r--r-- | IntelFspPkg/FspSecCore/Ia32/FspHelper.asm | 33 | ||||
-rw-r--r-- | IntelFspPkg/FspSecCore/Ia32/FspHelper.s | 33 | ||||
-rw-r--r-- | IntelFspPkg/FspSecCore/Ia32/MicrocodeLoad.inc | 49 | ||||
-rw-r--r-- | IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc | 95 | ||||
-rw-r--r-- | IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc | 63 |
7 files changed, 404 insertions, 288 deletions
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm index a7249599e2..01b0bfab31 100644 --- a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm +++ b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm @@ -17,7 +17,7 @@ .xmm
INCLUDE SaveRestoreSse.inc
-INCLUDE UcodeLoad.inc
+INCLUDE MicrocodeLoad.inc
;
; Following are fixed PCDs
@@ -40,8 +40,7 @@ EXTERN FspApiCallingCheck:PROC EXTERN GetFspBaseAddress:PROC
EXTERN GetBootFirmwareVolumeOffset:PROC
EXTERN Pei2LoaderSwitchStack:PROC
-EXTERN FspSelfCheck(FspSelfCheckDefault):PROC
-EXTERN LoadUcode(LoadUcodeDefault):PROC
+EXTERN LoadMicrocode(LoadMicrocodeDefault):PROC
EXTERN SecPlatformInit(SecPlatformInitDefault):PROC
EXTERN SecCarInit:PROC
@@ -69,7 +68,7 @@ ReturnAddress: ENDM
RET_ESI_EXT MACRO MmxRegister
- movd esi, MmxRegister ; restore ESP from MMX
+ movd esi, MmxRegister ; move ReturnAddress from MMX to ESI
jmp esi
ENDM
@@ -78,28 +77,10 @@ CALL_MMX MACRO RoutineLabel ENDM
RET_ESI MACRO
- RET_ESI_EXT mm7
+ RET_ESI_EXT mm7
ENDM
;------------------------------------------------------------------------------
-FspSelfCheckDefault 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
-FspSelfCheckDefault ENDP
-
-;------------------------------------------------------------------------------
SecPlatformInitDefault PROC NEAR PUBLIC
; Inputs:
; mm7 -> Return address
@@ -118,9 +99,9 @@ exit: SecPlatformInitDefault ENDP
;------------------------------------------------------------------------------
-LoadUcodeDefault PROC NEAR PUBLIC
+LoadMicrocodeDefault PROC NEAR PUBLIC
; Inputs:
- ; esp -> LOAD_UCODE_PARAMS pointer
+ ; esp -> LoadMicrocodeParams pointer
; Register Usage:
; esp Preserved
; All others destroyed
@@ -136,11 +117,11 @@ LoadUcodeDefault PROC NEAR PUBLIC cmp esp, 0
jz paramerror
- mov eax, dword ptr [esp] ; Parameter pointer
+ mov eax, dword ptr [esp + 4] ; Parameter pointer
cmp eax, 0
jz paramerror
mov esp, eax
- mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
+ mov esi, [esp].LoadMicrocodeParams.MicrocodeCodeAddr
cmp esi, 0
jnz check_main_header
@@ -148,7 +129,7 @@ paramerror: mov eax, 080000002h
jmp exit
- mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
+ mov esi, [esp].LoadMicrocodeParams.MicrocodeCodeAddr
check_main_header:
; Get processor signature and platform ID from the installed processor
@@ -175,60 +156,60 @@ check_main_header: ; 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
+ cmp [esi].MicrocodeHdr.MicrocodeHdrVersion, eax
jne advance_fixed_size
- cmp [esi].ucode_hdr.loader, eax
+ cmp [esi].MicrocodeHdr.MicrocodeHdrLoader, eax
jne advance_fixed_size
; Check if signature and plaform ID match
- cmp ebx, [esi].ucode_hdr.processor
+ cmp ebx, [esi].MicrocodeHdr.MicrocodeHdrProcessor
jne @f
- test edx, [esi].ucode_hdr.flags
+ test edx, [esi].MicrocodeHdr.MicrocodeHdrFlags
jnz load_check ; Jif signature and platform ID match
@@:
; Check if extended header exists
- ; First check if total_size and data_size are valid
+ ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
xor eax, eax
- cmp [esi].ucode_hdr.total_size, eax
+ cmp [esi].MicrocodeHdr.MicrocodeHdrTotalSize, eax
je next_microcode
- cmp [esi].ucode_hdr.data_size, eax
+ cmp [esi].MicrocodeHdr.MicrocodeHdrDataSize, 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
+ mov ecx, [esi].MicrocodeHdr.MicrocodeHdrTotalSize
+ sub ecx, sizeof MicrocodeHdr
+ cmp ecx, [esi].MicrocodeHdr.MicrocodeHdrDataSize
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
+ add edi, sizeof MicrocodeHdr
+ add edi, [esi].MicrocodeHdr.MicrocodeHdrDataSize
; Get count of extended structures
- mov ecx, [edi].ext_sig_hdr.count
+ mov ecx, [edi].ExtSigHdr.ExtSigHdrCount
; Move pointer to first signature structure
- add edi, sizeof ext_sig_hdr
+ add edi, sizeof ExtSigHdr
check_ext_sig:
; Check if extended signature and platform ID match
- cmp [edi].ext_sig.processor, ebx
+ cmp [edi].ExtSig.ExtSigProcessor, ebx
jne @f
- test [edi].ext_sig.flags, edx
+ test [edi].ExtSig.ExtSigFlags, edx
jnz load_check ; Jif signature and platform ID match
@@:
; Check if any more extended signatures exist
- add edi, sizeof ext_sig
+ add edi, sizeof ExtSig
loop check_ext_sig
next_microcode:
; Advance just after end of this microcode
xor eax, eax
- cmp [esi].ucode_hdr.total_size, eax
+ cmp [esi].MicrocodeHdr.MicrocodeHdrTotalSize, eax
je @f
- add esi, [esi].ucode_hdr.total_size
+ add esi, [esi].MicrocodeHdr.MicrocodeHdrTotalSize
jmp check_address
@@:
add esi, dword ptr 2048
@@ -240,18 +221,18 @@ advance_fixed_size: check_address:
; Is valid Microcode start point ?
- cmp dword ptr [esi].ucode_hdr.version, 0ffffffffh
+ cmp dword ptr [esi].MicrocodeHdr.MicrocodeHdrVersion, 0ffffffffh
jz done
; Is automatic size detection ?
- mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size
+ mov eax, [esp].LoadMicrocodeParams.MicrocodeCodeSize
cmp eax, 0ffffffffh
jz @f
; Address >= microcode region address + microcode region size?
- add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
+ add eax, [esp].LoadMicrocodeParams.MicrocodeCodeAddr
cmp esi, eax
- jae done ;Jif address is outside of ucode region
+ jae done ;Jif address is outside of microcode region
jmp check_main_header
@@:
@@ -268,7 +249,7 @@ load_check: rdmsr ; Get current microcode signature
; Verify this microcode update is not already loaded
- cmp [esi].ucode_hdr.revision, edx
+ cmp [esi].MicrocodeHdr.MicrocodeHdrRevision, edx
je continue
load_microcode:
@@ -277,7 +258,7 @@ load_microcode: ; ECX contains 79h (IA32_BIOS_UPDT_TRIG)
; Start microcode load with wrmsr
mov eax, esi
- add eax, sizeof ucode_hdr
+ add eax, sizeof MicrocodeHdr
xor edx, edx
mov ecx, MSR_IA32_BIOS_UPDT_TRIG
wrmsr
@@ -300,35 +281,27 @@ done: exit:
jmp ebp
-LoadUcodeDefault ENDP
+LoadMicrocodeDefault ENDP
EstablishStackFsp PROC NEAR PRIVATE
;
- ; Save parameter pointer in edx
+ ; Save parameter pointer in edx
;
- mov edx, dword ptr [esp + 4]
-
+ mov edx, dword ptr [esp + 4]
+
;
; Enable FSP STACK
;
mov esp, PcdGet32 (PcdTemporaryRamBase)
- add esp, PcdGet32 (PcdTemporaryRamSize)
+ add esp, PcdGet32 (PcdTemporaryRamSize)
- push DATA_LEN_OF_MCUD ; Size of the data region
+ push DATA_LEN_OF_MCUD ; Size of the data region
push 4455434Dh ; Signature of the data region 'MCUD'
push dword ptr [edx + 12] ; Code size
push dword ptr [edx + 8] ; Code base
- cmp edx, 0 ; Is parameter pointer valid ?
- jz InvalidMicrocodeRegion
push dword ptr [edx + 4] ; Microcode size
- push dword ptr [edx] ; Microcode base
- jmp @F
+ push dword ptr [edx] ; Microcode base
-InvalidMicrocodeRegion:
- push 0 ; Microcode size
- push 0 ; Microcode base
-
-@@:
;
; Save API entry/exit timestamp into stack
;
@@ -348,7 +321,7 @@ InvalidMicrocodeRegion: push 0
;
- ; Set ECX/EDX to the bootloader temporary memory range
+ ; Set ECX/EDX to the BootLoader temporary memory range
;
mov ecx, PcdGet32 (PcdTemporaryRamBase)
mov edx, ecx
@@ -356,7 +329,7 @@ InvalidMicrocodeRegion: sub edx, PcdGet32 (PcdFspTemporaryRamSize)
xor eax, eax
-
+
RET_ESI
EstablishStackFsp ENDP
@@ -398,22 +371,17 @@ TempRamInitApi PROC NEAR PUBLIC ;
; CPUID/DeviceID check
+ ; and Sec Platform Init
;
- mov eax, @F
- jmp FspSelfCheck ; Note: ESP can not be changed.
-@@:
- cmp eax, 0
- jnz NemInitExit
-
CALL_MMX SecPlatformInit
cmp eax, 0
jnz NemInitExit
; Load microcode
LOAD_ESP
- CALL_MMX LoadUcode
- cmp eax, 0
- jnz NemInitExit
+ CALL_MMX LoadMicrocode
+ SXMMN xmm6, 3, eax ;Save microcode return status in ECX-SLOT 3 in xmm6.
+ ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot.
; Call Sec CAR Init
LOAD_ESP
@@ -424,6 +392,8 @@ TempRamInitApi PROC NEAR PUBLIC LOAD_ESP
CALL_MMX EstablishStackFsp
+ LXMMN xmm6, eax, 3 ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6.
+
NemInitExit:
;
; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
@@ -519,9 +489,10 @@ FspApiCommon PROC C PUBLIC ; Verify the calling condition
;
pushad
+ push [esp + 4 * 8 + 4]
push eax
call FspApiCallingCheck
- add esp, 4
+ add esp, 8
cmp eax, 0
jz @F
mov dword ptr [esp + 4 * 7], eax
@@ -536,10 +507,10 @@ FspApiCommon PROC C PUBLIC jz @F
jmp Pei2LoaderSwitchStack
-@@:
+@@:
;
; FspInit and FspMemoryInit APIs, setup the initial stack frame
- ;
+ ;
;
; Store the address in FSP which will return control to the BL
@@ -555,7 +526,7 @@ FspApiCommon PROC C PUBLIC ; Reserve 8 bytes for IDT save/restore
sub esp, 8
- sidt fword ptr [esp]
+ sidt fword ptr [esp]
;
; Setup new FSP stack
@@ -571,7 +542,7 @@ FspApiCommon PROC C PUBLIC push eax
;
- ; Pass the bootloader stack to SecStartup
+ ; Pass the BootLoader stack to SecStartup
;
push edi
@@ -612,7 +583,7 @@ FspApiCommon PROC C PUBLIC ;
call SecStartup
-exit:
+exit:
ret
FspApiCommon ENDP
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s index d914075edc..1d8fe0bcd2 100644 --- a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s +++ b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s @@ -15,41 +15,31 @@ #
#------------------------------------------------------------------------------
-#.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
+
+MicrocodeHdr:
+.equ MicrocodeHdrVersion, 0x0000
+.equ MicrocodeHdrRevision, 0x0004
+.equ MicrocodeHdrDate, 0x0008
+.equ MicrocodeHdrProcessor, 0x000c
+.equ MicrocodeHdrChecksum, 0x0010
+.equ MicrocodeHdrLoader, 0x0014
+.equ MicrocodeHdrFlags, 0x0018
+.equ MicrocodeHdrDataSize, 0x001C
+.equ MicrocodeHdrTotalSize, 0x0020
+.equ MicrocodeHdrRsvd, 0x0024
+MicrocodeHdrEnd:
+.equ MicrocodeHdrLength, 0x0030 # MicrocodeHdrLength = MicrocodeHdrEnd - MicrocodeHdr
ExtSigHdr:
.equ ExtSigHdrCount, 0x0000
.equ ExtSigHdrChecksum, 0x0004
-.equ rsvd, 0x0008
+.equ ExtSigHdrRsvd, 0x0008
ExtSigHdrEnd:
.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr
@@ -60,14 +50,12 @@ ExtSig: ExtSigEnd:
.equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig
-LoadUcodeParams:
-.equ LoadUcodeParamsUcodeCodeAddr, 0x0000
-.equ LoadUcodeParamsUcodeCodeSize, 0x0004
-LoadUcodeParamsEnd:
+LoadMicrocodeParams:
+.equ MicrocodeCodeAddr, 0x0000
+.equ MicrocodeCodeSize, 0x0004
+LoadMicrocodeParamsEnd:
-#.INCLUDE "UcodeLoadGcc.inc" - end
-#.INCLUDE "SaveRestoreSseGcc.inc" - begin
.macro SAVE_REGS
pinsrw $0x00, %ebp, %xmm7
@@ -147,12 +135,68 @@ LoadUcodeParamsEnd: .endm
.macro ENABLE_SSE
- movl %cr4, %eax
- orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
- movl %eax,%cr4
+ jmp NextAddress
+.align 4
+ #
+ # 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
+SseError:
+ #
+ # Processor has to support SSE
+ #
+ jmp SseError
+NextAddress:
+ #
+ # 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 SseError
+
+ #
+ # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+ #
+ movl %cr4, %eax
+ orl $BIT9, %eax
+ movl %eax, %cr4
+
+ #
+ # The processor should support SSE instruction and we can use
+ # ldmxcsr instruction
+ #
+ ldmxcsr ASM_PFX(mMmxControlWord)
+.endm
+
+#Save in ECX-SLOT 3 in xmm6.
+.macro SAVE_EAX_MICROCODE_RET_STATUS
+ pinsrw $0x6, %eax, %xmm6
+ ror $0x10, %eax
+ pinsrw $0x7, %eax, %xmm6
+ rol $0x10, %eax
+.endm
+
+#Restore from ECX-SLOT 3 in xmm6.
+.macro LOAD_EAX_MICROCODE_RET_STATUS
+ pshufd $0x93, %xmm6, %xmm6
+ movd %xmm6, %eax
+ pshufd $0x39, %xmm6, %xmm6
.endm
-#.INCLUDE "SaveRestoreSseGcc.inc" - end
#
@@ -183,28 +227,6 @@ ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack) .equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)
#------------------------------------------------------------------------------
-# FspSelfCheckDefault
-# 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(FspSelfCheckDefault)
-ASM_PFX(FspSelfCheckDefault):
- #
- # Save return address to EBP
- #
- movl %eax, %ebp
- xorl %eax, %eax
-
-FspSelfCheckDefaultExit:
- jmp *%ebp
-
-
-#------------------------------------------------------------------------------
# SecPlatformInitDefault
# Inputs:
# mm7 -> Return address
@@ -227,10 +249,10 @@ SecPlatformInitDefaultExit: #------------------------------------------------------------------------------
-# LoadUcode
+# LoadMicrocodeDefault
#
# Inputs:
-# esp -> LOAD_UCODE_PARAMS pointer
+# esp -> LoadMicrocodeParams pointer
# Register Usage:
# esp Preserved
# All others destroyed
@@ -239,8 +261,8 @@ SecPlatformInitDefaultExit: # Executed by SBSP and NBSP
# Beginning of microcode update region starts on paragraph boundary
#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(LoadUcode)
-ASM_PFX(LoadUcode):
+ASM_GLOBAL ASM_PFX(LoadMicrocodeDefault)
+ASM_PFX(LoadMicrocodeDefault):
#
# Save return address to EBP
#
@@ -248,17 +270,17 @@ ASM_PFX(LoadUcode): cmpl $0x00, %esp
jz ParamError
- movl (%esp), %eax #dword ptr [] Parameter pointer
+ movl 4(%esp), %eax #dword ptr [] Parameter pointer
cmpl $0x00, %eax
jz ParamError
movl %eax, %esp
- movl LoadUcodeParamsUcodeCodeAddr(%esp), %esi #mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
+ movl MicrocodeCodeAddr(%esp), %esi
cmpl $0x00, %esi
jnz CheckMainHeader
ParamError:
movl $0x080000002, %eax
- jmp LoadUcodeExit
+ jmp LoadMicrocodeExit
CheckMainHeader:
#
@@ -291,68 +313,68 @@ CheckMainHeader: # Minimal test checking for header version and loader version as 1
#
movl $0x01, %eax
- cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax
+ cmpl %eax, MicrocodeHdrVersion(%esi)
jne AdvanceFixedSize
- cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax
+ cmpl %eax, MicrocodeHdrLoader(%esi)
jne AdvanceFixedSize
#
# Check if signature and plaform ID match
#
- cmpl UcodeHdrProcessor(%esi), %ebx #cmp ebx, [esi].ucode_hdr.processor
- jne LoadUcodeL0
- testl UcodeHdrFlags(%esi), %edx #test edx, [esi].ucode_hdr.flags
+ cmpl MicrocodeHdrProcessor(%esi), %ebx
+ jne LoadMicrocodeL0
+ testl MicrocodeHdrFlags(%esi), %edx
jnz LoadCheck #Jif signature and platform ID match
-LoadUcodeL0:
+LoadMicrocodeL0:
#
# Check if extended header exists
- # First check if total_size and data_size are valid
+ # First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
#
xorl %eax, %eax
- cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax
+ cmpl %eax, MicrocodeHdrTotalSize(%esi)
je NextMicrocode
- cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax
+ cmpl %eax, MicrocodeHdrDataSize(%esi)
je NextMicrocode
#
# 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
+ movl MicrocodeHdrTotalSize(%esi), %ecx
+ subl $MicrocodeHdrLength, %ecx
+ cmpl MicrocodeHdrDataSize(%esi), %ecx
+ 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
+ addl $MicrocodeHdrLength, %edi
+ addl MicrocodeHdrDataSize(%esi), %edi
#
# Get count of extended structures
#
- movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count
+ movl ExtSigHdrCount(%edi), %ecx
#
# Move pointer to first signature structure
#
- addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr
+ addl ExtSigHdrLength, %edi
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
+ cmpl %ebx, ExtSigProcessor(%edi)
+ jne LoadMicrocodeL1
+ test %edx, ExtSigFlags(%edi)
jnz LoadCheck # Jif signature and platform ID match
-LoadUcodeL1:
+LoadMicrocodeL1:
#
# Check if any more extended signatures exist
#
- addl $ExtSigLength, %edi #add edi, sizeof ext_sig
+ addl $ExtSigLength, %edi
loop CheckExtSig
NextMicrocode:
@@ -360,11 +382,11 @@ 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
+ cmpl %eax, MicrocodeHdrTotalSize(%esi)
+ je LoadMicrocodeL2
+ addl MicrocodeHdrTotalSize(%esi), %esi
jmp CheckAddress
-LoadUcodeL2:
+LoadMicrocodeL2:
addl $0x800, %esi #add esi, dword ptr 2048
jmp CheckAddress
@@ -378,24 +400,24 @@ CheckAddress: #
# Is valid Microcode start point ?
#
- cmpl $0x0ffffffff, UcodeHdrVersion(%esi)
+ cmpl $0x0ffffffff, MicrocodeHdrVersion(%esi)
#
# Is automatic size detection ?
#
- movl LoadUcodeParamsUcodeCodeSize(%esp), %eax
+ movl MicrocodeCodeSize(%esp), %eax
cmpl $0x0ffffffff, %eax
- jz LoadUcodeL3
+ jz LoadMicrocodeL3
#
# Address >= microcode region address + microcode region size?
#
- addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr
+ addl MicrocodeCodeAddr(%esp), %eax
cmpl %eax, %esi
- jae Done #Jif address is outside of ucode region
+ jae Done #Jif address is outside of microcode region
jmp CheckMainHeader
-LoadUcodeL3:
+LoadMicrocodeL3:
LoadCheck:
#
# Get the revision of the current microcode update loaded
@@ -413,10 +435,10 @@ LoadCheck: #
# Verify this microcode update is not already loaded
#
- cmpl %edx, UcodeHdrRevision(%esi) #cmp [esi].ucode_hdr.revision, edx
+ cmpl %edx, MicrocodeHdrRevision(%esi)
je Continue
-LoadMicrocode:
+LoadMicrocode0:
#
# EAX contains the linear address of the start of the Update Data
# EDX contains zero
@@ -424,7 +446,7 @@ LoadMicrocode: # Start microcode load with wrmsr
#
movl %esi, %eax
- addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr
+ addl $MicrocodeHdrLength, %eax
xorl %edx, %edx
movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx
wrmsr
@@ -441,10 +463,10 @@ Done: rdmsr # Get current microcode signature
xorl %eax, %eax
cmpl $0x00, %edx
- jnz LoadUcodeExit
+ jnz LoadMicrocodeExit
movl $0x08000000E, %eax
-LoadUcodeExit:
+LoadMicrocodeExit:
jmp *%ebp
@@ -455,10 +477,10 @@ LoadUcodeExit: ASM_GLOBAL ASM_PFX(EstablishStackFsp)
ASM_PFX(EstablishStackFsp):
#
- # Save parameter pointer in edx
+ # Save parameter pointer in edx
#
movl 4(%esp), %edx
-
+
#
# Enable FSP STACK
#
@@ -469,17 +491,9 @@ ASM_PFX(EstablishStackFsp): 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 EstablishStackFspExit
-InvalidMicrocodeRegion:
- push $0 # Microcode size
- push $0 # Microcode base
-
-EstablishStackFspExit:
#
# Save API entry/exit timestamp into stack
#
@@ -495,11 +509,11 @@ EstablishStackFspExit: #
# Terminator for the data on stack
- #
+ #
push $0x00
#
- # Set ECX/EDX to the bootloader temporary memory range
+ # Set ECX/EDX to the BootLoader temporary memory range
#
movl PcdGet32 (PcdTemporaryRamBase), %ecx
movl %ecx, %edx
@@ -507,7 +521,7 @@ EstablishStackFspExit: subl PcdGet32 (PcdFspTemporaryRamSize), %edx
xorl %eax, %eax
-
+
movd %mm7, %esi #RET_ESI
jmp *%esi
@@ -548,18 +562,12 @@ ASM_PFX(TempRamInitApi): #
# CPUID/DeviceID check
- #
- movl $TempRamInitApiL0, %eax
- jmp ASM_PFX(FspSelfCheckDefault) # @note: ESP can not be changed.
-TempRamInitApiL0:
- cmpl $0x00, %eax
- jnz NemInitExit
-
- #
- # Sec Platform Init
+ # and Sec Platform Init
#
movl $TempRamInitApiL1, %esi #CALL_MMX SecPlatformInit
- movd %mm7, %esi
+ movd %esi, %mm7
+ .weak ASM_PFX(SecPlatformInit)
+ .set ASM_PFX(SecPlatformInit), ASM_PFX(SecPlatformInitDefault)
jmp ASM_PFX(SecPlatformInit)
TempRamInitApiL1:
cmpl $0x00, %eax
@@ -569,19 +577,21 @@ TempRamInitApiL1: # Load microcode
#
LOAD_ESP
- movl $TempRamInitApiL2, %esi #CALL_MMX LoadUcode
- movd %mm7, %esi
- jmp ASM_PFX(LoadUcode)
+ movl $TempRamInitApiL2, %esi #CALL_MMX LoadMicrocode
+ movd %esi, %mm7
+ .weak ASM_PFX(LoadMicrocode)
+ .set ASM_PFX(LoadMicrocode), ASM_PFX(LoadMicrocodeDefault)
+ jmp ASM_PFX(LoadMicrocode)
TempRamInitApiL2:
- cmpl $0x00, %eax
- jnz NemInitExit
+ SAVE_EAX_MICROCODE_RET_STATUS #Save microcode return status in ECX-SLOT 3 in xmm6.
+ #@note If return value eax is not 0, microcode did not load, but continue and attempt to boot from ECX-SLOT 3 in xmm6.
#
# Call Sec CAR Init
#
LOAD_ESP
movl $TempRamInitApiL3, %esi #CALL_MMX SecCarInit
- movd %mm7, %esi
+ movd %esi, %mm7
jmp ASM_PFX(SecCarInit)
TempRamInitApiL3:
cmpl $0x00, %eax
@@ -592,10 +602,12 @@ TempRamInitApiL3: #
LOAD_ESP
movl $TempRamInitApiL4, %esi #CALL_MMX EstablishStackFsp
- movd %mm7, %esi
+ movd %esi, %mm7
jmp ASM_PFX(EstablishStackFsp)
TempRamInitApiL4:
+ LOAD_EAX_MICROCODE_RET_STATUS #Restore microcode status if no CAR init error.
+
NemInitExit:
#
# Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6
@@ -603,6 +615,7 @@ NemInitExit: LOAD_REGS
ret
+
#----------------------------------------------------------------------------
# FspInit API
#
@@ -743,7 +756,7 @@ FspApiCommonL2: pushl %eax
#
- # Pass the bootloader stack to SecStartup
+ # Pass the BootLoader stack to SecStartup
#
pushl %edi
@@ -787,4 +800,3 @@ FspApiCommonL2: FspApiCommonExit:
ret
-
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspHelper.asm b/IntelFspPkg/FspSecCore/Ia32/FspHelper.asm new file mode 100644 index 0000000000..51fd365c95 --- /dev/null +++ b/IntelFspPkg/FspSecCore/Ia32/FspHelper.asm @@ -0,0 +1,33 @@ +;; @file
+; Provide FSP helper function.
+;
+; Copyright (c) 2015, 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.
+;;
+
+ .586p
+ .model flat,C
+ .code
+
+FspInfoHeaderRelativeOff PROC NEAR PRIVATE
+ ;
+ ; This value will be pached by the build script
+ ;
+ DD 012345678h
+FspInfoHeaderRelativeOff ENDP
+
+GetFspBaseAddress PROC NEAR PUBLIC
+ mov eax, GetFspBaseAddress
+ sub eax, dword ptr [FspInfoHeaderRelativeOff]
+ add eax, 01Ch
+ mov eax, dword ptr [eax]
+ ret
+GetFspBaseAddress ENDP
+
+ END
\ No newline at end of file diff --git a/IntelFspPkg/FspSecCore/Ia32/FspHelper.s b/IntelFspPkg/FspSecCore/Ia32/FspHelper.s new file mode 100644 index 0000000000..40b822ac87 --- /dev/null +++ b/IntelFspPkg/FspSecCore/Ia32/FspHelper.s @@ -0,0 +1,33 @@ +#------------------------------------------------------------------------------
+#
+# Copyright (c) 2015, 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 helper function.
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(FspInfoHeaderRelativeOff)
+ASM_PFX(FspInfoHeaderRelativeOff):
+ #
+ # This value will be pached by the build script
+ #
+ .long 0x012345678
+
+
+ASM_GLOBAL ASM_PFX(GetFspBaseAddress)
+ASM_PFX(GetFspBaseAddress):
+ mov $GetFspBaseAddress, %eax
+ sub $FspInfoHeaderRelativeOff, %eax
+ add $0x01C, %eax
+ mov (%eax), %eax
+ ret
+
diff --git a/IntelFspPkg/FspSecCore/Ia32/MicrocodeLoad.inc b/IntelFspPkg/FspSecCore/Ia32/MicrocodeLoad.inc new file mode 100644 index 0000000000..6fbf430707 --- /dev/null +++ b/IntelFspPkg/FspSecCore/Ia32/MicrocodeLoad.inc @@ -0,0 +1,49 @@ +;------------------------------------------------------------------------------
+;
+; Copyright (c) 2014 - 2015, 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
+
+
+MicrocodeHdr STRUCT 1t
+ MicrocodeHdrVersion DWORD ?
+ MicrocodeHdrRevision DWORD ?
+ MicrocodeHdrDate DWORD ?
+ MicrocodeHdrProcessor DWORD ?
+ MicrocodeHdrChecksum DWORD ?
+ MicrocodeHdrLoader DWORD ?
+ MicrocodeHdrFlags DWORD ?
+ MicrocodeHdrDataSize DWORD ?
+ MicrocodeHdrTotalSize DWORD ?
+ MicrocodeHdrRsvd DWORD 3t DUP (?)
+MicrocodeHdr ENDS
+
+ExtSigHdr STRUCT 1t
+ ExtSigHdrCount DWORD ?
+ ExtSigHdrChecksum DWORD ?
+ ExtSigHdrRsvd DWORD 3t DUP (?)
+ExtSigHdr ENDS
+
+ExtSig STRUCT 1t
+ ExtSigProcessor DWORD ?
+ ExtSigFlags DWORD ?
+ ExtSigChecksum DWORD ?
+ExtSig ENDS
+
+LoadMicrocodeParams STRUCT 1t
+ MicrocodeCodeAddr DWORD ?
+ MicrocodeCodeSize DWORD ?
+LoadMicrocodeParams ENDS
diff --git a/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc b/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc index a3d5c47ffa..afc3ce061b 100644 --- a/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc +++ b/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc @@ -1,6 +1,6 @@ ;------------------------------------------------------------------------------
;
-; Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2014 - 2015, 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
@@ -47,7 +47,9 @@ LXMMN MACRO XMM, REG, IDX ENDM
ENDIF
-
+;
+; XMM7 to save/restore EBP, EBX, ESI, EDI
+;
SAVE_REGS MACRO
SXMMN xmm7, 0, ebp
SXMMN xmm7, 1, ebx
@@ -64,6 +66,9 @@ LOAD_REGS MACRO LOAD_ESP
ENDM
+;
+; XMM6 to save/restore EAX, EDX, ECX, ESP
+;
LOAD_EAX MACRO
LXMMN xmm6, eax, 1
ENDM
@@ -95,9 +100,85 @@ SAVE_ESP MACRO LOAD_ESP MACRO
movd esp, xmm6
ENDM
-
-ENABLE_SSE MACRO
- mov eax, cr4
- or eax, 00000600h
- mov cr4, eax
+
+;
+; XMM5 for calling stack
+;
+CALL_XMM MACRO Entry
+ local ReturnAddress
+ mov esi, offset ReturnAddress
+ pslldq xmm5, 4
+IFDEF USE_SSE41_FLAG
+ pinsrd xmm5, esi, 0
+ELSE
+ pinsrw xmm5, esi, 0
+ ror esi, 16
+ pinsrw xmm5, esi, 1
+ENDIF
+ mov esi, Entry
+ jmp esi
+ReturnAddress:
ENDM
+
+RET_XMM MACRO
+ movd esi, xmm5
+ psrldq xmm5, 4
+ jmp esi
+ ENDM
+
+ENABLE_SSE MACRO
+ ;
+ ; Initialize floating point units
+ ;
+ local NextAddress
+ jmp NextAddress
+ALIGN 4
+ ;
+ ; Float control word initial value:
+ ; all exceptions masked, double-precision, round-to-nearest
+ ;
+FpuControlWord DW 027Fh
+ ;
+ ; Multimedia-extensions control word:
+ ; all exceptions masked, round-to-nearest, flush to zero for masked underflow
+ ;
+MmxControlWord DD 01F80h
+SseError:
+ ;
+ ; Processor has to support SSE
+ ;
+ jmp SseError
+NextAddress:
+ finit
+ fldcw FpuControlWord
+
+ ;
+ ; 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 SseError
+
+IFDEF USE_SSE41_FLAG
+ ;
+ ; SSE 4.1 support
+ ;
+ bt ecx, 19
+ jnc SseError
+ENDIF
+
+ ;
+ ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
+ ;
+ mov eax, cr4
+ or eax, 00000600h
+ mov cr4, eax
+
+ ;
+ ; The processor should support SSE instruction and we can use
+ ; ldmxcsr instruction
+ ;
+ ldmxcsr MmxControlWord
+ ENDM
diff --git a/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc b/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc deleted file mode 100644 index 6be6ed097b..0000000000 --- a/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc +++ /dev/null @@ -1,63 +0,0 @@ -;------------------------------------------------------------------------------
-;
-; 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
|