]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
8f8453915e3b43c29c281838d132d2ad63942cb9
[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 This function gets the platform specific data pointer.
221
222 @param[in] PlatformData FSP platform specific data pointer.
223
224 **/
225 VOID *
226 EFIAPI
227 GetFspPlatformDataPointer (
228 VOID
229 )
230 {
231 FSP_GLOBAL_DATA *FspData;
232
233 FspData = GetFspGlobalDataPointer ();
234 return FspData->PlatformData.DataPtr;
235 }
236
237 /**
238 This function sets the UPD data pointer.
239
240 @param[in] UpdDataPtr UPD data pointer.
241 **/
242 VOID
243 EFIAPI
244 SetFspUpdDataPointer (
245 IN VOID *UpdDataPtr
246 )
247 {
248 FSP_GLOBAL_DATA *FspData;
249
250 //
251 // Get the FSP Global Data Pointer
252 //
253 FspData = GetFspGlobalDataPointer ();
254
255 //
256 // Set the UPD pointer.
257 //
258 FspData->UpdDataPtr = UpdDataPtr;
259 }
260
261 /**
262 This function gets the UPD data pointer.
263
264 @return UpdDataPtr UPD data pointer.
265 **/
266 VOID *
267 EFIAPI
268 GetFspUpdDataPointer (
269 VOID
270 )
271 {
272 FSP_GLOBAL_DATA *FspData;
273
274 FspData = GetFspGlobalDataPointer ();
275 return FspData->UpdDataPtr;
276 }
277
278 /**
279 This function sets the FspMemoryInit UPD data pointer.
280
281 @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
282 **/
283 VOID
284 EFIAPI
285 SetFspMemoryInitUpdDataPointer (
286 IN VOID *MemoryInitUpdPtr
287 )
288 {
289 FSP_GLOBAL_DATA *FspData;
290
291 //
292 // Get the FSP Global Data Pointer
293 //
294 FspData = GetFspGlobalDataPointer ();
295
296 //
297 // Set the FspMemoryInit UPD pointer.
298 //
299 FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;
300 }
301
302 /**
303 This function gets the FspMemoryInit UPD data pointer.
304
305 @return FspMemoryInit UPD data pointer.
306 **/
307 VOID *
308 EFIAPI
309 GetFspMemoryInitUpdDataPointer (
310 VOID
311 )
312 {
313 FSP_GLOBAL_DATA *FspData;
314
315 FspData = GetFspGlobalDataPointer ();
316 return FspData->MemoryInitUpdPtr;
317 }
318
319 /**
320 This function sets the FspSiliconInit UPD data pointer.
321
322 @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
323 **/
324 VOID
325 EFIAPI
326 SetFspSiliconInitUpdDataPointer (
327 IN VOID *SiliconInitUpdPtr
328 )
329 {
330 FSP_GLOBAL_DATA *FspData;
331
332 //
333 // Get the FSP Global Data Pointer
334 //
335 FspData = GetFspGlobalDataPointer ();
336
337 //
338 // Set the FspSiliconInit UPD data pointer.
339 //
340 FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;
341 }
342
343 /**
344 This function gets the FspSiliconInit UPD data pointer.
345
346 @return FspSiliconInit UPD data pointer.
347 **/
348 VOID *
349 EFIAPI
350 GetFspSiliconInitUpdDataPointer (
351 VOID
352 )
353 {
354 FSP_GLOBAL_DATA *FspData;
355
356 FspData = GetFspGlobalDataPointer ();
357 return FspData->SiliconInitUpdPtr;
358 }
359
360 /**
361 Set FSP measurement point timestamp.
362
363 @param[in] Id Measurement point ID.
364
365 @return performance timestamp.
366 **/
367 UINT64
368 EFIAPI
369 SetFspMeasurePoint (
370 IN UINT8 Id
371 )
372 {
373 FSP_GLOBAL_DATA *FspData;
374
375 //
376 // Bit [55: 0] will be the timestamp
377 // Bit [63:56] will be the ID
378 //
379 FspData = GetFspGlobalDataPointer ();
380 if (FspData->PerfIdx < sizeof (FspData->PerfData) / sizeof (FspData->PerfData[0])) {
381 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
382 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
383 }
384
385 return FspData->PerfData[(FspData->PerfIdx)++];
386 }
387
388 /**
389 This function gets the FSP info header pointer.
390
391 @retval FspInfoHeader FSP info header pointer
392 **/
393 FSP_INFO_HEADER *
394 EFIAPI
395 GetFspInfoHeader (
396 VOID
397 )
398 {
399 return GetFspGlobalDataPointer ()->FspInfoHeader;
400 }
401
402 /**
403 This function sets the FSP info header pointer.
404
405 @param[in] FspInfoHeader FSP info header pointer
406 **/
407 VOID
408 EFIAPI
409 SetFspInfoHeader (
410 FSP_INFO_HEADER *FspInfoHeader
411 )
412 {
413 GetFspGlobalDataPointer ()->FspInfoHeader = FspInfoHeader;
414 }
415
416 /**
417 This function gets the FSP info header pointer using the API stack context.
418
419 @retval FspInfoHeader FSP info header pointer using the API stack context
420 **/
421 FSP_INFO_HEADER *
422 EFIAPI
423 GetFspInfoHeaderFromApiContext (
424 VOID
425 )
426 {
427 FSP_GLOBAL_DATA *FspData;
428
429 FspData = GetFspGlobalDataPointer ();
430 return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET (FspInfoHeader)));
431 }
432
433 /**
434 This function gets the CfgRegion data pointer.
435
436 @return CfgRegion data pointer.
437 **/
438 VOID *
439 EFIAPI
440 GetFspCfgRegionDataPointer (
441 VOID
442 )
443 {
444 FSP_INFO_HEADER *FspInfoHeader;
445
446 FspInfoHeader = GetFspInfoHeader ();
447 return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
448 }
449
450 /**
451 This function gets FSP API calling index.
452
453 @retval API calling index
454 **/
455 UINT8
456 EFIAPI
457 GetFspApiCallingIndex (
458 VOID
459 )
460 {
461 return GetFspGlobalDataPointer ()->ApiIdx;
462 }
463
464 /**
465 This function sets FSP API calling mode.
466
467 @param[in] Index API calling index
468 **/
469 VOID
470 EFIAPI
471 SetFspApiCallingIndex (
472 UINT8 Index
473 )
474 {
475 FSP_GLOBAL_DATA *FspData;
476
477 FspData = GetFspGlobalDataPointer ();
478 FspData->ApiIdx = Index;
479 }
480
481 /**
482 This function gets FSP Phase StatusCode.
483
484 @retval StatusCode
485 **/
486 UINT32
487 EFIAPI
488 GetPhaseStatusCode (
489 VOID
490 )
491 {
492 return GetFspGlobalDataPointer ()->StatusCode;
493 }
494
495 /**
496 This function sets FSP Phase StatusCode.
497
498 @param[in] Mode Phase StatusCode
499 **/
500 VOID
501 EFIAPI
502 SetPhaseStatusCode (
503 UINT32 StatusCode
504 )
505 {
506 FSP_GLOBAL_DATA *FspData;
507
508 FspData = GetFspGlobalDataPointer ();
509 FspData->StatusCode = StatusCode;
510 }
511
512 /**
513 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
514
515 @param[in] FspResetType Reset type that needs to returned as API return status
516
517 **/
518 VOID
519 EFIAPI
520 FspApiReturnStatusReset (
521 IN UINT32 FspResetType
522 )
523 {
524 volatile BOOLEAN LoopUntilReset;
525
526 LoopUntilReset = TRUE;
527 DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n", FspResetType));
528 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
529 ///
530 /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
531 /// calls the FSP API without honoring the reset request by FSP
532 ///
533 do {
534 SetFspApiReturnStatus ((EFI_STATUS)FspResetType);
535 Pei2LoaderSwitchStack ();
536 DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
537 DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
538 } while (LoopUntilReset);
539 }
540 }