]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
IntelFsp2Pkg: BaseFspCommonLib Support for X64
[mirror_edk2.git] / IntelFsp2Pkg / Library / BaseFspCommonLib / FspCommonLib.c
index 0c5f0b306ea4a187ea86b60abf6d843216ce595f..cd10b63c95d35d1debbf3a718df835bab8d014bc 100644 (file)
@@ -1,13 +1,7 @@
 /** @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
@@ -17,7 +11,6 @@
 #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
@@ -37,38 +30,51 @@ typedef struct {
   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
@@ -81,18 +87,18 @@ GetFspGlobalDataPointer (
   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
@@ -100,16 +106,33 @@ GetFspApiParameter (
 {\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
@@ -117,8 +140,8 @@ GetFspApiParameter2 (
 {\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
@@ -130,13 +153,13 @@ GetFspApiParameter2 (
 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
@@ -148,13 +171,13 @@ SetFspApiParameter (
 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
@@ -166,23 +189,23 @@ SetFspApiReturnStatus (
 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
+  UINT           *OldStack;\r
+  UINT           *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
@@ -191,26 +214,25 @@ SetFspCoreStackPointer (
 /**\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
@@ -221,11 +243,10 @@ GetFspPlatformDataPointer (
 {\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
@@ -234,15 +255,15 @@ GetFspPlatformDataPointer (
 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
@@ -263,39 +284,38 @@ GetFspUpdDataPointer (
 {\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
@@ -305,39 +325,38 @@ GetFspMemoryInitUpdDataPointer (
 {\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
@@ -347,11 +366,10 @@ GetFspSiliconInitUpdDataPointer (
 {\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
@@ -371,9 +389,9 @@ SetFspMeasurePoint (
   // 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
@@ -391,7 +409,7 @@ GetFspInfoHeader (
   VOID\r
   )\r
 {\r
-  return  GetFspGlobalDataPointer()->FspInfoHeader;\r
+  return GetFspGlobalDataPointer ()->FspInfoHeader;\r
 }\r
 \r
 /**\r
@@ -402,10 +420,10 @@ GetFspInfoHeader (
 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
@@ -421,8 +439,8 @@ GetFspInfoHeaderFromApiContext (
 {\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
@@ -436,10 +454,10 @@ GetFspCfgRegionDataPointer (
   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
@@ -453,7 +471,7 @@ GetFspApiCallingIndex (
   VOID\r
   )\r
 {\r
-  return  GetFspGlobalDataPointer()->ApiIdx;\r
+  return GetFspGlobalDataPointer ()->ApiIdx;\r
 }\r
 \r
 /**\r
@@ -469,7 +487,7 @@ SetFspApiCallingIndex (
 {\r
   FSP_GLOBAL_DATA  *FspData;\r
 \r
-  FspData  = GetFspGlobalDataPointer ();\r
+  FspData         = GetFspGlobalDataPointer ();\r
   FspData->ApiIdx = Index;\r
 }\r
 \r
@@ -484,7 +502,7 @@ GetPhaseStatusCode (
   VOID\r
   )\r
 {\r
-  return  GetFspGlobalDataPointer()->StatusCode;\r
+  return GetFspGlobalDataPointer ()->StatusCode;\r
 }\r
 \r
 /**\r
@@ -500,52 +518,10 @@ SetPhaseStatusCode (
 {\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
@@ -555,21 +531,23 @@ GetFspCarSize (
 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