/** @file\r
\r
- Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Library/PcdLib.h>\r
#include <FspGlobalData.h>\r
#include <FspEas.h>\r
-#include <FspDataTable.h>\r
#include <Library/FspSwitchStackLib.h>\r
\r
#pragma pack(1)\r
UINT16 IdtrLimit;\r
UINT32 IdtrBase;\r
UINT16 Reserved;\r
- UINT32 Edi;\r
- UINT32 Esi;\r
- UINT32 Ebp;\r
- UINT32 Esp;\r
- UINT32 Ebx;\r
- UINT32 Edx;\r
- UINT32 Ecx;\r
- UINT32 Eax;\r
+ UINT32 Registers[8]; // General Purpose Registers: Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx and Eax\r
UINT16 Flags[2];\r
UINT32 FspInfoHeader;\r
UINT32 ApiRet;\r
UINT32 ApiParam[2];\r
} CONTEXT_STACK;\r
\r
-#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x\r
+//\r
+// API return address +0xB0\r
+// push API Parameter2 +0xA8\r
+// push API Parameter1 +0xA0\r
+// push FspInfoHeader +0x98\r
+// pushfq +0x90\r
+// cli\r
+// PUSHA_64 +0x10\r
+// sub rsp, 16 +0x00\r
+// sidt [rsp]\r
+//\r
+typedef struct {\r
+ UINT64 Idtr[2]; // IDTR Limit - bit0:bi15, IDTR Base - bit16:bit79\r
+ UINT64 Registers[16]; // General Purpose Registers: RDI, RSI, RBP, RSP, RBX, RDX, RCX, RAX, and R15 to R8\r
+ UINT32 Flags[2];\r
+ UINT64 FspInfoHeader;\r
+ UINT64 ApiParam[2];\r
+ UINT64 ApiRet; // 64bit stack format is different from the 32bit one due to x64 calling convention\r
+} CONTEXT_STACK_64;\r
+\r
+#define CONTEXT_STACK_OFFSET(x) (sizeof(UINTN) == sizeof (UINT32) ? (UINTN)&((CONTEXT_STACK *)(UINTN)0)->x : (UINTN)&((CONTEXT_STACK_64 *)(UINTN)0)->x)\r
\r
#pragma pack()\r
\r
/**\r
This function sets the FSP global data pointer.\r
\r
- @param[in] FspData Fsp global data pointer.\r
+ @param[in] FspData FSP global data pointer.\r
\r
**/\r
VOID\r
EFIAPI\r
SetFspGlobalDataPointer (\r
- IN FSP_GLOBAL_DATA *FspData\r
+ IN FSP_GLOBAL_DATA *FspData\r
)\r
{\r
ASSERT (FspData != NULL);\r
- *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;\r
+ *((volatile UINT32 *)(UINTN)PcdGet32 (PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- FSP_GLOBAL_DATA *FspData;\r
+ FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);\r
+ FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32 (PcdGlobalDataPointerAddress);\r
return FspData;\r
}\r
\r
/**\r
- This function gets back the FSP API first parameter passed by the bootlaoder.\r
+ This function gets back the FSP API first parameter passed by the bootloader.\r
\r
- @retval ApiParameter FSP API first parameter passed by the bootlaoder.\r
+ @retval ApiParameter FSP API first parameter passed by the bootloader.\r
**/\r
-UINT32\r
+UINTN\r
EFIAPI\r
GetFspApiParameter (\r
VOID\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
- return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0]));\r
+ FspData = GetFspGlobalDataPointer ();\r
+ return *(UINTN *)(FspData->CoreStack + CONTEXT_STACK_OFFSET (ApiParam[0]));\r
}\r
\r
/**\r
- This function gets back the FSP API second parameter passed by the bootlaoder.\r
+ This function returns the FSP entry stack pointer from address of the first API parameter.\r
\r
- @retval ApiParameter FSP API second parameter passed by the bootlaoder.\r
+ @retval FSP entry stack pointer.\r
**/\r
-UINT32\r
+VOID *\r
+EFIAPI\r
+GetFspEntryStack (\r
+ VOID\r
+ )\r
+{\r
+ FSP_GLOBAL_DATA *FspData;\r
+\r
+ FspData = GetFspGlobalDataPointer ();\r
+ return (VOID *)(FspData->CoreStack + CONTEXT_STACK_OFFSET (ApiParam[0]));\r
+}\r
+\r
+/**\r
+ This function gets back the FSP API second parameter passed by the bootloader.\r
+\r
+ @retval ApiParameter FSP API second parameter passed by the bootloader.\r
+**/\r
+UINTN\r
EFIAPI\r
GetFspApiParameter2 (\r
VOID\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
- return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[1]));\r
+ FspData = GetFspGlobalDataPointer ();\r
+ return *(UINTN *)(FspData->CoreStack + CONTEXT_STACK_OFFSET (ApiParam[1]));\r
}\r
\r
/**\r
VOID\r
EFIAPI\r
SetFspApiParameter (\r
- IN UINT32 Value\r
+ IN UINT32 Value\r
)\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
- *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;\r
+ FspData = GetFspGlobalDataPointer ();\r
+ *(UINTN *)(FspData->CoreStack + CONTEXT_STACK_OFFSET (ApiParam)) = Value;\r
}\r
\r
/**\r
VOID\r
EFIAPI\r
SetFspApiReturnStatus (\r
- IN UINT32 ReturnStatus\r
+ IN UINTN ReturnStatus\r
)\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
- *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;\r
+ FspData = GetFspGlobalDataPointer ();\r
+ *(UINTN *)(FspData->CoreStack + CONTEXT_STACK_OFFSET (Registers[7])) = ReturnStatus;\r
}\r
\r
/**\r
VOID\r
EFIAPI\r
SetFspCoreStackPointer (\r
- IN VOID *NewStackTop\r
+ IN VOID *NewStackTop\r
)\r
{\r
FSP_GLOBAL_DATA *FspData;\r
- UINT32 *OldStack;\r
- UINT32 *NewStack;\r
+ UINTN *OldStack;\r
+ UINTN *NewStack;\r
UINT32 StackContextLen;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
- StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);\r
+ FspData = GetFspGlobalDataPointer ();\r
+ StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINTN);\r
\r
//\r
// Reserve space for the ContinuationFunc two parameters\r
//\r
- OldStack = (UINT32 *)FspData->CoreStack;\r
- NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;\r
- FspData->CoreStack = (UINT32)NewStack;\r
+ OldStack = (UINTN *)FspData->CoreStack;\r
+ NewStack = (UINTN *)NewStackTop - StackContextLen - 2;\r
+ FspData->CoreStack = (UINTN)NewStack;\r
while (StackContextLen-- != 0) {\r
*NewStack++ = *OldStack++;\r
}\r
/**\r
This function sets the platform specific data pointer.\r
\r
- @param[in] PlatformData Fsp platform specific data pointer.\r
+ @param[in] PlatformData FSP platform specific data pointer.\r
\r
**/\r
VOID\r
EFIAPI\r
SetFspPlatformDataPointer (\r
- IN VOID *PlatformData\r
+ IN VOID *PlatformData\r
)\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
FspData->PlatformData.DataPtr = PlatformData;\r
}\r
\r
-\r
/**\r
This function gets the platform specific data pointer.\r
\r
- @param[in] PlatformData Fsp platform specific data pointer.\r
+ @param[in] PlatformData FSP platform specific data pointer.\r
\r
**/\r
VOID *\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
return FspData->PlatformData.DataPtr;\r
}\r
\r
-\r
/**\r
This function sets the UPD data pointer.\r
\r
VOID\r
EFIAPI\r
SetFspUpdDataPointer (\r
- IN VOID *UpdDataPtr\r
+ IN VOID *UpdDataPtr\r
)\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
//\r
- // Get the Fsp Global Data Pointer\r
+ // Get the FSP Global Data Pointer\r
//\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
\r
//\r
// Set the UPD pointer.\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
return FspData->UpdDataPtr;\r
}\r
\r
-\r
/**\r
- This function sets the memory init UPD data pointer.\r
+ This function sets the FspMemoryInit UPD data pointer.\r
\r
- @param[in] MemoryInitUpdPtr memory init UPD data pointer.\r
+ @param[in] MemoryInitUpdPtr FspMemoryInit UPD data pointer.\r
**/\r
VOID\r
EFIAPI\r
SetFspMemoryInitUpdDataPointer (\r
- IN VOID *MemoryInitUpdPtr\r
+ IN VOID *MemoryInitUpdPtr\r
)\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
//\r
- // Get the Fsp Global Data Pointer\r
+ // Get the FSP Global Data Pointer\r
//\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
\r
//\r
- // Set the memory init UPD pointer.\r
+ // Set the FspMemoryInit UPD pointer.\r
//\r
FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;\r
}\r
\r
/**\r
- This function gets the memory init UPD data pointer.\r
+ This function gets the FspMemoryInit UPD data pointer.\r
\r
- @return memory init UPD data pointer.\r
+ @return FspMemoryInit UPD data pointer.\r
**/\r
VOID *\r
EFIAPI\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
return FspData->MemoryInitUpdPtr;\r
}\r
\r
-\r
/**\r
- This function sets the silicon init UPD data pointer.\r
+ This function sets the FspSiliconInit UPD data pointer.\r
\r
- @param[in] SiliconInitUpdPtr silicon init UPD data pointer.\r
+ @param[in] SiliconInitUpdPtr FspSiliconInit UPD data pointer.\r
**/\r
VOID\r
EFIAPI\r
SetFspSiliconInitUpdDataPointer (\r
- IN VOID *SiliconInitUpdPtr\r
+ IN VOID *SiliconInitUpdPtr\r
)\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
//\r
- // Get the Fsp Global Data Pointer\r
+ // Get the FSP Global Data Pointer\r
//\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
\r
//\r
- // Set the silicon init UPD data pointer.\r
+ // Set the FspSiliconInit UPD data pointer.\r
//\r
FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;\r
}\r
\r
/**\r
- This function gets the silicon init UPD data pointer.\r
+ This function gets the FspSiliconInit UPD data pointer.\r
\r
- @return silicon init UPD data pointer.\r
+ @return FspSiliconInit UPD data pointer.\r
**/\r
VOID *\r
EFIAPI\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
return FspData->SiliconInitUpdPtr;\r
}\r
\r
-\r
/**\r
Set FSP measurement point timestamp.\r
\r
// Bit [55: 0] will be the timestamp\r
// Bit [63:56] will be the ID\r
//\r
- FspData = GetFspGlobalDataPointer ();\r
- if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {\r
- FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();\r
+ FspData = GetFspGlobalDataPointer ();\r
+ if (FspData->PerfIdx < sizeof (FspData->PerfData) / sizeof (FspData->PerfData[0])) {\r
+ FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();\r
((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;\r
}\r
\r
VOID\r
)\r
{\r
- return GetFspGlobalDataPointer()->FspInfoHeader;\r
+ return GetFspGlobalDataPointer ()->FspInfoHeader;\r
}\r
\r
/**\r
VOID\r
EFIAPI\r
SetFspInfoHeader (\r
- FSP_INFO_HEADER *FspInfoHeader\r
+ FSP_INFO_HEADER *FspInfoHeader\r
)\r
{\r
- GetFspGlobalDataPointer()->FspInfoHeader = FspInfoHeader;\r
+ GetFspGlobalDataPointer ()->FspInfoHeader = FspInfoHeader;\r
}\r
\r
/**\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
- return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader)));\r
+ FspData = GetFspGlobalDataPointer ();\r
+ return (FSP_INFO_HEADER *)(*(UINTN *)(FspData->CoreStack + CONTEXT_STACK_OFFSET (FspInfoHeader)));\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- FSP_INFO_HEADER *FspInfoHeader;\r
+ FSP_INFO_HEADER *FspInfoHeader;\r
\r
FspInfoHeader = GetFspInfoHeader ();\r
- return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);\r
+ return (VOID *)(UINTN)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);\r
}\r
\r
/**\r
VOID\r
)\r
{\r
- return GetFspGlobalDataPointer()->ApiIdx;\r
+ return GetFspGlobalDataPointer ()->ApiIdx;\r
}\r
\r
/**\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
FspData->ApiIdx = Index;\r
}\r
\r
VOID\r
)\r
{\r
- return GetFspGlobalDataPointer()->StatusCode;\r
+ return GetFspGlobalDataPointer ()->StatusCode;\r
}\r
\r
/**\r
{\r
FSP_GLOBAL_DATA *FspData;\r
\r
- FspData = GetFspGlobalDataPointer ();\r
+ FspData = GetFspGlobalDataPointer ();\r
FspData->StatusCode = StatusCode;\r
}\r
\r
-/**\r
- This function gets FSP CAR base.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-GetFspCarBase (\r
- VOID\r
- )\r
-{\r
- FSP_GLOBAL_DATA *FspData;\r
- UINT32 CarBase;\r
-\r
- FspData = GetFspGlobalDataPointer ();\r
- CarBase = FspData->PlatformData.CarBase;\r
- if (CarBase == 0) {\r
- CarBase = PcdGet32(PcdTemporaryRamBase);\r
- }\r
- return CarBase;\r
-}\r
-\r
-/**\r
- This function gets FSP CAR size.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-GetFspCarSize (\r
- VOID\r
- )\r
-{\r
- FSP_GLOBAL_DATA *FspData;\r
- UINT32 CarSize;\r
-\r
- FspData = GetFspGlobalDataPointer ();\r
- CarSize = FspData->PlatformData.CarSize;\r
- if (FspData->PlatformData.CarBase == 0) {\r
- CarSize = PcdGet32(PcdTemporaryRamSize);\r
- }\r
- return CarSize;\r
-}\r
-\r
/**\r
This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.\r
\r
VOID\r
EFIAPI\r
FspApiReturnStatusReset (\r
- IN UINT32 FspResetType\r
+ IN UINT32 FspResetType\r
)\r
{\r
volatile BOOLEAN LoopUntilReset;\r
- \r
+\r
LoopUntilReset = TRUE;\r
- DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n",FspResetType));\r
- ///\r
- /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader\r
- /// calls the FSP API without honoring the reset request by FSP\r
- ///\r
- do {\r
- SetFspApiReturnStatus ((EFI_STATUS)FspResetType);\r
- Pei2LoaderSwitchStack ();\r
- DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));\r
- DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honour the reset request from FSP\n"));\r
- } while (LoopUntilReset);\r
+ DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n", FspResetType));\r
+ if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {\r
+ ///\r
+ /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader\r
+ /// calls the FSP API without honoring the reset request by FSP\r
+ ///\r
+ do {\r
+ SetFspApiReturnStatus ((EFI_STATUS)FspResetType);\r
+ Pei2LoaderSwitchStack ();\r
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));\r
+ DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honor the reset request from FSP\n"));\r
+ } while (LoopUntilReset);\r
+ }\r
}\r