3 Copyright (c) 2014 - 2022, 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 +0xB8
43 // push API Parameter2 +0xA8
44 // push API Parameter1 +0xA0
45 // push FspInfoHeader +0x98
53 UINT64 Idtr
[2]; // IDTR Limit - bit0:bi15, IDTR Base - bit16:bit79
54 UINT64 Registers
[16]; // General Purpose Registers: RDI, RSI, RBP, RSP, RBX, RDX, RCX, RAX, and R15 to R8
58 UINT64 Reserved
; // The reserved QWORD is needed for stack alignment in X64.
59 UINT64 ApiRet
; // 64bit stack format is different from the 32bit one due to x64 calling convention
62 #define CONTEXT_STACK_OFFSET(x) (sizeof(UINTN) == sizeof (UINT32) ? (UINTN)&((CONTEXT_STACK *)(UINTN)0)->x : (UINTN)&((CONTEXT_STACK_64 *)(UINTN)0)->x)
67 This function sets the FSP global data pointer.
69 @param[in] FspData FSP global data pointer.
74 SetFspGlobalDataPointer (
75 IN FSP_GLOBAL_DATA
*FspData
78 ASSERT (FspData
!= NULL
);
79 *((volatile UINT32
*)(UINTN
)PcdGet32 (PcdGlobalDataPointerAddress
)) = (UINT32
)(UINTN
)FspData
;
83 This function gets the FSP global data pointer.
88 GetFspGlobalDataPointer (
92 FSP_GLOBAL_DATA
*FspData
;
94 FspData
= *(FSP_GLOBAL_DATA
**)(UINTN
)PcdGet32 (PcdGlobalDataPointerAddress
);
99 This function gets back the FSP API first parameter passed by the bootloader.
101 @retval ApiParameter FSP API first parameter passed by the bootloader.
109 FSP_GLOBAL_DATA
*FspData
;
111 FspData
= GetFspGlobalDataPointer ();
112 return *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[0]));
116 This function returns the FSP entry stack pointer from address of the first API parameter.
118 @retval FSP entry stack pointer.
126 FSP_GLOBAL_DATA
*FspData
;
128 FspData
= GetFspGlobalDataPointer ();
129 return (VOID
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[0]));
133 This function gets back the FSP API second parameter passed by the bootloader.
135 @retval ApiParameter FSP API second parameter passed by the bootloader.
139 GetFspApiParameter2 (
143 FSP_GLOBAL_DATA
*FspData
;
145 FspData
= GetFspGlobalDataPointer ();
146 return *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
[1]));
150 This function sets the FSP API parameter in the stack.
152 @param[in] Value New parameter value.
161 FSP_GLOBAL_DATA
*FspData
;
163 FspData
= GetFspGlobalDataPointer ();
164 *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (ApiParam
)) = Value
;
168 This function set the API status code returned to the BootLoader.
170 @param[in] ReturnStatus Status code to return.
175 SetFspApiReturnStatus (
176 IN UINTN ReturnStatus
179 FSP_GLOBAL_DATA
*FspData
;
181 FspData
= GetFspGlobalDataPointer ();
182 *(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (Registers
[7])) = ReturnStatus
;
186 This function sets the context switching stack to a new stack frame.
188 @param[in] NewStackTop New core stack to be set.
193 SetFspCoreStackPointer (
197 FSP_GLOBAL_DATA
*FspData
;
200 UINT32 StackContextLen
;
202 FspData
= GetFspGlobalDataPointer ();
203 StackContextLen
= sizeof(CONTEXT_STACK
) / sizeof(UINTN
);
206 // Reserve space for the ContinuationFunc two parameters
208 OldStack
= (UINTN
*)FspData
->CoreStack
;
209 NewStack
= (UINTN
*)NewStackTop
- StackContextLen
- 2;
210 FspData
->CoreStack
= (UINTN
)NewStack
;
211 while (StackContextLen
-- != 0) {
212 *NewStack
++ = *OldStack
++;
217 This function sets the platform specific data pointer.
219 @param[in] PlatformData FSP platform specific data pointer.
224 SetFspPlatformDataPointer (
225 IN VOID
*PlatformData
228 FSP_GLOBAL_DATA
*FspData
;
230 FspData
= GetFspGlobalDataPointer ();
231 FspData
->PlatformData
.DataPtr
= PlatformData
;
235 This function gets the platform specific data pointer.
237 @param[in] PlatformData FSP platform specific data pointer.
242 GetFspPlatformDataPointer (
246 FSP_GLOBAL_DATA
*FspData
;
248 FspData
= GetFspGlobalDataPointer ();
249 return FspData
->PlatformData
.DataPtr
;
253 This function sets the UPD data pointer.
255 @param[in] UpdDataPtr UPD data pointer.
259 SetFspUpdDataPointer (
263 FSP_GLOBAL_DATA
*FspData
;
266 // Get the FSP Global Data Pointer
268 FspData
= GetFspGlobalDataPointer ();
271 // Set the UPD pointer.
273 FspData
->UpdDataPtr
= UpdDataPtr
;
277 This function gets the UPD data pointer.
279 @return UpdDataPtr UPD data pointer.
283 GetFspUpdDataPointer (
287 FSP_GLOBAL_DATA
*FspData
;
289 FspData
= GetFspGlobalDataPointer ();
290 return FspData
->UpdDataPtr
;
294 This function sets the FspMemoryInit UPD data pointer.
296 @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.
300 SetFspMemoryInitUpdDataPointer (
301 IN VOID
*MemoryInitUpdPtr
304 FSP_GLOBAL_DATA
*FspData
;
307 // Get the FSP Global Data Pointer
309 FspData
= GetFspGlobalDataPointer ();
312 // Set the FspMemoryInit UPD pointer.
314 FspData
->MemoryInitUpdPtr
= MemoryInitUpdPtr
;
318 This function gets the FspMemoryInit UPD data pointer.
320 @return FspMemoryInit UPD data pointer.
324 GetFspMemoryInitUpdDataPointer (
328 FSP_GLOBAL_DATA
*FspData
;
330 FspData
= GetFspGlobalDataPointer ();
331 return FspData
->MemoryInitUpdPtr
;
335 This function sets the FspSiliconInit UPD data pointer.
337 @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.
341 SetFspSiliconInitUpdDataPointer (
342 IN VOID
*SiliconInitUpdPtr
345 FSP_GLOBAL_DATA
*FspData
;
348 // Get the FSP Global Data Pointer
350 FspData
= GetFspGlobalDataPointer ();
353 // Set the FspSiliconInit UPD data pointer.
355 FspData
->SiliconInitUpdPtr
= SiliconInitUpdPtr
;
359 This function gets the FspSiliconInit UPD data pointer.
361 @return FspSiliconInit UPD data pointer.
365 GetFspSiliconInitUpdDataPointer (
369 FSP_GLOBAL_DATA
*FspData
;
371 FspData
= GetFspGlobalDataPointer ();
372 return FspData
->SiliconInitUpdPtr
;
376 Set FSP measurement point timestamp.
378 @param[in] Id Measurement point ID.
380 @return performance timestamp.
388 FSP_GLOBAL_DATA
*FspData
;
391 // Bit [55: 0] will be the timestamp
392 // Bit [63:56] will be the ID
394 FspData
= GetFspGlobalDataPointer ();
395 if (FspData
->PerfIdx
< sizeof (FspData
->PerfData
) / sizeof (FspData
->PerfData
[0])) {
396 FspData
->PerfData
[FspData
->PerfIdx
] = AsmReadTsc ();
397 ((UINT8
*)(&FspData
->PerfData
[FspData
->PerfIdx
]))[7] = Id
;
400 return FspData
->PerfData
[(FspData
->PerfIdx
)++];
404 This function gets the FSP info header pointer.
406 @retval FspInfoHeader FSP info header pointer
414 return GetFspGlobalDataPointer ()->FspInfoHeader
;
418 This function sets the FSP info header pointer.
420 @param[in] FspInfoHeader FSP info header pointer
425 FSP_INFO_HEADER
*FspInfoHeader
428 GetFspGlobalDataPointer ()->FspInfoHeader
= FspInfoHeader
;
432 This function gets the FSP info header pointer using the API stack context.
434 @retval FspInfoHeader FSP info header pointer using the API stack context
438 GetFspInfoHeaderFromApiContext (
442 FSP_GLOBAL_DATA
*FspData
;
444 FspData
= GetFspGlobalDataPointer ();
445 return (FSP_INFO_HEADER
*)(*(UINTN
*)(FspData
->CoreStack
+ CONTEXT_STACK_OFFSET (FspInfoHeader
)));
449 This function gets the CfgRegion data pointer.
451 @return CfgRegion data pointer.
455 GetFspCfgRegionDataPointer (
459 FSP_INFO_HEADER
*FspInfoHeader
;
461 FspInfoHeader
= GetFspInfoHeader ();
462 return (VOID
*)(UINTN
)(FspInfoHeader
->ImageBase
+ FspInfoHeader
->CfgRegionOffset
);
466 This function gets FSP API calling index.
468 @retval API calling index
472 GetFspApiCallingIndex (
476 return GetFspGlobalDataPointer ()->ApiIdx
;
480 This function sets FSP API calling mode.
482 @param[in] Index API calling index
486 SetFspApiCallingIndex (
490 FSP_GLOBAL_DATA
*FspData
;
492 FspData
= GetFspGlobalDataPointer ();
493 FspData
->ApiIdx
= Index
;
497 This function gets FSP Phase StatusCode.
507 return GetFspGlobalDataPointer ()->StatusCode
;
511 This function sets FSP Phase StatusCode.
513 @param[in] Mode Phase StatusCode
521 FSP_GLOBAL_DATA
*FspData
;
523 FspData
= GetFspGlobalDataPointer ();
524 FspData
->StatusCode
= StatusCode
;
528 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
530 @param[in] FspResetType Reset type that needs to returned as API return status
535 FspApiReturnStatusReset (
536 IN UINT32 FspResetType
539 volatile BOOLEAN LoopUntilReset
;
541 LoopUntilReset
= TRUE
;
542 DEBUG ((DEBUG_INFO
, "FSP returning control to Bootloader with reset required return status %x\n", FspResetType
));
543 if (GetFspGlobalDataPointer ()->FspMode
== FSP_IN_API_MODE
) {
545 /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
546 /// calls the FSP API without honoring the reset request by FSP
549 SetFspApiReturnStatus ((EFI_STATUS
)FspResetType
);
550 Pei2LoaderSwitchStack ();
551 DEBUG ((DEBUG_ERROR
, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
552 DEBUG ((DEBUG_ERROR
, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));
553 } while (LoopUntilReset
);