IntelFsp2Pkg: Removing FSP Data Table
[mirror_edk2.git] / IntelFsp2Pkg / Library / BaseFspCommonLib / FspCommonLib.c
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
20 #include <Library/FspSwitchStackLib.h>\r
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
35 typedef 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
60   @param[in] FspData       FSP global data pointer.\r
61 \r
62 **/\r
63 VOID\r
64 EFIAPI\r
65 SetFspGlobalDataPointer (\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
77 FSP_GLOBAL_DATA *\r
78 EFIAPI\r
79 GetFspGlobalDataPointer (\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
94 UINT32\r
95 EFIAPI\r
96 GetFspApiParameter (\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
111 UINT32\r
112 EFIAPI\r
113 GetFspApiParameter2 (\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
129 VOID\r
130 EFIAPI\r
131 SetFspApiParameter (\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
147 VOID\r
148 EFIAPI\r
149 SetFspApiReturnStatus (\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
165 VOID\r
166 EFIAPI\r
167 SetFspCoreStackPointer (\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
193   @param[in] PlatformData       FSP platform specific data pointer.\r
194 \r
195 **/\r
196 VOID\r
197 EFIAPI\r
198 SetFspPlatformDataPointer (\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
212    @param[in] PlatformData       FSP platform specific data pointer.\r
213 \r
214 **/\r
215 VOID *\r
216 EFIAPI\r
217 GetFspPlatformDataPointer (\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
233 VOID\r
234 EFIAPI\r
235 SetFspUpdDataPointer (\r
236   IN VOID    *UpdDataPtr\r
237   )\r
238 {\r
239   FSP_GLOBAL_DATA  *FspData;\r
240 \r
241   //\r
242   // Get the FSP Global Data Pointer\r
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
257 VOID *\r
258 EFIAPI\r
259 GetFspUpdDataPointer (\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
271   This function sets the FspMemoryInit UPD data pointer.\r
272 \r
273   @param[in] MemoryInitUpdPtr   FspMemoryInit UPD data pointer.\r
274 **/\r
275 VOID\r
276 EFIAPI\r
277 SetFspMemoryInitUpdDataPointer (\r
278   IN VOID    *MemoryInitUpdPtr\r
279   )\r
280 {\r
281   FSP_GLOBAL_DATA  *FspData;\r
282 \r
283   //\r
284   // Get the FSP Global Data Pointer\r
285   //\r
286   FspData  = GetFspGlobalDataPointer ();\r
287 \r
288   //\r
289   // Set the FspMemoryInit UPD pointer.\r
290   //\r
291   FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;\r
292 }\r
293 \r
294 /**\r
295   This function gets the FspMemoryInit UPD data pointer.\r
296 \r
297   @return FspMemoryInit UPD data pointer.\r
298 **/\r
299 VOID *\r
300 EFIAPI\r
301 GetFspMemoryInitUpdDataPointer (\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
313   This function sets the FspSiliconInit UPD data pointer.\r
314 \r
315   @param[in] SiliconInitUpdPtr   FspSiliconInit UPD data pointer.\r
316 **/\r
317 VOID\r
318 EFIAPI\r
319 SetFspSiliconInitUpdDataPointer (\r
320   IN VOID    *SiliconInitUpdPtr\r
321   )\r
322 {\r
323   FSP_GLOBAL_DATA  *FspData;\r
324 \r
325   //\r
326   // Get the FSP Global Data Pointer\r
327   //\r
328   FspData  = GetFspGlobalDataPointer ();\r
329 \r
330   //\r
331   // Set the FspSiliconInit UPD data pointer.\r
332   //\r
333   FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;\r
334 }\r
335 \r
336 /**\r
337   This function gets the FspSiliconInit UPD data pointer.\r
338 \r
339   @return FspSiliconInit UPD data pointer.\r
340 **/\r
341 VOID *\r
342 EFIAPI\r
343 GetFspSiliconInitUpdDataPointer (\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
361 UINT64\r
362 EFIAPI\r
363 SetFspMeasurePoint (\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
387 FSP_INFO_HEADER *\r
388 EFIAPI\r
389 GetFspInfoHeader (\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
401 VOID\r
402 EFIAPI\r
403 SetFspInfoHeader (\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
415 FSP_INFO_HEADER *\r
416 EFIAPI\r
417 GetFspInfoHeaderFromApiContext (\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
428   This function gets the CfgRegion data pointer.\r
429 \r
430   @return CfgRegion data pointer.\r
431 **/\r
432 VOID *\r
433 EFIAPI\r
434 GetFspCfgRegionDataPointer (\r
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
449 UINT8\r
450 EFIAPI\r
451 GetFspApiCallingIndex (\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
463 VOID\r
464 EFIAPI\r
465 SetFspApiCallingIndex (\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
480 UINT32\r
481 EFIAPI\r
482 GetPhaseStatusCode (\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
494 VOID\r
495 EFIAPI\r
496 SetPhaseStatusCode (\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
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
512 VOID\r
513 EFIAPI\r
514 FspApiReturnStatusReset (\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
530     DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));\r
531   } while (LoopUntilReset);\r
532 }\r