rfence.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use super::SbiRet;
  2. use crate::hart_mask::HartMask;
  3. use crate::ipi::max_hart_id;
  4. use crate::rfence;
  5. const FUNCTION_RFENCE_REMOTE_FENCE_I: usize = 0x0;
  6. const FUNCTION_RFENCE_REMOTE_SFENCE_VMA: usize = 0x1;
  7. const FUNCTION_RFENCE_REMOTE_SFENCE_VMA_ASID: usize = 0x2;
  8. const FUNCTION_RFENCE_REMOTE_HFENCE_GVMA_VMID: usize = 0x3;
  9. const FUNCTION_RFENCE_REMOTE_HFENCE_GVMA: usize = 0x4;
  10. const FUNCTION_RFENCE_REMOTE_HFENCE_VVMA_ASID: usize = 0x5;
  11. const FUNCTION_RFENCE_REMOTE_HFENCE_VVMA: usize = 0x6;
  12. #[inline]
  13. pub fn handle_ecall_rfence(
  14. function: usize,
  15. param0: usize,
  16. param1: usize,
  17. param2: usize,
  18. param3: usize,
  19. param4: usize,
  20. ) -> SbiRet {
  21. match function {
  22. FUNCTION_RFENCE_REMOTE_FENCE_I => remote_fence_i(param0, param1),
  23. FUNCTION_RFENCE_REMOTE_SFENCE_VMA => remote_sfence_vma(param0, param1, param2, param3),
  24. FUNCTION_RFENCE_REMOTE_SFENCE_VMA_ASID => {
  25. remote_sfence_vma_asid(param0, param1, param2, param3, param4)
  26. }
  27. FUNCTION_RFENCE_REMOTE_HFENCE_GVMA_VMID => {
  28. remote_hfence_gvma_vmid(param0, param1, param2, param3, param4)
  29. }
  30. FUNCTION_RFENCE_REMOTE_HFENCE_GVMA => remote_hfence_gvma(param0, param1, param2, param3),
  31. FUNCTION_RFENCE_REMOTE_HFENCE_VVMA_ASID => {
  32. remote_hfence_vvma_asid(param0, param1, param2, param3, param4)
  33. }
  34. FUNCTION_RFENCE_REMOTE_HFENCE_VVMA => remote_hfence_vvma(param0, param1, param2, param3),
  35. _ => SbiRet::not_supported(),
  36. }
  37. }
  38. // If None = max_hart_id(), that means IPI extension is not supported.
  39. // In RustSBI, RFENCE support requires an IPI support is implemented.
  40. // If platform does not provide IPI support, RustSBI will disable RFENCE
  41. // interface access from supervisor level.
  42. #[inline]
  43. fn remote_fence_i(hart_mask: usize, hart_mask_base: usize) -> SbiRet {
  44. let max_hart_id = if let Some(id) = max_hart_id() {
  45. id
  46. } else {
  47. return SbiRet::not_supported();
  48. };
  49. let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
  50. rfence::remote_fence_i(hart_mask)
  51. }
  52. #[inline]
  53. fn remote_sfence_vma(
  54. hart_mask: usize,
  55. hart_mask_base: usize,
  56. start_addr: usize,
  57. size: usize,
  58. ) -> SbiRet {
  59. let max_hart_id = if let Some(id) = max_hart_id() {
  60. id
  61. } else {
  62. return SbiRet::not_supported();
  63. };
  64. let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
  65. rfence::remote_sfence_vma(hart_mask, start_addr, size)
  66. }
  67. #[inline]
  68. fn remote_sfence_vma_asid(
  69. hart_mask: usize,
  70. hart_mask_base: usize,
  71. start_addr: usize,
  72. size: usize,
  73. asid: usize,
  74. ) -> SbiRet {
  75. let max_hart_id = if let Some(id) = max_hart_id() {
  76. id
  77. } else {
  78. return SbiRet::not_supported();
  79. };
  80. let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
  81. rfence::remote_sfence_vma_asid(hart_mask, start_addr, size, asid)
  82. }
  83. #[inline]
  84. fn remote_hfence_gvma_vmid(
  85. hart_mask: usize,
  86. hart_mask_base: usize,
  87. start_addr: usize,
  88. size: usize,
  89. vmid: usize,
  90. ) -> SbiRet {
  91. let max_hart_id = if let Some(id) = max_hart_id() {
  92. id
  93. } else {
  94. return SbiRet::not_supported();
  95. };
  96. let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
  97. rfence::remote_hfence_gvma_vmid(hart_mask, start_addr, size, vmid)
  98. }
  99. #[inline]
  100. fn remote_hfence_gvma(
  101. hart_mask: usize,
  102. hart_mask_base: usize,
  103. start_addr: usize,
  104. size: usize,
  105. ) -> SbiRet {
  106. let max_hart_id = if let Some(id) = max_hart_id() {
  107. id
  108. } else {
  109. return SbiRet::not_supported();
  110. };
  111. let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
  112. rfence::remote_hfence_gvma(hart_mask, start_addr, size)
  113. }
  114. #[inline]
  115. fn remote_hfence_vvma_asid(
  116. hart_mask: usize,
  117. hart_mask_base: usize,
  118. start_addr: usize,
  119. size: usize,
  120. asid: usize,
  121. ) -> SbiRet {
  122. let max_hart_id = if let Some(id) = max_hart_id() {
  123. id
  124. } else {
  125. return SbiRet::not_supported();
  126. };
  127. let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
  128. rfence::remote_hfence_vvma_asid(hart_mask, start_addr, size, asid)
  129. }
  130. #[inline]
  131. fn remote_hfence_vvma(
  132. hart_mask: usize,
  133. hart_mask_base: usize,
  134. start_addr: usize,
  135. size: usize,
  136. ) -> SbiRet {
  137. let max_hart_id = if let Some(id) = max_hart_id() {
  138. id
  139. } else {
  140. return SbiRet::not_supported();
  141. };
  142. let hart_mask = unsafe { HartMask::from_addr(hart_mask, hart_mask_base, max_hart_id) };
  143. rfence::remote_hfence_vvma(hart_mask, start_addr, size)
  144. }