rfence.rs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. use crate::hart_mask::HartMask;
  2. use sbi_spec::binary::SbiRet;
  3. /// Remote fence support
  4. ///
  5. /// The remote fence function acts as a full TLB flush if
  6. /// - `start_addr` and `size` are both 0, or
  7. /// - `size` is equal to `usize::MAX`.
  8. pub trait Rfence: Send + Sync {
  9. /// Instructs remote harts to execute `FENCE.I` instruction.
  10. ///
  11. /// # Return value
  12. ///
  13. /// Returns `SbiRet::success()` when remote fence was sent to all the targeted harts successfully.
  14. fn remote_fence_i(&self, hart_mask: HartMask) -> SbiRet;
  15. /// Instructs the remote harts to execute one or more `SFENCE.VMA` instructions,
  16. /// covering the range of virtual addresses between `start_addr` and `size`.
  17. ///
  18. /// # Return value
  19. ///
  20. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  21. ///
  22. /// | Return code | Description
  23. /// |:----------------------------|:----------------------------------------------
  24. /// | `SbiRet::success()` | Remote fence was sent to all the targeted harts successfully.
  25. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  26. fn remote_sfence_vma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet;
  27. /// Instruct the remote harts to execute one or more `SFENCE.VMA` instructions,
  28. /// covering the range of virtual addresses between `start_addr` and `size`.
  29. /// This covers only the given address space by `asid`.
  30. ///
  31. /// # Return value
  32. ///
  33. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  34. ///
  35. /// | Return code | Description
  36. /// |:----------------------------|:----------------------------------------------
  37. /// | `SbiRet::success()` | Remote fence was sent to all the targeted harts successfully.
  38. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  39. fn remote_sfence_vma_asid(
  40. &self,
  41. hart_mask: HartMask,
  42. start_addr: usize,
  43. size: usize,
  44. asid: usize,
  45. ) -> SbiRet;
  46. /// Instruct the remote harts to execute one or more `HFENCE.GVMA` instructions,
  47. /// covering the range of guest physical addresses between `start_addr` and `size`
  48. /// only for the given virtual machine by `vmid`.
  49. ///
  50. /// This function call is only valid for harts implementing hypervisor extension.
  51. ///
  52. /// # Return value
  53. ///
  54. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  55. ///
  56. /// | Return code | Description
  57. /// |:----------------------------|:----------------------------------------------
  58. /// | `SbiRet::success()` | Remote fence was sent to all the targeted harts successfully.
  59. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension.
  60. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  61. fn remote_hfence_gvma_vmid(
  62. &self,
  63. hart_mask: HartMask,
  64. start_addr: usize,
  65. size: usize,
  66. vmid: usize,
  67. ) -> SbiRet {
  68. let _ = (hart_mask, start_addr, size, vmid);
  69. SbiRet::not_supported()
  70. }
  71. /// Instruct the remote harts to execute one or more `HFENCE.GVMA` instructions,
  72. /// covering the range of guest physical addresses between `start_addr` and `size`
  73. /// for all the guests.
  74. ///
  75. /// This function call is only valid for harts implementing hypervisor extension.
  76. ///
  77. /// # Return value
  78. ///
  79. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  80. ///
  81. /// | Return code | Description
  82. /// |:----------------------------|:----------------------------------------------
  83. /// | `SbiRet::success()` | Remote fence was sent to all the targeted harts successfully.
  84. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension.
  85. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  86. fn remote_hfence_gvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  87. let _ = (hart_mask, start_addr, size);
  88. SbiRet::not_supported()
  89. }
  90. /// Instruct the remote harts to execute one or more `HFENCE.VVMA` instructions,
  91. /// covering the range of guest virtual addresses between `start_addr` and `size` for the given
  92. /// address space by `asid` and current virtual machine (by `vmid` in `hgatp` CSR)
  93. /// of calling hart.
  94. ///
  95. /// This function call is only valid for harts implementing hypervisor extension.
  96. ///
  97. /// # Return value
  98. ///
  99. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  100. ///
  101. /// | Return code | Description
  102. /// |:----------------------------|:----------------------------------------------
  103. /// | `SbiRet::success()` | Remote fence was sent to all the targeted harts successfully.
  104. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension.
  105. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  106. fn remote_hfence_vvma_asid(
  107. &self,
  108. hart_mask: HartMask,
  109. start_addr: usize,
  110. size: usize,
  111. asid: usize,
  112. ) -> SbiRet {
  113. let _ = (hart_mask, start_addr, size, asid);
  114. SbiRet::not_supported()
  115. }
  116. /// Instruct the remote harts to execute one or more `HFENCE.VVMA` instructions,
  117. /// covering the range of guest virtual addresses between `start_addr` and `size`
  118. /// for current virtual machine (by `vmid` in `hgatp` CSR) of calling hart.
  119. ///
  120. /// This function call is only valid for harts implementing hypervisor extension.
  121. ///
  122. /// # Return value
  123. ///
  124. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  125. ///
  126. /// | Return code | Description
  127. /// |:----------------------------|:----------------------------------------------
  128. /// | `SbiRet::success()` | Remote fence was sent to all the targeted harts successfully.
  129. /// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension.
  130. /// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid.
  131. fn remote_hfence_vvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  132. let _ = (hart_mask, start_addr, size);
  133. SbiRet::not_supported()
  134. }
  135. }
  136. impl<T: Rfence> Rfence for &T {
  137. #[inline]
  138. fn remote_fence_i(&self, hart_mask: HartMask) -> SbiRet {
  139. T::remote_fence_i(self, hart_mask)
  140. }
  141. #[inline]
  142. fn remote_sfence_vma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  143. T::remote_sfence_vma(self, hart_mask, start_addr, size)
  144. }
  145. #[inline]
  146. fn remote_sfence_vma_asid(
  147. &self,
  148. hart_mask: HartMask,
  149. start_addr: usize,
  150. size: usize,
  151. asid: usize,
  152. ) -> SbiRet {
  153. T::remote_sfence_vma_asid(self, hart_mask, start_addr, size, asid)
  154. }
  155. #[inline]
  156. fn remote_hfence_gvma_vmid(
  157. &self,
  158. hart_mask: HartMask,
  159. start_addr: usize,
  160. size: usize,
  161. vmid: usize,
  162. ) -> SbiRet {
  163. T::remote_hfence_gvma_vmid(self, hart_mask, start_addr, size, vmid)
  164. }
  165. #[inline]
  166. fn remote_hfence_gvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  167. T::remote_hfence_gvma(self, hart_mask, start_addr, size)
  168. }
  169. #[inline]
  170. fn remote_hfence_vvma_asid(
  171. &self,
  172. hart_mask: HartMask,
  173. start_addr: usize,
  174. size: usize,
  175. asid: usize,
  176. ) -> SbiRet {
  177. T::remote_hfence_vvma_asid(self, hart_mask, start_addr, size, asid)
  178. }
  179. #[inline]
  180. fn remote_hfence_vvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  181. T::remote_hfence_vvma(self, hart_mask, start_addr, size)
  182. }
  183. }