1 ;; @file 2 ; Provide FSP API entry points. 3 ; 4 ; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> 5 ; This program and the accompanying materials 6 ; are licensed and made available under the terms and conditions of the BSD License 7 ; which accompanies this distribution. The full text of the license may be found at 8 ; http://opensource.org/licenses/bsd-license.php. 9 ; 10 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 ;; 13 14 SECTION .text 15 16 ; 17 ; Following are fixed PCDs 18 ; 19 extern ASM_PFX(PcdGet32(PcdTemporaryRamBase)) 20 extern ASM_PFX(PcdGet32(PcdTemporaryRamSize)) 21 extern ASM_PFX(PcdGet32(PcdFspTemporaryRamSize)) 22 23 struc FSPM_UPD_COMMON 24 ; FSP_UPD_HEADER { 25 .FspUpdHeader: resd 8 26 ; } 27 ; FSPM_ARCH_UPD { 28 .Revision: resb 1 29 .Reserved: resb 3 30 .NvsBufferPtr: resd 1 31 .StackBase: resd 1 32 .StackSize: resd 1 33 .BootLoaderTolumSize: resd 1 34 .BootMode: resd 1 35 .Reserved1: resb 8 36 ; } 37 .size: 38 endstruc 39 40 ; 41 ; Following functions will be provided in C 42 ; 43 extern ASM_PFX(SecStartup) 44 extern ASM_PFX(FspApiCommon) 45 46 ; 47 ; Following functions will be provided in PlatformSecLib 48 ; 49 extern ASM_PFX(AsmGetFspBaseAddress) 50 extern ASM_PFX(AsmGetFspInfoHeader) 51 52 API_PARAM1_OFFSET EQU 34h ; ApiParam1 [ sub esp,8 + pushad + pushfd + push eax + call] 53 FSP_HEADER_IMGBASE_OFFSET EQU 1Ch 54 FSP_HEADER_CFGREG_OFFSET EQU 24h 55 56 ;---------------------------------------------------------------------------- 57 ; FspMemoryInit API 58 ; 59 ; This FSP API is called after TempRamInit and initializes the memory. 60 ; 61 ;---------------------------------------------------------------------------- 62 global ASM_PFX(FspMemoryInitApi) 63 ASM_PFX(FspMemoryInitApi): 64 mov eax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex 65 jmp ASM_PFX(FspApiCommon) 66 67 ;---------------------------------------------------------------------------- 68 ; TempRamExitApi API 69 ; 70 ; This API tears down temporary RAM 71 ; 72 ;---------------------------------------------------------------------------- 73 global ASM_PFX(TempRamExitApi) 74 ASM_PFX(TempRamExitApi): 75 mov eax, 4 ; FSP_API_INDEX.TempRamExitApiIndex 76 jmp ASM_PFX(FspApiCommon) 77 78 ;---------------------------------------------------------------------------- 79 ; FspApiCommonContinue API 80 ; 81 ; This is the FSP API common entry point to resume the FSP execution 82 ; 83 ;---------------------------------------------------------------------------- 84 global ASM_PFX(FspApiCommonContinue) 85 ASM_PFX(FspApiCommonContinue): 86 ; 87 ; EAX holds the API index 88 ; 89 90 ; 91 ; FspMemoryInit API setup the initial stack frame 92 ; 93 94 ; 95 ; Place holder to store the FspInfoHeader pointer 96 ; 97 push eax 98 99 ; 100 ; Update the FspInfoHeader pointer 101 ; 102 push eax 103 call ASM_PFX(AsmGetFspInfoHeader) 104 mov [esp + 4], eax 105 pop eax 106 107 ; 108 ; Create a Task Frame in the stack for the Boot Loader 109 ; 110 pushfd ; 2 pushf for 4 byte alignment 111 cli 112 pushad 113 114 ; Reserve 8 bytes for IDT save/restore 115 sub esp, 8 116 sidt [esp] 117 118 119 ; Get Stackbase and StackSize from FSPM_UPD Param 120 mov edx, [esp + API_PARAM1_OFFSET] 121 cmp edx, 0 122 jnz FspStackSetup 123 124 ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null 125 push eax 126 call ASM_PFX(AsmGetFspInfoHeader) 127 mov edx, [eax + FSP_HEADER_IMGBASE_OFFSET] 128 add edx, [eax + FSP_HEADER_CFGREG_OFFSET] 129 pop eax 130 131 FspStackSetup: 132 mov edi, [edx + FSPM_UPD_COMMON.StackBase] 133 mov ecx, [edx + FSPM_UPD_COMMON.StackSize] 134 add edi, ecx 135 ; 136 ; Setup new FSP stack 137 ; 138 xchg edi, esp ; Exchange edi and esp, edi will be assigned to the current esp pointer and esp will be Stack base + Stack size 139 mov ebx, esp ; Put Stack base + Stack size in ebx 140 141 ; 142 ; Pass the API Idx to SecStartup 143 ; 144 push eax 145 146 ; 147 ; Pass the BootLoader stack to SecStartup 148 ; 149 push edi 150 151 ; 152 ; Pass entry point of the PEI core 153 ; 154 call ASM_PFX(AsmGetFspBaseAddress) 155 mov edi, eax 156 call ASM_PFX(AsmGetPeiCoreOffset) 157 add edi, eax 158 push edi 159 160 ; 161 ; Pass BFV into the PEI Core 162 ; It uses relative address to calucate the actual boot FV base 163 ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and 164 ; PcdFspAreaBaseAddress are the same. For FSP with mulitple FVs, 165 ; they are different. The code below can handle both cases. 166 ; 167 call ASM_PFX(AsmGetFspBaseAddress) 168 push eax 169 170 ; 171 ; Pass stack base and size into the PEI Core 172 ; 173 sub ebx, ecx ; Stack base + Stack size - Stack size 174 push ebx 175 push ecx 176 177 ; 178 ; Pass Control into the PEI Core 179 ; 180 call ASM_PFX(SecStartup) 181 add esp, 4 182 exit: 183 ret 184 185 global ASM_PFX(FspPeiCoreEntryOff) 186 ASM_PFX(FspPeiCoreEntryOff): 187 ; 188 ; This value will be pached by the build script 189 ; 190 DD 0x12345678 191 192 global ASM_PFX(AsmGetPeiCoreOffset) 193 ASM_PFX(AsmGetPeiCoreOffset): 194 mov eax, dword [ASM_PFX(FspPeiCoreEntryOff)] 195 ret 196 197 ;---------------------------------------------------------------------------- 198 ; Module Entrypoint API 199 ;---------------------------------------------------------------------------- 200 global ASM_PFX(_ModuleEntryPoint) 201 ASM_PFX(_ModuleEntryPoint): 202 jmp $ 203