3 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/BaseLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/PcdLib.h>
18 #include <FspGlobalData.h>
20 #include <Library/FspSwitchStackLib.h>
25 // API Parameter +0x34
26 // API return address +0x30
28 // push FspInfoHeader +0x2C
33 // sidt fword ptr [esp]
53 #define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x
58 This function sets the FSP global data pointer.
60 @param[in] FspData FSP global data pointer.
65 SetFspGlobalDataPointer (
66 IN FSP_GLOBAL_DATA
*FspData
69 ASSERT (FspData
!= NULL
);
70 *((volatile UINT32
*)(UINTN
)PcdGet32(PcdGlobalDataPointerAddress
)) = (UINT32
)(UINTN
)FspData
;
74 This function gets the FSP global data pointer.
79 GetFspGlobalDataPointer (
83 FSP_GLOBAL_DATA
*FspData
;
85 FspData
= *(FSP_GLOBAL_DATA
**)(UINTN
)PcdGet32(PcdGlobalDataPointerAddress
);
90 This function gets back the FSP API first parameter passed by the bootloader.
92 @retval ApiParameter FSP API first parameter passed by the bootloader.
100 FSP_GLOBAL_DATA
*FspData
;
102 FspData
= GetFspGlobalDataPointer ();
103 return *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET(ApiParam
[0]));
107 This function returns the FSP entry stack pointer from address of the first API parameter.
109 @retval FSP entry stack pointer.
117 FSP_GLOBAL_DATA
*FspData
;
119 FspData
= GetFspGlobalDataPointer ();
120 return (VOID
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET(ApiParam
[0]));
124 This function gets back the FSP API second parameter passed by the bootloader.
126 @retval ApiParameter FSP API second parameter passed by the bootloader.
130 GetFspApiParameter2 (
134 FSP_GLOBAL_DATA
*FspData
;
136 FspData
= GetFspGlobalDataPointer ();
137 return *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET(ApiParam
[1]));
141 This function sets the FSP API parameter in the stack.
143 @param[in] Value New parameter value.
152 FSP_GLOBAL_DATA
*FspData
;
154 FspData
= GetFspGlobalDataPointer ();
155 *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET(ApiParam
)) = Value
;
159 This function set the API status code returned to the BootLoader.
161 @param[in] ReturnStatus Status code to return.
166 SetFspApiReturnStatus (
167 IN UINT32 ReturnStatus
170 FSP_GLOBAL_DATA
*FspData
;
172 FspData
= GetFspGlobalDataPointer ();
173 *(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET(Eax
)) = ReturnStatus
;
177 This function sets the context switching stack to a new stack frame.
179 @param[in] NewStackTop New core stack to be set.
184 SetFspCoreStackPointer (
188 FSP_GLOBAL_DATA
*FspData
;
191 UINT32 StackContextLen
;
193 FspData
= GetFspGlobalDataPointer ();
194 StackContextLen
= sizeof(CONTEXT_STACK
) / sizeof(UINT32
);
197 // Reserve space for the ContinuationFunc two parameters
199 OldStack
= (UINT32
*)FspData
->CoreStack
;
200 NewStack
= (UINT32
*)NewStackTop
- StackContextLen
- 2;
201 FspData
->CoreStack
= (UINT32
)NewStack
;
202 while (StackContextLen
-- != 0) {
203 *NewStack
++ = *OldStack
++;
208 This function sets the platform specific data pointer.
210 @param[in] PlatformData FSP platform specific data pointer.
215 SetFspPlatformDataPointer (
216 IN VOID
*PlatformData
219 FSP_GLOBAL_DATA
*FspData
;
221 FspData
= GetFspGlobalDataPointer ();
222 FspData
->PlatformData
.DataPtr
= PlatformData
;
227 This function gets the platform specific data pointer.
229 @param[in] PlatformData FSP platform specific data pointer.
234 GetFspPlatformDataPointer (
238 FSP_GLOBAL_DATA
*FspData
;
240 FspData
= GetFspGlobalDataPointer ();
241 return FspData
->PlatformData
.DataPtr
;
246 This function sets the UPD data pointer.
248 @param[in] UpdDataPtr UPD data pointer.
252 SetFspUpdDataPointer (
256 FSP_GLOBAL_DATA
*FspData
;
259 // Get the FSP Global Data Pointer
261 FspData
= GetFspGlobalDataPointer ();
264 // Set the UPD pointer.
266 FspData
->UpdDataPtr
= UpdDataPtr
;
270 This function gets the UPD data pointer.
272 @return UpdDataPtr UPD data pointer.
276 GetFspUpdDataPointer (
280 FSP_GLOBAL_DATA
*FspData
;
282 FspData
= GetFspGlobalDataPointer ();
283 return FspData
->UpdDataPtr
;
288 This function sets the FspMemoryInit UPD data pointer.
290 @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
294 SetFspMemoryInitUpdDataPointer (
295 IN VOID
*MemoryInitUpdPtr
298 FSP_GLOBAL_DATA
*FspData
;
301 // Get the FSP Global Data Pointer
303 FspData
= GetFspGlobalDataPointer ();
306 // Set the FspMemoryInit UPD pointer.
308 FspData
->MemoryInitUpdPtr
= MemoryInitUpdPtr
;
312 This function gets the FspMemoryInit UPD data pointer.
314 @return FspMemoryInit UPD data pointer.
318 GetFspMemoryInitUpdDataPointer (
322 FSP_GLOBAL_DATA
*FspData
;
324 FspData
= GetFspGlobalDataPointer ();
325 return FspData
->MemoryInitUpdPtr
;
330 This function sets the FspSiliconInit UPD data pointer.
332 @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
336 SetFspSiliconInitUpdDataPointer (
337 IN VOID
*SiliconInitUpdPtr
340 FSP_GLOBAL_DATA
*FspData
;
343 // Get the FSP Global Data Pointer
345 FspData
= GetFspGlobalDataPointer ();
348 // Set the FspSiliconInit UPD data pointer.
350 FspData
->SiliconInitUpdPtr
= SiliconInitUpdPtr
;
354 This function gets the FspSiliconInit UPD data pointer.
356 @return FspSiliconInit UPD data pointer.
360 GetFspSiliconInitUpdDataPointer (
364 FSP_GLOBAL_DATA
*FspData
;
366 FspData
= GetFspGlobalDataPointer ();
367 return FspData
->SiliconInitUpdPtr
;
372 Set FSP measurement point timestamp.
374 @param[in] Id Measurement point ID.
376 @return performance timestamp.
384 FSP_GLOBAL_DATA
*FspData
;
387 // Bit [55: 0] will be the timestamp
388 // Bit [63:56] will be the ID
390 FspData
= GetFspGlobalDataPointer ();
391 if (FspData
->PerfIdx
< sizeof(FspData
->PerfData
) / sizeof(FspData
->PerfData
[0])) {
392 FspData
->PerfData
[FspData
->PerfIdx
] = AsmReadTsc ();
393 ((UINT8
*)(&FspData
->PerfData
[FspData
->PerfIdx
]))[7] = Id
;
396 return FspData
->PerfData
[(FspData
->PerfIdx
)++];
400 This function gets the FSP info header pointer.
402 @retval FspInfoHeader FSP info header pointer
410 return GetFspGlobalDataPointer()->FspInfoHeader
;
414 This function sets the FSP info header pointer.
416 @param[in] FspInfoHeader FSP info header pointer
421 FSP_INFO_HEADER
*FspInfoHeader
424 GetFspGlobalDataPointer()->FspInfoHeader
= FspInfoHeader
;
428 This function gets the FSP info header pointer using the API stack context.
430 @retval FspInfoHeader FSP info header pointer using the API stack context
434 GetFspInfoHeaderFromApiContext (
438 FSP_GLOBAL_DATA
*FspData
;
440 FspData
= GetFspGlobalDataPointer ();
441 return (FSP_INFO_HEADER
*)(*(UINT32
*)(UINTN
)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET(FspInfoHeader
)));
445 This function gets the CfgRegion data pointer.
447 @return CfgRegion data pointer.
451 GetFspCfgRegionDataPointer (
455 FSP_INFO_HEADER
*FspInfoHeader
;
457 FspInfoHeader
= GetFspInfoHeader ();
458 return (VOID
*)(FspInfoHeader
->ImageBase
+ FspInfoHeader
->CfgRegionOffset
);
462 This function gets FSP API calling index.
464 @retval API calling index
468 GetFspApiCallingIndex (
472 return GetFspGlobalDataPointer()->ApiIdx
;
476 This function sets FSP API calling mode.
478 @param[in] Index API calling index
482 SetFspApiCallingIndex (
486 FSP_GLOBAL_DATA
*FspData
;
488 FspData
= GetFspGlobalDataPointer ();
489 FspData
->ApiIdx
= Index
;
493 This function gets FSP Phase StatusCode.
503 return GetFspGlobalDataPointer()->StatusCode
;
507 This function sets FSP Phase StatusCode.
509 @param[in] Mode Phase StatusCode
517 FSP_GLOBAL_DATA
*FspData
;
519 FspData
= GetFspGlobalDataPointer ();
520 FspData
->StatusCode
= StatusCode
;
524 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
526 @param[in] FspResetType Reset type that needs to returned as API return status
531 FspApiReturnStatusReset (
532 IN UINT32 FspResetType
535 volatile BOOLEAN LoopUntilReset
;
537 LoopUntilReset
= TRUE
;
538 DEBUG ((DEBUG_INFO
, "FSP returning control to Bootloader with reset required return status %x\n",FspResetType
));
539 if (GetFspGlobalDataPointer ()->FspMode
== FSP_IN_API_MODE
) {
541 /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
542 /// calls the FSP API without honoring the reset request by FSP
545 SetFspApiReturnStatus ((EFI_STATUS
)FspResetType
);
546 Pei2LoaderSwitchStack ();
547 DEBUG ((DEBUG_ERROR
, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
548 DEBUG ((DEBUG_ERROR
, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
549 } while (LoopUntilReset
);