#------------------------------------------------------------------------------\r
#\r
-# Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
# which accompanies this distribution. The full text of the license may be found at\r
#\r
#------------------------------------------------------------------------------\r
\r
-#.INCLUDE "UcodeLoad.inc"\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
+\r
+ExtSigHdr:\r
+.equ ExtSigHdrCount, 0x0000\r
+.equ ExtSigHdrChecksum, 0x0004\r
+.equ rsvd, 0x0008\r
+ExtSigHdrEnd:\r
+.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr\r
+\r
+ExtSig:\r
+.equ ExtSigProcessor, 0x0000\r
+.equ ExtSigFlags, 0x0004\r
+.equ ExtSigChecksum, 0x0008\r
+ExtSigEnd:\r
+.equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig\r
+\r
+LoadUcodeParams:\r
+.equ LoadUcodeParamsUcodeCodeAddr, 0x0000\r
+.equ LoadUcodeParamsUcodeCodeSize, 0x0004\r
+LoadUcodeParamsEnd:\r
+\r
+#.INCLUDE "UcodeLoadGcc.inc" - end\r
+\r
+#.INCLUDE "SaveRestoreSseGcc.inc" - begin\r
\r
+.macro SAVE_REGS\r
+ pinsrw $0x00, %ebp, %xmm7\r
+ ror $0x10, %ebp\r
+ pinsrw $0x01, %ebp, %xmm7\r
+ ror $0x10, %ebp\r
#\r
-# Following are fixed PCDs\r
+ pinsrw $0x02, %ebx, %xmm7\r
+ ror $0x10, %ebx\r
+ pinsrw $0x03, %ebx, %xmm7\r
+ ror $0x10, %ebx\r
#\r
-\r
-.equ MSR_IA32_PLATFORM_ID, 0x000000017\r
-.equ MSR_IA32_BIOS_UPDT_TRIG, 0x000000079\r
-.equ MSR_IA32_BIOS_SIGN_ID, 0x00000008b\r
-\r
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)\r
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)\r
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)\r
-ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize)\r
-\r
-\r
+ pinsrw $0x04, %esi, %xmm7\r
+ ror $0x10, %esi\r
+ pinsrw $0x05, %esi, %xmm7\r
+ ror $0x10, %esi\r
#\r
-# Following functions will be provided in C\r
+ pinsrw $0x06, %edi, %xmm7\r
+ ror $0x10, %edi\r
+ pinsrw $0x07, %edi, %xmm7\r
+ ror $0x10, %edi\r
#\r
-#EXTERNDEF SecStartup:PROC\r
-#EXTERNDEF FspApiCallingCheck:PROC\r
+ pinsrw $0x00, %esp, %xmm6\r
+ ror $0x10, %esp\r
+ pinsrw $0x01, %esp, %xmm6\r
+ ror $0x10, %esp\r
+.endm\r
\r
+.macro LOAD_REGS\r
+ pshufd $0xe4, %xmm7, %xmm7\r
+ movd %xmm7, %ebp \r
+ pshufd $0xe4, %xmm7, %xmm7\r
#\r
-# Following functions will be provided in PlatformSecLib\r
+ pshufd $0x39, %xmm7, %xmm7\r
+ movd %xmm7, %ebx\r
+ pshufd $0x93, %xmm7, %xmm7\r
#\r
-#EXTERNDEF GetFspBaseAddress:PROC\r
-#EXTERNDEF GetBootFirmwareVolumeOffset:PROC\r
-#EXTERNDEF PlatformTempRamInit:PROC\r
-#EXTERNDEF Pei2LoaderSwitchStack:PROC\r
-#EXTERN FspSelfCheck(FspSelfCheckDflt):PROC\r
-#EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC\r
-\r
+ pshufd $0x4e, %xmm7, %xmm7\r
+ movd %xmm7, %esi\r
+ pshufd $0x4e, %xmm7, %xmm7\r
#\r
-# Define the data length that we saved on the stack top\r
+ pshufd $0x93, %xmm7, %xmm7\r
+ movd %xmm7, %edi\r
+ pshufd $0x39, %xmm7, %xmm7\r
#\r
-.equ DATA_LEN_OF_PER0, 0x018\r
-.equ DATA_LEN_OF_MCUD, 0x018\r
-.equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4)\r
+ movd %xmm6, %esp\r
+.endm\r
\r
-#\r
-# Define SSE macros\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
+.macro LOAD_EAX\r
+ pshufd $0x39, %xmm6, %xmm6\r
+ movd %xmm6, %eax\r
+ pshufd $0x93, %xmm6, %xmm6\r
.endm\r
\r
-.macro SAVE_REGS\r
- movd %ebp, %xmm7\r
- pshufd $0x93, %xmm7, %xmm7\r
- movd %ebx, %xmm6\r
- por %xmm6, %xmm7\r
- pshufd $0x93, %xmm7, %xmm7\r
- movd %esi,%xmm6\r
- por %xmm6, %xmm7\r
- pshufd $0x93, %xmm7, %xmm7\r
- movd %edi, %xmm6\r
- por %xmm6, %xmm7\r
- movd %esp, %xmm6\r
+.macro LOAD_EDX\r
+ pshufd $0xe4, %xmm6, %xmm6\r
+ movd %xmm6, %edx\r
+ pshufd $0xe4, %xmm6, %xmm6\r
.endm\r
\r
-.macro LOAD_REGS\r
- movd %xmm6, %esp\r
- movd %xmm7, %edi\r
- pshufd $0x39,%xmm7, %xmm7\r
- movd %xmm7, %esi\r
- pshufd $0x39,%xmm7, %xmm7\r
- movd %xmm7, %ebx\r
- pshufd $0x39, %xmm7, %xmm7\r
- movd %xmm7, %ebp\r
+.macro SAVE_EAX\r
+ pinsrw $0x02, %eax, %xmm6\r
+ ror $0x10, %eax\r
+ pinsrw $0x03, %eax, %xmm6\r
+ ror $0x10, %eax\r
+.endm\r
+\r
+.macro SAVE_EDX\r
+ pinsrw $0x04, %edx, %xmm6\r
+ ror $0x10, %edx\r
+ pinsrw $0x05, %edx, %xmm6\r
+ ror $0x10, %edx\r
.endm\r
\r
.macro LOAD_ESP\r
movd %xmm6, %esp\r
.endm\r
\r
-#------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(FspSelfCheckDflt)\r
-ASM_PFX(FspSelfCheckDflt):\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
+.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
+.endm\r
+\r
+#.INCLUDE "SaveRestoreSseGcc.inc" - end\r
+\r
+\r
+#\r
+# Following are fixed PCDs\r
+#\r
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase)\r
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize)\r
+ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)\r
+\r
+#\r
+# Following functions will be provided in C\r
+#\r
+ASM_GLOBAL ASM_PFX(SecStartup)\r
+ASM_GLOBAL ASM_PFX(FspApiCallingCheck)\r
+\r
+#\r
+# Following functions will be provided in PlatformSecLib\r
+#\r
+ASM_GLOBAL ASM_PFX(GetBootFirmwareVolumeOffset)\r
+ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack)\r
+\r
+\r
+#\r
+# Define the data length that we saved on the stack top\r
+#\r
+.equ DATA_LEN_OF_PER0, 0x018\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
-exit:\r
+\r
+FspSelfCheckDefaultExit:\r
jmp *%ebp\r
-#FspSelfCheckDflt ENDP\r
\r
-#------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(PlatformBasicInitDflt)\r
-ASM_PFX(PlatformBasicInitDflt):\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
+#------------------------------------------------------------------------------\r
+# SecPlatformInitDefault\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(SecPlatformInitDefault)\r
+ASM_PFX(SecPlatformInitDefault):\r
+ #\r
# Save return address to EBP\r
+ #\r
movl %eax, %ebp\r
xorl %eax, %eax\r
-exit2:\r
+\r
+SecPlatformInitDefaultExit:\r
jmp *%ebp\r
-#PlatformBasicInitDflt ENDP\r
\r
+\r
+#------------------------------------------------------------------------------\r
+# LoadUcode\r
+#\r
+# Inputs:\r
+# esp -> LOAD_UCODE_PARAMS pointer\r
+# Register Usage:\r
+# esp Preserved\r
+# All others destroyed\r
+# Assumptions:\r
+# No memory available, stack is hard-coded and used for return address\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
- # Inputs:\r
- # esp -> LOAD_UCODE_PARAMS pointer\r
- # Register Usage:\r
- # esp Preserved\r
- # All others destroyed\r
- # Assumptions:\r
- # No memory available, stack is hard-coded and used for return address\r
- # Executed by SBSP and NBSP\r
- # Beginning of microcode update region starts on paragraph boundary\r
-\r
- #\r
+ASM_PFX(LoadUcode): \r
#\r
# Save return address to EBP\r
- movl %eax, %ebp\r
- cmpl $0, %esp\r
- jz paramerror\r
- movl (%esp), %eax #dword ptr [] Parameter pointer\r
- cmpl $0, %eax\r
- jz paramerror\r
- movl %eax, %esp\r
- movl (%esp), %esi #LOAD_UCODE_PARAMS.ucode_code_addr\r
- cmpl $0, %esi\r
- jnz L0\r
+ #\r
+ movd %mm7, %ebp\r
\r
-paramerror:\r
- movl $0x080000002, %eax\r
- jmp exit4\r
+ cmpl $0x00, %esp\r
+ jz ParamError\r
+ movl (%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
+ cmpl $0x00, %esi\r
+ jnz CheckMainHeader\r
\r
- movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr\r
+ParamError:\r
+ movl $0x080000002, %eax\r
+ jmp LoadUcodeExit\r
\r
-check_main_header:\r
+CheckMainHeader:\r
+ #\r
# Get processor signature and platform ID from the installed processor\r
# and save into registers for later use\r
# ebx = processor signature\r
# edx = platform ID\r
- movl $1, %eax\r
+ #\r
+ movl $0x01, %eax\r
cpuid\r
movl %eax, %ebx\r
- movl MSR_IA32_PLATFORM_ID, %ecx\r
+ movl $MSR_IA32_PLATFORM_ID, %ecx\r
rdmsr\r
- movl %edx, %ecx\r
- #--------------------------------------------------------------------------------------------------------------------\r
- shrl $18, %ecx #($50-$32)\r
- andl $0x7, %ecx\r
- movl $1, %edx\r
- shll %cl,%edx\r
+ movl %edx, %ecx\r
+ shrl $0x12, %ecx #($50-$32)\r
+ andl $0x07, %ecx\r
+ movl $0x01, %edx\r
+ shll %cl,%edx\r
\r
+ #\r
# Current register usage\r
# esp -> stack with paramters\r
# esi -> microcode update to check\r
# ebx = processor signature\r
# edx = platform ID\r
+ #\r
\r
+ #\r
# Check for valid microcode header\r
# Minimal test checking for header version and loader version as 1\r
- movl $1, %eax\r
- cmpl %eax, (%esi) #.ucode_hdr.version\r
- jne advance_fixed_size\r
- cmpl %eax, 0x18(%esi) #.ucode_hdr.loader\r
- jne advance_fixed_size\r
+ #\r
+ movl $0x01, %eax\r
+ cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax\r
+ jne AdvanceFixedSize\r
+ cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax\r
+ jne AdvanceFixedSize\r
\r
+ #\r
# Check if signature and plaform ID match\r
- #--------------------------------------------------------------------------------------------------------------------------\r
- cmpl 0x10(%esi), %ebx #(%esi).ucode_hdr.processor\r
- jne L0\r
- testl 0x1c(%esi) , %edx #(%esi).ucode_hdr.flags\r
- jnz load_check # Jif signature and platform 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
+ jnz LoadCheck #Jif signature and platform ID match\r
\r
-L0:\r
+LoadUcodeL0:\r
+ #\r
# Check if extended header exists\r
# First check if total_size and data_size are valid\r
- xorl %eax, %eax\r
- cmpl %eax,0x24(%esi) #(%esi).ucode_hdr.total_size\r
- je next_microcode\r
- cmpl %eax,0x20(%esi) #(%esi) .ucode_hdr.data_size\r
- je next_microcode\r
+ #\r
+ xorl %eax, %eax\r
+ cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax\r
+ je NextMicrocode\r
+ cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax\r
+ je NextMicrocode\r
\r
+ #\r
# Then verify total size - sizeof header > data size\r
- movl 0x24(%esi), %ecx #(%esi).ucode_hdr.total_size\r
- subl $0x30, %ecx #sizeof ucode_hdr = 48\r
- cmpl 0x20(%esi), %ecx #(%esi).ucode_hdr.data_size\r
- jz load_check\r
- jb next_microcode # Jif extended header does not exist\r
-\r
- # Check if total size fits in microcode region\r
- movl %esi , %edi\r
- addl 0x24(%esi), %edi # (%esi).ucode_hdr.total_size\r
- movl (%esp), %ecx # (%esp).LOAD_UCODE_PARAMS.ucode_code_addr\r
- addl 4(%esp), %ecx #.LOAD_UCODE_PARAMS.ucode_code_size\r
- cmpl %ecx , %edi\r
- xorl %eax, %eax\r
- ja exit4 # Jif address is outside of ucode region\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
\r
+ #\r
# Set edi -> extended header\r
- movl %esi , %edi\r
- addl $0x30 , %edi #sizeof ucode_hdr = 48\r
- addl 0x20(%esi), %edi #%esi.ucode_hdr.data_size\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
\r
+ #\r
# Get count of extended structures\r
- movl (%edi), %ecx #(%edi).ext_sig_hdr.count\r
+ #\r
+ movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count\r
\r
+ #\r
# Move pointer to first signature structure\r
- addl $0x20, %edi # sizeof ext_sig_hdr = 20\r
+ #\r
+ addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr\r
\r
-check_ext_sig:\r
+CheckExtSig:\r
+ #\r
# Check if extended signature and platform ID match\r
- cmpl %ebx, (%edi) #[edi].ext_sig.processor\r
- jne L1\r
- test %edx, 4(%edi) #[edi].ext_sig.flags\r
- jnz load_check # Jif signature and platform ID match\r
-L9:\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
+ jnz LoadCheck # Jif signature and platform ID match\r
+LoadUcodeL1:\r
+ #\r
# Check if any more extended signatures exist\r
- addl $0xc, %edi #sizeof ext_sig = 12\r
- loop check_ext_sig\r
+ #\r
+ addl $ExtSigLength, %edi #add edi, sizeof ext_sig\r
+ loop CheckExtSig\r
\r
-next_microcode:\r
+NextMicrocode:\r
+ #\r
# Advance just after end of this microcode\r
+ #\r
xorl %eax, %eax\r
- cmpl %eax, 0x24(%esi) #(%esi).ucode_hdr.total_size\r
- je L2\r
- add 0x24(%esi) , %esi #(%esi).ucode_hdr.total_size\r
- jmp check_address\r
-L10:\r
- addl $0x800, %esi\r
- jmp check_address\r
-\r
-advance_fixed_size:\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
+ jmp CheckAddress\r
+LoadUcodeL2:\r
+ addl $0x800, %esi #add esi, dword ptr 2048\r
+ jmp CheckAddress\r
+\r
+AdvanceFixedSize:\r
+ #\r
# Advance by 4X dwords\r
- addl $0x400, %esi\r
+ #\r
+ addl $0x400, %esi #add esi, dword ptr 1024\r
\r
-check_address:\r
+CheckAddress:\r
+ #\r
# Is valid Microcode start point ?\r
- cmp $0x0ffffffff , %esi\r
- jz done\r
+ #\r
+ cmpl $0x0ffffffff, UcodeHdrVersion(%esi)\r
\r
+ #\r
+ # Is automatic size detection ?\r
+ #\r
+ movl LoadUcodeParamsUcodeCodeSize(%esp), %eax\r
+ cmpl $0x0ffffffff, %eax\r
+ jz LoadUcodeL3\r
+ #\r
# Address >= microcode region address + microcode region size?\r
- movl (%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_addr\r
- addl 4(%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_size\r
+ #\r
+ addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr\r
+\r
cmpl %eax, %esi\r
- jae done #Jif address is outside of ucode region\r
- jmp check_main_header\r
+ jae Done #Jif address is outside of ucode region\r
+ jmp CheckMainHeader\r
\r
-load_check:\r
+LoadUcodeL3:\r
+LoadCheck:\r
+ #\r
# Get the revision of the current microcode update loaded\r
- movl MSR_IA32_BIOS_SIGN_ID, %ecx\r
- xorl %eax, %eax # Clear EAX\r
- xorl %edx, %edx # Clear EDX\r
- wrmsr # Load 0 to MSR at 8Bh\r
+ #\r
+ movl $MSR_IA32_BIOS_SIGN_ID, %ecx\r
+ xorl %eax, %eax # Clear EAX\r
+ xorl %edx, %edx # Clear EDX\r
+ wrmsr # Load 0 to MSR at 8Bh\r
\r
- movl $1, %eax\r
+ movl $0x01, %eax\r
cpuid\r
- movl MSR_IA32_BIOS_SIGN_ID, %ecx\r
- rdmsr # Get current microcode signature\r
+ movl $MSR_IA32_BIOS_SIGN_ID, %ecx\r
+ rdmsr # Get current microcode signature\r
\r
+ #\r
# Verify this microcode update is not already loaded\r
- cmpl %edx, 4(%esi) #(%esi).ucode_hdr.revision\r
- je continue\r
+ #\r
+ cmpl %edx, UcodeHdrRevision(%esi) #cmp [esi].ucode_hdr.revision, edx\r
+ je Continue\r
\r
-load_microcode:\r
+LoadMicrocode:\r
+ #\r
# EAX contains the linear address of the start of the Update Data\r
# EDX contains zero\r
# ECX contains 79h (IA32_BIOS_UPDT_TRIG)\r
# Start microcode load with wrmsr\r
- mov %esi, %eax\r
- add $0x30, %eax #sizeof ucode_hdr = 48\r
- xorl %edx, %edx\r
- mov MSR_IA32_BIOS_UPDT_TRIG,%ecx\r
+ #\r
+ movl %esi, %eax\r
+ addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr\r
+ xorl %edx, %edx\r
+ movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx\r
wrmsr\r
- mov $1, %eax\r
+ movl $0x01, %eax\r
cpuid\r
\r
-continue:\r
- jmp next_microcode\r
+Continue:\r
+ jmp NextMicrocode\r
\r
-done:\r
- mov $1, %eax\r
+Done:\r
+ movl $0x01, %eax\r
cpuid\r
- mov MSR_IA32_BIOS_SIGN_ID, %ecx\r
- rdmsr # Get current microcode signature\r
+ movl $MSR_IA32_BIOS_SIGN_ID, %ecx\r
+ rdmsr # Get current microcode signature\r
xorl %eax, %eax\r
- cmp $0 , %edx\r
- jnz exit4\r
- mov $0x08000000E, %eax\r
+ cmpl $0x00, %edx\r
+ jnz LoadUcodeExit\r
+ movl $0x08000000E, %eax\r
\r
-exit4:\r
+LoadUcodeExit:\r
jmp *%ebp\r
\r
-#LoadUcode ENDP\r
+\r
+#----------------------------------------------------------------------------\r
+# EstablishStackFsp\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(EstablishStackFsp)\r
+ASM_PFX(EstablishStackFsp):\r
+ #\r
+ # Save parameter pointer in edx \r
+ #\r
+ movl 4(%esp), %edx\r
+ \r
+ #\r
+ # Enable FSP STACK\r
+ #\r
+ movl PcdGet32(PcdTemporaryRamBase), %esp\r
+ addl PcdGet32(PcdTemporaryRamSize), %esp\r
+\r
+ pushl $DATA_LEN_OF_MCUD # Size of the data region\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
+ pushl $DATA_LEN_OF_PER0 # Size of the data region\r
+ pushl $0x30524550 # Signature of the data region 'PER0'\r
+ LOAD_EDX\r
+ pushl %edx\r
+ LOAD_EAX\r
+ pushl %eax\r
+ rdtsc\r
+ pushl %edx\r
+ pushl %eax\r
+\r
+ #\r
+ # Terminator for the data on stack\r
+ # \r
+ push $0x00\r
+\r
+ #\r
+ # Set ECX/EDX to the bootloader temporary memory range\r
+ #\r
+ movl PcdGet32 (PcdTemporaryRamBase), %ecx\r
+ movl %ecx, %edx\r
+ addl PcdGet32 (PcdTemporaryRamSize), %edx\r
+ subl PcdGet32 (PcdFspTemporaryRamSize), %edx\r
+\r
+ xorl %eax, %eax\r
+ \r
+ movd %mm7, %esi #RET_ESI\r
+ jmp *%esi\r
\r
#----------------------------------------------------------------------------\r
# TempRamInit API\r
# Save timestamp into XMM4 & XMM5\r
#\r
rdtsc\r
- movd %edx, %xmm4\r
- movd %eax, %xmm5\r
-\r
- #\r
- # CPUID/DeviceID check\r
- #\r
- movl L11, %eax\r
- jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed.\r
-L11:\r
- cmpl $0, %eax\r
- jnz NemInitExit\r
-\r
- #\r
- # Platform Basic Init.\r
- #\r
- movl L1, %eax\r
- jmp ASM_PFX(PlatformBasicInitDflt)\r
-L1:\r
- cmp $0, %eax\r
- jnz NemInitExit\r
+ SAVE_EAX\r
+ SAVE_EDX\r
\r
#\r
- # Load microcode\r
- #\r
- movl L2, %eax\r
- addl $4, %esp\r
- jmp LoadUcode\r
-L2:\r
- LOAD_ESP\r
- cmpl $0, %eax\r
- jnz NemInitExit\r
-\r
+ # Check Parameter\r
#\r
- # Call platform NEM init\r
- #-------------------------------------------------------------------------------------------------------------------------\r
- movl L3, %eax\r
- addl $4, %esp\r
- jmp ASM_PFX(PlatformTempRamInit)\r
-L3:\r
- subl $4, %esp\r
- cmpl $0, %eax\r
- jnz NemInitExit\r
+ movl 4(%esp), %eax\r
+ cmpl $0x00, %eax\r
+ movl $0x80000002, %eax\r
+ jz NemInitExit\r
\r
#\r
- # Save parameter pointer in edx\r
+ # CPUID/DeviceID check\r
#\r
- movl 4(%esp), %edx\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
- # Enable FSP STACK\r
+ # Sec Platform Init\r
#\r
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp\r
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp\r
+ movl $TempRamInitApiL1, %esi #CALL_MMX SecPlatformInit\r
+ movd %mm7, %esi\r
+ jmp ASM_PFX(SecPlatformInit)\r
+TempRamInitApiL1:\r
+ cmpl $0x00, %eax\r
+ jnz NemInitExit\r
\r
- pushl $DATA_LEN_OF_MCUD # Size of the data region\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 L4\r
-\r
-InvalidMicrocodeRegion:\r
- pushl $0 # Microcode size\r
- pushl $0 # Microcode base\r
-\r
-L4:\r
#\r
- # Save API entry/exit timestamp into stack\r
+ # Load microcode\r
#\r
- pushl DATA_LEN_OF_PER0 # Size of the data region\r
- pushl 0x30524550 # Signature of the data region 'PER0'\r
- movd %xmm4, %eax\r
- pushl %eax\r
- movd %xmm5, %eax\r
- pushl %eax\r
- rdtsc\r
- pushl %edx\r
- pushl %eax\r
+ LOAD_ESP\r
+ movl $TempRamInitApiL2, %esi #CALL_MMX LoadUcode\r
+ movd %mm7, %esi\r
+ jmp ASM_PFX(LoadUcode)\r
+TempRamInitApiL2:\r
+ cmpl $0x00, %eax\r
+ jnz NemInitExit\r
\r
#\r
- # Terminator for the data on stack\r
+ # Call Sec CAR Init\r
#\r
- pushl $0\r
+ LOAD_ESP\r
+ movl $TempRamInitApiL3, %esi #CALL_MMX SecCarInit\r
+ movd %mm7, %esi\r
+ jmp ASM_PFX(SecCarInit)\r
+TempRamInitApiL3:\r
+ cmpl $0x00, %eax\r
+ jnz NemInitExit\r
\r
#\r
- # Set ECX/EDX to the bootloader temporary memory range\r
+ # EstablishStackFsp\r
#\r
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx\r
- movl %ecx, %edx\r
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx\r
- subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx\r
-\r
- xorl %eax, %eax\r
+ LOAD_ESP\r
+ movl $TempRamInitApiL4, %esi #CALL_MMX EstablishStackFsp\r
+ movd %mm7, %esi\r
+ jmp ASM_PFX(EstablishStackFsp)\r
+TempRamInitApiL4:\r
\r
NemInitExit:\r
#\r
#\r
LOAD_REGS\r
ret\r
-#TempRamInitApi ENDP\r
\r
#----------------------------------------------------------------------------\r
# FspInit API\r
#----------------------------------------------------------------------------\r
ASM_GLOBAL ASM_PFX(FspInitApi)\r
ASM_PFX(FspInitApi):\r
+ movl $0x01, %eax\r
+ jmp FspApiCommon\r
+\r
+#----------------------------------------------------------------------------\r
+# NotifyPhase API\r
+#\r
+# This FSP API will notify the FSP about the different phases in the boot\r
+# process\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(NotifyPhaseApi)\r
+ASM_PFX(NotifyPhaseApi):\r
+ movl $0x02, %eax\r
+ jmp FspApiCommon\r
+\r
+#----------------------------------------------------------------------------\r
+# FspMemoryInit API\r
+#\r
+# This FSP API is called after TempRamInit and initializes the memory.\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(FspMemoryInitApi)\r
+ASM_PFX(FspMemoryInitApi):\r
+ movl $0x03, %eax\r
+ jmp FspApiCommon\r
+\r
+#----------------------------------------------------------------------------\r
+# TempRamExitApi API\r
+#\r
+# This API tears down temporary RAM\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(TempRamExitApi)\r
+ASM_PFX(TempRamExitApi):\r
+ movl $0x04, %eax\r
+ jmp FspApiCommon\r
+\r
+#----------------------------------------------------------------------------\r
+# FspSiliconInit API\r
+#\r
+# This FSP API initializes the CPU and the chipset including the IO\r
+# controllers in the chipset to enable normal operation of these devices.\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(FspSiliconInitApi)\r
+ASM_PFX(FspSiliconInitApi):\r
+ movl $0x05, %eax\r
+ jmp FspApiCommon\r
+\r
+#----------------------------------------------------------------------------\r
+# FspApiCommon API\r
+#\r
+# This is the FSP API common entry point to resume the FSP execution\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(FspApiCommon)\r
+ASM_PFX(FspApiCommon):\r
#\r
- # Stack must be ready\r
+ # EAX holds the API index\r
+ #\r
+\r
#\r
- pushl $0x087654321\r
- pop %eax\r
- cmpl $0x087654321, %eax\r
- jz L5\r
+ # Stack must be ready\r
+ # \r
+ pushl %eax\r
+ addl $0x04, %esp\r
+ cmpl -4(%esp), %eax\r
+ jz FspApiCommonL0\r
movl $0x080000003, %eax\r
- jmp exit3\r
+ jmp FspApiCommonExit\r
\r
-L5:\r
+FspApiCommonL0:\r
#\r
- # Additional check\r
+ # Verify the calling condition\r
#\r
- pusha\r
- pushl $1\r
+ pushal\r
+ pushl %eax\r
call ASM_PFX(FspApiCallingCheck)\r
- addl $4, %esp\r
- movl %eax, 28(%esp)\r
- popa\r
- cmpl $0 , %eax\r
- jz L6\r
- jmp exit3\r
+ addl $0x04, %esp\r
+ cmpl $0x00, %eax\r
+ jz FspApiCommonL1\r
+ movl %eax, 0x1C(%esp) # mov dword ptr [esp + 4 * 7], eax\r
+ popal\r
+ ret\r
\r
-L6:\r
- #\r
- # Save the Platform Data Pointer in EDI\r
- #\r
- movl 4(%esp), %edi\r
+FspApiCommonL1:\r
+ popal\r
+ cmpl $0x01, %eax # FspInit API\r
+ jz FspApiCommonL2\r
+ cmpl $0x03, %eax # FspMemoryInit API\r
+ jz FspApiCommonL2\r
+ jmp Pei2LoaderSwitchStack\r
\r
+FspApiCommonL2:\r
+ #\r
+ # FspInit and FspMemoryInit APIs, setup the initial stack frame\r
+ # \r
+ \r
#\r
# Store the address in FSP which will return control to the BL\r
#\r
- pushl $exit3\r
+ pushl $FspApiCommonExit\r
\r
#\r
# Create a Task Frame in the stack for the Boot Loader\r
#\r
- pushfl\r
- pushfl # 2 pushf for 4 byte alignment\r
+ pushfl # 2 pushf for 4 byte alignment\r
cli\r
pushal\r
\r
+ #\r
# Reserve 8 bytes for IDT save/restore\r
- pushl $0\r
- pushl $0\r
- sidt (%esp)\r
+ #\r
+ subl $0x08, %esp\r
+ sidt (%esp)\r
\r
#\r
# Setup new FSP stack\r
#\r
- movl %esp, %eax\r
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp\r
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) , %esp\r
- subl DATA_LEN_AT_STACK_TOP, %esp\r
- addl $0x0FFFFFFC0, %esp\r
+ movl %esp, %edi\r
+ movl PcdGet32(PcdTemporaryRamBase), %esp\r
+ addl PcdGet32(PcdTemporaryRamSize), %esp\r
+ subl $(DATA_LEN_AT_STACK_TOP + 0x40), %esp\r
\r
#\r
- # Save the bootloader's stack pointer\r
+ # Pass the API Idx to SecStartup\r
+ #\r
+ pushl %eax\r
+ \r
+ #\r
+ # Pass the bootloader stack to SecStartup\r
#\r
- pushl %eax\r
+ pushl %edi\r
\r
#\r
# Pass entry point of the PEI core\r
#\r
- call ASM_PFX(GetFspBaseAddress)\r
- movl %eax, %edi\r
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi\r
- subl $0x20, %edi\r
- addl %ds:(%edi), %eax\r
- pushl %eax\r
+ call ASM_PFX(GetFspBaseAddress)\r
+ movl %eax, %edi\r
+ addl PcdGet32(PcdFspAreaSize), %edi\r
+ subl $0x20, %edi\r
+ addl %ds:(%edi), %eax\r
+ pushl %eax\r
\r
#\r
# Pass BFV into the PEI Core\r
# PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs,\r
# they are different. The code below can handle both cases.\r
#\r
- call ASM_PFX(GetFspBaseAddress)\r
- movl %eax , %edi\r
- call ASM_PFX(GetBootFirmwareVolumeOffset)\r
- addl %edi ,%eax\r
- pushl %eax\r
+ call ASM_PFX(GetFspBaseAddress)\r
+ movl %eax, %edi\r
+ call ASM_PFX(GetBootFirmwareVolumeOffset)\r
+ addl %edi, %eax\r
+ pushl %eax\r
\r
#\r
# Pass stack base and size into the PEI Core\r
#\r
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %eax\r
- addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %eax\r
- subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %eax\r
- pushl %eax\r
- pushl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize)\r
+ movl PcdGet32(PcdTemporaryRamBase), %eax\r
+ addl PcdGet32(PcdTemporaryRamSize), %eax\r
+ subl PcdGet32(PcdFspTemporaryRamSize), %eax\r
+ pushl %eax\r
+ pushl PcdGet32(PcdFspTemporaryRamSize)\r
\r
#\r
# Pass Control into the PEI Core\r
#\r
call ASM_PFX(SecStartup)\r
\r
-exit3:\r
- ret\r
-\r
-# FspInitApi ENDP\r
-\r
-#----------------------------------------------------------------------------\r
-# NotifyPhase API\r
-#\r
-# This FSP API will notify the FSP about the different phases in the boot\r
-# process\r
-#\r
-#----------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(NotifyPhaseApi)\r
-ASM_PFX(NotifyPhaseApi):\r
- #\r
- # Stack must be ready\r
- #\r
- pushl $0x0087654321\r
- pop %eax\r
- cmpl $0x087654321, %eax\r
- jz L7\r
- movl $0x080000003, %eax\r
- jmp err_exit\r
-\r
-L7:\r
- #\r
- # Verify the calling condition\r
- #\r
- pusha\r
- pushl $2\r
- call ASM_PFX(FspApiCallingCheck)\r
- add $4, %esp\r
- mov %eax, 28(%esp)\r
- popa\r
-\r
- cmpl $0, %eax\r
- jz L8\r
-\r
- #\r
- # Error return\r
- #\r
-err_exit:\r
+FspApiCommonExit:\r
ret\r
\r
-L8:\r
- jmp ASM_PFX(Pei2LoaderSwitchStack)\r
-\r
-#NotifyPhaseApi ENDP\r
-\r
\r
-#END\r