BaseRiscVSbiLib.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /** @file
  2. Instance of the SBI ecall library.
  3. It allows calling an SBI function via an ecall from S-Mode.
  4. Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include <Library/BaseLib.h>
  8. #include <Library/BaseMemoryLib.h>
  9. #include <Library/DebugLib.h>
  10. #include <Library/BaseRiscVSbiLib.h>
  11. //
  12. // Maximum arguments for SBI ecall
  13. #define SBI_CALL_MAX_ARGS 6
  14. /**
  15. Call SBI call using ecall instruction.
  16. Asserts when NumArgs exceeds SBI_CALL_MAX_ARGS.
  17. @param[in] ExtId SBI extension ID.
  18. @param[in] FuncId SBI function ID.
  19. @param[in] NumArgs Number of arguments to pass to the ecall.
  20. @param[in] ... Argument list for the ecall.
  21. @retval Returns SBI_RET structure with value and error code.
  22. **/
  23. STATIC
  24. SBI_RET
  25. EFIAPI
  26. SbiCall (
  27. IN UINTN ExtId,
  28. IN UINTN FuncId,
  29. IN UINTN NumArgs,
  30. ...
  31. )
  32. {
  33. UINTN I;
  34. SBI_RET Ret;
  35. UINTN Args[SBI_CALL_MAX_ARGS];
  36. VA_LIST ArgList;
  37. VA_START (ArgList, NumArgs);
  38. if (NumArgs > SBI_CALL_MAX_ARGS) {
  39. Ret.Error = SBI_ERR_INVALID_PARAM;
  40. Ret.Value = -1;
  41. return Ret;
  42. }
  43. for (I = 0; I < SBI_CALL_MAX_ARGS; I++) {
  44. if (I < NumArgs) {
  45. Args[I] = VA_ARG (ArgList, UINTN);
  46. } else {
  47. // Default to 0 for all arguments that are not given
  48. Args[I] = 0;
  49. }
  50. }
  51. VA_END (ArgList);
  52. // ECALL updates the a0 and a1 registers as return values.
  53. RiscVSbiEcall (
  54. &Args[0],
  55. &Args[1],
  56. Args[2],
  57. Args[3],
  58. Args[4],
  59. Args[5],
  60. (UINTN)(FuncId),
  61. (UINTN)(ExtId)
  62. );
  63. Ret.Error = Args[0];
  64. Ret.Value = Args[1];
  65. return Ret;
  66. }
  67. /**
  68. Translate SBI error code to EFI status.
  69. @param[in] SbiError SBI error code
  70. @retval EFI_STATUS
  71. **/
  72. STATIC
  73. EFI_STATUS
  74. EFIAPI
  75. TranslateError (
  76. IN UINTN SbiError
  77. )
  78. {
  79. switch (SbiError) {
  80. case SBI_SUCCESS:
  81. return EFI_SUCCESS;
  82. case SBI_ERR_FAILED:
  83. return EFI_DEVICE_ERROR;
  84. break;
  85. case SBI_ERR_NOT_SUPPORTED:
  86. return EFI_UNSUPPORTED;
  87. break;
  88. case SBI_ERR_INVALID_PARAM:
  89. return EFI_INVALID_PARAMETER;
  90. break;
  91. case SBI_ERR_DENIED:
  92. return EFI_ACCESS_DENIED;
  93. break;
  94. case SBI_ERR_INVALID_ADDRESS:
  95. return EFI_LOAD_ERROR;
  96. break;
  97. case SBI_ERR_ALREADY_AVAILABLE:
  98. return EFI_ALREADY_STARTED;
  99. break;
  100. default:
  101. //
  102. // Reaches here only if SBI has defined a new error type
  103. //
  104. ASSERT (FALSE);
  105. return EFI_UNSUPPORTED;
  106. break;
  107. }
  108. }
  109. /**
  110. Clear pending timer interrupt bit and set timer for next event after Time.
  111. To clear the timer without scheduling a timer event, set Time to a
  112. practically infinite value or mask the timer interrupt by clearing sie.STIE.
  113. @param[in] Time The time offset to the next scheduled timer interrupt.
  114. **/
  115. VOID
  116. EFIAPI
  117. SbiSetTimer (
  118. IN UINT64 Time
  119. )
  120. {
  121. SbiCall (SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, 1, Time);
  122. }
  123. /**
  124. Reset the system using SRST SBI extenion
  125. @param[in] ResetType The SRST System Reset Type.
  126. @param[in] ResetReason The SRST System Reset Reason.
  127. **/
  128. EFI_STATUS
  129. EFIAPI
  130. SbiSystemReset (
  131. IN UINTN ResetType,
  132. IN UINTN ResetReason
  133. )
  134. {
  135. SBI_RET Ret;
  136. Ret = SbiCall (
  137. SBI_EXT_SRST,
  138. SBI_EXT_SRST_RESET,
  139. 2,
  140. ResetType,
  141. ResetReason
  142. );
  143. return TranslateError (Ret.Error);
  144. }
  145. /**
  146. Get firmware context of the calling hart.
  147. @param[out] FirmwareContext The firmware context pointer.
  148. **/
  149. VOID
  150. EFIAPI
  151. GetFirmwareContext (
  152. OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContext
  153. )
  154. {
  155. *FirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT *)RiscVGetSupervisorScratch ();
  156. }
  157. /**
  158. Set firmware context of the calling hart.
  159. @param[in] FirmwareContext The firmware context pointer.
  160. **/
  161. VOID
  162. EFIAPI
  163. SetFirmwareContext (
  164. IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContext
  165. )
  166. {
  167. RiscVSetSupervisorScratch ((UINT64)FirmwareContext);
  168. }
  169. /**
  170. Get pointer to OpenSBI Firmware Context
  171. Get the pointer of firmware context through OpenSBI FW Extension SBI.
  172. @param FirmwareContextPtr Pointer to retrieve pointer to the
  173. Firmware Context.
  174. **/
  175. VOID
  176. EFIAPI
  177. GetFirmwareContextPointer (
  178. IN OUT EFI_RISCV_FIRMWARE_CONTEXT **FirmwareContextPtr
  179. )
  180. {
  181. GetFirmwareContext (FirmwareContextPtr);
  182. }
  183. /**
  184. Set the pointer to OpenSBI Firmware Context
  185. Set the pointer of firmware context through OpenSBI FW Extension SBI.
  186. @param FirmwareContextPtr Pointer to Firmware Context.
  187. **/
  188. VOID
  189. EFIAPI
  190. SetFirmwareContextPointer (
  191. IN EFI_RISCV_FIRMWARE_CONTEXT *FirmwareContextPtr
  192. )
  193. {
  194. SetFirmwareContext (FirmwareContextPtr);
  195. }