X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=IntelFspPkg%2FFspSecCore%2FIa32%2FFspApiEntry.s;h=995aef6088e9f160a5be03cfa1305a7041546e98;hb=95c95ac0efb10fe4b608a3388d928eb947c15085;hp=433ef921c4f1b679415b9d0dea90bd3bd7765329;hpb=c8ec22a266cdd134ac99c3021003710130613a40;p=mirror_edk2.git diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s index 433ef921c4..995aef6088 100644 --- a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s +++ b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ # -# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
# 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 @@ -15,310 +15,501 @@ # #------------------------------------------------------------------------------ -#.INCLUDE "UcodeLoad.inc" +#.INCLUDE "UcodeLoadGcc.inc" - begin + +.equ MSR_IA32_PLATFORM_ID, 0x00000017 +.equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079 +.equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b + +Ucode: +.equ UcodeVersion, 0x0000 +.equ UcodeRevision, 0x0004 +.equ UcodeDate, 0x0008 +.equ UcodeProcessor, 0x000C +.equ UcodeChecksum, 0x0010 +.equ UcodeLoader, 0x0014 +.equ UcodeRsvd, 0x0018 +UcodeEnd: + +UcodeHdr: +.equ UcodeHdrVersion, 0x0000 +.equ UcodeHdrRevision, 0x0004 +.equ UcodeHdrDate, 0x0008 +.equ UcodeHdrProcessor, 0x000c +.equ UcodeHdrChecksum, 0x0010 +.equ UcodeHdrLoader, 0x0014 +.equ UcodeHdrFlags, 0x0018 +.equ UcodeHdrDataSize, 0x001C +.equ UcodeHdrTotalSize, 0x0020 +.equ UcodeHdrRsvd, 0x0024 +UcodeHdrEnd: +.equ UcodeHdrLength, 0x0030 # UcodeHdrLength = UcodeHdrEnd - UcodeHdr + + +ExtSigHdr: +.equ ExtSigHdrCount, 0x0000 +.equ ExtSigHdrChecksum, 0x0004 +.equ rsvd, 0x0008 +ExtSigHdrEnd: +.equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr + +ExtSig: +.equ ExtSigProcessor, 0x0000 +.equ ExtSigFlags, 0x0004 +.equ ExtSigChecksum, 0x0008 +ExtSigEnd: +.equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig + +LoadUcodeParams: +.equ LoadUcodeParamsUcodeCodeAddr, 0x0000 +.equ LoadUcodeParamsUcodeCodeSize, 0x0004 +LoadUcodeParamsEnd: + +#.INCLUDE "UcodeLoadGcc.inc" - end + +#.INCLUDE "SaveRestoreSseGcc.inc" - begin +.macro SAVE_REGS + pinsrw $0x00, %ebp, %xmm7 + ror $0x10, %ebp + pinsrw $0x01, %ebp, %xmm7 + ror $0x10, %ebp # -# Following are fixed PCDs + pinsrw $0x02, %ebx, %xmm7 + ror $0x10, %ebx + pinsrw $0x03, %ebx, %xmm7 + ror $0x10, %ebx # - -.equ MSR_IA32_PLATFORM_ID, 0x000000017 -.equ MSR_IA32_BIOS_UPDT_TRIG, 0x000000079 -.equ MSR_IA32_BIOS_SIGN_ID, 0x00000008b - -ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase) -ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) -ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize) -ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize) - - + pinsrw $0x04, %esi, %xmm7 + ror $0x10, %esi + pinsrw $0x05, %esi, %xmm7 + ror $0x10, %esi # -# Following functions will be provided in C + pinsrw $0x06, %edi, %xmm7 + ror $0x10, %edi + pinsrw $0x07, %edi, %xmm7 + ror $0x10, %edi # -#EXTERNDEF SecStartup:PROC -#EXTERNDEF FspApiCallingCheck:PROC + pinsrw $0x00, %esp, %xmm6 + ror $0x10, %esp + pinsrw $0x01, %esp, %xmm6 + ror $0x10, %esp +.endm +.macro LOAD_REGS + pshufd $0xe4, %xmm7, %xmm7 + movd %xmm7, %ebp + pshufd $0xe4, %xmm7, %xmm7 # -# Following functions will be provided in PlatformSecLib + pshufd $0x39, %xmm7, %xmm7 + movd %xmm7, %ebx + pshufd $0x93, %xmm7, %xmm7 # -#EXTERNDEF GetFspBaseAddress:PROC -#EXTERNDEF GetBootFirmwareVolumeOffset:PROC -#EXTERNDEF PlatformTempRamInit:PROC -#EXTERNDEF Pei2LoaderSwitchStack:PROC -#EXTERN FspSelfCheck(FspSelfCheckDflt):PROC -#EXTERN PlatformBasicInit(PlatformBasicInitDflt):PROC - + pshufd $0x4e, %xmm7, %xmm7 + movd %xmm7, %esi + pshufd $0x4e, %xmm7, %xmm7 # -# Define the data length that we saved on the stack top + pshufd $0x93, %xmm7, %xmm7 + movd %xmm7, %edi + pshufd $0x39, %xmm7, %xmm7 # -.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) + movd %xmm6, %esp +.endm -# -# Define SSE macros -# -.macro ENABLE_SSE - movl %cr4, %eax - orl $0x00000600,%eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) - movl %eax,%cr4 +.macro LOAD_EAX + pshufd $0x39, %xmm6, %xmm6 + movd %xmm6, %eax + pshufd $0x93, %xmm6, %xmm6 .endm -.macro SAVE_REGS - movd %ebp, %xmm7 - pshufd $0x93, %xmm7, %xmm7 - movd %ebx, %xmm6 - por %xmm6, %xmm7 - pshufd $0x93, %xmm7, %xmm7 - movd %esi,%xmm6 - por %xmm6, %xmm7 - pshufd $0x93, %xmm7, %xmm7 - movd %edi, %xmm6 - por %xmm6, %xmm7 - movd %esp, %xmm6 +.macro LOAD_EDX + pshufd $0xe4, %xmm6, %xmm6 + movd %xmm6, %edx + pshufd $0xe4, %xmm6, %xmm6 .endm -.macro LOAD_REGS - movd %xmm6, %esp - movd %xmm7, %edi - pshufd $0x39,%xmm7, %xmm7 - movd %xmm7, %esi - pshufd $0x39,%xmm7, %xmm7 - movd %xmm7, %ebx - pshufd $0x39, %xmm7, %xmm7 - movd %xmm7, %ebp +.macro SAVE_EAX + pinsrw $0x02, %eax, %xmm6 + ror $0x10, %eax + pinsrw $0x03, %eax, %xmm6 + ror $0x10, %eax +.endm + +.macro SAVE_EDX + pinsrw $0x04, %edx, %xmm6 + ror $0x10, %edx + pinsrw $0x05, %edx, %xmm6 + ror $0x10, %edx .endm .macro LOAD_ESP movd %xmm6, %esp .endm +.macro ENABLE_SSE + movl %cr4, %eax + orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + movl %eax,%cr4 +.endm + +#.INCLUDE "SaveRestoreSseGcc.inc" - end + + +# +# Following are fixed PCDs +# +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(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_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 + # movl %eax, %ebp xorl %eax, %eax -exit: + +FspSelfCheckDfltExit: jmp *%ebp -#FspSelfCheckDflt ENDP -#------------------------------------------------------------------------------ -ASM_GLOBAL 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. +#------------------------------------------------------------------------------ +# SecPlatformInitDflt +# 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(SecPlatformInitDflt) +ASM_PFX(SecPlatformInitDflt): + # # Save return address to EBP + # movl %eax, %ebp xorl %eax, %eax -exit2: + +SecPlatformInitDfltExit: 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_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 - - # +ASM_PFX(LoadUcode): # # Save return address to EBP - movl %eax, %ebp - cmpl $0, %esp - jz paramerror - movl (%esp), %eax #dword ptr [] Parameter pointer - cmpl $0, %eax - jz paramerror - movl %eax, %esp - movl (%esp), %esi #LOAD_UCODE_PARAMS.ucode_code_addr - cmpl $0, %esi - jnz L0 + # + movd %mm7, %ebp -paramerror: - movl $0x080000002, %eax - jmp exit4 + cmpl $0x00, %esp + jz ParamError + movl (%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 + cmpl $0x00, %esi + jnz CheckMainHeader - movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr +ParamError: + movl $0x080000002, %eax + jmp LoadUcodeExit -check_main_header: +CheckMainHeader: + # # Get processor signature and platform ID from the installed processor # and save into registers for later use # ebx = processor signature # edx = platform ID - movl $1, %eax + # + movl $0x01, %eax cpuid movl %eax, %ebx - movl MSR_IA32_PLATFORM_ID, %ecx + movl $MSR_IA32_PLATFORM_ID, %ecx rdmsr - movl %edx, %ecx - #-------------------------------------------------------------------------------------------------------------------- - shrl $18, %ecx #($50-$32) - andl $0x7, %ecx - movl $1, %edx - shll %cl,%edx + movl %edx, %ecx + shrl $0x12, %ecx #($50-$32) + andl $0x07, %ecx + movl $0x01, %edx + shll %cl,%edx + # # Current register usage # esp -> stack with paramters # esi -> microcode update to check # ebx = processor signature # edx = platform ID + # + # # Check for valid microcode header # Minimal test checking for header version and loader version as 1 - movl $1, %eax - cmpl %eax, (%esi) #.ucode_hdr.version - jne advance_fixed_size - cmpl %eax, 0x18(%esi) #.ucode_hdr.loader - jne advance_fixed_size + # + movl $0x01, %eax + cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax + jne AdvanceFixedSize + cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax + jne AdvanceFixedSize + # # Check if signature and plaform ID match - #-------------------------------------------------------------------------------------------------------------------------- - cmpl 0x10(%esi), %ebx #(%esi).ucode_hdr.processor - jne L0 - testl 0x1c(%esi) , %edx #(%esi).ucode_hdr.flags - jnz load_check # Jif signature and platform ID match + # + cmpl UcodeHdrProcessor(%esi), %ebx #cmp ebx, [esi].ucode_hdr.processor + jne LoadUcodeL0 + testl UcodeHdrFlags(%esi), %edx #test edx, [esi].ucode_hdr.flags + jnz LoadCheck #Jif signature and platform ID match -L0: +LoadUcodeL0: + # # Check if extended header exists # 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 + # + xorl %eax, %eax + cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax + je NextMicrocode + cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax + je NextMicrocode + # # 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 + # + 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 $0x30 , %edi #sizeof ucode_hdr = 48 - addl 0x20(%esi), %edi #%esi.ucode_hdr.data_size + # + 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 (%edi), %ecx #(%edi).ext_sig_hdr.count + # + movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count + # # Move pointer to first signature structure - addl $0x20, %edi # sizeof ext_sig_hdr = 20 + # + addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr -check_ext_sig: +CheckExtSig: + # # Check if extended signature and platform ID match - 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: + # + 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 $0xc, %edi #sizeof ext_sig = 12 - loop check_ext_sig + # + addl $ExtSigLength, %edi #add edi, sizeof ext_sig + loop CheckExtSig -next_microcode: +NextMicrocode: + # # Advance just after end of this microcode + # xorl %eax, %eax - cmpl %eax, 0x24(%esi) #(%esi).ucode_hdr.total_size - je L2 - add 0x24(%esi) , %esi #(%esi).ucode_hdr.total_size - jmp check_address -L10: - addl $0x800, %esi - jmp check_address - -advance_fixed_size: + 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 - addl $0x400, %esi + # + addl $0x400, %esi #add esi, dword ptr 1024 -check_address: +CheckAddress: + # # 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? - movl (%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_addr - addl 4(%esp), %eax #(%esp).LOAD_UCODE_PARAMS.ucode_code_size + # + addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr + cmpl %eax, %esi - jae done #Jif address is outside of ucode region - jmp check_main_header + jae Done #Jif address is outside of ucode region + jmp CheckMainHeader -load_check: +LoadUcodeL3: +LoadCheck: + # # Get the revision of the current microcode update loaded - movl MSR_IA32_BIOS_SIGN_ID, %ecx - xorl %eax, %eax # Clear EAX - xorl %edx, %edx # Clear EDX - wrmsr # Load 0 to MSR at 8Bh + # + movl $MSR_IA32_BIOS_SIGN_ID, %ecx + xorl %eax, %eax # Clear EAX + xorl %edx, %edx # Clear EDX + wrmsr # Load 0 to MSR at 8Bh - movl $1, %eax + movl $0x01, %eax cpuid - movl MSR_IA32_BIOS_SIGN_ID, %ecx - rdmsr # Get current microcode signature + movl $MSR_IA32_BIOS_SIGN_ID, %ecx + rdmsr # Get current microcode signature + # # 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 # EDX contains zero # ECX contains 79h (IA32_BIOS_UPDT_TRIG) # Start microcode load with wrmsr - mov %esi, %eax - add $0x30, %eax #sizeof ucode_hdr = 48 - xorl %edx, %edx - mov MSR_IA32_BIOS_UPDT_TRIG,%ecx + # + movl %esi, %eax + addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr + xorl %edx, %edx + movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx wrmsr - mov $1, %eax + movl $0x01, %eax cpuid -continue: - jmp next_microcode +Continue: + jmp NextMicrocode -done: - mov $1, %eax +Done: + movl $0x01, %eax cpuid - mov MSR_IA32_BIOS_SIGN_ID, %ecx - rdmsr # Get current microcode signature + movl $MSR_IA32_BIOS_SIGN_ID, %ecx + rdmsr # Get current microcode signature xorl %eax, %eax - cmp $0 , %edx - jnz exit4 - mov $0x08000000E, %eax + cmpl $0x00, %edx + jnz LoadUcodeExit + movl $0x08000000E, %eax -exit4: +LoadUcodeExit: jmp *%ebp -#LoadUcode ENDP + +#---------------------------------------------------------------------------- +# EstablishStackFsp +# +#---------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(EstablishStackFsp) +ASM_PFX(EstablishStackFsp): + # + # Save parameter pointer in edx + # + movl 4(%esp), %edx + + # + # Enable FSP STACK + # + movl PcdGet32(PcdTemporaryRamBase), %esp + addl PcdGet32(PcdTemporaryRamSize), %esp + + pushl $DATA_LEN_OF_MCUD # Size of the data region + 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 + # + pushl $DATA_LEN_OF_PER0 # Size of the data region + pushl $0x30524550 # Signature of the data region 'PER0' + LOAD_EDX + pushl %edx + LOAD_EAX + pushl %eax + rdtsc + pushl %edx + pushl %eax + + # + # Terminator for the data on stack + # + push $0x00 + + # + # Set ECX/EDX to the bootloader temporary memory range + # + movl PcdGet32 (PcdTemporaryRamBase), %ecx + movl %ecx, %edx + addl PcdGet32 (PcdTemporaryRamSize), %edx + subl PcdGet32 (PcdFspTemporaryRamSize), %edx + + xorl %eax, %eax + + movd %mm7, %esi #RET_ESI + jmp *%esi #---------------------------------------------------------------------------- # TempRamInit API @@ -344,102 +535,66 @@ ASM_PFX(TempRamInitApi): # Save timestamp into XMM4 & XMM5 # rdtsc - movd %edx, %xmm4 - movd %eax, %xmm5 - - # - # CPUID/DeviceID check - # - movl L11, %eax - jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed. -L11: - cmpl $0, %eax - jnz NemInitExit - - # - # Platform Basic Init. - # - movl L1, %eax - jmp ASM_PFX(PlatformBasicInitDflt) -L1: - cmp $0, %eax - jnz NemInitExit + SAVE_EAX + SAVE_EDX # - # Load microcode - # - movl L2, %eax - addl $4, %esp - jmp LoadUcode -L2: - LOAD_ESP - cmpl $0, %eax - jnz NemInitExit - + # Check Parameter # - # Call platform NEM init - #------------------------------------------------------------------------------------------------------------------------- - movl L3, %eax - addl $4, %esp - jmp ASM_PFX(PlatformTempRamInit) -L3: - subl $4, %esp - cmpl $0, %eax - jnz NemInitExit + movl 4(%esp), %eax + cmpl $0x00, %eax + movl $0x80000002, %eax + jz NemInitExit # - # Save parameter pointer in edx + # CPUID/DeviceID check # - movl 4(%esp), %edx + movl $TempRamInitApiL0, %eax + jmp ASM_PFX(FspSelfCheckDflt) # @note: ESP can not be changed. +TempRamInitApiL0: + cmpl $0x00, %eax + jnz NemInitExit # - # Enable FSP STACK + # Sec Platform Init # - movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp - addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %esp + movl $TempRamInitApiL1, %esi #CALL_MMX SecPlatformInit + movd %mm7, %esi + jmp ASM_PFX(SecPlatformInit) +TempRamInitApiL1: + cmpl $0x00, %eax + jnz NemInitExit - pushl $DATA_LEN_OF_MCUD # Size of the data region - 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 L4 - -InvalidMicrocodeRegion: - pushl $0 # Microcode size - pushl $0 # Microcode base - -L4: # - # Save API entry/exit timestamp into stack + # Load microcode # - pushl DATA_LEN_OF_PER0 # Size of the data region - pushl 0x30524550 # Signature of the data region 'PER0' - movd %xmm4, %eax - pushl %eax - movd %xmm5, %eax - pushl %eax - rdtsc - pushl %edx - pushl %eax + LOAD_ESP + movl $TempRamInitApiL2, %esi #CALL_MMX LoadUcode + movd %mm7, %esi + jmp ASM_PFX(LoadUcode) +TempRamInitApiL2: + cmpl $0x00, %eax + jnz NemInitExit # - # Terminator for the data on stack + # Call Sec CAR Init # - pushl $0 + LOAD_ESP + movl $TempRamInitApiL3, %esi #CALL_MMX SecCarInit + movd %mm7, %esi + jmp ASM_PFX(SecCarInit) +TempRamInitApiL3: + cmpl $0x00, %eax + jnz NemInitExit # - # Set ECX/EDX to the bootloader temporary memory range + # EstablishStackFsp # - movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %ecx - movl %ecx, %edx - addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %edx - subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %edx - - xorl %eax, %eax + LOAD_ESP + movl $TempRamInitApiL4, %esi #CALL_MMX EstablishStackFsp + movd %mm7, %esi + jmp ASM_PFX(EstablishStackFsp) +TempRamInitApiL4: NemInitExit: # @@ -447,7 +602,6 @@ NemInitExit: # LOAD_REGS ret -#TempRamInitApi ENDP #---------------------------------------------------------------------------- # FspInit API @@ -459,77 +613,149 @@ NemInitExit: #---------------------------------------------------------------------------- ASM_GLOBAL ASM_PFX(FspInitApi) ASM_PFX(FspInitApi): + movl $0x01, %eax + jmp FspApiCommon + +#---------------------------------------------------------------------------- +# NotifyPhase API +# +# This FSP API will notify the FSP about the different phases in the boot +# process +# +#---------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(NotifyPhaseApi) +ASM_PFX(NotifyPhaseApi): + movl $0x02, %eax + jmp FspApiCommon + +#---------------------------------------------------------------------------- +# FspMemoryInit API +# +# This FSP API is called after TempRamInit and initializes the memory. +# +#---------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(FspMemoryInitApi) +ASM_PFX(FspMemoryInitApi): + movl $0x03, %eax + jmp FspApiCommon + +#---------------------------------------------------------------------------- +# TempRamExitApi API +# +# This API tears down temporary RAM +# +#---------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(TempRamExitApi) +ASM_PFX(TempRamExitApi): + movl $0x04, %eax + jmp FspApiCommon + +#---------------------------------------------------------------------------- +# FspSiliconInit API +# +# This FSP API initializes the CPU and the chipset including the IO +# controllers in the chipset to enable normal operation of these devices. +# +#---------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(FspSiliconInitApi) +ASM_PFX(FspSiliconInitApi): + movl $0x05, %eax + jmp FspApiCommon + +#---------------------------------------------------------------------------- +# FspApiCommon API +# +# This is the FSP API common entry point to resume the FSP execution +# +#---------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(FspApiCommon) +ASM_PFX(FspApiCommon): # - # Stack must be ready + # EAX holds the API index + # + # - pushl $0x087654321 - pop %eax - cmpl $0x087654321, %eax - jz L5 + # Stack must be ready + # + pushl %eax + addl $0x04, %esp + cmpl -4(%esp), %eax + jz FspApiCommonL0 movl $0x080000003, %eax - jmp exit3 + jmp FspApiCommonExit -L5: +FspApiCommonL0: # - # Additional check + # Verify the calling condition # - pusha - pushl $1 + pushal + pushl %eax call ASM_PFX(FspApiCallingCheck) - addl $4, %esp - movl %eax, 28(%esp) - popa - cmpl $0 , %eax - jz L6 - jmp exit3 + addl $0x04, %esp + cmpl $0x00, %eax + jz FspApiCommonL1 + movl %eax, 0x1C(%esp) # mov dword ptr [esp + 4 * 7], eax + popal + ret -L6: - # - # Save the Platform Data Pointer in EDI - # - movl 4(%esp), %edi +FspApiCommonL1: + popal + cmpl $0x01, %eax # FspInit API + jz FspApiCommonL2 + cmpl $0x03, %eax # FspMemoryInit API + jz FspApiCommonL2 + jmp Pei2LoaderSwitchStack +FspApiCommonL2: + # + # FspInit and FspMemoryInit APIs, setup the initial stack frame + # + # # Store the address in FSP which will return control to the BL # - pushl $exit3 + pushl $FspApiCommonExit # # 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 pushal + # # Reserve 8 bytes for IDT save/restore - pushl $0 - pushl $0 - sidt (%esp) + # + subl $0x08, %esp + sidt (%esp) # # Setup new FSP stack # - movl %esp, %eax - movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp - addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize) , %esp - subl DATA_LEN_AT_STACK_TOP, %esp - addl $0x0FFFFFFC0, %esp + movl %esp, %edi + movl PcdGet32(PcdTemporaryRamBase), %esp + addl PcdGet32(PcdTemporaryRamSize), %esp + subl $(DATA_LEN_AT_STACK_TOP + 0x40), %esp # - # Save the bootloader's stack pointer + # Pass the API Idx to SecStartup + # + pushl %eax + + # + # Pass the bootloader stack to SecStartup # - pushl %eax + pushl %edi # # Pass entry point of the PEI core # - call ASM_PFX(GetFspBaseAddress) - movl %eax, %edi - addl ASM_PFX(_gPcd_FixedAtBuild_PcdFspAreaSize), %edi - subl $0x20, %edi - addl %ds:(%edi), %eax - pushl %eax + call ASM_PFX(GetFspBaseAddress) + movl %eax, %edi + addl PcdGet32(PcdFspAreaSize), %edi + subl $0x20, %edi + addl %ds:(%edi), %eax + pushl %eax # # Pass BFV into the PEI Core @@ -538,74 +764,27 @@ L6: # PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs, # they are different. The code below can handle both cases. # - call ASM_PFX(GetFspBaseAddress) - movl %eax , %edi - call ASM_PFX(GetBootFirmwareVolumeOffset) - addl %edi ,%eax - pushl %eax + call ASM_PFX(GetFspBaseAddress) + movl %eax, %edi + call ASM_PFX(GetBootFirmwareVolumeOffset) + addl %edi, %eax + pushl %eax # # Pass stack base and size into the PEI Core # - movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %eax - addl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamSize), %eax - subl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize), %eax - pushl %eax - pushl ASM_PFX(_gPcd_FixedAtBuild_PcdFspTemporaryRamSize) + movl PcdGet32(PcdTemporaryRamBase), %eax + addl PcdGet32(PcdTemporaryRamSize), %eax + subl PcdGet32(PcdFspTemporaryRamSize), %eax + pushl %eax + pushl PcdGet32(PcdFspTemporaryRamSize) # # Pass Control into the PEI Core # call ASM_PFX(SecStartup) -exit3: - ret - -# FspInitApi ENDP - -#---------------------------------------------------------------------------- -# NotifyPhase API -# -# This FSP API will notify the FSP about the different phases in the boot -# process -# -#---------------------------------------------------------------------------- -ASM_GLOBAL ASM_PFX(NotifyPhaseApi) -ASM_PFX(NotifyPhaseApi): - # - # Stack must be ready - # - pushl $0x0087654321 - pop %eax - cmpl $0x087654321, %eax - jz L7 - movl $0x080000003, %eax - jmp err_exit - -L7: - # - # Verify the calling condition - # - pusha - pushl $2 - call ASM_PFX(FspApiCallingCheck) - add $4, %esp - mov %eax, 28(%esp) - popa - - cmpl $0, %eax - jz L8 - - # - # Error return - # -err_exit: +FspApiCommonExit: ret -L8: - jmp ASM_PFX(Pei2LoaderSwitchStack) - -#NotifyPhaseApi ENDP - -#END