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]
33 UINT32 Registers
[8]; // General Purpose Registers: Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx and Eax
41 // API return address +0xB0
42 // push API Parameter2 +0xA8
43 // push API Parameter1 +0xA0
44 // push FspInfoHeader +0x98
52 UINT64 Idtr
[2]; // IDTR Limit - bit0:bi15, IDTR Base - bit16:bit79
53 UINT64 Registers
[16]; // General Purpose Registers: RDI, RSI, RBP, RSP, RBX, RDX, RCX, RAX, and R15 to R8
57 UINT64 ApiRet
; // 64bit stack format is different from the 32bit one due to x64 calling convention
60 #define CONTEXT_STACK_OFFSET(x) (sizeof(UINTN) == sizeof (UINT32) ? (UINTN)&((CONTEXT_STACK *)(UINTN)0)->x : (UINTN)&((CONTEXT_STACK_64 *)(UINTN)0)->x)
65 This function sets the FSP global data pointer.
67 @param[in] FspData FSP global data pointer.
72 SetFspGlobalDataPointer (
73 IN FSP_GLOBAL_DATA
*FspData
76 ASSERT (FspData
!= NULL
);
77 *((volatile UINT32
*)(UINTN
)PcdGet32 (PcdGlobalDataPointerAddress
)) = (UINT32
)(UINTN
)FspData
;
81 This function gets the FSP global data pointer.
86 GetFspGlobalDataPointer (
90 FSP_GLOBAL_DATA
*FspData
;
92 FspData
= *(FSP_GLOBAL_DATA
**)(UINTN
)PcdGet32 (PcdGlobalDataPointerAddress
);
97 This function gets back the FSP API first parameter passed by the bootloader.
99 @retval ApiParameter FSP API first parameter passed by the bootloader.
107 FSP_GLOBAL_DATA
*FspData
;
109 FspData
= GetFspGlobalDataPointer ();
110 return *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[0]));
114 This function returns the FSP entry stack pointer from address of the first API parameter.
116 @retval FSP entry stack pointer.
124 FSP_GLOBAL_DATA
*FspData
;
126 FspData
= GetFspGlobalDataPointer ();
127 return (VOID
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[0]));
131 This function gets back the FSP API second parameter passed by the bootloader.
133 @retval ApiParameter FSP API second parameter passed by the bootloader.
137 GetFspApiParameter2 (
141 FSP_GLOBAL_DATA
*FspData
;
143 FspData
= GetFspGlobalDataPointer ();
144 return *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[1]));
148 This function sets the FSP API parameter in the stack.
150 @param[in] Value New parameter value.
159 FSP_GLOBAL_DATA
*FspData
;
161 FspData
= GetFspGlobalDataPointer ();
162 *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
)) = Value
;
166 This function set the API status code returned to the BootLoader.
168 @param[in] ReturnStatus Status code to return.
173 SetFspApiReturnStatus (
174 IN UINTN ReturnStatus
177 FSP_GLOBAL_DATA
*FspData
;
179 FspData
= GetFspGlobalDataPointer ();
180 *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (Registers
[7])) = ReturnStatus
;
184 This function sets the context switching stack to a new stack frame.
186 @param[in] NewStackTop New core stack to be set.
191 SetFspCoreStackPointer (
195 FSP_GLOBAL_DATA
*FspData
;
198 UINT32 StackContextLen
;
200 FspData
= GetFspGlobalDataPointer ();
201 StackContextLen
= sizeof(CONTEXT_STACK
) / sizeof(UINTN
);
204 // Reserve space for the ContinuationFunc two parameters
206 OldStack
= (UINTN
*)FspData
->CoreStack
;
207 NewStack
= (UINTN
*)NewStackTop
- StackContextLen
- 2;
208 FspData
->CoreStack
= (UINTN
)NewStack
;
209 while (StackContextLen
-- != 0) {
210 *NewStack
++ = *OldStack
++;
215 This function sets the platform specific data pointer.
217 @param[in] PlatformData FSP platform specific data pointer.
222 SetFspPlatformDataPointer (
223 IN VOID
*PlatformData
226 FSP_GLOBAL_DATA
*FspData
;
228 FspData
= GetFspGlobalDataPointer ();
229 FspData
->PlatformData
.DataPtr
= PlatformData
;
233 This function gets the platform specific data pointer.
235 @param[in] PlatformData FSP platform specific data pointer.
240 GetFspPlatformDataPointer (
244 FSP_GLOBAL_DATA
*FspData
;
246 FspData
= GetFspGlobalDataPointer ();
247 return FspData
->PlatformData
.DataPtr
;
251 This function sets the UPD data pointer.
253 @param[in] UpdDataPtr UPD data pointer.
257 SetFspUpdDataPointer (
261 FSP_GLOBAL_DATA
*FspData
;
264 // Get the FSP Global Data Pointer
266 FspData
= GetFspGlobalDataPointer ();
269 // Set the UPD pointer.
271 FspData
->UpdDataPtr
= UpdDataPtr
;
275 This function gets the UPD data pointer.
277 @return UpdDataPtr UPD data pointer.
281 GetFspUpdDataPointer (
285 FSP_GLOBAL_DATA
*FspData
;
287 FspData
= GetFspGlobalDataPointer ();
288 return FspData
->UpdDataPtr
;
292 This function sets the FspMemoryInit UPD data pointer.
294 @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
298 SetFspMemoryInitUpdDataPointer (
299 IN VOID
*MemoryInitUpdPtr
302 FSP_GLOBAL_DATA
*FspData
;
305 // Get the FSP Global Data Pointer
307 FspData
= GetFspGlobalDataPointer ();
310 // Set the FspMemoryInit UPD pointer.
312 FspData
->MemoryInitUpdPtr
= MemoryInitUpdPtr
;
316 This function gets the FspMemoryInit UPD data pointer.
318 @return FspMemoryInit UPD data pointer.
322 GetFspMemoryInitUpdDataPointer (
326 FSP_GLOBAL_DATA
*FspData
;
328 FspData
= GetFspGlobalDataPointer ();
329 return FspData
->MemoryInitUpdPtr
;
333 This function sets the FspSiliconInit UPD data pointer.
335 @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
339 SetFspSiliconInitUpdDataPointer (
340 IN VOID
*SiliconInitUpdPtr
343 FSP_GLOBAL_DATA
*FspData
;
346 // Get the FSP Global Data Pointer
348 FspData
= GetFspGlobalDataPointer ();
351 // Set the FspSiliconInit UPD data pointer.
353 FspData
->SiliconInitUpdPtr
= SiliconInitUpdPtr
;
357 This function gets the FspSiliconInit UPD data pointer.
359 @return FspSiliconInit UPD data pointer.
363 GetFspSiliconInitUpdDataPointer (
367 FSP_GLOBAL_DATA
*FspData
;
369 FspData
= GetFspGlobalDataPointer ();
370 return FspData
->SiliconInitUpdPtr
;
374 Set FSP measurement point timestamp.
376 @param[in] Id Measurement point ID.
378 @return performance timestamp.
386 FSP_GLOBAL_DATA
*FspData
;
389 // Bit [55: 0] will be the timestamp
390 // Bit [63:56] will be the ID
392 FspData
= GetFspGlobalDataPointer ();
393 if (FspData
->PerfIdx
< sizeof (FspData
->PerfData
) / sizeof (FspData
->PerfData
[0])) {
394 FspData
->PerfData
[FspData
->PerfIdx
] = AsmReadTsc ();
395 ((UINT8
*)(&FspData
->PerfData
[FspData
->PerfIdx
]))[7] = Id
;
398 return FspData
->PerfData
[(FspData
->PerfIdx
)++];
402 This function gets the FSP info header pointer.
404 @retval FspInfoHeader FSP info header pointer
412 return GetFspGlobalDataPointer ()->FspInfoHeader
;
416 This function sets the FSP info header pointer.
418 @param[in] FspInfoHeader FSP info header pointer
423 FSP_INFO_HEADER
*FspInfoHeader
426 GetFspGlobalDataPointer ()->FspInfoHeader
= FspInfoHeader
;
430 This function gets the FSP info header pointer using the API stack context.
432 @retval FspInfoHeader FSP info header pointer using the API stack context
436 GetFspInfoHeaderFromApiContext (
440 FSP_GLOBAL_DATA
*FspData
;
442 FspData
= GetFspGlobalDataPointer ();
443 return (FSP_INFO_HEADER
*)(*(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (FspInfoHeader
)));
447 This function gets the CfgRegion data pointer.
449 @return CfgRegion data pointer.
453 GetFspCfgRegionDataPointer (
457 FSP_INFO_HEADER
*FspInfoHeader
;
459 FspInfoHeader
= GetFspInfoHeader ();
460 return (VOID
*)(UINTN
)(FspInfoHeader
->ImageBase
+ FspInfoHeader
->CfgRegionOffset
);
464 This function gets FSP API calling index.
466 @retval API calling index
470 GetFspApiCallingIndex (
474 return GetFspGlobalDataPointer ()->ApiIdx
;
478 This function sets FSP API calling mode.
480 @param[in] Index API calling index
484 SetFspApiCallingIndex (
488 FSP_GLOBAL_DATA
*FspData
;
490 FspData
= GetFspGlobalDataPointer ();
491 FspData
->ApiIdx
= Index
;
495 This function gets FSP Phase StatusCode.
505 return GetFspGlobalDataPointer ()->StatusCode
;
509 This function sets FSP Phase StatusCode.
511 @param[in] Mode Phase StatusCode
519 FSP_GLOBAL_DATA
*FspData
;
521 FspData
= GetFspGlobalDataPointer ();
522 FspData
->StatusCode
= StatusCode
;
526 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
528 @param[in] FspResetType Reset type that needs to returned as API return status
533 FspApiReturnStatusReset (
534 IN UINT32 FspResetType
537 volatile BOOLEAN LoopUntilReset
;
539 LoopUntilReset
= TRUE
;
540 DEBUG ((DEBUG_INFO
, "FSP returning control to Bootloader with reset required return status %x\n", FspResetType
));
541 if (GetFspGlobalDataPointer ()->FspMode
== FSP_IN_API_MODE
) {
543 /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
544 /// calls the FSP API without honoring the reset request by FSP
547 SetFspApiReturnStatus ((EFI_STATUS
)FspResetType
);
548 Pei2LoaderSwitchStack ();
549 DEBUG ((DEBUG_ERROR
, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
550 DEBUG ((DEBUG_ERROR
, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
551 } while (LoopUntilReset
);