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