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