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