;; @file ; Provide FSP API entry points. ; ; Copyright (c) 2016, 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. ;; SECTION .text ; ; Following are fixed PCDs ; extern ASM_PFX(PcdGet32(PcdTemporaryRamBase)) extern ASM_PFX(PcdGet32(PcdTemporaryRamSize)) extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize)) struc FSPM_UPD_COMMON ; FSP_UPD_HEADER { .FspUpdHeader: resd 8 ; } ; FSPM_ARCH_UPD { .Revision: resb 1 .Reserved: resb 3 .NvsBufferPtr: resd 1 .StackBase: resd 1 .StackSize: resd 1 .BootLoaderTolumSize: resd 1 .BootMode: resd 1 .Reserved1: resb 8 ; } .size: endstruc ; ; Following functions will be provided in C ; extern ASM_PFX(SecStartup) extern ASM_PFX(FspApiCommon) ; ; Following functions will be provided in PlatformSecLib ; extern ASM_PFX(AsmGetFspBaseAddress) extern ASM_PFX(AsmGetFspInfoHeader) API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call] FSP_HEADER_IMGBASE_OFFSET EQU 1Ch FSP_HEADER_CFGREG_OFFSET EQU 24h ;---------------------------------------------------------------------------- ; FspMemoryInit API ; ; This FSP API is called after TempRamInit and initializes the memory. ; ;---------------------------------------------------------------------------- global ASM_PFX(FspMemoryInitApi) ASM_PFX(FspMemoryInitApi): mov eax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex jmp ASM_PFX(FspApiCommon) ;---------------------------------------------------------------------------- ; TempRamExitApi API ; ; This API tears down temporary RAM ; ;---------------------------------------------------------------------------- global ASM_PFX(TempRamExitApi) ASM_PFX(TempRamExitApi): mov eax, 4 ; FSP_API_INDEX.TempRamExitApiIndex jmp ASM_PFX(FspApiCommon) ;---------------------------------------------------------------------------- ; FspApiCommonContinue API ; ; This is the FSP API common entry point to resume the FSP execution ; ;---------------------------------------------------------------------------- global ASM_PFX(FspApiCommonContinue) ASM_PFX(FspApiCommonContinue): ; ; EAX holds the API index ; ; ; FspMemoryInit API setup the initial stack frame ; ; ; Place holder to store the FspInfoHeader pointer ; push eax ; ; Update the FspInfoHeader pointer ; push eax call ASM_PFX(AsmGetFspInfoHeader) mov [esp + 4], eax pop eax ; ; Create a Task Frame in the stack for the Boot Loader ; pushfd ; 2 pushf for 4 byte alignment cli pushad ; Reserve 8 bytes for IDT save/restore sub esp, 8 sidt [esp] ; Get Stackbase and StackSize from FSPM_UPD Param mov edx, [esp + API_PARAM1_OFFSET] cmp edx, 0 jnz FspStackSetup ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null push eax call ASM_PFX(AsmGetFspInfoHeader) mov edx, [eax + FSP_HEADER_IMGBASE_OFFSET] add edx, [eax + FSP_HEADER_CFGREG_OFFSET] pop eax FspStackSetup: mov edi, [edx + FSPM_UPD_COMMON.StackBase] mov ecx, [edx + FSPM_UPD_COMMON.StackSize] add edi, ecx ; ; Setup new FSP stack ; xchg edi, esp ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size mov ebx, esp ; Put Stack base + Stack size in ebx ; ; Pass the API Idx to SecStartup ; push eax ; ; Pass the BootLoader stack to SecStartup ; push edi ; ; Pass entry point of the PEI core ; call ASM_PFX(AsmGetFspBaseAddress) mov edi, eax call ASM_PFX(AsmGetPeiCoreOffset) add edi, eax push edi ; ; Pass BFV into the PEI Core ; It uses relative address to calucate the actual boot FV base ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and ; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs, ; they are different. The code below can handle both cases. ; call ASM_PFX(AsmGetFspBaseAddress) push eax ; ; Pass stack base and size into the PEI Core ; sub ebx, ecx ; Stack base + Stack size - Stack size push ebx push ecx ; ; Pass Control into the PEI Core ; call ASM_PFX(SecStartup) add esp, 4 exit: ret global ASM_PFX(FspPeiCoreEntryOff) ASM_PFX(FspPeiCoreEntryOff): ; ; This value will be pached by the build script ; DD 0x12345678 global ASM_PFX(AsmGetPeiCoreOffset) ASM_PFX(AsmGetPeiCoreOffset): mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)] ret ;---------------------------------------------------------------------------- ; Module Entrypoint API ;---------------------------------------------------------------------------- global ASM_PFX(_ModuleEntryPoint) ASM_PFX(_ModuleEntryPoint): jmp $