3 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Library/BaseLib.h>
10 #include <Library/DebugLib.h>
11 #include <Library/PcdLib.h>
12 #include <FspGlobalData.h>
14 #include <Library/FspSwitchStackLib.h>
19 // API Parameter +0x34
20 // API return address +0x30
22 // push FspInfoHeader +0x2C
27 // sidt fword ptr [esp]
47 #define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x
52 This function sets the FSP global data pointer.
54 @param[in] FspData FSP global data pointer.
59 SetFspGlobalDataPointer (
60 IN FSP_GLOBAL_DATA
*FspData
63 ASSERT (FspData
!= NULL
);
64 *((volatile UINT32
*)(UINTN
)PcdGet32 (PcdGlobalDataPointerAddress
)) = (UINT32
)(UINTN
)FspData
;
68 This function gets the FSP global data pointer.
73 GetFspGlobalDataPointer (
77 FSP_GLOBAL_DATA
*FspData
;
79 FspData
= *(FSP_GLOBAL_DATA
**)(UINTN
)PcdGet32 (PcdGlobalDataPointerAddress
);
84 This function gets back the FSP API first parameter passed by the bootloader.
86 @retval ApiParameter FSP API first parameter passed by the bootloader.
94 FSP_GLOBAL_DATA
*FspData
;
96 FspData
= GetFspGlobalDataPointer ();
97 return *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[0]));
101 This function returns the FSP entry stack pointer from address of the first API parameter.
103 @retval FSP entry stack pointer.
111 FSP_GLOBAL_DATA
*FspData
;
113 FspData
= GetFspGlobalDataPointer ();
114 return (VOID
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[0]));
118 This function gets back the FSP API second parameter passed by the bootloader.
120 @retval ApiParameter FSP API second parameter passed by the bootloader.
124 GetFspApiParameter2 (
128 FSP_GLOBAL_DATA
*FspData
;
130 FspData
= GetFspGlobalDataPointer ();
131 return *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[1]));
135 This function sets the FSP API parameter in the stack.
137 @param[in] Value New parameter value.
146 FSP_GLOBAL_DATA
*FspData
;
148 FspData
= GetFspGlobalDataPointer ();
149 *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
)) = Value
;
153 This function set the API status code returned to the BootLoader.
155 @param[in] ReturnStatus Status code to return.
160 SetFspApiReturnStatus (
161 IN UINT32 ReturnStatus
164 FSP_GLOBAL_DATA
*FspData
;
166 FspData
= GetFspGlobalDataPointer ();
167 *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (Eax
)) = ReturnStatus
;
171 This function sets the context switching stack to a new stack frame.
173 @param[in] NewStackTop New core stack to be set.
178 SetFspCoreStackPointer (
182 FSP_GLOBAL_DATA
*FspData
;
185 UINT32 StackContextLen
;
187 FspData
= GetFspGlobalDataPointer ();
188 StackContextLen
= sizeof (CONTEXT_STACK
) / sizeof (UINT32
);
191 // Reserve space for the ContinuationFunc two parameters
193 OldStack
= (UINT32
*)FspData
->CoreStack
;
194 NewStack
= (UINT32
*)NewStackTop
- StackContextLen
- 2;
195 FspData
->CoreStack
= (UINT32
)NewStack
;
196 while (StackContextLen
-- != 0) {
197 *NewStack
++ = *OldStack
++;
202 This function sets the platform specific data pointer.
204 @param[in] PlatformData FSP platform specific data pointer.
209 SetFspPlatformDataPointer (
210 IN VOID
*PlatformData
213 FSP_GLOBAL_DATA
*FspData
;
215 FspData
= GetFspGlobalDataPointer ();
216 FspData
->PlatformData
.DataPtr
= PlatformData
;
220 This function gets the platform specific data pointer.
222 @param[in] PlatformData FSP platform specific data pointer.
227 GetFspPlatformDataPointer (
231 FSP_GLOBAL_DATA
*FspData
;
233 FspData
= GetFspGlobalDataPointer ();
234 return FspData
->PlatformData
.DataPtr
;
238 This function sets the UPD data pointer.
240 @param[in] UpdDataPtr UPD data pointer.
244 SetFspUpdDataPointer (
248 FSP_GLOBAL_DATA
*FspData
;
251 // Get the FSP Global Data Pointer
253 FspData
= GetFspGlobalDataPointer ();
256 // Set the UPD pointer.
258 FspData
->UpdDataPtr
= UpdDataPtr
;
262 This function gets the UPD data pointer.
264 @return UpdDataPtr UPD data pointer.
268 GetFspUpdDataPointer (
272 FSP_GLOBAL_DATA
*FspData
;
274 FspData
= GetFspGlobalDataPointer ();
275 return FspData
->UpdDataPtr
;
279 This function sets the FspMemoryInit UPD data pointer.
281 @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
285 SetFspMemoryInitUpdDataPointer (
286 IN VOID
*MemoryInitUpdPtr
289 FSP_GLOBAL_DATA
*FspData
;
292 // Get the FSP Global Data Pointer
294 FspData
= GetFspGlobalDataPointer ();
297 // Set the FspMemoryInit UPD pointer.
299 FspData
->MemoryInitUpdPtr
= MemoryInitUpdPtr
;
303 This function gets the FspMemoryInit UPD data pointer.
305 @return FspMemoryInit UPD data pointer.
309 GetFspMemoryInitUpdDataPointer (
313 FSP_GLOBAL_DATA
*FspData
;
315 FspData
= GetFspGlobalDataPointer ();
316 return FspData
->MemoryInitUpdPtr
;
320 This function sets the FspSiliconInit UPD data pointer.
322 @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
326 SetFspSiliconInitUpdDataPointer (
327 IN VOID
*SiliconInitUpdPtr
330 FSP_GLOBAL_DATA
*FspData
;
333 // Get the FSP Global Data Pointer
335 FspData
= GetFspGlobalDataPointer ();
338 // Set the FspSiliconInit UPD data pointer.
340 FspData
->SiliconInitUpdPtr
= SiliconInitUpdPtr
;
344 This function gets the FspSiliconInit UPD data pointer.
346 @return FspSiliconInit UPD data pointer.
350 GetFspSiliconInitUpdDataPointer (
354 FSP_GLOBAL_DATA
*FspData
;
356 FspData
= GetFspGlobalDataPointer ();
357 return FspData
->SiliconInitUpdPtr
;
361 Set FSP measurement point timestamp.
363 @param[in] Id Measurement point ID.
365 @return performance timestamp.
373 FSP_GLOBAL_DATA
*FspData
;
376 // Bit [55: 0] will be the timestamp
377 // Bit [63:56] will be the ID
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
;
385 return FspData
->PerfData
[(FspData
->PerfIdx
)++];
389 This function gets the FSP info header pointer.
391 @retval FspInfoHeader FSP info header pointer
399 return GetFspGlobalDataPointer ()->FspInfoHeader
;
403 This function sets the FSP info header pointer.
405 @param[in] FspInfoHeader FSP info header pointer
410 FSP_INFO_HEADER
*FspInfoHeader
413 GetFspGlobalDataPointer ()->FspInfoHeader
= FspInfoHeader
;
417 This function gets the FSP info header pointer using the API stack context.
419 @retval FspInfoHeader FSP info header pointer using the API stack context
423 GetFspInfoHeaderFromApiContext (
427 FSP_GLOBAL_DATA
*FspData
;
429 FspData
= GetFspGlobalDataPointer ();
430 return (FSP_INFO_HEADER
*)(*(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (FspInfoHeader
)));
434 This function gets the CfgRegion data pointer.
436 @return CfgRegion data pointer.
440 GetFspCfgRegionDataPointer (
444 FSP_INFO_HEADER
*FspInfoHeader
;
446 FspInfoHeader
= GetFspInfoHeader ();
447 return (VOID
*)(FspInfoHeader
->ImageBase
+ FspInfoHeader
->CfgRegionOffset
);
451 This function gets FSP API calling index.
453 @retval API calling index
457 GetFspApiCallingIndex (
461 return GetFspGlobalDataPointer ()->ApiIdx
;
465 This function sets FSP API calling mode.
467 @param[in] Index API calling index
471 SetFspApiCallingIndex (
475 FSP_GLOBAL_DATA
*FspData
;
477 FspData
= GetFspGlobalDataPointer ();
478 FspData
->ApiIdx
= Index
;
482 This function gets FSP Phase StatusCode.
492 return GetFspGlobalDataPointer ()->StatusCode
;
496 This function sets FSP Phase StatusCode.
498 @param[in] Mode Phase StatusCode
506 FSP_GLOBAL_DATA
*FspData
;
508 FspData
= GetFspGlobalDataPointer ();
509 FspData
->StatusCode
= StatusCode
;
513 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
515 @param[in] FspResetType Reset type that needs to returned as API return status
520 FspApiReturnStatusReset (
521 IN UINT32 FspResetType
524 volatile BOOLEAN LoopUntilReset
;
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
) {
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
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
);