]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/FspSecCore/X64/Fsp24ApiEntryM.nasm
IntelFsp2Pkg: Adopt FSP 2.4 MultiPhase functions.
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / X64 / Fsp24ApiEntryM.nasm
1 ;; @file
2 ; Provide FSP API entry points.
3 ;
4 ; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
5 ; SPDX-License-Identifier: BSD-2-Clause-Patent
6 ;;
7
8 SECTION .text
9
10 %include "PushPopRegsNasm.inc"
11
12 ;
13 ; Following are fixed PCDs
14 ;
15 extern ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
16
17 struc FSPM_UPD_COMMON_FSP24
18 ; FSP_UPD_HEADER {
19 .FspUpdHeader: resd 8
20 ; }
21 ; FSPM_ARCH2_UPD {
22 .Revision: resb 1
23 .Reserved: resb 3
24 .Length resd 1
25 .StackBase: resq 1
26 .StackSize: resq 1
27 .BootLoaderTolumSize: resd 1
28 .BootMode: resd 1
29 .FspEventHandler resq 1
30 .Reserved1: resb 24
31 ; }
32 .size:
33 endstruc
34
35 ;
36 ; Following functions will be provided in C
37 ;
38 extern ASM_PFX(SecStartup)
39 extern ASM_PFX(FspApiCommon)
40
41 ;
42 ; Following functions will be provided in PlatformSecLib
43 ;
44 extern ASM_PFX(AsmGetFspBaseAddress)
45 extern ASM_PFX(AsmGetFspInfoHeader)
46 extern ASM_PFX(FspMultiPhaseMemInitApiHandler)
47
48 STACK_SAVED_RAX_OFFSET EQU 8 * 7 ; size of a general purpose register * rax index
49 FSP_HEADER_IMGBASE_OFFSET EQU 1Ch
50 FSP_HEADER_CFGREG_OFFSET EQU 24h
51
52 ;----------------------------------------------------------------------------
53 ; FspMemoryInit API
54 ;
55 ; This FSP API is called after TempRamInit and initializes the memory.
56 ;
57 ;----------------------------------------------------------------------------
58 global ASM_PFX(FspMemoryInitApi)
59 ASM_PFX(FspMemoryInitApi):
60 mov rax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex
61 jmp ASM_PFX(FspApiCommon)
62
63 ;----------------------------------------------------------------------------
64 ; FspMultiPhaseMemoryInitApi API
65 ;
66 ; This FSP API provides multi-phase Memory initialization, which brings greater
67 ; modularity beyond the existing FspMemoryInit() API.
68 ; Increased modularity is achieved by adding an extra API to FSP-M.
69 ; This allows the bootloader to add board specific initialization steps throughout
70 ; the MemoryInit flow as needed.
71 ;
72 ;----------------------------------------------------------------------------
73 global ASM_PFX(FspMultiPhaseMemoryInitApi)
74 ASM_PFX(FspMultiPhaseMemoryInitApi):
75 mov rax, 8 ; FSP_API_INDEX.FspMultiPhaseMemInitApiIndex
76 jmp ASM_PFX(FspApiCommon)
77 ;----------------------------------------------------------------------------
78 ; TempRamExitApi API
79 ;
80 ; This API tears down temporary RAM
81 ;
82 ;----------------------------------------------------------------------------
83 global ASM_PFX(TempRamExitApi)
84 ASM_PFX(TempRamExitApi):
85 mov rax, 4 ; FSP_API_INDEX.TempRamExitApiIndex
86 jmp ASM_PFX(FspApiCommon)
87
88 ;----------------------------------------------------------------------------
89 ; FspApiCommonContinue API
90 ;
91 ; This is the FSP API common entry point to resume the FSP execution
92 ;
93 ;----------------------------------------------------------------------------
94 global ASM_PFX(FspApiCommonContinue)
95 ASM_PFX(FspApiCommonContinue):
96 ;
97 ; Handle FspMultiPhaseMemoInitApiIndex API
98 ;
99 push rdx ; Push a QWORD data for stack alignment
100
101 cmp rax, 8 ; FspMultiPhaseMemInitApiIndex
102 jnz NotMultiPhaseMemoryInitApi
103
104 PUSHA_64
105 mov rdx, rcx ; move ApiParam to rdx
106 mov rcx, rax ; move ApiIdx to rcx
107 sub rsp, 0x20 ; calling C function may need shadow space
108 call ASM_PFX(FspMultiPhaseMemInitApiHandler)
109 add rsp, 0x20 ; restore shadow space
110 mov qword [rsp + STACK_SAVED_RAX_OFFSET], rax
111 POPA_64
112 add rsp, 0x08
113 ret
114
115 NotMultiPhaseMemoryInitApi:
116 ; Push RDX and RCX to form CONTEXT_STACK_64
117 push rdx ; Push API Parameter2 on stack
118 push rcx ; Push API Parameter1 on stack
119
120 ;
121 ; FspMemoryInit API setup the initial stack frame
122 ;
123
124 ;
125 ; Place holder to store the FspInfoHeader pointer
126 ;
127 push rax
128
129 ;
130 ; Update the FspInfoHeader pointer
131 ;
132 push rax
133 call ASM_PFX(AsmGetFspInfoHeader)
134 mov [rsp + 8], rax
135 pop rax
136
137 ;
138 ; Create a Task Frame in the stack for the Boot Loader
139 ;
140 pushfq
141 cli
142 PUSHA_64
143
144 ; Reserve 16 bytes for IDT save/restore
145 sub rsp, 16
146 sidt [rsp]
147
148 ; Get Stackbase and StackSize from FSPM_UPD Param
149 mov rdx, rcx ; Put FSPM_UPD Param to rdx
150 cmp rdx, 0
151 jnz FspStackSetup
152
153 ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null
154 xchg rbx, rax
155 call ASM_PFX(AsmGetFspInfoHeader)
156 mov edx, [rax + FSP_HEADER_IMGBASE_OFFSET]
157 add edx, [rax + FSP_HEADER_CFGREG_OFFSET]
158 xchg rbx, rax
159
160 FspStackSetup:
161 mov cl, [rdx + FSPM_UPD_COMMON_FSP24.Revision]
162 cmp cl, 3
163 jae FspmUpdCommonFsp24
164
165 mov rax, 08000000000000002h ; RETURN_INVALID_PARAMETER
166 sub rsp, 0b8h
167 ret
168
169 FspmUpdCommonFsp24:
170 ;
171 ; StackBase = temp memory base, StackSize = temp memory size
172 ;
173 mov rdi, [rdx + FSPM_UPD_COMMON_FSP24.StackBase]
174 mov ecx, [rdx + FSPM_UPD_COMMON_FSP24.StackSize]
175
176 ;
177 ; Keep using bootloader stack if heap size % is 0
178 ;
179 mov rbx, ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))
180 mov bl, BYTE [rbx]
181 cmp bl, 0
182 jz SkipStackSwitch
183
184 ;
185 ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0
186 ;
187 add rdi, rcx
188 ;
189 ; Switch to new FSP stack
190 ;
191 xchg rdi, rsp ; Exchange rdi and rsp, rdi will be assigned to the current rsp pointer and rsp will be Stack base + Stack size
192
193 SkipStackSwitch:
194 ;
195 ; If heap size % is 0:
196 ; EDI is FSPM_UPD_COMMON_FSP24.StackBase and will hold ESP later (boot loader stack pointer)
197 ; ECX is FSPM_UPD_COMMON_FSP24.StackSize
198 ; ESP is boot loader stack pointer (no stack switch)
199 ; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON_FSP24.StackBase later)
200 ;
201 ; If heap size % is not 0
202 ; EDI is boot loader stack pointer
203 ; ECX is FSPM_UPD_COMMON_FSP24.StackSize
204 ; ESP is new stack (FSPM_UPD_COMMON_FSP24.StackBase + FSPM_UPD_COMMON_FSP24.StackSize)
205 ; BL is NOT 0 to indicate stack has switched
206 ;
207 cmp bl, 0
208 jnz StackHasBeenSwitched
209
210 mov rbx, rdi ; Put FSPM_UPD_COMMON_FSP24.StackBase to rbx as temp memory base
211 mov rdi, rsp ; Put boot loader stack pointer to rdi
212 jmp StackSetupDone
213
214 StackHasBeenSwitched:
215 mov rbx, rsp ; Put Stack base + Stack size in ebx
216 sub rbx, rcx ; Stack base + Stack size - Stack size as temp memory base
217
218 StackSetupDone:
219
220 ;
221 ; Per X64 calling convention, make sure RSP is 16-byte aligned.
222 ;
223 mov rdx, rsp
224 and rdx, 0fh
225 sub rsp, rdx
226
227 ;
228 ; Pass the API Idx to SecStartup
229 ;
230 push rax
231
232 ;
233 ; Pass the BootLoader stack to SecStartup
234 ;
235 push rdi
236
237 ;
238 ; Pass BFV into the PEI Core
239 ; It uses relative address to calculate the actual boot FV base
240 ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and
241 ; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,
242 ; they are different. The code below can handle both cases.
243 ;
244 call ASM_PFX(AsmGetFspBaseAddress)
245 mov r8, rax
246
247 ;
248 ; Pass entry point of the PEI core
249 ;
250 call ASM_PFX(AsmGetPeiCoreOffset)
251 lea r9, [r8 + rax]
252
253 ;
254 ; Pass stack base and size into the PEI Core
255 ;
256 mov rcx, rcx
257 mov rdx, rbx
258
259 ;
260 ; Pass Control into the PEI Core
261 ; RCX = SizeOfRam, RDX = TempRamBase, R8 = BFV, R9 = PeiCoreEntry, Last 1 Stack = BL stack, Last 2 Stack = API index
262 ; According to X64 calling convention, caller has to allocate 32 bytes as a shadow store on call stack right before
263 ; calling the function.
264 ;
265 sub rsp, 20h
266 call ASM_PFX(SecStartup)
267 add rsp, 20h
268 exit:
269 ret
270
271 global ASM_PFX(FspPeiCoreEntryOff)
272 ASM_PFX(FspPeiCoreEntryOff):
273 ;
274 ; This value will be patched by the build script
275 ;
276 DD 0x12345678
277
278 global ASM_PFX(AsmGetPeiCoreOffset)
279 ASM_PFX(AsmGetPeiCoreOffset):
280 push rbx
281 mov rbx, ASM_PFX(FspPeiCoreEntryOff)
282 mov eax, dword[ebx]
283 pop rbx
284 ret
285
286 ;----------------------------------------------------------------------------
287 ; TempRamInit API
288 ;
289 ; Empty function for WHOLEARCHIVE build option
290 ;
291 ;----------------------------------------------------------------------------
292 global ASM_PFX(TempRamInitApi)
293 ASM_PFX(TempRamInitApi):
294 jmp $
295 ret
296
297 ;----------------------------------------------------------------------------
298 ; Module Entrypoint API
299 ;----------------------------------------------------------------------------
300 global ASM_PFX(_ModuleEntryPoint)
301 ASM_PFX(_ModuleEntryPoint):
302 jmp $
303