--- /dev/null
+/** @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
--- /dev/null
+/** @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
--- /dev/null
+## @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
--- /dev/null
+//------------------------------------------------------------------------------\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
## @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
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