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