X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=IntelFspPkg%2FFspSecCore%2FIa32%2FFspApiEntry.s;h=8f4093ca1940a7adad50ba5b895950ec0ea51fb5;hp=433ef921c4f1b679415b9d0dea90bd3bd7765329;hb=12a92f51f0efaa0c4f7abdaf869984ae1c65f430;hpb=c8ec22a266cdd134ac99c3021003710130613a40
diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s
index 433ef921c4..8f4093ca19 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,517 @@
#
#------------------------------------------------------------------------------
-#.INCLUDE "UcodeLoad.inc"
-#
-# Following are fixed PCDs
-#
+.equ MSR_IA32_PLATFORM_ID, 0x00000017
+.equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079
+.equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b
-.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)
+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 ExtSigHdrRsvd, 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
+LoadMicrocodeParams:
+.equ MicrocodeCodeAddr, 0x0000
+.equ MicrocodeCodeSize, 0x0004
+LoadMicrocodeParamsEnd:
+
+
+
+.macro SAVE_REGS
+ pinsrw $0x00, %ebp, %xmm7
+ ror $0x10, %ebp
+ pinsrw $0x01, %ebp, %xmm7
+ ror $0x10, %ebp
#
-# Following functions will be provided in C
+ pinsrw $0x02, %ebx, %xmm7
+ ror $0x10, %ebx
+ pinsrw $0x03, %ebx, %xmm7
+ ror $0x10, %ebx
#
-#EXTERNDEF SecStartup:PROC
-#EXTERNDEF FspApiCallingCheck:PROC
-
+ pinsrw $0x04, %esi, %xmm7
+ ror $0x10, %esi
+ pinsrw $0x05, %esi, %xmm7
+ ror $0x10, %esi
#
-# Following functions will be provided in PlatformSecLib
+ pinsrw $0x06, %edi, %xmm7
+ ror $0x10, %edi
+ pinsrw $0x07, %edi, %xmm7
+ ror $0x10, %edi
#
-#EXTERNDEF GetFspBaseAddress:PROC
-#EXTERNDEF GetBootFirmwareVolumeOffset:PROC
-#EXTERNDEF PlatformTempRamInit:PROC
-#EXTERNDEF Pei2LoaderSwitchStack:PROC
-#EXTERN FspSelfCheck(FspSelfCheckDflt):PROC
-#EXTERN PlatformBasicInit(PlatformBasicInitDflt):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
#
-# Define the data length that we saved on the stack top
+ pshufd $0x39, %xmm7, %xmm7
+ movd %xmm7, %ebx
+ pshufd $0x93, %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)
-
+ pshufd $0x4e, %xmm7, %xmm7
+ movd %xmm7, %esi
+ pshufd $0x4e, %xmm7, %xmm7
#
-# Define SSE macros
+ pshufd $0x93, %xmm7, %xmm7
+ movd %xmm7, %edi
+ pshufd $0x39, %xmm7, %xmm7
#
-.macro ENABLE_SSE
- movl %cr4, %eax
- orl $0x00000600,%eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
- movl %eax,%cr4
+ movd %xmm6, %esp
.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_EAX
+ pshufd $0x39, %xmm6, %xmm6
+ movd %xmm6, %eax
+ pshufd $0x93, %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 LOAD_EDX
+ pshufd $0xe4, %xmm6, %xmm6
+ movd %xmm6, %edx
+ pshufd $0xe4, %xmm6, %xmm6
+.endm
+
+.macro SAVE_EAX
+ pinsrw $0x02, %eax, %xmm6
+ ror $0x10, %eax
+ pinsrw $0x03, %eax, %xmm6
+ ror $0x10, %eax
+.endm
+
+.macro SAVE_EDX
+ pinsrw $0x04, %edx, %xmm6
+ ror $0x10, %edx
+ pinsrw $0x05, %edx, %xmm6
+ ror $0x10, %edx
.endm
.macro LOAD_ESP
movd %xmm6, %esp
.endm
-#------------------------------------------------------------------------------
-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.
+.macro ENABLE_SSE
+ 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 return address to EBP
- movl %eax, %ebp
- xorl %eax, %eax
-exit:
- jmp *%ebp
-#FspSelfCheckDflt ENDP
+#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
-#------------------------------------------------------------------------------
-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.
+#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
+
+
+
+#
+# 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(AsmGetFspBaseAddress)
+ASM_GLOBAL ASM_PFX(AsmGetFspInfoHeader)
+ASM_GLOBAL ASM_PFX(GetBootFirmwareVolumeOffset)
+ASM_GLOBAL ASM_PFX(Loader2PeiSwitchStack)
+
+
+#
+# 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)
+#------------------------------------------------------------------------------
+# SecPlatformInitDefault
+# Inputs:
+# mm7 -> 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(SecPlatformInitDefault)
+ASM_PFX(SecPlatformInitDefault):
+ #
# Save return address to EBP
- movl %eax, %ebp
+ #
+ movd %mm7, %ebp
xorl %eax, %eax
-exit2:
+
+SecPlatformInitDefaultExit:
jmp *%ebp
-#PlatformBasicInitDflt ENDP
-#------------------------------------------------------------------------------
-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
- #
+#------------------------------------------------------------------------------
+# LoadMicrocodeDefault
+#
+# Inputs:
+# esp -> LoadMicrocodeParams 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(LoadMicrocodeDefault)
+ASM_PFX(LoadMicrocodeDefault):
#
# 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 4(%esp), %eax #dword ptr [] Parameter pointer
+ cmpl $0x00, %eax
+ jz ParamError
+ movl %eax, %esp
+ movl MicrocodeCodeAddr(%esp), %esi
+ cmpl $0x00, %esi
+ jnz CheckMainHeader
- movl (%esp), %esi #.LOAD_UCODE_PARAMS.ucode_code_addr
+ParamError:
+ movl $0x080000002, %eax
+ jmp LoadMicrocodeExit
-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, MicrocodeHdrVersion(%esi)
+ jne AdvanceFixedSize
+ cmpl %eax, MicrocodeHdrLoader(%esi)
+ 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 MicrocodeHdrProcessor(%esi), %ebx
+ jne LoadMicrocodeL0
+ testl MicrocodeHdrFlags(%esi), %edx
+ jnz LoadCheck #Jif signature and platform ID match
-L0:
+LoadMicrocodeL0:
+ #
# 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
+ # First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid
+ #
+ xorl %eax, %eax
+ cmpl %eax, MicrocodeHdrTotalSize(%esi)
+ je NextMicrocode
+ cmpl %eax, MicrocodeHdrDataSize(%esi)
+ 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 MicrocodeHdrTotalSize(%esi), %ecx
+ subl $MicrocodeHdrLength, %ecx
+ cmpl MicrocodeHdrDataSize(%esi), %ecx
+ 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 $MicrocodeHdrLength, %edi
+ addl MicrocodeHdrDataSize(%esi), %edi
+ #
# Get count of extended structures
- movl (%edi), %ecx #(%edi).ext_sig_hdr.count
+ #
+ movl ExtSigHdrCount(%edi), %ecx
+ #
# Move pointer to first signature structure
- addl $0x20, %edi # sizeof ext_sig_hdr = 20
+ #
+ addl ExtSigHdrLength, %edi
-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)
+ jne LoadMicrocodeL1
+ test %edx, ExtSigFlags(%edi)
+ jnz LoadCheck # Jif signature and platform ID match
+LoadMicrocodeL1:
+ #
# Check if any more extended signatures exist
- addl $0xc, %edi #sizeof ext_sig = 12
- loop check_ext_sig
+ #
+ addl $ExtSigLength, %edi
+ 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, MicrocodeHdrTotalSize(%esi)
+ je LoadMicrocodeL2
+ addl MicrocodeHdrTotalSize(%esi), %esi
+ jmp CheckAddress
+LoadMicrocodeL2:
+ 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, MicrocodeHdrVersion(%esi)
+ #
+ # Is automatic size detection ?
+ #
+ movl MicrocodeCodeSize(%esp), %eax
+ cmpl $0x0ffffffff, %eax
+ jz LoadMicrocodeL3
+ #
# 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 MicrocodeCodeAddr(%esp), %eax
+
cmpl %eax, %esi
- jae done #Jif address is outside of ucode region
- jmp check_main_header
+ jae Done #Jif address is outside of microcode region
+ jmp CheckMainHeader
-load_check:
+LoadMicrocodeL3:
+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, MicrocodeHdrRevision(%esi)
+ je Continue
-load_microcode:
+LoadMicrocode0:
+ #
# 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 $MicrocodeHdrLength, %eax
+ 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 LoadMicrocodeExit
+ movl $0x08000000E, %eax
-exit4:
+LoadMicrocodeExit:
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
+ pushl 4(%edx) # Microcode size
+ pushl (%edx) # Microcode base
+
+ #
+ # 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
@@ -341,105 +548,66 @@ ASM_PFX(TempRamInitApi):
SAVE_REGS
#
- # Save timestamp into XMM4 & XMM5
+ # Save timestamp into XMM6
#
rdtsc
- movd %edx, %xmm4
- movd %eax, %xmm5
+ SAVE_EAX
+ SAVE_EDX
#
- # CPUID/DeviceID check
+ # Check Parameter
#
- movl L11, %eax
- jmp ASM_PFX(FspSelfCheck) # Note: ESP can not be changed.
-L11:
- cmpl $0, %eax
- jnz NemInitExit
+ movl 4(%esp), %eax
+ cmpl $0x00, %eax
+ movl $0x80000002, %eax
+ jz NemInitExit
#
- # Platform Basic Init.
+ # Sec Platform Init
#
- movl L1, %eax
- jmp ASM_PFX(PlatformBasicInitDflt)
-L1:
- cmp $0, %eax
- jnz NemInitExit
+ movl $TempRamInitApiL1, %esi #CALL_MMX SecPlatformInit
+ movd %esi, %mm7
+ .weak ASM_PFX(SecPlatformInit)
+ .set ASM_PFX(SecPlatformInit), ASM_PFX(SecPlatformInitDefault)
+ jmp ASM_PFX(SecPlatformInit)
+TempRamInitApiL1:
+ cmpl $0x00, %eax
+ jnz NemInitExit
#
# Load microcode
#
- movl L2, %eax
- addl $4, %esp
- jmp LoadUcode
-L2:
LOAD_ESP
- cmpl $0, %eax
- jnz NemInitExit
-
- #
- # Call platform NEM init
- #-------------------------------------------------------------------------------------------------------------------------
- movl L3, %eax
- addl $4, %esp
- jmp ASM_PFX(PlatformTempRamInit)
-L3:
- subl $4, %esp
- cmpl $0, %eax
- jnz NemInitExit
+ 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:
+ 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.
#
- # Save parameter pointer in edx
- #
- movl 4(%esp), %edx
-
- #
- # Enable FSP STACK
- #
- movl ASM_PFX(_gPcd_FixedAtBuild_PcdTemporaryRamBase), %esp
- addl ASM_PFX(_gPcd_FixedAtBuild_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 L4
-
-InvalidMicrocodeRegion:
- pushl $0 # Microcode size
- pushl $0 # Microcode base
-
-L4:
- #
- # 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'
- movd %xmm4, %eax
- pushl %eax
- movd %xmm5, %eax
- pushl %eax
- rdtsc
- pushl %edx
- pushl %eax
-
- #
- # Terminator for the data on stack
+ # Call Sec CAR Init
#
- pushl $0
+ LOAD_ESP
+ movl $TempRamInitApiL3, %esi #CALL_MMX SecCarInit
+ movd %esi, %mm7
+ 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
+ LOAD_ESP
+ movl $TempRamInitApiL4, %esi #CALL_MMX EstablishStackFsp
+ movd %esi, %mm7
+ jmp ASM_PFX(EstablishStackFsp)
+TempRamInitApiL4:
- xorl %eax, %eax
+ LOAD_EAX_MICROCODE_RET_STATUS #Restore microcode status if no CAR init error.
NemInitExit:
#
@@ -447,7 +615,7 @@ NemInitExit:
#
LOAD_REGS
ret
-#TempRamInitApi ENDP
+
#----------------------------------------------------------------------------
# FspInit API
@@ -459,77 +627,159 @@ 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 36(%esp) #push ApiParam [esp + 4 * 8 + 4]
+ pushl %eax #push ApiIdx
call ASM_PFX(FspApiCallingCheck)
- addl $4, %esp
- movl %eax, 28(%esp)
- popa
- cmpl $0 , %eax
- jz L6
- jmp exit3
+ addl $0x08, %esp
+ cmpl $0x00, %eax
+ jz FspApiCommonL1
+ movl %eax, 0x1C(%esp) # mov dword ptr [esp + 4 * 7], eax
+ popal
+ ret
+
+FspApiCommonL1:
+ popal
+ cmpl $0x01, %eax # FspInit API
+ jz FspApiCommonL2
+ cmpl $0x03, %eax # FspMemoryInit API
+ jz FspApiCommonL2
+ call ASM_PFX(AsmGetFspInfoHeader)
+ jmp Loader2PeiSwitchStack
-L6:
+FspApiCommonL2:
#
- # Save the Platform Data Pointer in EDI
+ # FspInit and FspMemoryInit APIs, setup the initial stack frame
+ #
+
#
- movl 4(%esp), %edi
+ # Place holder to store the FspInfoHeader pointer
+ #
+ pushl %eax
#
- # Store the address in FSP which will return control to the BL
+ # Update the FspInfoHeader pointer
#
- pushl $exit3
+ pushl %eax
+ call ASM_PFX(AsmGetFspInfoHeader)
+ movl %eax, 4(%esp)
+ popl %eax
#
# 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
+ pushl %eax
+
+ #
+ # Pass the BootLoader stack to SecStartup
+ #
+ 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(AsmGetFspBaseAddress)
+ movl %eax, %edi
+ addl PcdGet32(PcdFspAreaSize), %edi
+ subl $0x20, %edi
+ addl %ds:(%edi), %eax
+ pushl %eax
#
# Pass BFV into the PEI Core
@@ -538,74 +788,26 @@ 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(AsmGetFspBaseAddress)
+ 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:
+ addl $4, %esp
+FspApiCommonExit:
ret
-L8:
- jmp ASM_PFX(Pei2LoaderSwitchStack)
-
-#NotifyPhaseApi ENDP
-
-
-#END