]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
IntelFsp2Pkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFsp2Pkg / Library / BaseFspCommonLib / FspCommonLib.c
CommitLineData
cf1d4549
JY
1/** @file\r
2\r
35897da2 3 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>\r
9672cd30 4 SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf1d4549
JY
5\r
6**/\r
7\r
8#include <PiPei.h>\r
9#include <Library/BaseLib.h>\r
10#include <Library/DebugLib.h>\r
11#include <Library/PcdLib.h>\r
12#include <FspGlobalData.h>\r
13#include <FspEas.h>\r
6b5677e1 14#include <Library/FspSwitchStackLib.h>\r
cf1d4549
JY
15\r
16#pragma pack(1)\r
17\r
18//\r
19// API Parameter +0x34\r
20// API return address +0x30\r
21//\r
22// push FspInfoHeader +0x2C\r
23// pushfd +0x28\r
24// cli\r
25// pushad +0x24\r
26// sub esp, 8 +0x00\r
27// sidt fword ptr [esp]\r
28//\r
29typedef struct {\r
30 UINT16 IdtrLimit;\r
31 UINT32 IdtrBase;\r
32 UINT16 Reserved;\r
33 UINT32 Edi;\r
34 UINT32 Esi;\r
35 UINT32 Ebp;\r
36 UINT32 Esp;\r
37 UINT32 Ebx;\r
38 UINT32 Edx;\r
39 UINT32 Ecx;\r
40 UINT32 Eax;\r
41 UINT16 Flags[2];\r
42 UINT32 FspInfoHeader;\r
43 UINT32 ApiRet;\r
44 UINT32 ApiParam[2];\r
45} CONTEXT_STACK;\r
46\r
47#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x\r
48\r
49#pragma pack()\r
50\r
51/**\r
52 This function sets the FSP global data pointer.\r
53\r
86079a4d 54 @param[in] FspData FSP global data pointer.\r
cf1d4549
JY
55\r
56**/\r
57VOID\r
58EFIAPI\r
59SetFspGlobalDataPointer (\r
60 IN FSP_GLOBAL_DATA *FspData\r
61 )\r
62{\r
63 ASSERT (FspData != NULL);\r
64 *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;\r
65}\r
66\r
67/**\r
68 This function gets the FSP global data pointer.\r
69\r
70**/\r
71FSP_GLOBAL_DATA *\r
72EFIAPI\r
73GetFspGlobalDataPointer (\r
74 VOID\r
75 )\r
76{\r
77 FSP_GLOBAL_DATA *FspData;\r
78\r
79 FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);\r
80 return FspData;\r
81}\r
82\r
83/**\r
35897da2 84 This function gets back the FSP API first parameter passed by the bootloader.\r
cf1d4549 85\r
35897da2 86 @retval ApiParameter FSP API first parameter passed by the bootloader.\r
cf1d4549
JY
87**/\r
88UINT32\r
89EFIAPI\r
90GetFspApiParameter (\r
91 VOID\r
92 )\r
93{\r
94 FSP_GLOBAL_DATA *FspData;\r
95\r
96 FspData = GetFspGlobalDataPointer ();\r
97 return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0]));\r
98}\r
99\r
100/**\r
35897da2 101 This function returns the FSP entry stack pointer from address of the first API parameter.\r
cf1d4549 102\r
35897da2
CC
103 @retval FSP entry stack pointer.\r
104**/\r
105VOID*\r
106EFIAPI\r
107GetFspEntryStack (\r
108 VOID\r
109 )\r
110{\r
111 FSP_GLOBAL_DATA *FspData;\r
112\r
113 FspData = GetFspGlobalDataPointer ();\r
114 return (VOID*)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0]));\r
115}\r
116\r
117/**\r
118 This function gets back the FSP API second parameter passed by the bootloader.\r
119\r
120 @retval ApiParameter FSP API second parameter passed by the bootloader.\r
cf1d4549
JY
121**/\r
122UINT32\r
123EFIAPI\r
124GetFspApiParameter2 (\r
125 VOID\r
126 )\r
127{\r
128 FSP_GLOBAL_DATA *FspData;\r
129\r
130 FspData = GetFspGlobalDataPointer ();\r
131 return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[1]));\r
132}\r
133\r
134/**\r
135 This function sets the FSP API parameter in the stack.\r
136\r
137 @param[in] Value New parameter value.\r
138\r
139**/\r
140VOID\r
141EFIAPI\r
142SetFspApiParameter (\r
143 IN UINT32 Value\r
144 )\r
145{\r
146 FSP_GLOBAL_DATA *FspData;\r
147\r
148 FspData = GetFspGlobalDataPointer ();\r
149 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;\r
150}\r
151\r
152/**\r
153 This function set the API status code returned to the BootLoader.\r
154\r
155 @param[in] ReturnStatus Status code to return.\r
156\r
157**/\r
158VOID\r
159EFIAPI\r
160SetFspApiReturnStatus (\r
161 IN UINT32 ReturnStatus\r
162 )\r
163{\r
164 FSP_GLOBAL_DATA *FspData;\r
165\r
166 FspData = GetFspGlobalDataPointer ();\r
167 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;\r
168}\r
169\r
170/**\r
171 This function sets the context switching stack to a new stack frame.\r
172\r
173 @param[in] NewStackTop New core stack to be set.\r
174\r
175**/\r
176VOID\r
177EFIAPI\r
178SetFspCoreStackPointer (\r
179 IN VOID *NewStackTop\r
180 )\r
181{\r
182 FSP_GLOBAL_DATA *FspData;\r
183 UINT32 *OldStack;\r
184 UINT32 *NewStack;\r
185 UINT32 StackContextLen;\r
186\r
187 FspData = GetFspGlobalDataPointer ();\r
188 StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);\r
189\r
190 //\r
191 // Reserve space for the ContinuationFunc two parameters\r
192 //\r
193 OldStack = (UINT32 *)FspData->CoreStack;\r
194 NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;\r
195 FspData->CoreStack = (UINT32)NewStack;\r
196 while (StackContextLen-- != 0) {\r
197 *NewStack++ = *OldStack++;\r
198 }\r
199}\r
200\r
201/**\r
202 This function sets the platform specific data pointer.\r
203\r
86079a4d 204 @param[in] PlatformData FSP platform specific data pointer.\r
cf1d4549
JY
205\r
206**/\r
207VOID\r
208EFIAPI\r
209SetFspPlatformDataPointer (\r
210 IN VOID *PlatformData\r
211 )\r
212{\r
213 FSP_GLOBAL_DATA *FspData;\r
214\r
215 FspData = GetFspGlobalDataPointer ();\r
216 FspData->PlatformData.DataPtr = PlatformData;\r
217}\r
218\r
219\r
220/**\r
221 This function gets the platform specific data pointer.\r
222\r
86079a4d 223 @param[in] PlatformData FSP platform specific data pointer.\r
cf1d4549
JY
224\r
225**/\r
226VOID *\r
227EFIAPI\r
228GetFspPlatformDataPointer (\r
229 VOID\r
230 )\r
231{\r
232 FSP_GLOBAL_DATA *FspData;\r
233\r
234 FspData = GetFspGlobalDataPointer ();\r
235 return FspData->PlatformData.DataPtr;\r
236}\r
237\r
238\r
239/**\r
240 This function sets the UPD data pointer.\r
241\r
242 @param[in] UpdDataPtr UPD data pointer.\r
243**/\r
244VOID\r
245EFIAPI\r
246SetFspUpdDataPointer (\r
247 IN VOID *UpdDataPtr\r
248 )\r
249{\r
250 FSP_GLOBAL_DATA *FspData;\r
251\r
252 //\r
86079a4d 253 // Get the FSP Global Data Pointer\r
cf1d4549
JY
254 //\r
255 FspData = GetFspGlobalDataPointer ();\r
256\r
257 //\r
258 // Set the UPD pointer.\r
259 //\r
260 FspData->UpdDataPtr = UpdDataPtr;\r
261}\r
262\r
263/**\r
264 This function gets the UPD data pointer.\r
265\r
266 @return UpdDataPtr UPD data pointer.\r
267**/\r
268VOID *\r
269EFIAPI\r
270GetFspUpdDataPointer (\r
271 VOID\r
272 )\r
273{\r
274 FSP_GLOBAL_DATA *FspData;\r
275\r
276 FspData = GetFspGlobalDataPointer ();\r
277 return FspData->UpdDataPtr;\r
278}\r
279\r
280\r
281/**\r
86079a4d 282 This function sets the FspMemoryInit UPD data pointer.\r
cf1d4549 283\r
86079a4d 284 @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.\r
cf1d4549
JY
285**/\r
286VOID\r
287EFIAPI\r
288SetFspMemoryInitUpdDataPointer (\r
289 IN VOID *MemoryInitUpdPtr\r
290 )\r
291{\r
292 FSP_GLOBAL_DATA *FspData;\r
293\r
294 //\r
86079a4d 295 // Get the FSP Global Data Pointer\r
cf1d4549
JY
296 //\r
297 FspData = GetFspGlobalDataPointer ();\r
298\r
299 //\r
86079a4d 300 // Set the FspMemoryInit UPD pointer.\r
cf1d4549
JY
301 //\r
302 FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;\r
303}\r
304\r
305/**\r
86079a4d 306 This function gets the FspMemoryInit UPD data pointer.\r
cf1d4549 307\r
86079a4d 308 @return FspMemoryInit UPD data pointer.\r
cf1d4549
JY
309**/\r
310VOID *\r
311EFIAPI\r
312GetFspMemoryInitUpdDataPointer (\r
313 VOID\r
314 )\r
315{\r
316 FSP_GLOBAL_DATA *FspData;\r
317\r
318 FspData = GetFspGlobalDataPointer ();\r
319 return FspData->MemoryInitUpdPtr;\r
320}\r
321\r
322\r
323/**\r
86079a4d 324 This function sets the FspSiliconInit UPD data pointer.\r
cf1d4549 325\r
86079a4d 326 @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.\r
cf1d4549
JY
327**/\r
328VOID\r
329EFIAPI\r
330SetFspSiliconInitUpdDataPointer (\r
331 IN VOID *SiliconInitUpdPtr\r
332 )\r
333{\r
334 FSP_GLOBAL_DATA *FspData;\r
335\r
336 //\r
86079a4d 337 // Get the FSP Global Data Pointer\r
cf1d4549
JY
338 //\r
339 FspData = GetFspGlobalDataPointer ();\r
340\r
341 //\r
86079a4d 342 // Set the FspSiliconInit UPD data pointer.\r
cf1d4549
JY
343 //\r
344 FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;\r
345}\r
346\r
347/**\r
86079a4d 348 This function gets the FspSiliconInit UPD data pointer.\r
cf1d4549 349\r
86079a4d 350 @return FspSiliconInit UPD data pointer.\r
cf1d4549
JY
351**/\r
352VOID *\r
353EFIAPI\r
354GetFspSiliconInitUpdDataPointer (\r
355 VOID\r
356 )\r
357{\r
358 FSP_GLOBAL_DATA *FspData;\r
359\r
360 FspData = GetFspGlobalDataPointer ();\r
361 return FspData->SiliconInitUpdPtr;\r
362}\r
363\r
364\r
365/**\r
366 Set FSP measurement point timestamp.\r
367\r
368 @param[in] Id Measurement point ID.\r
369\r
370 @return performance timestamp.\r
371**/\r
372UINT64\r
373EFIAPI\r
374SetFspMeasurePoint (\r
375 IN UINT8 Id\r
376 )\r
377{\r
378 FSP_GLOBAL_DATA *FspData;\r
379\r
380 //\r
381 // Bit [55: 0] will be the timestamp\r
382 // Bit [63:56] will be the ID\r
383 //\r
384 FspData = GetFspGlobalDataPointer ();\r
385 if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {\r
386 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();\r
387 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;\r
388 }\r
389\r
390 return FspData->PerfData[(FspData->PerfIdx)++];\r
391}\r
392\r
393/**\r
394 This function gets the FSP info header pointer.\r
395\r
396 @retval FspInfoHeader FSP info header pointer\r
397**/\r
398FSP_INFO_HEADER *\r
399EFIAPI\r
400GetFspInfoHeader (\r
401 VOID\r
402 )\r
403{\r
404 return GetFspGlobalDataPointer()->FspInfoHeader;\r
405}\r
406\r
407/**\r
408 This function sets the FSP info header pointer.\r
409\r
410 @param[in] FspInfoHeader FSP info header pointer\r
411**/\r
412VOID\r
413EFIAPI\r
414SetFspInfoHeader (\r
415 FSP_INFO_HEADER *FspInfoHeader\r
416 )\r
417{\r
418 GetFspGlobalDataPointer()->FspInfoHeader = FspInfoHeader;\r
419}\r
420\r
421/**\r
422 This function gets the FSP info header pointer using the API stack context.\r
423\r
424 @retval FspInfoHeader FSP info header pointer using the API stack context\r
425**/\r
426FSP_INFO_HEADER *\r
427EFIAPI\r
428GetFspInfoHeaderFromApiContext (\r
429 VOID\r
430 )\r
431{\r
432 FSP_GLOBAL_DATA *FspData;\r
433\r
434 FspData = GetFspGlobalDataPointer ();\r
435 return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader)));\r
436}\r
437\r
438/**\r
cc0b456a 439 This function gets the CfgRegion data pointer.\r
cf1d4549 440\r
cc0b456a 441 @return CfgRegion data pointer.\r
cf1d4549
JY
442**/\r
443VOID *\r
444EFIAPI\r
cc0b456a 445GetFspCfgRegionDataPointer (\r
cf1d4549
JY
446 VOID\r
447 )\r
448{\r
449 FSP_INFO_HEADER *FspInfoHeader;\r
450\r
451 FspInfoHeader = GetFspInfoHeader ();\r
452 return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);\r
453}\r
454\r
455/**\r
456 This function gets FSP API calling index.\r
457\r
458 @retval API calling index\r
459**/\r
460UINT8\r
461EFIAPI\r
462GetFspApiCallingIndex (\r
463 VOID\r
464 )\r
465{\r
466 return GetFspGlobalDataPointer()->ApiIdx;\r
467}\r
468\r
469/**\r
470 This function sets FSP API calling mode.\r
471\r
472 @param[in] Index API calling index\r
473**/\r
474VOID\r
475EFIAPI\r
476SetFspApiCallingIndex (\r
477 UINT8 Index\r
478 )\r
479{\r
480 FSP_GLOBAL_DATA *FspData;\r
481\r
482 FspData = GetFspGlobalDataPointer ();\r
483 FspData->ApiIdx = Index;\r
484}\r
485\r
486/**\r
487 This function gets FSP Phase StatusCode.\r
488\r
489 @retval StatusCode\r
490**/\r
491UINT32\r
492EFIAPI\r
493GetPhaseStatusCode (\r
494 VOID\r
495 )\r
496{\r
497 return GetFspGlobalDataPointer()->StatusCode;\r
498}\r
499\r
500/**\r
501 This function sets FSP Phase StatusCode.\r
502\r
503 @param[in] Mode Phase StatusCode\r
504**/\r
505VOID\r
506EFIAPI\r
507SetPhaseStatusCode (\r
508 UINT32 StatusCode\r
509 )\r
510{\r
511 FSP_GLOBAL_DATA *FspData;\r
512\r
513 FspData = GetFspGlobalDataPointer ();\r
514 FspData->StatusCode = StatusCode;\r
515}\r
516\r
6b5677e1
YS
517/**\r
518 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.\r
519\r
520 @param[in] FspResetType Reset type that needs to returned as API return status\r
521\r
522**/\r
523VOID\r
524EFIAPI\r
525FspApiReturnStatusReset (\r
526 IN UINT32 FspResetType\r
527 )\r
528{\r
529 volatile BOOLEAN LoopUntilReset;\r
e37bb20c 530\r
6b5677e1
YS
531 LoopUntilReset = TRUE;\r
532 DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n",FspResetType));\r
a2e61f34
CC
533 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {\r
534 ///\r
535 /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader\r
536 /// calls the FSP API without honoring the reset request by FSP\r
537 ///\r
538 do {\r
539 SetFspApiReturnStatus ((EFI_STATUS)FspResetType);\r
540 Pei2LoaderSwitchStack ();\r
541 DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));\r
542 DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));\r
543 } while (LoopUntilReset);\r
544 }\r
6b5677e1 545}\r