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
;
221 This function gets the platform specific data pointer.
223 @param[in] PlatformData FSP platform specific data pointer.
228 GetFspPlatformDataPointer (
232 FSP_GLOBAL_DATA
*FspData
;
234 FspData
= GetFspGlobalDataPointer ();
235 return FspData
->PlatformData
.DataPtr
;
240 This function sets the UPD data pointer.
242 @param[in] UpdDataPtr UPD data pointer.
246 SetFspUpdDataPointer (
250 FSP_GLOBAL_DATA
*FspData
;
253 // Get the FSP Global Data Pointer
255 FspData
= GetFspGlobalDataPointer ();
258 // Set the UPD pointer.
260 FspData
->UpdDataPtr
= UpdDataPtr
;
264 This function gets the UPD data pointer.
266 @return UpdDataPtr UPD data pointer.
270 GetFspUpdDataPointer (
274 FSP_GLOBAL_DATA
*FspData
;
276 FspData
= GetFspGlobalDataPointer ();
277 return FspData
->UpdDataPtr
;
282 This function sets the FspMemoryInit UPD data pointer.
284 @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
288 SetFspMemoryInitUpdDataPointer (
289 IN VOID
*MemoryInitUpdPtr
292 FSP_GLOBAL_DATA
*FspData
;
295 // Get the FSP Global Data Pointer
297 FspData
= GetFspGlobalDataPointer ();
300 // Set the FspMemoryInit UPD pointer.
302 FspData
->MemoryInitUpdPtr
= MemoryInitUpdPtr
;
306 This function gets the FspMemoryInit UPD data pointer.
308 @return FspMemoryInit UPD data pointer.
312 GetFspMemoryInitUpdDataPointer (
316 FSP_GLOBAL_DATA
*FspData
;
318 FspData
= GetFspGlobalDataPointer ();
319 return FspData
->MemoryInitUpdPtr
;
324 This function sets the FspSiliconInit UPD data pointer.
326 @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
330 SetFspSiliconInitUpdDataPointer (
331 IN VOID
*SiliconInitUpdPtr
334 FSP_GLOBAL_DATA
*FspData
;
337 // Get the FSP Global Data Pointer
339 FspData
= GetFspGlobalDataPointer ();
342 // Set the FspSiliconInit UPD data pointer.
344 FspData
->SiliconInitUpdPtr
= SiliconInitUpdPtr
;
348 This function gets the FspSiliconInit UPD data pointer.
350 @return FspSiliconInit UPD data pointer.
354 GetFspSiliconInitUpdDataPointer (
358 FSP_GLOBAL_DATA
*FspData
;
360 FspData
= GetFspGlobalDataPointer ();
361 return FspData
->SiliconInitUpdPtr
;
366 Set FSP measurement point timestamp.
368 @param[in] Id Measurement point ID.
370 @return performance timestamp.
378 FSP_GLOBAL_DATA
*FspData
;
381 // Bit [55: 0] will be the timestamp
382 // Bit [63:56] will be the ID
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
;
390 return FspData
->PerfData
[(FspData
->PerfIdx
)++];
394 This function gets the FSP info header pointer.
396 @retval FspInfoHeader FSP info header pointer
404 return GetFspGlobalDataPointer()->FspInfoHeader
;
408 This function sets the FSP info header pointer.
410 @param[in] FspInfoHeader FSP info header pointer
415 FSP_INFO_HEADER
*FspInfoHeader
418 GetFspGlobalDataPointer()->FspInfoHeader
= FspInfoHeader
;
422 This function gets the FSP info header pointer using the API stack context.
424 @retval FspInfoHeader FSP info header pointer using the API stack context
428 GetFspInfoHeaderFromApiContext (
432 FSP_GLOBAL_DATA
*FspData
;
434 FspData
= GetFspGlobalDataPointer ();
435 return (FSP_INFO_HEADER
*)(*(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET(FspInfoHeader
)));
439 This function gets the CfgRegion data pointer.
441 @return CfgRegion data pointer.
445 GetFspCfgRegionDataPointer (
449 FSP_INFO_HEADER
*FspInfoHeader
;
451 FspInfoHeader
= GetFspInfoHeader ();
452 return (VOID
*)(FspInfoHeader
->ImageBase
+ FspInfoHeader
->CfgRegionOffset
);
456 This function gets FSP API calling index.
458 @retval API calling index
462 GetFspApiCallingIndex (
466 return GetFspGlobalDataPointer()->ApiIdx
;
470 This function sets FSP API calling mode.
472 @param[in] Index API calling index
476 SetFspApiCallingIndex (
480 FSP_GLOBAL_DATA
*FspData
;
482 FspData
= GetFspGlobalDataPointer ();
483 FspData
->ApiIdx
= Index
;
487 This function gets FSP Phase StatusCode.
497 return GetFspGlobalDataPointer()->StatusCode
;
501 This function sets FSP Phase StatusCode.
503 @param[in] Mode Phase StatusCode
511 FSP_GLOBAL_DATA
*FspData
;
513 FspData
= GetFspGlobalDataPointer ();
514 FspData
->StatusCode
= StatusCode
;
518 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
520 @param[in] FspResetType Reset type that needs to returned as API return status
525 FspApiReturnStatusReset (
526 IN UINT32 FspResetType
529 volatile BOOLEAN LoopUntilReset
;
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
) {
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
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
);