From: Yao, Jiewen Date: Thu, 23 Apr 2015 08:52:21 +0000 (+0000) Subject: Update IntelFspPkg to support FSP1.1 X-Git-Tag: edk2-stable201903~10018 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=9da591867c0bad1abbe17a321dc5b16d95226c6a Update IntelFspPkg to support FSP1.1 -- Add BootLoaderTolumSize support -- Extend FspApiCallingCheck with ApiParam for BootLoaderTolumSize -- Rename all Bootloader to BootLoader as official name -- Rename Ucode to Microcode -- Remove FspSelfCheck API, because it is merged into SecPlatformInit -- Add GetFspVpdDataPointer() in FspCommonLib.h -- Document FspSecPlatformLib.h -- Reorg FSP_PLAT_DATA data structure to let it match FSP spec. -- Move helper function in FspSecCore to reduce platform enabling effort -- Fix LibraryClasses declaration in DEC file. -- Enhance PatchFv to check if it is valid FSP bin. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" Reviewed-by: "Ma, Maurice" Reviewed-by: "Rangarajan, Ravi P" Reviewed-by: "Mudusuru, Giri P" git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17196 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/IntelFspPkg/FspDxeIpl/DxeIpl.c b/IntelFspPkg/FspDxeIpl/DxeIpl.c index cddc29e054..f6e1116f57 100644 --- a/IntelFspPkg/FspDxeIpl/DxeIpl.c +++ b/IntelFspPkg/FspDxeIpl/DxeIpl.c @@ -1,6 +1,6 @@ /** @file - 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 @@ -430,13 +430,13 @@ DxeLoadCore ( ASSERT_EFI_ERROR (Status); // - // Give control back to bootloader after FspInit + // Give control back to BootLoader after FspInit // DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n")); FspInitDone (); // - // Bootloader called FSP again through NotifyPhase + // BootLoader called FSP again through NotifyPhase // FspWaitForNotify (); diff --git a/IntelFspPkg/FspSecCore/FspSecCore.inf b/IntelFspPkg/FspSecCore/FspSecCore.inf index aaeb28a5db..8dd476a0e1 100644 --- a/IntelFspPkg/FspSecCore/FspSecCore.inf +++ b/IntelFspPkg/FspSecCore/FspSecCore.inf @@ -36,10 +36,12 @@ Ia32/Stack.asm | MSFT Ia32/InitializeFpu.asm | MSFT Ia32/FspApiEntry.asm | MSFT + Ia32/FspHelper.asm | MSFT Ia32/Stacks.s | GCC Ia32/InitializeFpu.s | GCC Ia32/FspApiEntry.s | GCC + Ia32/FspHelper.s | GCC [Binaries.Ia32] RAW|Vtf0/Bin/ResetVec.ia32.raw |GCC @@ -56,6 +58,7 @@ SerialPortLib FspSwitchStackLib FspCommonLib + FspSecPlatformLib [Pcd] gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## UNDEFINED @@ -63,6 +66,9 @@ gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize ## CONSUMES + gIntelFspPkgTokenSpaceGuid.PcdFspBootFirmwareVolumeBase ## CONSUMES + gIntelFspPkgTokenSpaceGuid.PcdFspAreaBaseAddress ## CONSUMES + gIntelFspPkgTokenSpaceGuid.PcdFspAreaSize ## CONSUMES [FixedPcd] gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry ## CONSUMES diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm index a7249599e2..01b0bfab31 100644 --- a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm +++ b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.asm @@ -17,7 +17,7 @@ .xmm INCLUDE SaveRestoreSse.inc -INCLUDE UcodeLoad.inc +INCLUDE MicrocodeLoad.inc ; ; Following are fixed PCDs @@ -40,8 +40,7 @@ EXTERN FspApiCallingCheck:PROC EXTERN GetFspBaseAddress:PROC EXTERN GetBootFirmwareVolumeOffset:PROC EXTERN Pei2LoaderSwitchStack:PROC -EXTERN FspSelfCheck(FspSelfCheckDefault):PROC -EXTERN LoadUcode(LoadUcodeDefault):PROC +EXTERN LoadMicrocode(LoadMicrocodeDefault):PROC EXTERN SecPlatformInit(SecPlatformInitDefault):PROC EXTERN SecCarInit:PROC @@ -69,7 +68,7 @@ ReturnAddress: ENDM RET_ESI_EXT MACRO MmxRegister - movd esi, MmxRegister ; restore ESP from MMX + movd esi, MmxRegister ; move ReturnAddress from MMX to ESI jmp esi ENDM @@ -78,27 +77,9 @@ CALL_MMX MACRO RoutineLabel ENDM RET_ESI MACRO - RET_ESI_EXT mm7 + RET_ESI_EXT mm7 ENDM -;------------------------------------------------------------------------------ -FspSelfCheckDefault PROC NEAR PUBLIC - ; Inputs: - ; eax -> Return address - ; Outputs: - ; eax -> 0 - Successful, Non-zero - Failed. - ; Register Usage: - ; eax is cleared and ebp is used for return address. - ; All others reserved. - - ; Save return address to EBP - mov ebp, eax - - xor eax, eax -exit: - jmp ebp -FspSelfCheckDefault ENDP - ;------------------------------------------------------------------------------ SecPlatformInitDefault PROC NEAR PUBLIC ; Inputs: @@ -118,9 +99,9 @@ exit: SecPlatformInitDefault ENDP ;------------------------------------------------------------------------------ -LoadUcodeDefault PROC NEAR PUBLIC +LoadMicrocodeDefault PROC NEAR PUBLIC ; Inputs: - ; esp -> LOAD_UCODE_PARAMS pointer + ; esp -> LoadMicrocodeParams pointer ; Register Usage: ; esp Preserved ; All others destroyed @@ -136,11 +117,11 @@ LoadUcodeDefault PROC NEAR PUBLIC cmp esp, 0 jz paramerror - mov eax, dword ptr [esp] ; Parameter pointer + mov eax, dword ptr [esp + 4] ; Parameter pointer cmp eax, 0 jz paramerror mov esp, eax - mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr + mov esi, [esp].LoadMicrocodeParams.MicrocodeCodeAddr cmp esi, 0 jnz check_main_header @@ -148,7 +129,7 @@ paramerror: mov eax, 080000002h jmp exit - mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr + mov esi, [esp].LoadMicrocodeParams.MicrocodeCodeAddr check_main_header: ; Get processor signature and platform ID from the installed processor @@ -175,60 +156,60 @@ check_main_header: ; Check for valid microcode header ; Minimal test checking for header version and loader version as 1 mov eax, dword ptr 1 - cmp [esi].ucode_hdr.version, eax + cmp [esi].MicrocodeHdr.MicrocodeHdrVersion, eax jne advance_fixed_size - cmp [esi].ucode_hdr.loader, eax + cmp [esi].MicrocodeHdr.MicrocodeHdrLoader, eax jne advance_fixed_size ; Check if signature and plaform ID match - cmp ebx, [esi].ucode_hdr.processor + cmp ebx, [esi].MicrocodeHdr.MicrocodeHdrProcessor jne @f - test edx, [esi].ucode_hdr.flags + test edx, [esi].MicrocodeHdr.MicrocodeHdrFlags jnz load_check ; Jif signature and platform ID match @@: ; Check if extended header exists - ; First check if total_size and data_size are valid + ; First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid xor eax, eax - cmp [esi].ucode_hdr.total_size, eax + cmp [esi].MicrocodeHdr.MicrocodeHdrTotalSize, eax je next_microcode - cmp [esi].ucode_hdr.data_size, eax + cmp [esi].MicrocodeHdr.MicrocodeHdrDataSize, eax je next_microcode ; Then verify total size - sizeof header > data size - mov ecx, [esi].ucode_hdr.total_size - sub ecx, sizeof ucode_hdr - cmp ecx, [esi].ucode_hdr.data_size + mov ecx, [esi].MicrocodeHdr.MicrocodeHdrTotalSize + sub ecx, sizeof MicrocodeHdr + cmp ecx, [esi].MicrocodeHdr.MicrocodeHdrDataSize jng next_microcode ; Jif extended header does not exist ; Set edi -> extended header mov edi, esi - add edi, sizeof ucode_hdr - add edi, [esi].ucode_hdr.data_size + add edi, sizeof MicrocodeHdr + add edi, [esi].MicrocodeHdr.MicrocodeHdrDataSize ; Get count of extended structures - mov ecx, [edi].ext_sig_hdr.count + mov ecx, [edi].ExtSigHdr.ExtSigHdrCount ; Move pointer to first signature structure - add edi, sizeof ext_sig_hdr + add edi, sizeof ExtSigHdr check_ext_sig: ; Check if extended signature and platform ID match - cmp [edi].ext_sig.processor, ebx + cmp [edi].ExtSig.ExtSigProcessor, ebx jne @f - test [edi].ext_sig.flags, edx + test [edi].ExtSig.ExtSigFlags, edx jnz load_check ; Jif signature and platform ID match @@: ; Check if any more extended signatures exist - add edi, sizeof ext_sig + add edi, sizeof ExtSig loop check_ext_sig next_microcode: ; Advance just after end of this microcode xor eax, eax - cmp [esi].ucode_hdr.total_size, eax + cmp [esi].MicrocodeHdr.MicrocodeHdrTotalSize, eax je @f - add esi, [esi].ucode_hdr.total_size + add esi, [esi].MicrocodeHdr.MicrocodeHdrTotalSize jmp check_address @@: add esi, dword ptr 2048 @@ -240,18 +221,18 @@ advance_fixed_size: check_address: ; Is valid Microcode start point ? - cmp dword ptr [esi].ucode_hdr.version, 0ffffffffh + cmp dword ptr [esi].MicrocodeHdr.MicrocodeHdrVersion, 0ffffffffh jz done ; Is automatic size detection ? - mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_size + mov eax, [esp].LoadMicrocodeParams.MicrocodeCodeSize cmp eax, 0ffffffffh jz @f ; Address >= microcode region address + microcode region size? - add eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr + add eax, [esp].LoadMicrocodeParams.MicrocodeCodeAddr cmp esi, eax - jae done ;Jif address is outside of ucode region + jae done ;Jif address is outside of microcode region jmp check_main_header @@: @@ -268,7 +249,7 @@ load_check: rdmsr ; Get current microcode signature ; Verify this microcode update is not already loaded - cmp [esi].ucode_hdr.revision, edx + cmp [esi].MicrocodeHdr.MicrocodeHdrRevision, edx je continue load_microcode: @@ -277,7 +258,7 @@ load_microcode: ; ECX contains 79h (IA32_BIOS_UPDT_TRIG) ; Start microcode load with wrmsr mov eax, esi - add eax, sizeof ucode_hdr + add eax, sizeof MicrocodeHdr xor edx, edx mov ecx, MSR_IA32_BIOS_UPDT_TRIG wrmsr @@ -300,35 +281,27 @@ done: exit: jmp ebp -LoadUcodeDefault ENDP +LoadMicrocodeDefault ENDP EstablishStackFsp PROC NEAR PRIVATE ; - ; Save parameter pointer in edx + ; Save parameter pointer in edx ; - mov edx, dword ptr [esp + 4] - + mov edx, dword ptr [esp + 4] + ; ; Enable FSP STACK ; mov esp, PcdGet32 (PcdTemporaryRamBase) - add esp, PcdGet32 (PcdTemporaryRamSize) + add esp, PcdGet32 (PcdTemporaryRamSize) - push DATA_LEN_OF_MCUD ; Size of the data region + push DATA_LEN_OF_MCUD ; Size of the data region push 4455434Dh ; Signature of the data region 'MCUD' push dword ptr [edx + 12] ; Code size push dword ptr [edx + 8] ; Code base - cmp edx, 0 ; Is parameter pointer valid ? - jz InvalidMicrocodeRegion push dword ptr [edx + 4] ; Microcode size - push dword ptr [edx] ; Microcode base - jmp @F + push dword ptr [edx] ; Microcode base -InvalidMicrocodeRegion: - push 0 ; Microcode size - push 0 ; Microcode base - -@@: ; ; Save API entry/exit timestamp into stack ; @@ -348,7 +321,7 @@ InvalidMicrocodeRegion: push 0 ; - ; Set ECX/EDX to the bootloader temporary memory range + ; Set ECX/EDX to the BootLoader temporary memory range ; mov ecx, PcdGet32 (PcdTemporaryRamBase) mov edx, ecx @@ -356,7 +329,7 @@ InvalidMicrocodeRegion: sub edx, PcdGet32 (PcdFspTemporaryRamSize) xor eax, eax - + RET_ESI EstablishStackFsp ENDP @@ -398,22 +371,17 @@ TempRamInitApi PROC NEAR PUBLIC ; ; CPUID/DeviceID check + ; and Sec Platform Init ; - mov eax, @F - jmp FspSelfCheck ; Note: ESP can not be changed. -@@: - cmp eax, 0 - jnz NemInitExit - CALL_MMX SecPlatformInit cmp eax, 0 jnz NemInitExit ; Load microcode LOAD_ESP - CALL_MMX LoadUcode - cmp eax, 0 - jnz NemInitExit + CALL_MMX LoadMicrocode + SXMMN xmm6, 3, eax ;Save microcode return status in ECX-SLOT 3 in xmm6. + ;@note If return value eax is not 0, microcode did not load, but continue and attempt to boot. ; Call Sec CAR Init LOAD_ESP @@ -424,6 +392,8 @@ TempRamInitApi PROC NEAR PUBLIC LOAD_ESP CALL_MMX EstablishStackFsp + LXMMN xmm6, eax, 3 ;Restore microcode status if no CAR init error from ECX-SLOT 3 in xmm6. + NemInitExit: ; ; Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6 @@ -519,9 +489,10 @@ FspApiCommon PROC C PUBLIC ; Verify the calling condition ; pushad + push [esp + 4 * 8 + 4] push eax call FspApiCallingCheck - add esp, 4 + add esp, 8 cmp eax, 0 jz @F mov dword ptr [esp + 4 * 7], eax @@ -536,10 +507,10 @@ FspApiCommon PROC C PUBLIC jz @F jmp Pei2LoaderSwitchStack -@@: +@@: ; ; FspInit and FspMemoryInit APIs, setup the initial stack frame - ; + ; ; ; Store the address in FSP which will return control to the BL @@ -555,7 +526,7 @@ FspApiCommon PROC C PUBLIC ; Reserve 8 bytes for IDT save/restore sub esp, 8 - sidt fword ptr [esp] + sidt fword ptr [esp] ; ; Setup new FSP stack @@ -571,7 +542,7 @@ FspApiCommon PROC C PUBLIC push eax ; - ; Pass the bootloader stack to SecStartup + ; Pass the BootLoader stack to SecStartup ; push edi @@ -612,7 +583,7 @@ FspApiCommon PROC C PUBLIC ; call SecStartup -exit: +exit: ret FspApiCommon ENDP diff --git a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s index d914075edc..1d8fe0bcd2 100644 --- a/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s +++ b/IntelFspPkg/FspSecCore/Ia32/FspApiEntry.s @@ -15,41 +15,31 @@ # #------------------------------------------------------------------------------ -#.INCLUDE "UcodeLoadGcc.inc" - begin .equ MSR_IA32_PLATFORM_ID, 0x00000017 .equ MSR_IA32_BIOS_UPDT_TRIG, 0x00000079 .equ MSR_IA32_BIOS_SIGN_ID, 0x0000008b -Ucode: -.equ UcodeVersion, 0x0000 -.equ UcodeRevision, 0x0004 -.equ UcodeDate, 0x0008 -.equ UcodeProcessor, 0x000C -.equ UcodeChecksum, 0x0010 -.equ UcodeLoader, 0x0014 -.equ UcodeRsvd, 0x0018 -UcodeEnd: - -UcodeHdr: -.equ UcodeHdrVersion, 0x0000 -.equ UcodeHdrRevision, 0x0004 -.equ UcodeHdrDate, 0x0008 -.equ UcodeHdrProcessor, 0x000c -.equ UcodeHdrChecksum, 0x0010 -.equ UcodeHdrLoader, 0x0014 -.equ UcodeHdrFlags, 0x0018 -.equ UcodeHdrDataSize, 0x001C -.equ UcodeHdrTotalSize, 0x0020 -.equ UcodeHdrRsvd, 0x0024 -UcodeHdrEnd: -.equ UcodeHdrLength, 0x0030 # UcodeHdrLength = UcodeHdrEnd - UcodeHdr + +MicrocodeHdr: +.equ MicrocodeHdrVersion, 0x0000 +.equ MicrocodeHdrRevision, 0x0004 +.equ MicrocodeHdrDate, 0x0008 +.equ MicrocodeHdrProcessor, 0x000c +.equ MicrocodeHdrChecksum, 0x0010 +.equ MicrocodeHdrLoader, 0x0014 +.equ MicrocodeHdrFlags, 0x0018 +.equ MicrocodeHdrDataSize, 0x001C +.equ MicrocodeHdrTotalSize, 0x0020 +.equ MicrocodeHdrRsvd, 0x0024 +MicrocodeHdrEnd: +.equ MicrocodeHdrLength, 0x0030 # MicrocodeHdrLength = MicrocodeHdrEnd - MicrocodeHdr ExtSigHdr: .equ ExtSigHdrCount, 0x0000 .equ ExtSigHdrChecksum, 0x0004 -.equ rsvd, 0x0008 +.equ ExtSigHdrRsvd, 0x0008 ExtSigHdrEnd: .equ ExtSigHdrLength, 0x0014 #ExtSigHdrLength = ExtSigHdrEnd - ExtSigHdr @@ -60,14 +50,12 @@ ExtSig: ExtSigEnd: .equ ExtSigLength, 0x000C #ExtSigLength = ExtSigEnd - ExtSig -LoadUcodeParams: -.equ LoadUcodeParamsUcodeCodeAddr, 0x0000 -.equ LoadUcodeParamsUcodeCodeSize, 0x0004 -LoadUcodeParamsEnd: +LoadMicrocodeParams: +.equ MicrocodeCodeAddr, 0x0000 +.equ MicrocodeCodeSize, 0x0004 +LoadMicrocodeParamsEnd: -#.INCLUDE "UcodeLoadGcc.inc" - end -#.INCLUDE "SaveRestoreSseGcc.inc" - begin .macro SAVE_REGS pinsrw $0x00, %ebp, %xmm7 @@ -147,12 +135,68 @@ LoadUcodeParamsEnd: .endm .macro ENABLE_SSE - movl %cr4, %eax - orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) - movl %eax,%cr4 + jmp NextAddress +.align 4 + # + # Float control word initial value: + # all exceptions masked, double-precision, round-to-nearest + # +ASM_PFX(mFpuControlWord): .word 0x027F + # + # Multimedia-extensions control word: + # all exceptions masked, round-to-nearest, flush to zero for masked underflow + # +ASM_PFX(mMmxControlWord): .long 0x01F80 +SseError: + # + # Processor has to support SSE + # + jmp SseError +NextAddress: + # + # Initialize floating point units + # + finit + fldcw ASM_PFX(mFpuControlWord) + + # + # Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test + # whether the processor supports SSE instruction. + # + movl $1, %eax + cpuid + btl $25, %edx + jnc SseError + + # + # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + # + movl %cr4, %eax + orl $BIT9, %eax + movl %eax, %cr4 + + # + # The processor should support SSE instruction and we can use + # ldmxcsr instruction + # + ldmxcsr ASM_PFX(mMmxControlWord) +.endm + +#Save in ECX-SLOT 3 in xmm6. +.macro SAVE_EAX_MICROCODE_RET_STATUS + pinsrw $0x6, %eax, %xmm6 + ror $0x10, %eax + pinsrw $0x7, %eax, %xmm6 + rol $0x10, %eax +.endm + +#Restore from ECX-SLOT 3 in xmm6. +.macro LOAD_EAX_MICROCODE_RET_STATUS + pshufd $0x93, %xmm6, %xmm6 + movd %xmm6, %eax + pshufd $0x39, %xmm6, %xmm6 .endm -#.INCLUDE "SaveRestoreSseGcc.inc" - end # @@ -182,28 +226,6 @@ ASM_GLOBAL ASM_PFX(Pei2LoaderSwitchStack) .equ DATA_LEN_OF_MCUD, 0x018 .equ DATA_LEN_AT_STACK_TOP, (DATA_LEN_OF_PER0 + DATA_LEN_OF_MCUD + 4) -#------------------------------------------------------------------------------ -# FspSelfCheckDefault -# Inputs: -# eax -> Return address -# Outputs: -# eax -> 0 - Successful, Non-zero - Failed. -# Register Usage: -# eax is cleared and ebp is used for return address. -# All others reserved. -#------------------------------------------------------------------------------ -ASM_GLOBAL ASM_PFX(FspSelfCheckDefault) -ASM_PFX(FspSelfCheckDefault): - # - # Save return address to EBP - # - movl %eax, %ebp - xorl %eax, %eax - -FspSelfCheckDefaultExit: - jmp *%ebp - - #------------------------------------------------------------------------------ # SecPlatformInitDefault # Inputs: @@ -227,10 +249,10 @@ SecPlatformInitDefaultExit: #------------------------------------------------------------------------------ -# LoadUcode +# LoadMicrocodeDefault # # Inputs: -# esp -> LOAD_UCODE_PARAMS pointer +# esp -> LoadMicrocodeParams pointer # Register Usage: # esp Preserved # All others destroyed @@ -239,8 +261,8 @@ SecPlatformInitDefaultExit: # Executed by SBSP and NBSP # Beginning of microcode update region starts on paragraph boundary #------------------------------------------------------------------------------ -ASM_GLOBAL ASM_PFX(LoadUcode) -ASM_PFX(LoadUcode): +ASM_GLOBAL ASM_PFX(LoadMicrocodeDefault) +ASM_PFX(LoadMicrocodeDefault): # # Save return address to EBP # @@ -248,17 +270,17 @@ ASM_PFX(LoadUcode): cmpl $0x00, %esp jz ParamError - movl (%esp), %eax #dword ptr [] Parameter pointer + movl 4(%esp), %eax #dword ptr [] Parameter pointer cmpl $0x00, %eax jz ParamError movl %eax, %esp - movl LoadUcodeParamsUcodeCodeAddr(%esp), %esi #mov esi, [esp].LOAD_UCODE_PARAMS.ucode_code_addr + movl MicrocodeCodeAddr(%esp), %esi cmpl $0x00, %esi jnz CheckMainHeader ParamError: movl $0x080000002, %eax - jmp LoadUcodeExit + jmp LoadMicrocodeExit CheckMainHeader: # @@ -291,68 +313,68 @@ CheckMainHeader: # Minimal test checking for header version and loader version as 1 # movl $0x01, %eax - cmpl %eax, UcodeHdrVersion(%esi) #cmp [esi].ucode_hdr.version, eax + cmpl %eax, MicrocodeHdrVersion(%esi) jne AdvanceFixedSize - cmpl %eax, UcodeHdrLoader(%esi) #cmp [esi].ucode_hdr.loader, eax + cmpl %eax, MicrocodeHdrLoader(%esi) jne AdvanceFixedSize # # Check if signature and plaform ID match # - cmpl UcodeHdrProcessor(%esi), %ebx #cmp ebx, [esi].ucode_hdr.processor - jne LoadUcodeL0 - testl UcodeHdrFlags(%esi), %edx #test edx, [esi].ucode_hdr.flags + cmpl MicrocodeHdrProcessor(%esi), %ebx + jne LoadMicrocodeL0 + testl MicrocodeHdrFlags(%esi), %edx jnz LoadCheck #Jif signature and platform ID match -LoadUcodeL0: +LoadMicrocodeL0: # # Check if extended header exists - # First check if total_size and data_size are valid + # First check if MicrocodeHdrTotalSize and MicrocodeHdrDataSize are valid # xorl %eax, %eax - cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax + cmpl %eax, MicrocodeHdrTotalSize(%esi) je NextMicrocode - cmpl %eax, UcodeHdrDataSize(%esi) #cmp [esi].ucode_hdr.data_size, eax + cmpl %eax, MicrocodeHdrDataSize(%esi) je NextMicrocode # # Then verify total size - sizeof header > data size # - movl UcodeHdrTotalSize(%esi), %ecx #mov ecx, [esi].ucode_hdr.total_size - subl $UcodeHdrLength, %ecx #sub ecx, sizeof ucode_hdr - cmpl UcodeHdrDataSize(%esi), %ecx #cmp ecx, [esi].ucode_hdr.data_size - jle NextMicrocode + movl MicrocodeHdrTotalSize(%esi), %ecx + subl $MicrocodeHdrLength, %ecx + cmpl MicrocodeHdrDataSize(%esi), %ecx + jle NextMicrocode # # Set edi -> extended header # movl %esi, %edi - addl $UcodeHdrLength, %edi #add edi, sizeof ucode_hdr - addl UcodeHdrDataSize(%esi), %edi #add edi, [esi].ucode_hdr.data_size + addl $MicrocodeHdrLength, %edi + addl MicrocodeHdrDataSize(%esi), %edi # # Get count of extended structures # - movl ExtSigHdrCount(%edi), %ecx #mov ecx, [edi].ext_sig_hdr.count + movl ExtSigHdrCount(%edi), %ecx # # Move pointer to first signature structure # - addl ExtSigHdrLength, %edi #add edi, sizeof ext_sig_hdr + addl ExtSigHdrLength, %edi CheckExtSig: # # Check if extended signature and platform ID match # - cmpl %ebx, ExtSigProcessor(%edi) #cmp [edi].ext_sig.processor, ebx - jne LoadUcodeL1 - test %edx, ExtSigFlags(%edi) #test [edi].ext_sig.flags, edx + cmpl %ebx, ExtSigProcessor(%edi) + jne LoadMicrocodeL1 + test %edx, ExtSigFlags(%edi) jnz LoadCheck # Jif signature and platform ID match -LoadUcodeL1: +LoadMicrocodeL1: # # Check if any more extended signatures exist # - addl $ExtSigLength, %edi #add edi, sizeof ext_sig + addl $ExtSigLength, %edi loop CheckExtSig NextMicrocode: @@ -360,11 +382,11 @@ NextMicrocode: # Advance just after end of this microcode # xorl %eax, %eax - cmpl %eax, UcodeHdrTotalSize(%esi) #cmp [esi].ucode_hdr.total_size, eax - je LoadUcodeL2 - addl UcodeHdrTotalSize(%esi), %esi #add esi, [esi].ucode_hdr.total_size + cmpl %eax, MicrocodeHdrTotalSize(%esi) + je LoadMicrocodeL2 + addl MicrocodeHdrTotalSize(%esi), %esi jmp CheckAddress -LoadUcodeL2: +LoadMicrocodeL2: addl $0x800, %esi #add esi, dword ptr 2048 jmp CheckAddress @@ -378,24 +400,24 @@ CheckAddress: # # Is valid Microcode start point ? # - cmpl $0x0ffffffff, UcodeHdrVersion(%esi) + cmpl $0x0ffffffff, MicrocodeHdrVersion(%esi) # # Is automatic size detection ? # - movl LoadUcodeParamsUcodeCodeSize(%esp), %eax + movl MicrocodeCodeSize(%esp), %eax cmpl $0x0ffffffff, %eax - jz LoadUcodeL3 + jz LoadMicrocodeL3 # # Address >= microcode region address + microcode region size? # - addl LoadUcodeParamsUcodeCodeAddr(%esp), %eax #mov eax, [esp].LOAD_UCODE_PARAMS.ucode_code_addr + addl MicrocodeCodeAddr(%esp), %eax cmpl %eax, %esi - jae Done #Jif address is outside of ucode region + jae Done #Jif address is outside of microcode region jmp CheckMainHeader -LoadUcodeL3: +LoadMicrocodeL3: LoadCheck: # # Get the revision of the current microcode update loaded @@ -413,10 +435,10 @@ LoadCheck: # # Verify this microcode update is not already loaded # - cmpl %edx, UcodeHdrRevision(%esi) #cmp [esi].ucode_hdr.revision, edx + cmpl %edx, MicrocodeHdrRevision(%esi) je Continue -LoadMicrocode: +LoadMicrocode0: # # EAX contains the linear address of the start of the Update Data # EDX contains zero @@ -424,7 +446,7 @@ LoadMicrocode: # Start microcode load with wrmsr # movl %esi, %eax - addl $UcodeHdrLength, %eax #add eax, sizeof ucode_hdr + addl $MicrocodeHdrLength, %eax xorl %edx, %edx movl $MSR_IA32_BIOS_UPDT_TRIG, %ecx wrmsr @@ -441,10 +463,10 @@ Done: rdmsr # Get current microcode signature xorl %eax, %eax cmpl $0x00, %edx - jnz LoadUcodeExit + jnz LoadMicrocodeExit movl $0x08000000E, %eax -LoadUcodeExit: +LoadMicrocodeExit: jmp *%ebp @@ -455,10 +477,10 @@ LoadUcodeExit: ASM_GLOBAL ASM_PFX(EstablishStackFsp) ASM_PFX(EstablishStackFsp): # - # Save parameter pointer in edx + # Save parameter pointer in edx # movl 4(%esp), %edx - + # # Enable FSP STACK # @@ -469,17 +491,9 @@ ASM_PFX(EstablishStackFsp): pushl $0x4455434D # Signature of the data region 'MCUD' pushl 12(%edx) # Code size pushl 8(%edx) # Code base - cmpl $0, %edx # Is parameter pointer valid ? - jz InvalidMicrocodeRegion pushl 4(%edx) # Microcode size pushl (%edx) # Microcode base - jmp EstablishStackFspExit -InvalidMicrocodeRegion: - push $0 # Microcode size - push $0 # Microcode base - -EstablishStackFspExit: # # Save API entry/exit timestamp into stack # @@ -495,11 +509,11 @@ EstablishStackFspExit: # # Terminator for the data on stack - # + # push $0x00 # - # Set ECX/EDX to the bootloader temporary memory range + # Set ECX/EDX to the BootLoader temporary memory range # movl PcdGet32 (PcdTemporaryRamBase), %ecx movl %ecx, %edx @@ -507,7 +521,7 @@ EstablishStackFspExit: subl PcdGet32 (PcdFspTemporaryRamSize), %edx xorl %eax, %eax - + movd %mm7, %esi #RET_ESI jmp *%esi @@ -548,18 +562,12 @@ ASM_PFX(TempRamInitApi): # # CPUID/DeviceID check - # - movl $TempRamInitApiL0, %eax - jmp ASM_PFX(FspSelfCheckDefault) # @note: ESP can not be changed. -TempRamInitApiL0: - cmpl $0x00, %eax - jnz NemInitExit - - # - # Sec Platform Init + # and Sec Platform Init # movl $TempRamInitApiL1, %esi #CALL_MMX SecPlatformInit - movd %mm7, %esi + movd %esi, %mm7 + .weak ASM_PFX(SecPlatformInit) + .set ASM_PFX(SecPlatformInit), ASM_PFX(SecPlatformInitDefault) jmp ASM_PFX(SecPlatformInit) TempRamInitApiL1: cmpl $0x00, %eax @@ -569,19 +577,21 @@ TempRamInitApiL1: # Load microcode # LOAD_ESP - movl $TempRamInitApiL2, %esi #CALL_MMX LoadUcode - movd %mm7, %esi - jmp ASM_PFX(LoadUcode) + movl $TempRamInitApiL2, %esi #CALL_MMX LoadMicrocode + movd %esi, %mm7 + .weak ASM_PFX(LoadMicrocode) + .set ASM_PFX(LoadMicrocode), ASM_PFX(LoadMicrocodeDefault) + jmp ASM_PFX(LoadMicrocode) TempRamInitApiL2: - cmpl $0x00, %eax - jnz NemInitExit + SAVE_EAX_MICROCODE_RET_STATUS #Save microcode return status in ECX-SLOT 3 in xmm6. + #@note If return value eax is not 0, microcode did not load, but continue and attempt to boot from ECX-SLOT 3 in xmm6. # # Call Sec CAR Init # LOAD_ESP movl $TempRamInitApiL3, %esi #CALL_MMX SecCarInit - movd %mm7, %esi + movd %esi, %mm7 jmp ASM_PFX(SecCarInit) TempRamInitApiL3: cmpl $0x00, %eax @@ -592,10 +602,12 @@ TempRamInitApiL3: # LOAD_ESP movl $TempRamInitApiL4, %esi #CALL_MMX EstablishStackFsp - movd %mm7, %esi + movd %esi, %mm7 jmp ASM_PFX(EstablishStackFsp) TempRamInitApiL4: + LOAD_EAX_MICROCODE_RET_STATUS #Restore microcode status if no CAR init error. + NemInitExit: # # Load EBP, EBX, ESI, EDI & ESP from XMM7 & XMM6 @@ -603,6 +615,7 @@ NemInitExit: LOAD_REGS ret + #---------------------------------------------------------------------------- # FspInit API # @@ -743,7 +756,7 @@ FspApiCommonL2: pushl %eax # - # Pass the bootloader stack to SecStartup + # Pass the BootLoader stack to SecStartup # pushl %edi @@ -787,4 +800,3 @@ FspApiCommonL2: FspApiCommonExit: ret - diff --git a/IntelFspPkg/FspSecCore/Ia32/FspHelper.asm b/IntelFspPkg/FspSecCore/Ia32/FspHelper.asm new file mode 100644 index 0000000000..51fd365c95 --- /dev/null +++ b/IntelFspPkg/FspSecCore/Ia32/FspHelper.asm @@ -0,0 +1,33 @@ +;; @file +; Provide FSP helper function. +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + + .586p + .model flat,C + .code + +FspInfoHeaderRelativeOff PROC NEAR PRIVATE + ; + ; This value will be pached by the build script + ; + DD 012345678h +FspInfoHeaderRelativeOff ENDP + +GetFspBaseAddress PROC NEAR PUBLIC + mov eax, GetFspBaseAddress + sub eax, dword ptr [FspInfoHeaderRelativeOff] + add eax, 01Ch + mov eax, dword ptr [eax] + ret +GetFspBaseAddress ENDP + + END \ No newline at end of file diff --git a/IntelFspPkg/FspSecCore/Ia32/FspHelper.s b/IntelFspPkg/FspSecCore/Ia32/FspHelper.s new file mode 100644 index 0000000000..40b822ac87 --- /dev/null +++ b/IntelFspPkg/FspSecCore/Ia32/FspHelper.s @@ -0,0 +1,33 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# Provide FSP helper function. +# +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(FspInfoHeaderRelativeOff) +ASM_PFX(FspInfoHeaderRelativeOff): + # + # This value will be pached by the build script + # + .long 0x012345678 + + +ASM_GLOBAL ASM_PFX(GetFspBaseAddress) +ASM_PFX(GetFspBaseAddress): + mov $GetFspBaseAddress, %eax + sub $FspInfoHeaderRelativeOff, %eax + add $0x01C, %eax + mov (%eax), %eax + ret + diff --git a/IntelFspPkg/FspSecCore/Ia32/MicrocodeLoad.inc b/IntelFspPkg/FspSecCore/Ia32/MicrocodeLoad.inc new file mode 100644 index 0000000000..6fbf430707 --- /dev/null +++ b/IntelFspPkg/FspSecCore/Ia32/MicrocodeLoad.inc @@ -0,0 +1,49 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +; Abstract: +; +;------------------------------------------------------------------------------ + +MSR_IA32_PLATFORM_ID EQU 000000017h +MSR_IA32_BIOS_UPDT_TRIG EQU 000000079h +MSR_IA32_BIOS_SIGN_ID EQU 00000008bh + + +MicrocodeHdr STRUCT 1t + MicrocodeHdrVersion DWORD ? + MicrocodeHdrRevision DWORD ? + MicrocodeHdrDate DWORD ? + MicrocodeHdrProcessor DWORD ? + MicrocodeHdrChecksum DWORD ? + MicrocodeHdrLoader DWORD ? + MicrocodeHdrFlags DWORD ? + MicrocodeHdrDataSize DWORD ? + MicrocodeHdrTotalSize DWORD ? + MicrocodeHdrRsvd DWORD 3t DUP (?) +MicrocodeHdr ENDS + +ExtSigHdr STRUCT 1t + ExtSigHdrCount DWORD ? + ExtSigHdrChecksum DWORD ? + ExtSigHdrRsvd DWORD 3t DUP (?) +ExtSigHdr ENDS + +ExtSig STRUCT 1t + ExtSigProcessor DWORD ? + ExtSigFlags DWORD ? + ExtSigChecksum DWORD ? +ExtSig ENDS + +LoadMicrocodeParams STRUCT 1t + MicrocodeCodeAddr DWORD ? + MicrocodeCodeSize DWORD ? +LoadMicrocodeParams ENDS diff --git a/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc b/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc index a3d5c47ffa..afc3ce061b 100644 --- a/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc +++ b/IntelFspPkg/FspSecCore/Ia32/SaveRestoreSse.inc @@ -1,6 +1,6 @@ ;------------------------------------------------------------------------------ ; -; Copyright (c) 2014, Intel Corporation. All rights reserved.
+; 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 @@ -47,7 +47,9 @@ LXMMN MACRO XMM, REG, IDX ENDM ENDIF - +; +; XMM7 to save/restore EBP, EBX, ESI, EDI +; SAVE_REGS MACRO SXMMN xmm7, 0, ebp SXMMN xmm7, 1, ebx @@ -64,6 +66,9 @@ LOAD_REGS MACRO LOAD_ESP ENDM +; +; XMM6 to save/restore EAX, EDX, ECX, ESP +; LOAD_EAX MACRO LXMMN xmm6, eax, 1 ENDM @@ -95,9 +100,85 @@ SAVE_ESP MACRO LOAD_ESP MACRO movd esp, xmm6 ENDM - -ENABLE_SSE MACRO - mov eax, cr4 - or eax, 00000600h - mov cr4, eax + +; +; XMM5 for calling stack +; +CALL_XMM MACRO Entry + local ReturnAddress + mov esi, offset ReturnAddress + pslldq xmm5, 4 +IFDEF USE_SSE41_FLAG + pinsrd xmm5, esi, 0 +ELSE + pinsrw xmm5, esi, 0 + ror esi, 16 + pinsrw xmm5, esi, 1 +ENDIF + mov esi, Entry + jmp esi +ReturnAddress: ENDM + +RET_XMM MACRO + movd esi, xmm5 + psrldq xmm5, 4 + jmp esi + ENDM + +ENABLE_SSE MACRO + ; + ; Initialize floating point units + ; + local NextAddress + jmp NextAddress +ALIGN 4 + ; + ; Float control word initial value: + ; all exceptions masked, double-precision, round-to-nearest + ; +FpuControlWord DW 027Fh + ; + ; Multimedia-extensions control word: + ; all exceptions masked, round-to-nearest, flush to zero for masked underflow + ; +MmxControlWord DD 01F80h +SseError: + ; + ; Processor has to support SSE + ; + jmp SseError +NextAddress: + finit + fldcw FpuControlWord + + ; + ; Use CpuId instructuion (CPUID.01H:EDX.SSE[bit 25] = 1) to test + ; whether the processor supports SSE instruction. + ; + mov eax, 1 + cpuid + bt edx, 25 + jnc SseError + +IFDEF USE_SSE41_FLAG + ; + ; SSE 4.1 support + ; + bt ecx, 19 + jnc SseError +ENDIF + + ; + ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + ; + mov eax, cr4 + or eax, 00000600h + mov cr4, eax + + ; + ; The processor should support SSE instruction and we can use + ; ldmxcsr instruction + ; + ldmxcsr MmxControlWord + ENDM diff --git a/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc b/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc deleted file mode 100644 index 6be6ed097b..0000000000 --- a/IntelFspPkg/FspSecCore/Ia32/UcodeLoad.inc +++ /dev/null @@ -1,63 +0,0 @@ -;------------------------------------------------------------------------------ -; -; Copyright (c) 2014, Intel Corporation. All rights reserved.
-; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which accompanies this distribution. The full text of the license may be found at -; http://opensource.org/licenses/bsd-license.php. -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -; -; Abstract: -; -;------------------------------------------------------------------------------ - -MSR_IA32_PLATFORM_ID EQU 000000017h -MSR_IA32_BIOS_UPDT_TRIG EQU 000000079h -MSR_IA32_BIOS_SIGN_ID EQU 00000008bh - -ucode STRUCT 1t - version DWORD ? - revision DWORD ? - date DWORD ? - processor DWORD ? - checksum DWORD ? - loader DWORD ? - rsvd DWORD 6t DUP (?) - data DWORD 500t DUP (?) -ucode ENDS -ucode_t TYPEDEF ucode - -ucode_hdr STRUCT 1t - version DWORD ? - revision DWORD ? - date DWORD ? - processor DWORD ? - checksum DWORD ? - loader DWORD ? - flags DWORD ? - data_size DWORD ? - total_size DWORD ? - rsvd DWORD 3t DUP (?) -ucode_hdr ENDS -ucode_hdr_t TYPEDEF ucode_hdr - -ext_sig_hdr STRUCT 1t - count DWORD ? - checksum DWORD ? - rsvd DWORD 3t DUP (?) -ext_sig_hdr ENDS -ext_sig_hdr_t TYPEDEF ext_sig_hdr - -ext_sig STRUCT 1t - processor DWORD ? - flags DWORD ? - checksum DWORD ? -ext_sig ENDS -ext_sig_t TYPEDEF ext_sig - -LOAD_UCODE_PARAMS STRUCT 1t - ucode_code_addr DWORD ? - ucode_code_size DWORD ? -LOAD_UCODE_PARAMS ENDS diff --git a/IntelFspPkg/FspSecCore/SecFsp.c b/IntelFspPkg/FspSecCore/SecFsp.c index 53ff8b7c0f..b4566045f9 100644 --- a/IntelFspPkg/FspSecCore/SecFsp.c +++ b/IntelFspPkg/FspSecCore/SecFsp.c @@ -97,10 +97,10 @@ SecGetPlatformData ( TopOfCar = PcdGet32 (PcdTemporaryRamBase) + PcdGet32 (PcdTemporaryRamSize); FspPlatformData->DataPtr = NULL; - FspPlatformData->CodeRegionSize = 0; + FspPlatformData->MicrocodeRegionBase = 0; + FspPlatformData->MicrocodeRegionSize = 0; FspPlatformData->CodeRegionBase = 0; - FspPlatformData->MicorcodeRegionBase = 0; - FspPlatformData->MicorcodeRegionSize = 0; + FspPlatformData->CodeRegionSize = 0; // // Pointer to the size field @@ -114,7 +114,7 @@ SecGetPlatformData ( // DwordSize = 4; StackPtr = StackPtr - 1 - DwordSize; - CopyMem (&(FspPlatformData->CodeRegionBase), StackPtr, (DwordSize << 2)); + CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2)); StackPtr--; } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) { // @@ -138,14 +138,14 @@ SecGetPlatformData ( It needs to be done as soon as possible after the stack is setup. @param[in,out] PeiFspData Pointer of the FSP global data. - @param[in] BootloaderStack Bootloader stack. + @param[in] BootLoaderStack BootLoader stack. @param[in] ApiIdx The index of the FSP API. **/ VOID FspGlobalDataInit ( IN OUT FSP_GLOBAL_DATA *PeiFspData, - IN UINT32 BootloaderStack, + IN UINT32 BootLoaderStack, IN UINT8 ApiIdx ) { @@ -162,7 +162,7 @@ FspGlobalDataInit ( ZeroMem ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA)); PeiFspData->Signature = FSP_GLOBAL_DATA_SIGNATURE; - PeiFspData->CoreStack = BootloaderStack; + PeiFspData->CoreStack = BootLoaderStack; PeiFspData->PerfIdx = 2; SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_ENTRY); @@ -239,25 +239,34 @@ FspDataPointerFixUp ( This function check the FSP API calling condition. @param[in] ApiIdx Internal index of the FSP API. + @param[in] ApiParam Parameter of the FSP API. **/ EFI_STATUS EFIAPI FspApiCallingCheck ( - UINT32 ApiIdx + IN UINT32 ApiIdx, + IN VOID *ApiParam ) { - EFI_STATUS Status; - FSP_GLOBAL_DATA *FspData; + EFI_STATUS Status; + FSP_GLOBAL_DATA *FspData; + FSP_INIT_PARAMS *FspInitParams; + FSP_INIT_RT_COMMON_BUFFER *FspRtBuffer; + + FspInitParams = (FSP_INIT_PARAMS *) ApiParam; + FspRtBuffer = ((FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr); Status = EFI_SUCCESS; - FspData = GetFspGlobalDataPointer (); + FspData = GetFspGlobalDataPointer (); if (ApiIdx == 1) { // // FspInit check // if ((UINT32)FspData != 0xFFFFFFFF) { Status = EFI_UNSUPPORTED; + } else if ((FspRtBuffer == NULL) || ((FspRtBuffer->BootLoaderTolumSize % EFI_PAGE_SIZE) != 0)) { + Status = EFI_INVALID_PARAMETER; } } else if (ApiIdx == 2) { // @@ -276,6 +285,8 @@ FspApiCallingCheck ( // if ((UINT32)FspData != 0xFFFFFFFF) { Status = EFI_UNSUPPORTED; + } else if ((FspRtBuffer == NULL) || ((FspRtBuffer->BootLoaderTolumSize % EFI_PAGE_SIZE) != 0)) { + Status = EFI_INVALID_PARAMETER; } } else if (ApiIdx == 4) { // @@ -305,3 +316,17 @@ FspApiCallingCheck ( return Status; } + +/** + This function gets the boot FV offset in FSP. + @return the boot firmware volumen offset inside FSP binary + +**/ +UINT32 +EFIAPI +GetBootFirmwareVolumeOffset ( + VOID + ) +{ + return PcdGet32 (PcdFspBootFirmwareVolumeBase) - PcdGet32 (PcdFspAreaBaseAddress); +} diff --git a/IntelFspPkg/FspSecCore/SecFsp.h b/IntelFspPkg/FspSecCore/SecFsp.h index 6582bb10f8..8e48a13f18 100644 --- a/IntelFspPkg/FspSecCore/SecFsp.h +++ b/IntelFspPkg/FspSecCore/SecFsp.h @@ -47,14 +47,14 @@ FspGetExceptionHandler( It needs to be done as soon as possible after the stack is setup. @param[in,out] PeiFspData Pointer of the FSP global data. - @param[in] BootloaderStack Bootloader stack. + @param[in] BootLoaderStack BootLoader stack. @param[in] ApiIdx The index of the FSP API. **/ VOID FspGlobalDataInit ( IN OUT FSP_GLOBAL_DATA *PeiFspData, - IN UINT32 BootloaderStack, + IN UINT32 BootLoaderStack, IN UINT8 ApiIdx ); diff --git a/IntelFspPkg/FspSecCore/SecMain.c b/IntelFspPkg/FspSecCore/SecMain.c index 12c9526d83..63376e9b6e 100644 --- a/IntelFspPkg/FspSecCore/SecMain.c +++ b/IntelFspPkg/FspSecCore/SecMain.c @@ -42,7 +42,7 @@ UINT64 mIdtEntryTemplate = 0xffff8e000008ffe4ULL; @param[in] TempRamBase Base address of tempory ram @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. @param[in] PeiCore PeiCore entry point. - @param[in] BootloaderStack Bootloader stack. + @param[in] BootLoaderStack BootLoader stack. @param[in] ApiIdx the index of API. @return This function never returns. @@ -55,7 +55,7 @@ SecStartup ( IN UINT32 TempRamBase, IN VOID *BootFirmwareVolume, IN PEI_CORE_ENTRY PeiCore, - IN UINT32 BootloaderStack, + IN UINT32 BootLoaderStack, IN UINT32 ApiIdx ) { @@ -106,7 +106,7 @@ SecStartup ( // // Iniitalize the global FSP data region // - FspGlobalDataInit (&PeiFspData, BootloaderStack, (UINT8)ApiIdx); + FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx); // // Update the base address and length of Pei temporary memory diff --git a/IntelFspPkg/FspSecCore/SecMain.h b/IntelFspPkg/FspSecCore/SecMain.h index 7efd2f0983..1fd2f2bdb2 100644 --- a/IntelFspPkg/FspSecCore/SecMain.h +++ b/IntelFspPkg/FspSecCore/SecMain.h @@ -108,7 +108,7 @@ InitializeFloatingPointUnits ( @param[in] TempRamBase Base address of tempory ram @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume. @param[in] PeiCore PeiCore entry point. - @param[in] BootloaderStack Bootloader stack. + @param[in] BootLoaderStack BootLoader stack. @param[in] ApiIdx the index of API. @return This function never returns. @@ -121,7 +121,7 @@ SecStartup ( IN UINT32 TempRamBase, IN VOID *BootFirmwareVolume, IN PEI_CORE_ENTRY PeiCore, - IN UINT32 BootloaderStack, + IN UINT32 BootLoaderStack, IN UINT32 ApiIdx ); diff --git a/IntelFspPkg/Include/FspApi.h b/IntelFspPkg/Include/FspApi.h index b3616d69e8..8fd73fb44e 100644 --- a/IntelFspPkg/Include/FspApi.h +++ b/IntelFspPkg/Include/FspApi.h @@ -83,10 +83,19 @@ typedef struct { /// User platform configuraiton data region pointer. /// VOID *UpdDataRgnPtr; + // + // Below field is added in FSP EAS v1.1 + // + /// + /// The size of memory to be reserved below the top of low usable memory (TOLUM) + /// for BootLoader usage. This is optional and value can be zero. If non-zero, the + /// size must be a multiple of 4KB. + /// + UINT32 BootLoaderTolumSize; /// /// Reserved /// - UINT32 Reserved[7]; + UINT32 Reserved[6]; } FSP_INIT_RT_COMMON_BUFFER; typedef enum { @@ -212,7 +221,7 @@ EFI_STATUS and defined for each FSP binary. This will be documented in Integration guide with each FSP release. After FspMemInit completes its execution, it passes the pointer to the HobList and - returns to the boot loader from where it was called. Bootloader is responsible to + returns to the boot loader from where it was called. BootLoader is responsible to migrate it's stack and data to Memory. FspMemoryInit, TempRamExit and FspSiliconInit APIs provide an alternate method to complete the silicon initialization and provides bootloader an opportunity to get diff --git a/IntelFspPkg/Include/FspInfoHeader.h b/IntelFspPkg/Include/FspInfoHeader.h index 3033659ea0..9513acdb76 100644 --- a/IntelFspPkg/Include/FspInfoHeader.h +++ b/IntelFspPkg/Include/FspInfoHeader.h @@ -64,7 +64,7 @@ typedef struct { /// UINT32 ImageSize; /// - /// Byte 0x18: FSP binary preferred base address + /// Byte 0x1C: FSP binary preferred base address /// UINT32 ImageBase; @@ -78,7 +78,7 @@ typedef struct { /// UINT32 CfgRegionOffset; /// - /// Byte 0x24: Size of the FSP configuration region + /// Byte 0x28: Size of the FSP configuration region /// UINT32 CfgRegionSize; /// @@ -103,7 +103,7 @@ typedef struct { UINT32 NotifyPhaseEntryOffset; /// - /// Below field is added in FSP 1.1 + /// Below fields are added in FSP Revision 2 /// /// @@ -122,7 +122,7 @@ typedef struct { } FSP_INFO_HEADER; /// -/// Below structure is added in FSP 1.1 +/// Below structure is added in FSP version 2 /// typedef struct { /// diff --git a/IntelFspPkg/Include/Guid/GuidHobFspEas.h b/IntelFspPkg/Include/Guid/GuidHobFspEas.h index 45a6e25f0a..4e723af2f4 100644 --- a/IntelFspPkg/Include/Guid/GuidHobFspEas.h +++ b/IntelFspPkg/Include/Guid/GuidHobFspEas.h @@ -18,6 +18,7 @@ extern EFI_GUID gFspBootLoaderTemporaryMemoryGuid; +extern EFI_GUID gFspBootLoaderTolumHobGuid; // FSP EAS v1.1 extern EFI_GUID gFspReservedMemoryResourceHobGuid; extern EFI_GUID gFspNonVolatileStorageHobGuid; diff --git a/IntelFspPkg/Include/Library/FspCommonLib.h b/IntelFspPkg/Include/Library/FspCommonLib.h index e7d7b0271a..22db27708d 100644 --- a/IntelFspPkg/Include/Library/FspCommonLib.h +++ b/IntelFspPkg/Include/Library/FspCommonLib.h @@ -76,7 +76,7 @@ SetFspContinuationFuncParameter ( ); /** - This function changes the Bootloader return address in stack. + This function changes the BootLoader return address in stack. @param[in] ReturnAddress Address to return. @@ -88,7 +88,7 @@ SetFspApiReturnAddress ( ); /** - This function set the API status code returned to the bootloader. + This function set the API status code returned to the BootLoader. @param[in] ReturnStatus Status code to return. @@ -181,6 +181,17 @@ GetFspInfoHeader ( VOID ); +/** + This function gets the VPD data pointer. + + @return VpdDataRgnPtr VPD data pointer. +**/ +VOID * +EFIAPI +GetFspVpdDataPointer ( + VOID + ); + /** This function gets FSP API calling mode. diff --git a/IntelFspPkg/Include/Library/FspPlatformLib.h b/IntelFspPkg/Include/Library/FspPlatformLib.h index 51d296835e..23460983ec 100644 --- a/IntelFspPkg/Include/Library/FspPlatformLib.h +++ b/IntelFspPkg/Include/Library/FspPlatformLib.h @@ -28,7 +28,7 @@ FspGetSystemMemorySize ( ); /** - Migrate bootloader data before destroying CAR. + Migrate BootLoader data before destroying CAR. **/ VOID @@ -49,7 +49,7 @@ FspSetNewStackFrame ( /** This function transfer control to the ContinuationFunc passed in by the - bootloader. + BootLoader. **/ VOID @@ -59,8 +59,8 @@ FspInitDone ( ); /** - This function handle NotifyPhase API call from the bootloader. - It gives control back to the bootloader after it is handled. If the + This function handle NotifyPhase API call from the BootLoader. + It gives control back to the BootLoader after it is handled. If the Notification code is a ReadyToBoot event, this function will return and FSP continues the remaining execution until it reaches the DxeIpl. diff --git a/IntelFspPkg/Include/Library/FspSecPlatformLib.h b/IntelFspPkg/Include/Library/FspSecPlatformLib.h new file mode 100644 index 0000000000..c6ed43001d --- /dev/null +++ b/IntelFspPkg/Include/Library/FspSecPlatformLib.h @@ -0,0 +1,74 @@ +/** @file + + Copyright (c) 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 + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _FSP_SEC_PLATFORM_LIB_H_ +#define _FSP_SEC_PLATFORM_LIB_H_ + +/** + This function performs platform level initialization. + + This function must be in ASM file, because stack is not established yet. + This function is optional. If a library instance does not provide this function, the default empty one will be used. + + The callee should not use XMM6/XMM7. + The return address is saved in MM7. + + @retval in saved in EAX - 0 means platform initialization success. + other means platform initialization fail. +**/ +UINT32 +EFIAPI +SecPlatformInit ( + VOID + ); + +/** + This function loads Microcode. + + This function must be in ASM file, because stack is not established yet. + This function is optional. If a library instance does not provide this function, the default one will be used. + + The callee should not use XMM6/XMM7. + The return address is saved in MM7. + + @param TempRamInitParamPtr A data structure to hold microcode parameter. It is saved in ESP. + + @retval in saved in EAX - 0 means Microcode is loaded successfully. + other means Microcode is not loaded successfully. +**/ +UINT32 +EFIAPI +LoadMicrocode ( + IN FSP_TEMP_RAM_INIT_PARAMS *TempRamInitParamPtr + ); + +/** + This function initializes the CAR. + + This function must be in ASM file, because stack is not established yet. + + The callee should not use XMM6/XMM7. + The return address is saved in MM7. + + @param TempRamInitParamPtr A data structure to hold microcode parameter. It is saved in ESP. + + @retval in saved in EAX - 0 means CAR initialization success. + other means CAR initialization fail. +**/ +UINT32 +EFIAPI +SecCarInit ( + IN FSP_TEMP_RAM_INIT_PARAMS *TempRamInitParamPtr + ); + +#endif diff --git a/IntelFspPkg/Include/Private/FspGlobalData.h b/IntelFspPkg/Include/Private/FspGlobalData.h index 436891af44..f50255fa7f 100644 --- a/IntelFspPkg/Include/Private/FspGlobalData.h +++ b/IntelFspPkg/Include/Private/FspGlobalData.h @@ -20,10 +20,10 @@ typedef struct { VOID *DataPtr; + UINT32 MicrocodeRegionBase; + UINT32 MicrocodeRegionSize; UINT32 CodeRegionBase; UINT32 CodeRegionSize; - UINT32 MicorcodeRegionBase; - UINT32 MicorcodeRegionSize; } FSP_PLAT_DATA; #define FSP_GLOBAL_DATA_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'D') diff --git a/IntelFspPkg/IntelFspPkg.dec b/IntelFspPkg/IntelFspPkg.dec index 1f286c1c7d..6f8a6306ab 100644 --- a/IntelFspPkg/IntelFspPkg.dec +++ b/IntelFspPkg/IntelFspPkg.dec @@ -24,22 +24,25 @@ [LibraryClasses] ## @libraryclass Provides cache-as-ram support. - CacheAsRamLib|IntelFspPkg/Include/Library/CacheAsRamLib.h + CacheAsRamLib|Include/Library/CacheAsRamLib.h ## @libraryclass Provides cache setting on MTRR. - CacheLib|IntelFspPkg/Include/Library/CacheLib.h + CacheLib|Include/Library/CacheLib.h ## @libraryclass Provides debug device abstraction. - DebugDeviceLib|IntelFspPkg/Include/Library/DebugDeviceLib.h + DebugDeviceLib|Include/Library/DebugDeviceLib.h ## @libraryclass Provides FSP related services. - FspCommonLib|IntelFspPkg/Include/Library/FspCommonLib.h + FspCommonLib|Include/Library/FspCommonLib.h ## @libraryclass Provides FSP platform related actions. - FspPlatformLib|IntelFspPkg/Include/Library/FspPlatformLib.h + FspPlatformLib|Include/Library/FspPlatformLib.h ## @libraryclass Provides FSP switch stack function. - FspSwitchStackLib|IntelFspPkg/Include/Library/FspSwitchStackLib.h + FspSwitchStackLib|Include/Library/FspSwitchStackLib.h + + ## @libraryclass Provides FSP platform sec related actions. + FspSecPlatformLib|Include/Library/FspSecPlatformLib.h [Guids] # @@ -52,6 +55,7 @@ gFspBootLoaderTemporaryMemoryGuid = { 0xbbcff46c, 0xc8d3, 0x4113, { 0x89, 0x85, 0xb9, 0xd4, 0xf3, 0xb3, 0xf6, 0x4e } } gFspReservedMemoryResourceHobGuid = { 0x69a79759, 0x1373, 0x4367, { 0xa6, 0xc4, 0xc7, 0xf5, 0x9e, 0xfd, 0x98, 0x6e } } gFspNonVolatileStorageHobGuid = { 0x721acf02, 0x4d77, 0x4c2a, { 0xb3, 0xdc, 0x27, 0x0b, 0x7b, 0xa9, 0xe4, 0xb0 } } + gFspBootLoaderTolumHobGuid = { 0x73ff4f56, 0xaa8e, 0x4451, { 0xb3, 0x16, 0x36, 0x35, 0x36, 0x67, 0xad, 0x44 } } # FSP EAS v1.1 # Guid defined by platform gFspReservedMemoryResourceHobTsegGuid = { 0xd038747c, 0xd00c, 0x4980, { 0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55 } } @@ -59,12 +63,15 @@ gFspReservedMemoryResourceHobMiscGuid = { 0x00d6b14b, 0x7dd0, 0x4062, { 0x88, 0x21, 0xe5, 0xf9, 0x6a, 0x2a, 0x1b, 0x00 } } [PcdsFixedAtBuild] - gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress|0xFED00108|UINT32|0x00000001 - gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase |0xFEF00000|UINT32|0x10001001 - gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize | 0x2000|UINT32|0x10001002 - gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize | 0x1000|UINT32|0x10001003 - gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry | 32|UINT32|0x00002001 - gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry | 5|UINT32|0x00002002 + gIntelFspPkgTokenSpaceGuid.PcdGlobalDataPointerAddress |0xFED00108|UINT32|0x00000001 + gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamBase |0xFEF00000|UINT32|0x10001001 + gIntelFspPkgTokenSpaceGuid.PcdTemporaryRamSize | 0x2000|UINT32|0x10001002 + gIntelFspPkgTokenSpaceGuid.PcdFspTemporaryRamSize | 0x1000|UINT32|0x10001003 + gIntelFspPkgTokenSpaceGuid.PcdFspMaxPerfEntry | 32|UINT32|0x00002001 + gIntelFspPkgTokenSpaceGuid.PcdFspMaxPatchEntry | 6|UINT32|0x00002002 + gIntelFspPkgTokenSpaceGuid.PcdFspAreaBaseAddress |0xFFF80000|UINT32|0x10000001 + gIntelFspPkgTokenSpaceGuid.PcdFspAreaSize |0x00040000|UINT32|0x10000002 + gIntelFspPkgTokenSpaceGuid.PcdFspBootFirmwareVolumeBase|0xFFF80000|UINT32|0x10000003 [PcdsFixedAtBuild,PcdsDynamic,PcdsDynamicEx] gIntelFspPkgTokenSpaceGuid.PcdFspReservedMemoryLength |0x00100000|UINT32|0x46530000 diff --git a/IntelFspPkg/IntelFspPkg.dsc b/IntelFspPkg/IntelFspPkg.dsc index 0c0b2b80e4..c8c604eac9 100644 --- a/IntelFspPkg/IntelFspPkg.dsc +++ b/IntelFspPkg/IntelFspPkg.dsc @@ -46,6 +46,7 @@ FspCommonLib|IntelFspPkg/Library/BaseFspCommonLib/BaseFspCommonLib.inf FspPlatformLib|IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf FspSwitchStackLib|IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf + FspSecPlatformLib|IntelFspPkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf [LibraryClasses.common.PEIM] PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf @@ -64,10 +65,7 @@ IntelFspPkg/Library/BaseFspPlatformLib/BaseFspPlatformLib.inf IntelFspPkg/Library/BaseFspSwitchStackLib/BaseFspSwitchStackLib.inf - IntelFspPkg/FspSecCore/FspSecCore.inf { - - NULL|IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf - } + IntelFspPkg/FspSecCore/FspSecCore.inf IntelFspPkg/FspDxeIpl/FspDxeIpl.inf [PcdsFixedAtBuild.common] diff --git a/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c index 2c0c3ad9bb..f80dff1a56 100644 --- a/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c +++ b/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c @@ -144,7 +144,7 @@ SetFspContinuationFuncParameter ( /** - This function changes the Bootloader return address in stack. + This function changes the BootLoader return address in stack. @param[in] ReturnAddress Address to return. @@ -162,7 +162,7 @@ SetFspApiReturnAddress ( } /** - This function set the API status code returned to the bootloader. + This function set the API status code returned to the BootLoader. @param[in] ReturnStatus Status code to return. @@ -331,6 +331,23 @@ GetFspInfoHeader ( return GetFspGlobalDataPointer()->FspInfoHeader; } +/** + This function gets the VPD data pointer. + + @return VpdDataRgnPtr VPD data pointer. +**/ +VOID * +EFIAPI +GetFspVpdDataPointer ( + VOID + ) +{ + FSP_INFO_HEADER *FspInfoHeader; + + FspInfoHeader = GetFspInfoHeader (); + return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset); +} + /** This function gets FSP API calling mode. diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformMemory.c b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformMemory.c index 241cd284fb..97cae9ad9d 100644 --- a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformMemory.c +++ b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformMemory.c @@ -68,7 +68,7 @@ FspGetSystemMemorySize ( } /** - Migrate bootloader data before destroying CAR. + Migrate BootLoader data before destroying CAR. **/ VOID @@ -93,7 +93,7 @@ FspMigrateTemporaryMemory ( ApiMode = GetFspApiCallingMode (); // - // Get the temporary memory range used by the bootloader + // Get the temporary memory range used by the BootLoader // BootLoaderTempRamStart = PcdGet32(PcdTemporaryRamBase); BootLoaderTempRamSize = PcdGet32(PcdTemporaryRamSize) - PcdGet32(PcdFspTemporaryRamSize); diff --git a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c index 33b2ebfe12..e6f5fe8f5b 100644 --- a/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c +++ b/IntelFspPkg/Library/BaseFspPlatformLib/FspPlatformNotify.c @@ -89,7 +89,7 @@ FspNotificationHandler ( /** This function transfer control to the ContinuationFunc passed in by the - bootloader. + BootLoader. **/ VOID @@ -101,9 +101,9 @@ FspInitDone ( FSP_INIT_PARAMS *FspInitParams; if (GetFspApiCallingMode() == 0) { - // - // FspInit API is used, so jump into the ContinuationFunc - // + // + // FspInit API is used, so jump into the ContinuationFunc + // FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter (); // @@ -139,8 +139,8 @@ FspInitDone ( } /** - This function handle NotifyPhase API call from the bootloader. - It gives control back to the bootloader after it is handled. If the + This function handle NotifyPhase API call from the BootLoader. + It gives control back to the BootLoader after it is handled. If the Notification code is a ReadyToBoot event, this function will return and FSP continues the remaining execution until it reaches the DxeIpl. diff --git a/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm new file mode 100644 index 0000000000..391fdf893a --- /dev/null +++ b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.asm @@ -0,0 +1,183 @@ +;; @file +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector, configures the stack. +; +; Copyright (c) 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 +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + +; +; Define assembler characteristics +; +.586p +.xmm +.model flat, c + +EXTRN TempRamInitApi:NEAR +EXTRN FspInitApi:NEAR + +; +; Contrary to the name, this file contains 16 bit code as well. +; +_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE + +;---------------------------------------------------------------------------- +; +; Procedure: _ModuleEntryPoint +; +; Input: None +; +; Output: None +; +; Destroys: Assume all registers +; +; Description: +; +; Transition to non-paged flat-model protected mode from a +; hard-coded GDT that provides exactly two descriptors. +; This is a bare bones transition to protected mode only +; used for a while in PEI and possibly DXE. +; +; After enabling protected mode, a far jump is executed to +; transfer to PEI using the newly loaded GDT. +; +; Return: None +; +;---------------------------------------------------------------------------- +align 16 +_ModuleEntryPoint PROC C PUBLIC + ; + ; Load the GDT table in GdtDesc + ; + mov esi, OFFSET GdtDesc + db 66h + lgdt fword ptr cs:[si] + + ; + ; Transition to 16 bit protected mode + ; + mov eax, cr0 ; Get control register 0 + or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1) + mov cr0, eax ; Activate protected mode + + ; + ; Now we're in 16 bit protected mode + ; Set up the selectors for 32 bit protected mode entry + ; + mov ax, SYS_DATA_SEL + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + ; + ; Transition to Flat 32 bit protected mode + ; The jump to a far pointer causes the transition to 32 bit mode + ; + mov esi, offset ProtectedModeEntryLinearAddress + jmp fword ptr cs:[si] + +_ModuleEntryPoint ENDP + +_TEXT_REALMODE ENDS + +.code +; +; Protected mode portion initializes stack, configures cache, and calls C entry point +; + +;---------------------------------------------------------------------------- +; +; Procedure: ProtectedModeEntryPoint +; +; Input: Executing in 32 Bit Protected (flat) mode +; cs: 0-4GB +; ds: 0-4GB +; es: 0-4GB +; fs: 0-4GB +; gs: 0-4GB +; ss: 0-4GB +; +; Output: This function never returns +; +; Destroys: +; ecx +; edi +; esi +; esp +; +; Description: +; Perform any essential early platform initilaisation +; Setup a stack +; +;---------------------------------------------------------------------------- + +ProtectedModeEntryPoint PROC NEAR C PUBLIC + ; + ; Dummy function. Consume 2 API to make sure they can be linked. + ; + mov eax, TempRamInitApi + mov eax, FspInitApi + + ; Should never return + jmp $ + +ProtectedModeEntryPoint ENDP + +; +; ROM-based Global-Descriptor Table for the PEI Phase +; +align 16 +PUBLIC BootGdtTable + +; +; GDT[0]: 0x00: Null entry, never used. +; +NULL_SEL equ $ - GDT_BASE ; Selector [0] +GDT_BASE: +BootGdtTable DD 0 + DD 0 +; +; Linear code segment descriptor +; +LINEAR_CODE_SEL equ $ - GDT_BASE ; Selector [0x8] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 09Bh ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; System data segment descriptor +; +SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x10] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 + +GDT_SIZE EQU $ - BootGDTtable ; Size, in bytes + +; +; GDT Descriptor +; +GdtDesc: ; GDT descriptor + DW GDT_SIZE - 1 ; GDT limit + DD OFFSET BootGdtTable ; GDT base address + +ProtectedModeEntryLinearAddress LABEL FWORD +ProtectedModeEntryLinearOffset LABEL DWORD + DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code + DW LINEAR_CODE_SEL + +END diff --git a/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s new file mode 100644 index 0000000000..4136e7646e --- /dev/null +++ b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/Flat32.s @@ -0,0 +1,171 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 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 +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# This is the code that goes from real-mode to protected mode. +# It consumes the reset vector, configures the stack. +# +#------------------------------------------------------------------------------ + + +# +# Contrary to the name, this file contains 16 bit code as well. +# +.text +#---------------------------------------------------------------------------- +# +# Procedure: _ModuleEntryPoint +# +# Input: None +# +# Output: None +# +# Destroys: Assume all registers +# +# Description: +# +# Transition to non-paged flat-model protected mode from a +# hard-coded GDT that provides exactly two descriptors. +# This is a bare bones transition to protected mode only +# used for a while in PEI and possibly DXE. +# +# After enabling protected mode, a far jump is executed to +# transfer to PEI using the newly loaded GDT. +# +# Return: None +# +#---------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + + # + # Load the GDT table in GdtDesc + # + .byte 0x66,0xbe #movl $GdtDesc, %esi + .long GdtDesc + + .byte 0x66,0x2e,0x0f,0x01,0x14 #lgdt %cs:(%si) + + # + # Transition to 16 bit protected mode + # + .byte 0x0f,0x20,0xc0 #movl %cr0, %eax # Get control register 0 + .byte 0x66,0x83,0xc8,0x03 #orl $0x0000003, %eax # Set PE bit (bit #0) & MP bit (bit #1) + .byte 0x0f,0x22,0xc0 #movl %eax, %cr0 # Activate protected mode + + # + # Now we're in 16 bit protected mode + # Set up the selectors for 32 bit protected mode entry + # + .byte 0xb8 #movw SYS_DATA_SEL, %ax + .word SYS_DATA_SEL + + .byte 0x8e,0xd8 #movw %ax, %ds + .byte 0x8e,0xc0 #movw %ax, %es + .byte 0x8e,0xe0 #movw %ax, %fs + .byte 0x8e,0xe8 #movw %ax, %gs + .byte 0x8e,0xd0 #movw %ax, %ss + + # + # Transition to Flat 32 bit protected mode + # The jump to a far pointer causes the transition to 32 bit mode + # + .byte 0x66,0xbe #movl ProtectedModeEntryLinearAddress, %esi + .long ProtectedModeEntryLinearAddress + .byte 0x66,0x2e,0xff,0x2c #jmp %cs:(%esi) + +# +# Protected mode portion initializes stack, configures cache, and calls C entry point +# + +#---------------------------------------------------------------------------- +# +# Procedure: ProtectedModeEntryPoint +# +# Input: Executing in 32 Bit Protected (flat) mode +# cs: 0-4GB +# ds: 0-4GB +# es: 0-4GB +# fs: 0-4GB +# gs: 0-4GB +# ss: 0-4GB +# +# Output: This function never returns +# +# Destroys: +# ecx +# edi +# esi +# esp +# +# Description: +# Perform any essential early platform initilaisation +# Setup a stack +# +#---------------------------------------------------------------------------- +ProtectedModeEntryPoint: + # + # Dummy function. Consume 2 API to make sure they can be linked. + # + movl ASM_PFX(TempRamInitApi), %eax + movl ASM_PFX(FspInitApi), %eax + # + # Should never return + # + jmp . #'$' + +# +# ROM-based Global-Descriptor Table for the PEI Phase +# +.align 16 +# +# GDT[0]: 000h: Null entry, never used. +# +.equ NULL_SEL, . - GDT_BASE # Selector [0] +GDT_BASE: +BootGdtTable: + .long 0 + .long 0 +# +# Linear code segment descriptor +# +.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [08h] + .word 0xFFFF # limit 0FFFFh + .word 0 # base 0 + .byte 0 + .byte 0x9B # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# System data segment descriptor +# +.equ SYS_DATA_SEL, . - GDT_BASE # Selector [010h] + .word 0xFFFF # limit 0FFFFh + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +.equ GDT_SIZE, . - BootGdtTable # Size, in bytes + +# +# GDT Descriptor +# +GdtDesc: # GDT descriptor + .word GDT_SIZE - 1 + .long BootGdtTable + +ProtectedModeEntryLinearAddress: +ProtectedModeEntryLinearOffset: + .long ProtectedModeEntryPoint + .word LINEAR_CODE_SEL diff --git a/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm new file mode 100644 index 0000000000..31296e0043 --- /dev/null +++ b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.asm @@ -0,0 +1,51 @@ +;; @file +; SEC CAR function +; +; Copyright (c) 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 +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +;; + +; +; Define assembler characteristics +; +.586p +.xmm +.model flat, c + +RET_ESI MACRO + + movd esi, mm7 ; move ReturnAddress from MM7 to ESI + jmp esi + +ENDM + +.code + +;----------------------------------------------------------------------------- +; +; Section: SecCarInit +; +; Description: This function initializes the Cache for Data, Stack, and Code +; +;----------------------------------------------------------------------------- +SecCarInit PROC NEAR PUBLIC + + ; + ; Set up CAR + ; + + xor eax, eax + +SecCarInitExit: + + RET_ESI + +SecCarInit ENDP + +END diff --git a/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s new file mode 100644 index 0000000000..7bd40df36a --- /dev/null +++ b/IntelFspPkg/Library/SecFspSecPlatformLibNull/Ia32/SecCarInit.s @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 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 +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# Abstract: +# +# SEC CAR function +# +#------------------------------------------------------------------------------ + +#----------------------------------------------------------------------------- +# +# Section: SecCarInit +# +# Description: This function initializes the Cache for Data, Stack, and Code +# +#----------------------------------------------------------------------------- +ASM_GLOBAL ASM_PFX(SecCarInit) +ASM_PFX(SecCarInit): + + # + # Set up CAR + # + + xor %eax, %eax + +SecCarInitExit: + + movd %mm7, %esi #RET_ESI + jmp *%esi diff --git a/IntelFspPkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c b/IntelFspPkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c new file mode 100644 index 0000000000..4de2a1d755 --- /dev/null +++ b/IntelFspPkg/Library/SecFspSecPlatformLibNull/PlatformSecLibNull.c @@ -0,0 +1,17 @@ +/** @file + Null instance of Platform Sec Lib. + + 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 + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + diff --git a/IntelFspPkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf b/IntelFspPkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf new file mode 100644 index 0000000000..4d88bf8295 --- /dev/null +++ b/IntelFspPkg/Library/SecFspSecPlatformLibNull/SecFspSecPlatformLibNull.inf @@ -0,0 +1,58 @@ +## @file +# NULL instance of Platform Sec Lib. +# +# 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 +# http://opensource.org/licenses/bsd-license.php. +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspSecPlatformLibNull + FILE_GUID = 03DA99B3-DDF4-4c7e-8CCA-216FC3F1F311 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspSecPlatformLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + PlatformSecLibNull.c + +[Sources.IA32] + Ia32/Flat32.asm + Ia32/Flat32.s + Ia32/SecCarInit.asm + Ia32/SecCarInit.s + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFspPkg/IntelFspPkg.dec diff --git a/IntelFspPkg/Library/SecPlatformSecLibNull/PlatformSecLibNull.c b/IntelFspPkg/Library/SecPlatformSecLibNull/PlatformSecLibNull.c deleted file mode 100644 index ed65aa5cdc..0000000000 --- a/IntelFspPkg/Library/SecPlatformSecLibNull/PlatformSecLibNull.c +++ /dev/null @@ -1,29 +0,0 @@ -/** @file - Null instance of Platform Sec Lib. - - Copyright (c) 2014, 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 - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -/** - This function provides dummy function so that SecCore can pass build - validation in IntelFspPkg. All real platform library instances needs - to implement the real entry point in assembly. -**/ -VOID -EFIAPI -_ModuleEntryPoint ( - VOID - ) -{ - return; -} diff --git a/IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf b/IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf deleted file mode 100644 index 4f0424e873..0000000000 --- a/IntelFspPkg/Library/SecPlatformSecLibNull/SecPlatformSecLibNull.inf +++ /dev/null @@ -1,53 +0,0 @@ -## @file -# NULL instance of Platform Sec Lib. -# -# 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 -# http://opensource.org/licenses/bsd-license.php. -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -################################################################################ -# -# Defines Section - statements that will be processed to create a Makefile. -# -################################################################################ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = SecPlatformSecLibNull - FILE_GUID = 03DA99B3-DDF4-4c7e-8CCA-216FC3F1F311 - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - LIBRARY_CLASS = NULL - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -################################################################################ -# -# Sources Section - list of files that are required for the build to succeed. -# -################################################################################ - -[Sources] - PlatformSecLibNull.c - - -################################################################################ -# -# Package Dependency Section - list of Package files that are required for -# this module. -# -################################################################################ - -[Packages] - MdePkg/MdePkg.dec - diff --git a/IntelFspPkg/Tools/PatchFv.py b/IntelFspPkg/Tools/PatchFv.py index cc22cc201e..2143161d2c 100644 --- a/IntelFspPkg/Tools/PatchFv.py +++ b/IntelFspPkg/Tools/PatchFv.py @@ -1,6 +1,6 @@ ## @ PatchFv.py # -# 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 that accompanies this distribution. # The full text of the license may be found at @@ -23,14 +23,33 @@ def readDataFromFile (binfile, offset, len=1): offval = fsize - (0xFFFFFFFF - offval + 1) fd.seek(offval) bytearray = [ord(b) for b in fd.read(len)] - value = 0; - idx = len - 1; + value = 0 + idx = len - 1 while idx >= 0: value = value << 8 | bytearray[idx] idx = idx - 1 fd.close() return value +def IsFspHeaderValid (binfile): + fd = open (binfile, "rb") + bindat = fd.read(0x200) + fd.close() + HeaderList = ['FSPH' , 'FSPP' , 'FSPE'] + OffsetList = [] + for each in HeaderList: + if each in bindat: + idx = bindat.index(each) + else: + idx = 0 + OffsetList.append(idx) + if not OffsetList[0] or not OffsetList[1]: + return False + Revision = ord(bindat[OffsetList[0] + 0x0B]) + if Revision > 1 and not OffsetList[2]: + return False + return True + def patchDataInFile (binfile, offset, value, len=1): fd = open(binfile, "r+b") fsize = os.path.getsize(binfile) @@ -38,7 +57,7 @@ def patchDataInFile (binfile, offset, value, len=1): if (offval & 0x80000000): offval = fsize - (0xFFFFFFFF - offval + 1) bytearray = [] - idx = 0; + idx = 0 while idx < len: bytearray.append(value & 0xFF) value = value >> 8 @@ -46,7 +65,7 @@ def patchDataInFile (binfile, offset, value, len=1): fd.seek(offval) fd.write("".join(chr(b) for b in bytearray)) fd.close() - return len; + return len class Symbols: @@ -346,7 +365,7 @@ class Symbols: values.append(self.parseBrace()) else: break - value = 1; + value = 1 for each in values: value *= each return value @@ -354,7 +373,7 @@ class Symbols: def parseAndOr(self): values = [self.parseMul()] op = None - value = 0xFFFFFFFF; + value = 0xFFFFFFFF while True: self.skipSpace() char = self.getCurr() @@ -500,6 +519,9 @@ def main(): fdSize = symTables.getFdSize() try: + ret = IsFspHeaderValid(fdFile) + if ret == False: + raise Exception ("The FSP header is not valid. Stop patching FD.") comment = "" for fvFile in sys.argv[3:]: items = fvFile.split(",")