X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=IntelFsp2Pkg%2FFspSecCore%2FIa32%2FFsp24ApiEntryM.nasm;fp=IntelFsp2Pkg%2FFspSecCore%2FIa32%2FFsp24ApiEntryM.nasm;h=997b9c0bffb1212c7db35893414c1027a731146b;hp=0000000000000000000000000000000000000000;hb=3d35a6c243ffe749a2ae71d5d72ce0361f168f49;hpb=5eeb088ad64124229b32a5593fada578b935e207 diff --git a/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm new file mode 100644 index 0000000000..997b9c0bff --- /dev/null +++ b/IntelFsp2Pkg/FspSecCore/Ia32/Fsp24ApiEntryM.nasm @@ -0,0 +1,304 @@ +;; @file +; Provide FSP API entry points. +; +; Copyright (c) 2022, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +;; + + SECTION .text + +; +; Following are fixed PCDs +; +extern ASM_PFX(PcdGet32(PcdTemporaryRamBase)) +extern ASM_PFX(PcdGet32(PcdTemporaryRamSize)) +extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize)) +extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage)) + +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 + +struc FSPM_UPD_COMMON_FSP24 + ; FSP_UPD_HEADER { + .FspUpdHeader: resd 8 + ; } + ; FSPM_ARCH2_UPD { + .Revision: resb 1 + .Reserved: resb 3 + .Length resd 1 + .StackBase: resq 1 + .StackSize: resq 1 + .BootLoaderTolumSize: resd 1 + .BootMode: resd 1 + .FspEventHandler resq 1 + .Reserved1: resb 24 + ; } + .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) +extern ASM_PFX(FspMultiPhaseMemInitApiHandler) + +STACK_SAVED_EAX_OFFSET EQU 4 * 7 ; size of a general purpose register * eax index +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) + +;---------------------------------------------------------------------------- +; FspMultiPhaseMemoryInitApi API +; +; This FSP API provides multi-phase Memory initialization, which brings greater +; modularity beyond the existing FspMemoryInit() API. +; Increased modularity is achieved by adding an extra API to FSP-M. +; This allows the bootloader to add board specific initialization steps throughout +; the MemoryInit flow as needed. +; +;---------------------------------------------------------------------------- +global ASM_PFX(FspMultiPhaseMemoryInitApi) +ASM_PFX(FspMultiPhaseMemoryInitApi): + mov eax, 8 ; FSP_API_INDEX.FspMultiPhaseMemInitApiIndex + 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): + ; + ; Handle FspMultiPhaseMemInitApiIndex API + ; + cmp eax, 8 ; FspMultiPhaseMemInitApiIndex + jnz NotMultiPhaseMemoryInitApi + + pushad + push DWORD [esp + (4 * 8 + 4)] ; push ApiParam + push eax ; push ApiIdx + call ASM_PFX(FspMultiPhaseMemInitApiHandler) + add esp, 8 + mov dword [esp + STACK_SAVED_EAX_OFFSET], eax + popad + ret + +NotMultiPhaseMemoryInitApi: + + ; + ; 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 ecx, [edx + FSPM_UPD_COMMON.Revision] + cmp ecx, 3 + jae FspmUpdCommon2 + + ; + ; StackBase = temp memory base, StackSize = temp memory size + ; + mov edi, [edx + FSPM_UPD_COMMON.StackBase] + mov ecx, [edx + FSPM_UPD_COMMON.StackSize] + jmp ChkFspHeapSize + +FspmUpdCommon2: + mov edi, [edx + FSPM_UPD_COMMON_FSP24.StackBase] + mov ecx, [edx + FSPM_UPD_COMMON_FSP24.StackSize] + +ChkFspHeapSize: + ; + ; Keep using bootloader stack if heap size % is 0 + ; + mov bl, BYTE [ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))] + cmp bl, 0 + jz SkipStackSwitch + + ; + ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0 + ; + add edi, ecx + ; + ; Switch to 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 + +SkipStackSwitch: + ; + ; If heap size % is 0: + ; EDI is FSPM_UPD_COMMON.StackBase and will hold ESP later (boot loader stack pointer) + ; ECX is FSPM_UPD_COMMON.StackSize + ; ESP is boot loader stack pointer (no stack switch) + ; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON.StackBase later) + ; + ; If heap size % is not 0 + ; EDI is boot loader stack pointer + ; ECX is FSPM_UPD_COMMON.StackSize + ; ESP is new stack (FSPM_UPD_COMMON.StackBase + FSPM_UPD_COMMON.StackSize) + ; BL is NOT 0 to indicate stack has switched + ; + cmp bl, 0 + jnz StackHasBeenSwitched + + mov ebx, edi ; Put FSPM_UPD_COMMON.StackBase to ebx as temp memory base + mov edi, esp ; Put boot loader stack pointer to edi + jmp StackSetupDone + +StackHasBeenSwitched: + mov ebx, esp ; Put Stack base + Stack size in ebx + sub ebx, ecx ; Stack base + Stack size - Stack size as temp memory base + +StackSetupDone: + + ; + ; 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 calculate the actual boot FV base + ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and + ; PcdFspAreaBaseAddress are the same. For FSP with multiple 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 + ; + 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 patched by the build script + ; + DD 0x12345678 + +global ASM_PFX(AsmGetPeiCoreOffset) +ASM_PFX(AsmGetPeiCoreOffset): + mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)] + ret + +;---------------------------------------------------------------------------- +; TempRamInit API +; +; Empty function for WHOLEARCHIVE build option +; +;---------------------------------------------------------------------------- +global ASM_PFX(TempRamInitApi) +ASM_PFX(TempRamInitApi): + jmp $ + ret + +;---------------------------------------------------------------------------- +; Module Entrypoint API +;---------------------------------------------------------------------------- +global ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + jmp $