]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg: Add BaseRiscVSbiLib Library for RISC-V
authorSunil V L <sunilvl@ventanamicro.com>
Wed, 7 Sep 2022 06:53:32 +0000 (12:23 +0530)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Thu, 16 Feb 2023 05:53:28 +0000 (05:53 +0000)
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4076

This library is required to make SBI ecalls from the S-mode EDK2.
This is mostly copied from
edk2-platforms/Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Abner Chang <abner.chang@amd.com>
Reviewed-by: Andrei Warkentin <andrei.warkentin@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
MdePkg/Include/Library/BaseRiscVSbiLib.h [new file with mode: 0644]
MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c [new file with mode: 0644]
MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf [new file with mode: 0644]
MdePkg/Library/BaseRiscVSbiLib/RiscVSbiEcall.S [new file with mode: 0644]
MdePkg/MdePkg.dec
MdePkg/MdePkg.dsc

diff --git a/MdePkg/Include/Library/BaseRiscVSbiLib.h b/MdePkg/Include/Library/BaseRiscVSbiLib.h
new file mode 100644 (file)
index 0000000..e75520b
--- /dev/null
@@ -0,0 +1,154 @@
+/** @file\r
+  Library to call the RISC-V SBI ecalls\r
+\r
+  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+  @par Glossary:\r
+    - Hart - Hardware Thread, similar to a CPU core\r
+\r
+  Currently, EDK2 needs to call SBI only to set the time and to do system reset.\r
+\r
+**/\r
+\r
+#ifndef RISCV_SBI_LIB_H_\r
+#define RISCV_SBI_LIB_H_\r
+\r
+#include <Uefi.h>\r
+\r
+/* SBI Extension IDs */\r
+#define SBI_EXT_TIME  0x54494D45\r
+#define SBI_EXT_SRST  0x53525354\r
+\r
+/* SBI function IDs for TIME extension*/\r
+#define SBI_EXT_TIME_SET_TIMER  0x0\r
+\r
+/* SBI function IDs for SRST extension */\r
+#define SBI_EXT_SRST_RESET  0x0\r
+\r
+#define SBI_SRST_RESET_TYPE_SHUTDOWN     0x0\r
+#define SBI_SRST_RESET_TYPE_COLD_REBOOT  0x1\r
+#define SBI_SRST_RESET_TYPE_WARM_REBOOT  0x2\r
+\r
+#define SBI_SRST_RESET_REASON_NONE     0x0\r
+#define SBI_SRST_RESET_REASON_SYSFAIL  0x1\r
+\r
+/* SBI return error codes */\r
+#define SBI_SUCCESS                0\r
+#define SBI_ERR_FAILED             -1\r
+#define SBI_ERR_NOT_SUPPORTED      -2\r
+#define SBI_ERR_INVALID_PARAM      -3\r
+#define SBI_ERR_DENIED             -4\r
+#define SBI_ERR_INVALID_ADDRESS    -5\r
+#define SBI_ERR_ALREADY_AVAILABLE  -6\r
+#define SBI_ERR_ALREADY_STARTED    -7\r
+#define SBI_ERR_ALREADY_STOPPED    -8\r
+\r
+#define SBI_LAST_ERR  SBI_ERR_ALREADY_STOPPED\r
+\r
+typedef struct {\r
+  UINT64    BootHartId;\r
+  VOID      *PeiServiceTable;    // PEI Service table\r
+  VOID      *PrePiHobList;       // Pre PI Hob List\r
+  UINT64    FlattenedDeviceTree; // Pointer to Flattened Device tree\r
+} EFI_RISCV_FIRMWARE_CONTEXT;\r
+\r
+//\r
+// EDK2 OpenSBI firmware extension return status.\r
+//\r
+typedef struct {\r
+  UINTN    Error; ///< SBI status code\r
+  UINTN    Value; ///< Value returned\r
+} SBI_RET;\r
+\r
+VOID\r
+EFIAPI\r
+SbiSetTimer (\r
+  IN  UINT64  Time\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+SbiSystemReset (\r
+  IN  UINTN  ResetType,\r
+  IN  UINTN  ResetReason\r
+  );\r
+\r
+/**\r
+  Get firmware context of the calling hart.\r
+\r
+  @param[out] FirmwareContext      The firmware context pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+GetFirmwareContext (\r
+  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext\r
+  );\r
+\r
+/**\r
+  Set firmware context of the calling hart.\r
+\r
+  @param[in] FirmwareContext       The firmware context pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFirmwareContext (\r
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext\r
+  );\r
+\r
+/**\r
+  Get pointer to OpenSBI Firmware Context\r
+\r
+  Get the pointer of firmware context.\r
+\r
+  @param    FirmwareContextPtr   Pointer to retrieve pointer to the\r
+                                 Firmware Context.\r
+**/\r
+VOID\r
+EFIAPI\r
+GetFirmwareContextPointer (\r
+  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr\r
+  );\r
+\r
+/**\r
+  Set pointer to OpenSBI Firmware Context\r
+\r
+  Set the pointer of firmware context.\r
+\r
+  @param    FirmwareContextPtr   Pointer to Firmware Context.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFirmwareContextPointer (\r
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr\r
+  );\r
+\r
+/**\r
+  Make ECALL in assembly\r
+\r
+  Switch to M-mode\r
+\r
+  @param[in,out]   Arg0\r
+  @param[in,out]   Arg1\r
+  @param[in]       Arg2\r
+  @param[in]       Arg3\r
+  @param[in]       Arg4\r
+  @param[in]       Arg5\r
+  @param[in]       FID\r
+  @param[in]       EXT\r
+**/\r
+VOID\r
+EFIAPI\r
+RiscVSbiEcall (\r
+  IN OUT UINTN  *Arg0,\r
+  IN OUT UINTN  *Arg1,\r
+  IN UINTN      Arg2,\r
+  IN UINTN      Arg3,\r
+  IN UINTN      Arg4,\r
+  IN UINTN      Arg5,\r
+  IN UINTN      Fid,\r
+  IN UINTN      Ext\r
+  );\r
+\r
+#endif\r
diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.c
new file mode 100644 (file)
index 0000000..2ba8f5e
--- /dev/null
@@ -0,0 +1,231 @@
+/** @file\r
+  Instance of the SBI ecall library.\r
+\r
+  It allows calling an SBI function via an ecall from S-Mode.\r
+\r
+  Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseRiscVSbiLib.h>\r
+\r
+//\r
+// Maximum arguments for SBI ecall\r
+#define SBI_CALL_MAX_ARGS  6\r
+\r
+/**\r
+  Call SBI call using ecall instruction.\r
+\r
+  Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.\r
+\r
+  @param[in] ExtId    SBI extension ID.\r
+  @param[in] FuncId   SBI function ID.\r
+  @param[in] NumArgs  Number of arguments to pass to the ecall.\r
+  @param[in] ...      Argument list for the ecall.\r
+\r
+  @retval  Returns SBI_RET structure with value and error code.\r
+\r
+**/\r
+STATIC\r
+SBI_RET\r
+EFIAPI\r
+SbiCall (\r
+  IN  UINTN  ExtId,\r
+  IN  UINTN  FuncId,\r
+  IN  UINTN  NumArgs,\r
+  ...\r
+  )\r
+{\r
+  UINTN    I;\r
+  SBI_RET  Ret;\r
+  UINTN    Args[SBI_CALL_MAX_ARGS];\r
+  VA_LIST  ArgList;\r
+\r
+  VA_START (ArgList, NumArgs);\r
+\r
+  if (NumArgs > SBI_CALL_MAX_ARGS) {\r
+    Ret.Error = SBI_ERR_INVALID_PARAM;\r
+    Ret.Value = -1;\r
+    return Ret;\r
+  }\r
+\r
+  for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {\r
+    if (I < NumArgs) {\r
+      Args[I] = VA_ARG (ArgList, UINTN);\r
+    } else {\r
+      // Default to 0 for all arguments that are not given\r
+      Args[I] = 0;\r
+    }\r
+  }\r
+\r
+  VA_END (ArgList);\r
+\r
+  // ECALL updates the a0 and a1 registers as return values.\r
+  RiscVSbiEcall (\r
+    &Args[0],\r
+    &Args[1],\r
+    Args[2],\r
+    Args[3],\r
+    Args[4],\r
+    Args[5],\r
+    (UINTN)(FuncId),\r
+    (UINTN)(ExtId)\r
+    );\r
+\r
+  Ret.Error = Args[0];\r
+  Ret.Value = Args[1];\r
+  return Ret;\r
+}\r
+\r
+/**\r
+  Translate SBI error code to EFI status.\r
+\r
+  @param[in] SbiError   SBI error code\r
+  @retval EFI_STATUS\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+TranslateError (\r
+  IN  UINTN  SbiError\r
+  )\r
+{\r
+  switch (SbiError) {\r
+    case SBI_SUCCESS:\r
+      return EFI_SUCCESS;\r
+    case SBI_ERR_FAILED:\r
+      return EFI_DEVICE_ERROR;\r
+      break;\r
+    case SBI_ERR_NOT_SUPPORTED:\r
+      return EFI_UNSUPPORTED;\r
+      break;\r
+    case SBI_ERR_INVALID_PARAM:\r
+      return EFI_INVALID_PARAMETER;\r
+      break;\r
+    case SBI_ERR_DENIED:\r
+      return EFI_ACCESS_DENIED;\r
+      break;\r
+    case SBI_ERR_INVALID_ADDRESS:\r
+      return EFI_LOAD_ERROR;\r
+      break;\r
+    case SBI_ERR_ALREADY_AVAILABLE:\r
+      return EFI_ALREADY_STARTED;\r
+      break;\r
+    default:\r
+      //\r
+      // Reaches here only if SBI has defined a new error type\r
+      //\r
+      ASSERT (FALSE);\r
+      return EFI_UNSUPPORTED;\r
+      break;\r
+  }\r
+}\r
+\r
+/**\r
+  Clear pending timer interrupt bit and set timer for next event after Time.\r
+\r
+  To clear the timer without scheduling a timer event, set Time to a\r
+  practically infinite value or mask the timer interrupt by clearing sie.STIE.\r
+\r
+  @param[in]  Time                 The time offset to the next scheduled timer interrupt.\r
+**/\r
+VOID\r
+EFIAPI\r
+SbiSetTimer (\r
+  IN  UINT64  Time\r
+  )\r
+{\r
+  SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time);\r
+}\r
+\r
+/**\r
+  Reset the system using SRST SBI extenion\r
+\r
+  @param[in]  ResetType            The SRST System Reset Type.\r
+  @param[in]  ResetReason          The SRST System Reset Reason.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SbiSystemReset (\r
+  IN  UINTN  ResetType,\r
+  IN  UINTN  ResetReason\r
+  )\r
+{\r
+  SBI_RET  Ret;\r
+\r
+  Ret = SbiCall (\r
+          SBI_EXT_SRST,\r
+          SBI_EXT_SRST_RESET,\r
+          2,\r
+          ResetType,\r
+          ResetReason\r
+          );\r
+\r
+  return TranslateError (Ret.Error);\r
+}\r
+\r
+/**\r
+  Get firmware context of the calling hart.\r
+\r
+  @param[out] FirmwareContext      The firmware context pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+GetFirmwareContext (\r
+  OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContext\r
+  )\r
+{\r
+  *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT *)RiscVGetSupervisorScratch ();\r
+}\r
+\r
+/**\r
+  Set firmware context of the calling hart.\r
+\r
+  @param[in] FirmwareContext       The firmware context pointer.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFirmwareContext (\r
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContext\r
+  )\r
+{\r
+  RiscVSetSupervisorScratch ((UINT64)FirmwareContext);\r
+}\r
+\r
+/**\r
+  Get pointer to OpenSBI Firmware Context\r
+\r
+  Get the pointer of firmware context through OpenSBI FW Extension SBI.\r
+\r
+  @param    FirmwareContextPtr   Pointer to retrieve pointer to the\r
+                                 Firmware Context.\r
+**/\r
+VOID\r
+EFIAPI\r
+GetFirmwareContextPointer (\r
+  IN OUT EFI_RISCV_FIRMWARE_CONTEXT  **FirmwareContextPtr\r
+  )\r
+{\r
+  GetFirmwareContext (FirmwareContextPtr);\r
+}\r
+\r
+/**\r
+  Set the pointer to OpenSBI Firmware Context\r
+\r
+  Set the pointer of firmware context through OpenSBI FW Extension SBI.\r
+\r
+  @param    FirmwareContextPtr   Pointer to Firmware Context.\r
+**/\r
+VOID\r
+EFIAPI\r
+SetFirmwareContextPointer (\r
+  IN EFI_RISCV_FIRMWARE_CONTEXT  *FirmwareContextPtr\r
+  )\r
+{\r
+  SetFirmwareContext (FirmwareContextPtr);\r
+}\r
diff --git a/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf b/MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf
new file mode 100644 (file)
index 0000000..d6fd3f6
--- /dev/null
@@ -0,0 +1,26 @@
+## @file\r
+# RISC-V Library to call SBI ecalls\r
+#\r
+#  Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION         = 0x0001001b\r
+  BASE_NAME           = BaseRiscVSbiLib\r
+  FILE_GUID           = D742CF3D-E600-4009-8FB5-318073008508\r
+  MODULE_TYPE         = BASE\r
+  VERSION_STRING      = 1.0\r
+  LIBRARY_CLASS       = RiscVSbiLib\r
+\r
+[Sources]\r
+  BaseRiscVSbiLib.c\r
+  RiscVSbiEcall.S\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
diff --git a/MdePkg/Library/BaseRiscVSbiLib/RiscVSbiEcall.S b/MdePkg/Library/BaseRiscVSbiLib/RiscVSbiEcall.S
new file mode 100644 (file)
index 0000000..8ba69f8
--- /dev/null
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------\r
+//\r
+// Make ECALL to SBI\r
+//\r
+// Copyright (c) 2023, Ventana Micro Systems Inc. All rights reserved.<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+//------------------------------------------------------------------------------\r
+\r
+#include <Register/RiscV64/RiscVImpl.h>\r
+\r
+.data\r
+.align 3\r
+.section .text\r
+\r
+//\r
+// Make ECALL to SBI\r
+// ecall updates the same a0 and a1 registers with\r
+// return values. Hence, the C function which calls\r
+// this should pass the address of Arg0 and Arg1.\r
+// This routine saves the address and updates it\r
+// with a0 and a1 once ecall returns.\r
+//\r
+// @param a0 : Pointer to Arg0\r
+// @param a1 : Pointer to Arg1\r
+// @param a2 : Arg2\r
+// @param a3 : Arg3\r
+// @param a4 : Arg4\r
+// @param a5 : Arg5\r
+// @param a6 : FunctionID\r
+// @param a7 : ExtensionId\r
+//\r
+ASM_FUNC (RiscVSbiEcall)\r
+  mv t0, a0\r
+  mv t1, a1\r
+  ld a0, 0(a0)\r
+  ld a1, 0(a1)\r
+  ecall\r
+  sd a0, 0(t0)\r
+  sd a1, 0(t1)\r
+  ret\r
index a7ad5204197bda0626bd121e5324a20b8efaff35..80b655905314786ea96062d15b2c4174f4e1bc82 100644 (file)
   ##  @libraryclass  Provides function to support TDX processing.\r
   TdxLib|Include/Library/TdxLib.h\r
 \r
+[LibraryClasses.RISCV64]\r
+  ##  @libraryclass  Provides function to make ecalls to SBI\r
+  BaseRiscVSbiLib|Include/Library/BaseRiscVSbiLib.h\r
+\r
 [Guids]\r
   #\r
   # GUID defined in UEFI2.1/UEFI2.0/EFI1.1\r
index 32a852dc466e09535eaf4cdc3cc789bd91440fbc..0ac7618b46234516263b78e1987d91dd052e9a90 100644 (file)
   MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicArmVirt.inf\r
   MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf\r
 \r
+[Components.RISCV64]\r
+  MdePkg/Library/BaseRiscVSbiLib/BaseRiscVSbiLib.inf\r
+\r
 [BuildOptions]\r