]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c
Add IntelFspPkg to support create FSP bin based on EDKII.
[mirror_edk2.git] / IntelFspPkg / Library / BaseFspCommonLib / FspCommonLib.c
diff --git a/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c b/IntelFspPkg/Library/BaseFspCommonLib/FspCommonLib.c
new file mode 100644 (file)
index 0000000..958a732
--- /dev/null
@@ -0,0 +1,318 @@
+/** @file\r
+\r
+  Copyright (c) 2014, 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
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <FspGlobalData.h>\r
+#include <FspApi.h>\r
+\r
+#pragma pack(1)\r
+\r
+//\r
+//   Cont Func Parameter 2        +0x3C\r
+//   Cont Func Parameter 1        +0x38\r
+//\r
+//   API Parameter                +0x34\r
+//   API return address           +0x30\r
+//\r
+//   push    offset exit          +0x2C\r
+//   pushfd                       +0x28\r
+//   cli\r
+//   pushad                       +0x24\r
+//   sub     esp, 8               +0x00\r
+//   sidt    fword ptr [esp]\r
+//\r
+typedef struct {\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
+  UINT16    Flags[2];\r
+  UINT32    ExitOff;\r
+  UINT32    ApiRet;\r
+  UINT32    ApiParam;\r
+} CONTEXT_STACK;\r
+\r
+#define CONTEXT_STACK_OFFSET(x)  (UINT32)&((CONTEXT_STACK *)(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
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspGlobalDataPointer (\r
+  IN FSP_GLOBAL_DATA   *FspData\r
+  )\r
+{\r
+  ASSERT (FspData != NULL);\r
+  *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;\r
+}\r
+\r
+/**\r
+  This function gets the FSP global data pointer.\r
+\r
+**/\r
+FSP_GLOBAL_DATA *\r
+EFIAPI\r
+GetFspGlobalDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA   *FspData;\r
+\r
+  FspData = *(FSP_GLOBAL_DATA  **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);\r
+  return FspData;\r
+}\r
+\r
+/**\r
+  This function gets back the FSP API paramter passed by the bootlaoder.\r
+\r
+  @retval ApiParameter FSP API paramter passed by the bootlaoder.\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFspApiParameter (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam));\r
+}\r
+\r
+/**\r
+  This function sets the FSP API paramter in the stack.\r
+\r
+   @param[in] Value       New parameter value.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiParameter (\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
+}\r
+\r
+/**\r
+  This function sets the FSP continuation function parameters in the stack.\r
+\r
+  @param[in] Value             New parameter value to set.\r
+  @param[in] Index             Parameter index.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspContinuationFuncParameter (\r
+  IN UINT32      Value,\r
+  IN UINT32      Index\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam) + (Index + 1) * sizeof(UINT32)) = Value;\r
+}\r
+\r
+\r
+/**\r
+  This function changes the Bootloader return address in stack.\r
+\r
+  @param[in] ReturnAddress       Address to return.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiReturnAddress (\r
+  IN UINT32  ReturnAddress\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiRet)) = ReturnAddress;\r
+}\r
+\r
+/**\r
+  This function set the API status code returned to the bootloader.\r
+\r
+  @param[in] ReturnStatus       Status code to return.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspApiReturnStatus (\r
+  IN UINT32  ReturnStatus\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;\r
+}\r
+\r
+/**\r
+  This function sets the context switching stack to a new stack frame.\r
+\r
+  @param[in] NewStackTop       New core stack to be set.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspCoreStackPointer (\r
+  IN VOID   *NewStackTop\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+  UINT32           *OldStack;\r
+  UINT32           *NewStack;\r
+  UINT32           StackContextLen;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);\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
+  while (StackContextLen-- != 0) {\r
+    *NewStack++ = *OldStack++;\r
+  }\r
+}\r
+\r
+/**\r
+  This function sets the platform specific data pointer.\r
+\r
+  @param[in] PlatformData       Fsp platform specific data pointer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspPlatformDataPointer (\r
+  IN VOID   *PlatformData\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\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
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspPlatformDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return FspData->PlatformData.DataPtr;\r
+}\r
+\r
+\r
+/**\r
+  This function sets the UPD data pointer.\r
+\r
+  @param[in] UpdDataRgnPtr   UPD data pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFspUpdDataPointer (\r
+  IN VOID    *UpdDataRgnPtr\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  //\r
+  // Get the Fsp Global Data Pointer\r
+  //\r
+  FspData  = GetFspGlobalDataPointer ();\r
+\r
+  //\r
+  // Set the UPD pointer.\r
+  //\r
+  FspData->UpdDataRgnPtr = UpdDataRgnPtr;\r
+}\r
+\r
+/**\r
+  This function gets the UPD data pointer.\r
+\r
+  @return UpdDataRgnPtr   UPD data pointer.\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFspUpdDataPointer (\r
+  VOID\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\r
+  FspData  = GetFspGlobalDataPointer ();\r
+  return FspData->UpdDataRgnPtr;\r
+}\r
+\r
+/**\r
+  Set FSP measurement point timestamp.\r
+\r
+  @param[in] Id       Measurement point ID.\r
+\r
+  @return performance timestamp.\r
+**/\r
+UINT64\r
+EFIAPI\r
+SetFspMeasurePoint (\r
+  IN UINT8  Id\r
+  )\r
+{\r
+  FSP_GLOBAL_DATA  *FspData;\r
+\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
+    ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;\r
+  }\r
+\r
+  return FspData->PerfData[(FspData->PerfIdx)++];\r
+}\r