RiscVEdk2SbiLib.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /** @file
  2. Library to call the RISC-V SBI ecalls
  3. Copyright (c) 2021-2022, Hewlett Packard Development LP. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. @par Glossary:
  6. - Hart - Hardware Thread, similar to a CPU core
  7. **/
  8. #ifndef RISCV_SBI_LIB_H_
  9. #define RISCV_SBI_LIB_H_
  10. #include <Uefi.h>
  11. #include <IndustryStandard/RiscVOpensbi.h>
  12. #include <sbi/sbi_scratch.h>
  13. #include <sbi/sbi_platform.h>
  14. #include <sbi/sbi_ecall.h>
  15. //
  16. // EDK2 OpenSBI Firmware extension.
  17. //
  18. #define SBI_EDK2_FW_EXT (SBI_EXT_FIRMWARE_START | SBI_OPENSBI_IMPID)
  19. //
  20. // EDK2 OpenSBI Firmware extension functions.
  21. //
  22. #define SBI_EXT_FW_MSCRATCH_FUNC 0
  23. #define SBI_EXT_FW_MSCRATCH_HARTID_FUNC 1
  24. //
  25. // EDK2 OpenSBI firmware extension return status.
  26. //
  27. typedef struct {
  28. UINTN Error; ///< SBI status code
  29. UINTN Value; ///< Value returned
  30. } SBI_RET;
  31. /**
  32. Get the implemented SBI specification version
  33. The minor number of the SBI specification is encoded in the low 24 bits,
  34. with the major number encoded in the next 7 bits. Bit 32 must be 0 and is
  35. reserved for future expansion.
  36. @param[out] SpecVersion The Version of the SBI specification.
  37. **/
  38. VOID
  39. EFIAPI
  40. SbiGetSpecVersion (
  41. OUT UINTN *SpecVersion
  42. );
  43. /**
  44. Get the SBI implementation ID
  45. This ID is used to identify a specific SBI implementation in order to work
  46. around any quirks it might have.
  47. @param[out] ImplId The ID of the SBI implementation.
  48. **/
  49. VOID
  50. EFIAPI
  51. SbiGetImplId (
  52. OUT UINTN *ImplId
  53. );
  54. /**
  55. Get the SBI implementation version
  56. The version of this SBI implementation.
  57. The encoding of this number is determined by the specific SBI implementation.
  58. @param[out] ImplVersion The version of the SBI implementation.
  59. **/
  60. VOID
  61. EFIAPI
  62. SbiGetImplVersion (
  63. OUT UINTN *ImplVersion
  64. );
  65. /**
  66. Probe whether an SBI extension is available
  67. ProbeResult is set to 0 if the extension is not available or to an extension
  68. specified value if it is available.
  69. @param[in] ExtensionId The extension ID.
  70. @param[out] ProbeResult The return value of the probe.
  71. **/
  72. VOID
  73. EFIAPI
  74. SbiProbeExtension (
  75. IN INTN ExtensionId,
  76. OUT INTN *ProbeResult
  77. );
  78. /**
  79. Get the CPU's vendor ID
  80. Reads the mvendorid CSR.
  81. @param[out] MachineVendorId The CPU's vendor ID.
  82. **/
  83. VOID
  84. EFIAPI
  85. SbiGetMachineVendorId (
  86. OUT UINTN *MachineVendorId
  87. );
  88. /**
  89. Get the CPU's architecture ID
  90. Reads the marchid CSR.
  91. @param[out] MachineArchId The CPU's architecture ID.
  92. **/
  93. VOID
  94. EFIAPI
  95. SbiGetMachineArchId (
  96. OUT UINTN *MachineArchId
  97. );
  98. /**
  99. Get the CPU's implementation ID
  100. Reads the mimpid CSR.
  101. @param[out] MachineImplId The CPU's implementation ID.
  102. **/
  103. VOID
  104. EFIAPI
  105. SbiGetMachineImplId (
  106. OUT UINTN *MachineImplId
  107. );
  108. /**
  109. Politely ask the SBI to start a given hart.
  110. This call may return before the hart has actually started executing, if the
  111. SBI implementation can guarantee that the hart is actually going to start.
  112. Before the hart jumps to StartAddr, the hart MUST configure PMP if present
  113. and switch to S-mode.
  114. @param[in] HartId The id of the hart to start.
  115. @param[in] StartAddr The physical address, where the hart starts
  116. executing from.
  117. @param[in] Priv An XLEN-bit value, which will be in register
  118. a1 when the hart starts.
  119. @retval EFI_SUCCESS Hart was stopped and will start executing from StartAddr.
  120. @retval EFI_LOAD_ERROR StartAddr is not valid, possibly due to following reasons:
  121. - It is not a valid physical address.
  122. - The address is prohibited by PMP to run in
  123. supervisor mode.
  124. @retval EFI_INVALID_PARAMETER HartId is not a valid hart id
  125. @retval EFI_ALREADY_STARTED The hart is already running.
  126. @retval other The start request failed for unknown reasons.
  127. **/
  128. EFI_STATUS
  129. EFIAPI
  130. SbiHartStart (
  131. IN UINTN HartId,
  132. IN UINTN StartAddr,
  133. IN UINTN Priv
  134. );
  135. /**
  136. Return execution of the calling hart to SBI.
  137. MUST be called in S-Mode with user interrupts disabled.
  138. This call is not expected to return, unless a failure occurs.
  139. @retval EFI_SUCCESS Never occurs. When successful, the call does not return.
  140. @retval other Failed to stop hard for an unknown reason.
  141. **/
  142. EFI_STATUS
  143. EFIAPI
  144. SbiHartStop (
  145. );
  146. /**
  147. Get the current status of a hart.
  148. Since harts can transition between states at any time, the status retrieved
  149. by this function may already be out of date, once it returns.
  150. Possible values for HartStatus are:
  151. 0: STARTED
  152. 1: STOPPED
  153. 2: START_REQUEST_PENDING
  154. 3: STOP_REQUEST_PENDING
  155. @param[out] HartStatus The pointer in which the hart's status is
  156. stored.
  157. @retval EFI_SUCCESS The operation succeeds.
  158. @retval EFI_INVALID_PARAMETER A parameter is invalid.
  159. **/
  160. EFI_STATUS
  161. EFIAPI
  162. SbiHartGetStatus (
  163. IN UINTN HartId,
  164. OUT UINTN *HartStatus
  165. );
  166. ///
  167. /// Timer extension
  168. ///
  169. /**
  170. Clear pending timer interrupt bit and set timer for next event after Time.
  171. To clear the timer without scheduling a timer event, set Time to a
  172. practically infinite value or mask the timer interrupt by clearing sie.STIE.
  173. @param[in] Time The time offset to the next scheduled timer interrupt.
  174. **/
  175. VOID
  176. EFIAPI
  177. SbiSetTimer (
  178. IN UINT64 Time
  179. );
  180. ///
  181. /// IPI extension
  182. ///
  183. /**
  184. Send IPI to all harts specified in the mask.
  185. The interrupts are registered as supervisor software interrupts at the
  186. receiving hart.
  187. @param[in] HartMask Scalar bit-vector containing hart ids
  188. @param[in] HartMaskBase The starting hartid from which the bit-vector
  189. must be computed. If set to -1, HartMask is
  190. ignored and all harts are considered.
  191. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  192. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  193. from hart_mask is not valid i.e. either the
  194. hartid is not enabled by the platform or is
  195. not available to the supervisor.
  196. **/
  197. EFI_STATUS
  198. EFIAPI
  199. SbiSendIpi (
  200. IN UINTN *HartMask,
  201. IN UINTN HartMaskBase
  202. );
  203. ///
  204. /// Remote fence extension
  205. ///
  206. /**
  207. Instructs remote harts to execute a FENCE.I instruction.
  208. @param[in] HartMask Scalar bit-vector containing hart ids
  209. @param[in] HartMaskBase The starting hartid from which the bit-vector
  210. must be computed. If set to -1, HartMask is
  211. ignored and all harts are considered.
  212. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  213. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  214. from hart_mask is not valid i.e. either the
  215. hartid is not enabled by the platform or is
  216. not available to the supervisor.
  217. **/
  218. EFI_STATUS
  219. EFIAPI
  220. SbiRemoteFenceI (
  221. IN UINTN *HartMask,
  222. IN UINTN HartMaskBase
  223. );
  224. /**
  225. Instructs the remote harts to execute one or more SFENCE.VMA instructions.
  226. The SFENCE.VMA covers the range of virtual addresses between StartAddr and Size.
  227. The remote fence function acts as a full tlb flush if * StartAddr and size
  228. are both 0 * size is equal to 2^XLEN-1
  229. @param[in] HartMask Scalar bit-vector containing hart ids
  230. @param[in] HartMaskBase The starting hartid from which the bit-vector
  231. must be computed. If set to -1, HartMask is
  232. ignored and all harts are considered.
  233. @param[in] StartAddr The first address of the affected range.
  234. @param[in] Size How many addresses are affected.
  235. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  236. @retval EFI_LOAD_ERROR StartAddr or Size is not valid.
  237. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  238. from hart_mask is not valid i.e. either the
  239. hartid is not enabled by the platform or is
  240. not available to the supervisor.
  241. **/
  242. EFI_STATUS
  243. EFIAPI
  244. SbiRemoteSfenceVma (
  245. IN UINTN *HartMask,
  246. IN UINTN HartMaskBase,
  247. IN UINTN StartAddr,
  248. IN UINTN Size
  249. );
  250. /**
  251. Instructs the remote harts to execute one or more SFENCE.VMA instructions.
  252. The SFENCE.VMA covers the range of virtual addresses between StartAddr and Size.
  253. Covers only the given ASID.
  254. The remote fence function acts as a full tlb flush if * StartAddr and size
  255. are both 0 * size is equal to 2^XLEN-1
  256. @param[in] HartMask Scalar bit-vector containing hart ids
  257. @param[in] HartMaskBase The starting hartid from which the bit-vector
  258. must be computed. If set to -1, HartMask is
  259. ignored and all harts are considered.
  260. @param[in] StartAddr The first address of the affected range.
  261. @param[in] Size How many addresses are affected.
  262. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  263. @retval EFI_LOAD_ERROR StartAddr or Size is not valid.
  264. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  265. from hart_mask is not valid i.e. either the
  266. hartid is not enabled by the platform or is
  267. not available to the supervisor.
  268. **/
  269. EFI_STATUS
  270. EFIAPI
  271. SbiRemoteSfenceVmaAsid (
  272. IN UINTN *HartMask,
  273. IN UINTN HartMaskBase,
  274. IN UINTN StartAddr,
  275. IN UINTN Size,
  276. IN UINTN Asid
  277. );
  278. /**
  279. Instructs the remote harts to execute one or more SFENCE.GVMA instructions.
  280. The SFENCE.GVMA covers the range of virtual addresses between StartAddr and Size.
  281. Covers only the given VMID.
  282. This function call is only valid for harts implementing the hypervisor extension.
  283. The remote fence function acts as a full tlb flush if * StartAddr and size
  284. are both 0 * size is equal to 2^XLEN-1
  285. @param[in] HartMask Scalar bit-vector containing hart ids
  286. @param[in] HartMaskBase The starting hartid from which the bit-vector
  287. must be computed. If set to -1, HartMask is
  288. ignored and all harts are considered.
  289. @param[in] StartAddr The first address of the affected range.
  290. @param[in] Size How many addresses are affected.
  291. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  292. @retval EFI_LOAD_ERROR StartAddr or Size is not valid.
  293. @retval EFI_UNSUPPORTED SBI does not implement this function or one
  294. of the target harts does not support the
  295. hypervisor extension.
  296. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  297. from hart_mask is not valid i.e. either the
  298. hartid is not enabled by the platform or is
  299. not available to the supervisor.
  300. **/
  301. EFI_STATUS
  302. EFIAPI
  303. SbiRemoteHfenceGvmaVmid (
  304. IN UINTN *HartMask,
  305. IN UINTN HartMaskBase,
  306. IN UINTN StartAddr,
  307. IN UINTN Size,
  308. IN UINTN Vmid
  309. );
  310. /**
  311. Instructs the remote harts to execute one or more SFENCE.GVMA instructions.
  312. The SFENCE.GVMA covers the range of virtual addresses between StartAddr and Size.
  313. This function call is only valid for harts implementing the hypervisor extension.
  314. The remote fence function acts as a full tlb flush if * StartAddr and size
  315. are both 0 * size is equal to 2^XLEN-1
  316. @param[in] HartMask Scalar bit-vector containing hart ids
  317. @param[in] HartMaskBase The starting hartid from which the bit-vector
  318. must be computed. If set to -1, HartMask is
  319. ignored and all harts are considered.
  320. @param[in] StartAddr The first address of the affected range.
  321. @param[in] Size How many addresses are affected.
  322. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  323. @retval EFI_LOAD_ERROR StartAddr or Size is not valid.
  324. @retval EFI_UNSUPPORTED SBI does not implement this function or one
  325. of the target harts does not support the
  326. hypervisor extension.
  327. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  328. from hart_mask is not valid i.e. either the
  329. hartid is not enabled by the platform or is
  330. not available to the supervisor.
  331. **/
  332. EFI_STATUS
  333. EFIAPI
  334. SbiRemoteHfenceGvma (
  335. IN UINTN *HartMask,
  336. IN UINTN HartMaskBase,
  337. IN UINTN StartAddr,
  338. IN UINTN Size
  339. );
  340. /**
  341. Instructs the remote harts to execute one or more SFENCE.VVMA instructions.
  342. The SFENCE.GVMA covers the range of virtual addresses between StartAddr and Size.
  343. Covers only the given ASID.
  344. This function call is only valid for harts implementing the hypervisor extension.
  345. The remote fence function acts as a full tlb flush if * StartAddr and size
  346. are both 0 * size is equal to 2^XLEN-1
  347. @param[in] HartMask Scalar bit-vector containing hart ids
  348. @param[in] HartMaskBase The starting hartid from which the bit-vector
  349. must be computed. If set to -1, HartMask is
  350. ignored and all harts are considered.
  351. @param[in] StartAddr The first address of the affected range.
  352. @param[in] Size How many addresses are affected.
  353. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  354. @retval EFI_LOAD_ERROR StartAddr or Size is not valid.
  355. @retval EFI_UNSUPPORTED SBI does not implement this function or one
  356. of the target harts does not support the
  357. hypervisor extension.
  358. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  359. from hart_mask is not valid i.e. either the
  360. hartid is not enabled by the platform or is
  361. not available to the supervisor.
  362. **/
  363. EFI_STATUS
  364. EFIAPI
  365. SbiRemoteHfenceVvmaAsid (
  366. IN UINTN *HartMask,
  367. IN UINTN HartMaskBase,
  368. IN UINTN StartAddr,
  369. IN UINTN Size,
  370. IN UINTN Asid
  371. );
  372. /**
  373. Instructs the remote harts to execute one or more SFENCE.VVMA instructions.
  374. The SFENCE.GVMA covers the range of virtual addresses between StartAddr and Size.
  375. This function call is only valid for harts implementing the hypervisor extension.
  376. The remote fence function acts as a full tlb flush if * StartAddr and size
  377. are both 0 * size is equal to 2^XLEN-1
  378. @param[in] HartMask Scalar bit-vector containing hart ids
  379. @param[in] HartMaskBase The starting hartid from which the bit-vector
  380. must be computed. If set to -1, HartMask is
  381. ignored and all harts are considered.
  382. @param[in] StartAddr The first address of the affected range.
  383. @param[in] Size How many addresses are affected.
  384. @retval EFI_SUCCESS IPI was sent to all the targeted harts.
  385. @retval EFI_LOAD_ERROR StartAddr or Size is not valid.
  386. @retval EFI_UNSUPPORTED SBI does not implement this function or one
  387. of the target harts does not support the
  388. hypervisor extension.
  389. @retval EFI_INVALID_PARAMETER Either hart_mask_base or any of the hartid
  390. from hart_mask is not valid i.e. either the
  391. hartid is not enabled by the platform or is
  392. not available to the supervisor.
  393. **/
  394. EFI_STATUS
  395. EFIAPI
  396. SbiRemoteHfenceVvma (
  397. IN UINTN *HartMask,
  398. IN UINTN HartMaskBase,
  399. IN UINTN StartAddr,
  400. IN UINTN Size
  401. );
  402. ///
  403. /// Firmware System Reset (SRST) Extension
  404. ///
  405. /**
  406. Reset the system
  407. The System Reset Extension provides a function that allow the supervisor
  408. software to request system-level reboot or shutdown. The term "system" refers
  409. to the world-view of supervisor software and the underlying SBI
  410. implementation could be machine mode firmware or hypervisor.
  411. Valid parameters for ResetType and ResetReason are defined in sbi_ecall_interface.h
  412. #define SBI_SRST_RESET_TYPE_SHUTDOWN 0x0
  413. #define SBI_SRST_RESET_TYPE_COLD_REBOOT 0x1
  414. #define SBI_SRST_RESET_TYPE_WARM_REBOOT 0x2
  415. #define SBI_SRST_RESET_REASON_NONE 0x0
  416. #define SBI_SRST_RESET_REASON_SYSFAIL 0x1
  417. When the call is successful, it will not return.
  418. @param[in] ResetType Typ of reset: Shutdown, cold-, or warm-reset.
  419. @param[in] ResetReason Why the system resets. No reason or system failure.
  420. @retval EFI_INVALID_PARAMETER Either ResetType or ResetReason is invalid.
  421. @retval EFI_UNSUPPORTED ResetType is valid but not implemented on the platform.
  422. @retval EFI_DEVICE_ERROR Unknown error.
  423. **/
  424. EFI_STATUS
  425. EFIAPI
  426. SbiSystemReset (
  427. IN UINTN ResetType,
  428. IN UINTN ResetReason
  429. );
  430. ///
  431. /// Vendor Specific extension space: Extension Ids 0x09000000 through 0x09FFFFFF
  432. ///
  433. /**
  434. Call a function in a vendor defined SBI extension
  435. ASSERT() if the ExtensionId is not in the designated SBI Vendor Extension
  436. Space.
  437. @param[in] ExtensionId The SBI vendor extension ID.
  438. @param[in] FunctionId The function ID to call in this extension.
  439. @param[in] NumArgs How many arguments are passed.
  440. @param[in] ... Actual Arguments to the function.
  441. @retval EFI_SUCCESS if the SBI function was called and it was successful
  442. @retval EFI_INVALID_PARAMETER if NumArgs exceeds 6
  443. @retval others if the called SBI function returns an error
  444. **/
  445. EFI_STATUS
  446. EFIAPI
  447. SbiVendorCall (
  448. IN UINTN ExtensionId,
  449. IN UINTN FunctionId,
  450. IN UINTN NumArgs,
  451. ...
  452. );
  453. ///
  454. /// Firmware SBI Extension
  455. ///
  456. /// This SBI Extension is defined and used by EDK2 only in order to be able to
  457. /// run PI and DXE phase in S-Mode.
  458. ///
  459. /**
  460. Get scratch space of the current hart.
  461. Please consider using the wrapper SbiGetFirmwareContext if you only need to
  462. access the firmware context.
  463. @param[out] ScratchSpace The scratch space pointer.
  464. **/
  465. VOID
  466. EFIAPI
  467. SbiGetMscratch (
  468. OUT SBI_SCRATCH **ScratchSpace
  469. );
  470. /**
  471. Get scratch space of the given hart id.
  472. @param[in] HartId The hart id.
  473. @param[out] ScratchSpace The scratch space pointer.
  474. **/
  475. VOID
  476. EFIAPI
  477. SbiGetMscratchHartid (
  478. IN UINTN HartId,
  479. OUT SBI_SCRATCH **ScratchSpace
  480. );
  481. /**
  482. Get firmware context of the calling hart.
  483. @param[out] FirmwareContext The firmware context pointer.
  484. **/
  485. VOID
  486. EFIAPI
  487. SbiGetFirmwareContext (
  488. OUT EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT **FirmwareContext
  489. );
  490. /**
  491. Set firmware context of the calling hart.
  492. @param[in] FirmwareContext The firmware context pointer.
  493. **/
  494. VOID
  495. EFIAPI
  496. SbiSetFirmwareContext (
  497. IN EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext
  498. );
  499. #endif