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