rfnc.rs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. //! Chapter 8. RFENCE Extension (EID #0x52464E43 "RFNC")
  2. use crate::binary::{sbi_call_2, sbi_call_4, sbi_call_5};
  3. use sbi_spec::{
  4. binary::{HartMask, SbiRet},
  5. rfnc::{
  6. EID_RFNC, REMOTE_FENCE_I, REMOTE_HFENCE_GVMA, REMOTE_HFENCE_GVMA_VMID, REMOTE_HFENCE_VVMA,
  7. REMOTE_HFENCE_VVMA_ASID, REMOTE_SFENCE_VMA, REMOTE_SFENCE_VMA_ASID,
  8. },
  9. };
  10. /// Execute `FENCE.I` instruction on remote harts.
  11. ///
  12. /// # Return value
  13. ///
  14. /// Returns `SbiRet::success()` when a remote fence was sent to all the targeted harts successfully.
  15. ///
  16. /// This function is defined in RISC-V SBI Specification chapter 8.1.
  17. #[inline]
  18. pub fn remote_fence_i(hart_mask: HartMask) -> SbiRet {
  19. let (hart_mask, hart_mask_base) = hart_mask.into_inner();
  20. sbi_call_2(EID_RFNC, REMOTE_FENCE_I, hart_mask, hart_mask_base)
  21. }
  22. /// Execute `SFENCE.VMA` instructions for all address spaces on remote harts.
  23. ///
  24. /// This function instructs the remote harts to execute one or more `SFENCE.VMA` instructions,
  25. /// covering the range of virtual addresses between `start_addr` and `size`.
  26. ///
  27. /// # Return value
  28. ///
  29. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  30. ///
  31. /// | Return code | Description
  32. /// |:----------------------------|:----------------------------------------------
  33. /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
  34. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  35. ///
  36. /// This function is defined in RISC-V SBI Specification chapter 8.2.
  37. #[inline]
  38. pub fn remote_sfence_vma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  39. let (hart_mask, hart_mask_base) = hart_mask.into_inner();
  40. sbi_call_4(
  41. EID_RFNC,
  42. REMOTE_SFENCE_VMA,
  43. hart_mask,
  44. hart_mask_base,
  45. start_addr,
  46. size,
  47. )
  48. }
  49. /// Execute address-space-based `SFENCE.VMA` instructions on remote harts.
  50. ///
  51. /// This function instructs the remote harts to execute one or more `SFENCE.VMA` instructions,
  52. /// covering the range of virtual addresses between `start_addr` and `size`.
  53. /// This covers only the given address space by `asid`.
  54. ///
  55. /// # Return value
  56. ///
  57. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  58. ///
  59. /// | Return code | Description
  60. /// |:----------------------------|:----------------------------------------------
  61. /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
  62. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  63. ///
  64. /// This function is defined in RISC-V SBI Specification chapter 8.3.
  65. #[inline]
  66. pub fn remote_sfence_vma_asid(
  67. hart_mask: HartMask,
  68. start_addr: usize,
  69. size: usize,
  70. asid: usize,
  71. ) -> SbiRet {
  72. let (hart_mask, hart_mask_base) = hart_mask.into_inner();
  73. sbi_call_5(
  74. EID_RFNC,
  75. REMOTE_SFENCE_VMA_ASID,
  76. hart_mask,
  77. hart_mask_base,
  78. start_addr,
  79. size,
  80. asid,
  81. )
  82. }
  83. /// Execute virtual machine id based `HFENCE.GVMA` instructions on remote harts.
  84. ///
  85. /// This function instructs the remote harts to execute one or more `HFENCE.GVMA`
  86. /// instructions, covering the range of guest physical addresses between `start_addr`
  87. /// and `size` only for the given virtual machine by `vmid`.
  88. ///
  89. /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
  90. ///
  91. /// # Return value
  92. ///
  93. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  94. ///
  95. /// | Return code | Description
  96. /// |:----------------------------|:----------------------------------------------
  97. /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
  98. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension.
  99. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  100. ///
  101. /// This function is defined in RISC-V SBI Specification chapter 8.4.
  102. #[inline]
  103. pub fn remote_hfence_gvma_vmid(
  104. hart_mask: HartMask,
  105. start_addr: usize,
  106. size: usize,
  107. vmid: usize,
  108. ) -> SbiRet {
  109. let (hart_mask, hart_mask_base) = hart_mask.into_inner();
  110. sbi_call_5(
  111. EID_RFNC,
  112. REMOTE_HFENCE_GVMA_VMID,
  113. hart_mask,
  114. hart_mask_base,
  115. start_addr,
  116. size,
  117. vmid,
  118. )
  119. }
  120. /// Execute `HFENCE.GVMA` instructions for all virtual machines on remote harts.
  121. ///
  122. /// This function instructs the remote harts to execute one or more `HFENCE.GVMA` instructions,
  123. /// covering the range of guest physical addresses between `start_addr` and `size`
  124. /// for all the guests.
  125. ///
  126. /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
  127. ///
  128. /// # Return value
  129. ///
  130. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  131. ///
  132. /// | Return code | Description
  133. /// |:----------------------------|:----------------------------------------------
  134. /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
  135. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension.
  136. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  137. ///
  138. /// This function is defined in RISC-V SBI Specification chapter 8.5.
  139. #[inline]
  140. pub fn remote_hfence_gvma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  141. let (hart_mask, hart_mask_base) = hart_mask.into_inner();
  142. sbi_call_4(
  143. EID_RFNC,
  144. REMOTE_HFENCE_GVMA,
  145. hart_mask,
  146. hart_mask_base,
  147. start_addr,
  148. size,
  149. )
  150. }
  151. /// Execute address space based `HFENCE.VVMA` for current virtual machine on remote harts.
  152. ///
  153. /// This function instructs the remote harts to execute one or more `HFENCE.VVMA` instructions,
  154. /// covering the range of guest virtual addresses between `start_addr` and `size` for the given
  155. /// address space by `asid` and current virtual machine (by `vmid` in `hgatp` CSR)
  156. /// of calling hart.
  157. ///
  158. /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
  159. ///
  160. /// # Return value
  161. ///
  162. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  163. ///
  164. /// | Return code | Description
  165. /// |:----------------------------|:----------------------------------------------
  166. /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
  167. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension.
  168. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  169. ///
  170. /// This function is defined in RISC-V SBI Specification chapter 8.6.
  171. #[inline]
  172. pub fn remote_hfence_vvma_asid(
  173. hart_mask: HartMask,
  174. start_addr: usize,
  175. size: usize,
  176. asid: usize,
  177. ) -> SbiRet {
  178. let (hart_mask, hart_mask_base) = hart_mask.into_inner();
  179. sbi_call_5(
  180. EID_RFNC,
  181. REMOTE_HFENCE_VVMA_ASID,
  182. hart_mask,
  183. hart_mask_base,
  184. start_addr,
  185. size,
  186. asid,
  187. )
  188. }
  189. /// Execute `HFENCE.VVMA` for all address spaces in the current virtual machine on remote harts.
  190. ///
  191. /// This function instructs the remote harts to execute one or more `HFENCE.VVMA` instructions,
  192. /// covering the range of guest virtual addresses between `start_addr` and `size`
  193. /// for current virtual machine (by `vmid` in `hgatp` CSR) of calling hart.
  194. ///
  195. /// This function call is only valid on harts implementing the RISC-V hypervisor extension.
  196. ///
  197. /// # Return value
  198. ///
  199. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  200. ///
  201. /// | Return code | Description
  202. /// |:----------------------------|:----------------------------------------------
  203. /// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully.
  204. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension.
  205. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  206. ///
  207. /// This function is defined in RISC-V SBI Specification chapter 8.7.
  208. #[inline]
  209. pub fn remote_hfence_vvma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  210. let (hart_mask, hart_mask_base) = hart_mask.into_inner();
  211. sbi_call_4(
  212. EID_RFNC,
  213. REMOTE_HFENCE_VVMA,
  214. hart_mask,
  215. hart_mask_base,
  216. start_addr,
  217. size,
  218. )
  219. }