]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2Pkg/FspSecCore/X64/FspApiEntryM.nasm
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / X64 / FspApiEntryM.nasm
CommitLineData
00aa71ce
TK
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
a2b61de2 25 .NvsBufferPtr resq 1\r
00aa71ce
TK
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
a2b61de2 31 .Reserved1: resb 16\r
00aa71ce
TK
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
47\r
48FSP_HEADER_IMGBASE_OFFSET EQU 1Ch\r
49FSP_HEADER_CFGREG_OFFSET EQU 24h\r
50\r
51;----------------------------------------------------------------------------\r
52; FspMemoryInit API\r
53;\r
54; This FSP API is called after TempRamInit and initializes the memory.\r
55;\r
56;----------------------------------------------------------------------------\r
57global ASM_PFX(FspMemoryInitApi)\r
58ASM_PFX(FspMemoryInitApi):\r
48249243 59 mov rax, 3 ; FSP_API_INDEX.FspMemoryInitApiIndex\r
00aa71ce
TK
60 jmp ASM_PFX(FspApiCommon)\r
61\r
62;----------------------------------------------------------------------------\r
63; TempRamExitApi API\r
64;\r
65; This API tears down temporary RAM\r
66;\r
67;----------------------------------------------------------------------------\r
68global ASM_PFX(TempRamExitApi)\r
69ASM_PFX(TempRamExitApi):\r
48249243 70 mov rax, 4 ; FSP_API_INDEX.TempRamExitApiIndex\r
00aa71ce
TK
71 jmp ASM_PFX(FspApiCommon)\r
72\r
73;----------------------------------------------------------------------------\r
74; FspApiCommonContinue API\r
75;\r
76; This is the FSP API common entry point to resume the FSP execution\r
77;\r
78;----------------------------------------------------------------------------\r
79global ASM_PFX(FspApiCommonContinue)\r
80ASM_PFX(FspApiCommonContinue):\r
81 ;\r
82 ; RAX holds the API index\r
83 ; Push RDX and RCX to form CONTEXT_STACK_64\r
84 ;\r
85 push rdx ; Push a QWORD data for stack alignment\r
86 push rdx ; Push API Parameter2 on stack\r
87 push rcx ; Push API Parameter1 on stack\r
88\r
89 ;\r
90 ; FspMemoryInit API setup the initial stack frame\r
91 ;\r
92\r
93 ;\r
94 ; Place holder to store the FspInfoHeader pointer\r
95 ;\r
96 push rax\r
97\r
98 ;\r
99 ; Update the FspInfoHeader pointer\r
100 ;\r
101 push rax\r
102 call ASM_PFX(AsmGetFspInfoHeader)\r
103 mov [rsp + 8], rax\r
104 pop rax\r
105\r
106 ;\r
107 ; Create a Task Frame in the stack for the Boot Loader\r
108 ;\r
109 pushfq\r
110 cli\r
111 PUSHA_64\r
112\r
113 ; Reserve 16 bytes for IDT save/restore\r
114 sub rsp, 16\r
115 sidt [rsp]\r
116\r
117 ; Get Stackbase and StackSize from FSPM_UPD Param\r
118 mov rdx, rcx ; Put FSPM_UPD Param to rdx\r
119 cmp rdx, 0\r
120 jnz FspStackSetup\r
121\r
122 ; Get UPD default values if FspmUpdDataPtr (ApiParam1) is null\r
123 xchg rbx, rax\r
124 call ASM_PFX(AsmGetFspInfoHeader)\r
125 mov edx, [rax + FSP_HEADER_IMGBASE_OFFSET]\r
126 add edx, [rax + FSP_HEADER_CFGREG_OFFSET]\r
127 xchg rbx, rax\r
128\r
129FspStackSetup:\r
130 mov cl, [rdx + FSPM_UPD_COMMON_FSP24.Revision]\r
131 cmp cl, 3\r
132 jae FspmUpdCommonFsp24\r
133\r
134 mov rax, 08000000000000002h ; RETURN_INVALID_PARAMETER\r
135 sub rsp, 0b8h\r
136 ret\r
137\r
138FspmUpdCommonFsp24:\r
139 ;\r
140 ; StackBase = temp memory base, StackSize = temp memory size\r
141 ;\r
142 mov rdi, [rdx + FSPM_UPD_COMMON_FSP24.StackBase]\r
143 mov ecx, [rdx + FSPM_UPD_COMMON_FSP24.StackSize]\r
144\r
145 ;\r
146 ; Keep using bootloader stack if heap size % is 0\r
147 ;\r
148 mov rbx, ASM_PFX(PcdGet8 (PcdFspHeapSizePercentage))\r
149 mov bl, BYTE [rbx]\r
150 cmp bl, 0\r
151 jz SkipStackSwitch\r
152\r
153 ;\r
154 ; Set up a dedicated temp ram stack for FSP if FSP heap size % doesn't equal 0\r
155 ;\r
156 add rdi, rcx\r
157 ;\r
158 ; Switch to new FSP stack\r
159 ;\r
160 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
161\r
162SkipStackSwitch:\r
163 ;\r
164 ; If heap size % is 0:\r
165 ; EDI is FSPM_UPD_COMMON_FSP24.StackBase and will hold ESP later (boot loader stack pointer)\r
166 ; ECX is FSPM_UPD_COMMON_FSP24.StackSize\r
167 ; ESP is boot loader stack pointer (no stack switch)\r
168 ; BL is 0 to indicate no stack switch (EBX will hold FSPM_UPD_COMMON_FSP24.StackBase later)\r
169 ;\r
170 ; If heap size % is not 0\r
171 ; EDI is boot loader stack pointer\r
172 ; ECX is FSPM_UPD_COMMON_FSP24.StackSize\r
173 ; ESP is new stack (FSPM_UPD_COMMON_FSP24.StackBase + FSPM_UPD_COMMON_FSP24.StackSize)\r
174 ; BL is NOT 0 to indicate stack has switched\r
175 ;\r
176 cmp bl, 0\r
177 jnz StackHasBeenSwitched\r
178\r
179 mov rbx, rdi ; Put FSPM_UPD_COMMON_FSP24.StackBase to rbx as temp memory base\r
180 mov rdi, rsp ; Put boot loader stack pointer to rdi\r
181 jmp StackSetupDone\r
182\r
183StackHasBeenSwitched:\r
184 mov rbx, rsp ; Put Stack base + Stack size in ebx\r
185 sub rbx, rcx ; Stack base + Stack size - Stack size as temp memory base\r
186\r
187StackSetupDone:\r
188\r
189 ;\r
190 ; Per X64 calling convention, make sure RSP is 16-byte aligned.\r
191 ;\r
192 mov rdx, rsp\r
193 and rdx, 0fh\r
194 sub rsp, rdx\r
195\r
196 ;\r
197 ; Pass the API Idx to SecStartup\r
198 ;\r
199 push rax\r
200\r
201 ;\r
202 ; Pass the BootLoader stack to SecStartup\r
203 ;\r
204 push rdi\r
205\r
206 ;\r
207 ; Pass BFV into the PEI Core\r
208 ; It uses relative address to calculate the actual boot FV base\r
209 ; For FSP implementation with single FV, PcdFspBootFirmwareVolumeBase and\r
210 ; PcdFspAreaBaseAddress are the same. For FSP with multiple FVs,\r
211 ; they are different. The code below can handle both cases.\r
212 ;\r
213 call ASM_PFX(AsmGetFspBaseAddress)\r
214 mov r8, rax\r
215\r
216 ;\r
217 ; Pass entry point of the PEI core\r
218 ;\r
219 call ASM_PFX(AsmGetPeiCoreOffset)\r
220 lea r9, [r8 + rax]\r
221\r
222 ;\r
223 ; Pass stack base and size into the PEI Core\r
224 ;\r
225 mov rcx, rcx\r
226 mov rdx, rbx\r
227\r
228 ;\r
229 ; Pass Control into the PEI Core\r
230 ; RCX = SizeOfRam, RDX = TempRamBase, R8 = BFV, R9 = PeiCoreEntry, Last 1 Stack = BL stack, Last 2 Stack = API index\r
231 ; According to X64 calling convention, caller has to allocate 32 bytes as a shadow store on call stack right before\r
232 ; calling the function.\r
233 ;\r
234 sub rsp, 20h\r
235 call ASM_PFX(SecStartup)\r
236 add rsp, 20h\r
237exit:\r
238 ret\r
239\r
240global ASM_PFX(FspPeiCoreEntryOff)\r
241ASM_PFX(FspPeiCoreEntryOff):\r
242 ;\r
243 ; This value will be patched by the build script\r
244 ;\r
245 DD 0x12345678\r
246\r
247global ASM_PFX(AsmGetPeiCoreOffset)\r
248ASM_PFX(AsmGetPeiCoreOffset):\r
249 push rbx\r
250 mov rbx, ASM_PFX(FspPeiCoreEntryOff)\r
251 mov eax, dword[ebx]\r
252 pop rbx\r
253 ret\r
254\r
255;----------------------------------------------------------------------------\r
256; TempRamInit API\r
257;\r
258; Empty function for WHOLEARCHIVE build option\r
259;\r
260;----------------------------------------------------------------------------\r
261global ASM_PFX(TempRamInitApi)\r
262ASM_PFX(TempRamInitApi):\r
263 jmp $\r
264 ret\r
265\r
266;----------------------------------------------------------------------------\r
267; Module Entrypoint API\r
268;----------------------------------------------------------------------------\r
269global ASM_PFX(_ModuleEntryPoint)\r
270ASM_PFX(_ModuleEntryPoint):\r
271 jmp $\r
272\r