#\r
#------------------------------------------------------------------------------\r
\r
-#.INCLUDE "UcodeLoadGcc.inc" - begin\r
\r
.equ MSR_IA32_PLATFORM_ID, 0x00000017\r
.equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079\r
.equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b\r
\r
-Ucode:\r
-.equ UcodeVersion, 0x0000\r
-.equ UcodeRevision, 0x0004\r
-.equ UcodeDate, 0x0008\r
-.equ UcodeProcessor, 0x000C\r
-.equ UcodeChecksum, 0x0010\r
-.equ UcodeLoader, 0x0014\r
-.equ UcodeRsvd, 0x0018\r
-UcodeEnd:\r
-\r
-UcodeHdr:\r
-.equ UcodeHdrVersion, 0x0000\r
-.equ UcodeHdrRevision, 0x0004\r
-.equ UcodeHdrDate, 0x0008\r
-.equ UcodeHdrProcessor, 0x000c\r
-.equ UcodeHdrChecksum, 0x0010\r
-.equ UcodeHdrLoader, 0x0014\r
-.equ UcodeHdrFlags, 0x0018\r
-.equ UcodeHdrDataSize, 0x001C\r
-.equ UcodeHdrTotalSize, 0x0020\r
-.equ UcodeHdrRsvd, 0x0024\r
-UcodeHdrEnd:\r
-.equ UcodeHdrLength, 0x0030 # UcodeHdrLength = UcodeHdrEnd - UcodeHdr\r
+\r
+MicrocodeHdr:\r
+.equ MicrocodeHdrVersion, 0x0000\r
+.equ MicrocodeHdrRevision, 0x0004\r
+.equ MicrocodeHdrDate, 0x0008\r
+.equ MicrocodeHdrProcessor, 0x000c\r
+.equ MicrocodeHdrChecksum, 0x0010\r
+.equ MicrocodeHdrLoader, 0x0014\r
+.equ MicrocodeHdrFlags, 0x0018\r
+.equ MicrocodeHdrDataSize, 0x001C\r
+.equ MicrocodeHdrTotalSize, 0x0020\r
+.equ MicrocodeHdrRsvd, 0x0024\r
+MicrocodeHdrEnd:\r
+.equ MicrocodeHdrLength, 0x0030 # MicrocodeHdrLength = MicrocodeHdrEnd - MicrocodeHdr\r
\r
\r
ExtSigHdr:\r
.equ ExtSigHdrCount, 0x0000\r
.equ ExtSigHdrChecksum, 0x0004\r
-.equ rsvd, 0x0008\r
+.equ ExtSigHdrRsvd, 0x0008\r
ExtSigHdrEnd:\r
.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr\r
\r
ExtSigEnd:\r
.equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig\r
\r
-LoadUcodeParams:\r
-.equ LoadUcodeParamsUcodeCodeAddr, 0x0000\r
-.equ LoadUcodeParamsUcodeCodeSize, 0x0004\r
-LoadUcodeParamsEnd:\r
+LoadMicrocodeParams:\r
+.equ MicrocodeCodeAddr, 0x0000\r
+.equ MicrocodeCodeSize, 0x0004\r
+LoadMicrocodeParamsEnd:\r
\r
-#.INCLUDE "UcodeLoadGcc.inc" - end\r
\r
-#.INCLUDE "SaveRestoreSseGcc.inc" - begin\r
\r
.macro SAVE_REGS\r
pinsrw $0x00, %ebp, %xmm7\r
.endm\r
\r
.macro ENABLE_SSE\r
- movl %cr4, %eax\r
- orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
- movl %eax,%cr4\r
+ jmp NextAddress\r
+.align 4\r
+ #\r
+ # Float control word initial value:\r
+ # all exceptions masked, double-precision, round-to-nearest\r
+ #\r
+ASM_PFX(mFpuControlWord): .word 0x027F\r
+ #\r
+ # Multimedia-extensions control word:\r
+ # all exceptions masked, round-to-nearest, flush to zero for masked underflow\r
+ #\r
+ASM_PFX(mMmxControlWord): .long 0x01F80\r
+SseError: \r
+ #\r
+ # Processor has to support SSE\r
+ #\r
+ jmp SseError \r
+NextAddress: \r
+ #\r
+ # Initialize floating point units\r
+ #\r
+ finit\r
+ fldcw ASM_PFX(mFpuControlWord)\r
+\r
+ #\r
+ # Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test\r
+ # whether the processor supports SSE instruction.\r
+ #\r
+ movl $1, %eax\r
+ cpuid\r
+ btl $25, %edx\r
+ jnc SseError\r
+\r
+ #\r
+ # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)\r
+ #\r
+ movl %cr4, %eax\r
+ orl $BIT9, %eax\r
+ movl %eax, %cr4\r
+\r
+ #\r
+ # The processor should support SSE instruction and we can use\r
+ # ldmxcsr instruction\r
+ #\r
+ ldmxcsr ASM_PFX(mMmxControlWord)\r
+.endm\r
+\r
+#Save in ECX-SLOT 3 in xmm6.\r
+.macro SAVE_EAX_MICROCODE_RET_STATUS\r
+ pinsrw $0x6, %eax, %xmm6\r
+ ror $0x10, %eax\r
+ pinsrw $0x7, %eax, %xmm6\r
+ rol $0x10, %eax\r
+.endm\r
+\r
+#Restore from ECX-SLOT 3 in xmm6.\r
+.macro LOAD_EAX_MICROCODE_RET_STATUS\r
+ pshufd $0x93, %xmm6, %xmm6\r
+ movd %xmm6, %eax\r
+ pshufd $0x39, %xmm6, %xmm6\r
.endm\r
\r
-#.INCLUDE "SaveRestoreSseGcc.inc" - end\r
\r
\r
#\r
.equ DATA_LEN_OF_MCUD, 0x018\r
.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
\r
-#------------------------------------------------------------------------------\r
-# FspSelfCheckDefault\r
-# Inputs:\r
-# eax -> Return address\r
-# Outputs:\r
-# eax -> 0 - Successful, Non-zero - Failed.\r
-# Register Usage:\r
-# eax is cleared and ebp is used for return address.\r
-# All others reserved.\r
-#------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(FspSelfCheckDefault)\r
-ASM_PFX(FspSelfCheckDefault):\r
- #\r
- # Save return address to EBP\r
- #\r
- movl %eax, %ebp\r
- xorl %eax, %eax\r
-\r
-FspSelfCheckDefaultExit:\r
- jmp *%ebp\r
-\r
-\r
#------------------------------------------------------------------------------\r
# SecPlatformInitDefault\r
# Inputs:\r
\r
\r
#------------------------------------------------------------------------------\r
-# LoadUcode\r
+# LoadMicrocodeDefault\r
#\r
# Inputs:\r
-# esp -> LOAD_UCODE_PARAMS pointer\r
+# esp -> LoadMicrocodeParams pointer\r
# Register Usage:\r
# esp Preserved\r
# All others destroyed\r
# Executed by SBSP and NBSP\r
# Beginning of microcode update region starts on paragraph boundary\r
#------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(LoadUcode)\r
-ASM_PFX(LoadUcode): \r
+ASM_GLOBAL ASM_PFX(LoadMicrocodeDefault)\r
+ASM_PFX(LoadMicrocodeDefault):\r
#\r
# Save return address to EBP\r
#\r
\r
cmpl $0x00, %esp\r
jz ParamError\r
- movl (%esp), %eax #dword ptr [] Parameter pointer\r
+ movl 4(%esp), %eax #dword ptr [] Parameter pointer\r
cmpl $0x00, %eax\r
jz ParamError\r
movl %eax, %esp\r
- movl LoadUcodeParamsUcodeCodeAddr(%esp), %esi #mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+ movl MicrocodeCodeAddr(%esp), %esi\r
cmpl $0x00, %esi\r
jnz CheckMainHeader\r
\r
ParamError:\r
movl $0x080000002, %eax\r
- jmp LoadUcodeExit\r
+ jmp LoadMicrocodeExit\r
\r
CheckMainHeader:\r
#\r
# Minimal test checking for header version and loader version as 1\r
#\r
movl $0x01, %eax\r
- cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax\r
+ cmpl %eax, MicrocodeHdrVersion(%esi)\r
jne AdvanceFixedSize\r
- cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax\r
+ cmpl %eax, MicrocodeHdrLoader(%esi)\r
jne AdvanceFixedSize\r
\r
#\r
# Check if signature and plaform ID match\r
#\r
- cmpl UcodeHdrProcessor(%esi), %ebx #cmp ebx, [esi].ucode_hdr.processor \r
- jne LoadUcodeL0\r
- testl UcodeHdrFlags(%esi), %edx #test edx, [esi].ucode_hdr.flags\r
+ cmpl MicrocodeHdrProcessor(%esi), %ebx\r
+ jne LoadMicrocodeL0\r
+ testl MicrocodeHdrFlags(%esi), %edx\r
jnz LoadCheck #Jif signature and platform ID match\r
\r
-LoadUcodeL0:\r
+LoadMicrocodeL0:\r
#\r
# Check if extended header exists\r
- # First check if total_size and data_size are valid\r
+ # First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid\r
#\r
xorl %eax, %eax\r
- cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax\r
+ cmpl %eax, MicrocodeHdrTotalSize(%esi)\r
je NextMicrocode\r
- cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax\r
+ cmpl %eax, MicrocodeHdrDataSize(%esi)\r
je NextMicrocode\r
\r
#\r
# Then verify total size - sizeof header > data size\r
#\r
- movl UcodeHdrTotalSize(%esi), %ecx #mov ecx, [esi].ucode_hdr.total_size\r
- subl $UcodeHdrLength, %ecx #sub ecx, sizeof ucode_hdr\r
- cmpl UcodeHdrDataSize(%esi), %ecx #cmp ecx, [esi].ucode_hdr.data_size\r
- jle NextMicrocode \r
+ movl MicrocodeHdrTotalSize(%esi), %ecx\r
+ subl $MicrocodeHdrLength, %ecx\r
+ cmpl MicrocodeHdrDataSize(%esi), %ecx\r
+ jle NextMicrocode\r
\r
#\r
# Set edi -> extended header\r
#\r
movl %esi, %edi\r
- addl $UcodeHdrLength, %edi #add edi, sizeof ucode_hdr\r
- addl UcodeHdrDataSize(%esi), %edi #add edi, [esi].ucode_hdr.data_size\r
+ addl $MicrocodeHdrLength, %edi\r
+ addl MicrocodeHdrDataSize(%esi), %edi\r
\r
#\r
# Get count of extended structures\r
#\r
- movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count\r
+ movl ExtSigHdrCount(%edi), %ecx\r
\r
#\r
# Move pointer to first signature structure\r
#\r
- addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr\r
+ addl ExtSigHdrLength, %edi\r
\r
CheckExtSig:\r
#\r
# Check if extended signature and platform ID match\r
#\r
- cmpl %ebx, ExtSigProcessor(%edi) #cmp [edi].ext_sig.processor, ebx\r
- jne LoadUcodeL1\r
- test %edx, ExtSigFlags(%edi) #test [edi].ext_sig.flags, edx\r
+ cmpl %ebx, ExtSigProcessor(%edi)\r
+ jne LoadMicrocodeL1\r
+ test %edx, ExtSigFlags(%edi)\r
jnz LoadCheck # Jif signature and platform ID match\r
-LoadUcodeL1:\r
+LoadMicrocodeL1:\r
#\r
# Check if any more extended signatures exist\r
#\r
- addl $ExtSigLength, %edi #add edi, sizeof ext_sig\r
+ addl $ExtSigLength, %edi\r
loop CheckExtSig\r
\r
NextMicrocode:\r
# Advance just after end of this microcode\r
#\r
xorl %eax, %eax\r
- cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax\r
- je LoadUcodeL2\r
- addl UcodeHdrTotalSize(%esi), %esi #add esi, [esi].ucode_hdr.total_size\r
+ cmpl %eax, MicrocodeHdrTotalSize(%esi)\r
+ je LoadMicrocodeL2\r
+ addl MicrocodeHdrTotalSize(%esi), %esi\r
jmp CheckAddress\r
-LoadUcodeL2:\r
+LoadMicrocodeL2:\r
addl $0x800, %esi #add esi, dword ptr 2048\r
jmp CheckAddress\r
\r
#\r
# Is valid Microcode start point ?\r
#\r
- cmpl $0x0ffffffff, UcodeHdrVersion(%esi)\r
+ cmpl $0x0ffffffff, MicrocodeHdrVersion(%esi)\r
\r
#\r
# Is automatic size detection ?\r
#\r
- movl LoadUcodeParamsUcodeCodeSize(%esp), %eax\r
+ movl MicrocodeCodeSize(%esp), %eax\r
cmpl $0x0ffffffff, %eax\r
- jz LoadUcodeL3\r
+ jz LoadMicrocodeL3\r
#\r
# Address >= microcode region address + microcode region size?\r
#\r
- addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+ addl MicrocodeCodeAddr(%esp), %eax\r
\r
cmpl %eax, %esi\r
- jae Done #Jif address is outside of ucode region\r
+ jae Done #Jif address is outside of microcode region\r
jmp CheckMainHeader\r
\r
-LoadUcodeL3:\r
+LoadMicrocodeL3:\r
LoadCheck:\r
#\r
# Get the revision of the current microcode update loaded\r
#\r
# Verify this microcode update is not already loaded\r
#\r
- cmpl %edx, UcodeHdrRevision(%esi) #cmp [esi].ucode_hdr.revision, edx\r
+ cmpl %edx, MicrocodeHdrRevision(%esi)\r
je Continue\r
\r
-LoadMicrocode:\r
+LoadMicrocode0:\r
#\r
# EAX contains the linear address of the start of the Update Data\r
# EDX contains zero\r
# Start microcode load with wrmsr\r
#\r
movl %esi, %eax\r
- addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr\r
+ addl $MicrocodeHdrLength, %eax\r
xorl %edx, %edx\r
movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx\r
wrmsr\r
rdmsr # Get current microcode signature\r
xorl %eax, %eax\r
cmpl $0x00, %edx\r
- jnz LoadUcodeExit\r
+ jnz LoadMicrocodeExit\r
movl $0x08000000E, %eax\r
\r
-LoadUcodeExit:\r
+LoadMicrocodeExit:\r
jmp *%ebp\r
\r
\r
ASM_GLOBAL ASM_PFX(EstablishStackFsp)\r
ASM_PFX(EstablishStackFsp):\r
#\r
- # Save parameter pointer in edx \r
+ # Save parameter pointer in edx\r
#\r
movl 4(%esp), %edx\r
- \r
+\r
#\r
# Enable FSP STACK\r
#\r
pushl $0x4455434D # Signature of the data region 'MCUD'\r
pushl 12(%edx) # Code size\r
pushl 8(%edx) # Code base\r
- cmpl $0, %edx # Is parameter pointer valid ?\r
- jz InvalidMicrocodeRegion\r
pushl 4(%edx) # Microcode size\r
pushl (%edx) # Microcode base\r
- jmp EstablishStackFspExit\r
\r
-InvalidMicrocodeRegion:\r
- push $0 # Microcode size\r
- push $0 # Microcode base\r
- \r
-EstablishStackFspExit:\r
#\r
# Save API entry/exit timestamp into stack\r
#\r
\r
#\r
# Terminator for the data on stack\r
- # \r
+ #\r
push $0x00\r
\r
#\r
- # Set ECX/EDX to the bootloader temporary memory range\r
+ # Set ECX/EDX to the BootLoader temporary memory range\r
#\r
movl PcdGet32 (PcdTemporaryRamBase), %ecx\r
movl %ecx, %edx\r
subl PcdGet32 (PcdFspTemporaryRamSize), %edx\r
\r
xorl %eax, %eax\r
- \r
+\r
movd %mm7, %esi #RET_ESI\r
jmp *%esi\r
\r
\r
#\r
# CPUID/DeviceID check\r
- #\r
- movl $TempRamInitApiL0, %eax\r
- jmp ASM_PFX(FspSelfCheckDefault) # @note: ESP can not be changed.\r
-TempRamInitApiL0:\r
- cmpl $0x00, %eax\r
- jnz NemInitExit\r
-\r
- #\r
- # Sec Platform Init\r
+ # and Sec Platform Init\r
#\r
movl $TempRamInitApiL1, %esi #CALL_MMX SecPlatformInit\r
- movd %mm7, %esi\r
+ movd %esi, %mm7\r
+ .weak ASM_PFX(SecPlatformInit)\r
+ .set ASM_PFX(SecPlatformInit), ASM_PFX(SecPlatformInitDefault)\r
jmp ASM_PFX(SecPlatformInit)\r
TempRamInitApiL1:\r
cmpl $0x00, %eax\r
# Load microcode\r
#\r
LOAD_ESP\r
- movl $TempRamInitApiL2, %esi #CALL_MMX LoadUcode\r
- movd %mm7, %esi\r
- jmp ASM_PFX(LoadUcode)\r
+ movl $TempRamInitApiL2, %esi #CALL_MMX LoadMicrocode\r
+ movd %esi, %mm7\r
+ .weak ASM_PFX(LoadMicrocode)\r
+ .set ASM_PFX(LoadMicrocode), ASM_PFX(LoadMicrocodeDefault)\r
+ jmp ASM_PFX(LoadMicrocode)\r
TempRamInitApiL2:\r
- cmpl $0x00, %eax\r
- jnz NemInitExit\r
+ SAVE_EAX_MICROCODE_RET_STATUS #Save microcode return status in ECX-SLOT 3 in xmm6.\r
+ #@note If return value eax is not 0, microcode did not load, but continue and attempt to boot from ECX-SLOT 3 in xmm6.\r
\r
#\r
# Call Sec CAR Init\r
#\r
LOAD_ESP\r
movl $TempRamInitApiL3, %esi #CALL_MMX SecCarInit\r
- movd %mm7, %esi\r
+ movd %esi, %mm7\r
jmp ASM_PFX(SecCarInit)\r
TempRamInitApiL3:\r
cmpl $0x00, %eax\r
#\r
LOAD_ESP\r
movl $TempRamInitApiL4, %esi #CALL_MMX EstablishStackFsp\r
- movd %mm7, %esi\r
+ movd %esi, %mm7\r
jmp ASM_PFX(EstablishStackFsp)\r
TempRamInitApiL4:\r
\r
+ LOAD_EAX_MICROCODE_RET_STATUS #Restore microcode status if no CAR init error.\r
+\r
NemInitExit:\r
#\r
# Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6\r
LOAD_REGS\r
ret\r
\r
+\r
#----------------------------------------------------------------------------\r
# FspInit API\r
#\r
pushl %eax\r
\r
#\r
- # Pass the bootloader stack to SecStartup\r
+ # Pass the BootLoader stack to SecStartup\r
#\r
pushl %edi\r
\r
FspApiCommonExit:\r
ret\r
\r
-\r