nacl.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. use spec::{
  2. binary::{SbiRet, SharedPtr},
  3. nacl::shmem_size::NATIVE,
  4. };
  5. /// Nested Acceleration extension.
  6. ///
  7. /// Nested virtualization is the ability of a hypervisor to run another hypervisor
  8. /// as a guest. RISC-V nested virtualization requires an L0 hypervisor (running
  9. /// in hypervisor-mode) to trap-and-emulate the RISC-V H-extension functionality
  10. /// (such as CSR accesses, HFENCE instructions, HLV/HSV instructions,
  11. /// etc.) for the L1 hypervisor (running in virtualized supervisor-mode).
  12. ///
  13. /// The SBI nested acceleration extension defines a shared memory based interface
  14. /// between the SBI implementation (or L0 hypervisor) and the supervisor software
  15. /// (or L1 hypervisor), which allows both to collaboratively reduce traps taken
  16. /// by the L0 hypervisor for emulating RISC-V H-extension functionality. The
  17. /// nested acceleration shared memory allows the L1 hypervisor to batch multiple
  18. /// RISC-V H-extension CSR accesses and HFENCE requests which are then emulated
  19. /// by the L0 hypervisor upon an explicit synchronization SBI call.
  20. ///
  21. /// *NOTE:* The M-mode firmware should not implement the SBI nested acceleration
  22. /// extension if the underlying platform has the RISC-V H-extension implemented
  23. /// in hardware.
  24. pub trait Nacl {
  25. /// Probe nested acceleration feature.
  26. ///
  27. /// Probe a nested acceleration feature. This is a mandatory function of the
  28. /// SBI nested acceleration extension.
  29. ///
  30. /// # Parameters
  31. ///
  32. /// The `feature_id` parameter specifies the nested acceleration feature to probe.
  33. ///
  34. /// # Return Value
  35. ///
  36. /// This function always returns SBI_SUCCESS in `SbiRet.error`. It returns `0`
  37. /// in `SbiRet.value` if the given `feature_id` is not available, or `1` in
  38. /// `SbiRet.value` if it is available.
  39. fn probe_feature(&self, feature_id: u32) -> SbiRet;
  40. /// Set nested acceleration shared memory.
  41. ///
  42. /// Set and enable the shared memory for nested acceleration on the calling
  43. /// hart.
  44. ///
  45. /// # Parameters
  46. ///
  47. /// If the physical address of `shmem` is not all-ones bitwise, then the `shmem` pointer
  48. /// specifies the shared memory physical base address. The physical address of `shmem`
  49. /// MUST be 4096-byte aligned. The size of the shared memory must be 4096 + (XLEN * 128) bytes.
  50. /// The SBI implementation MUST zero the shared memory before returning from the SBI
  51. /// call.
  52. ///
  53. /// If the physical address of `shmem` is all-ones bitwise, then the nested acceleration features
  54. /// are disabled.
  55. ///
  56. /// The `flags` parameter is reserved for future use and must be zero.
  57. ///
  58. /// # Return Value
  59. ///
  60. /// The possible return error codes returned in `SbiRet.error` are shown in the table below:
  61. ///
  62. /// | Return code | Description
  63. /// |:----------------------------|:----------------------------------------------
  64. /// | `SbiRet::success()` | The steal-time shared memory physical base address was set or cleared successfully.
  65. /// | `SbiRet::invalid_param()` | The `flags` parameter is not zero or the `shmem` is not 4096-byte aligned.
  66. /// | `SbiRet::invalid_address()` | The shared memory pointed to by the `shmem` parameter is not writable or does not satisfy other requirements of shared memory physical address range.
  67. fn set_shmem(&self, shmem: SharedPtr<[u8; NATIVE]>, flags: usize) -> SbiRet;
  68. /// Synchronize shared memory CSRs.
  69. ///
  70. /// Synchronize CSRs in the nested acceleration shared memory. This is an
  71. /// optional function that is only available if the SBI_NACL_FEAT_SYNC_CSR
  72. /// feature is available.
  73. ///
  74. /// # Parameters
  75. ///
  76. /// The parameter `csr_num` specifies the set of RISC-V H-extension CSRs to be synchronized.
  77. ///
  78. /// If `csr_num` is all-ones bitwise, then all RISC-V H-extension CSRs implemented by the SBI
  79. /// implementation (or L0 hypervisor) are synchronized.
  80. ///
  81. /// If `(csr_num & 0x300) == 0x200` and `csr_num < 0x1000` then only a single RISC-V H-extension
  82. /// CSR specified by the `csr_num` parameter is synchronized.
  83. ///
  84. /// # Return Value
  85. ///
  86. /// The possible error codes returned in `SbiRet.error` are shown in the table below:
  87. ///
  88. /// | Return code | Description
  89. /// |:--------------------------|:----------------------------------------------
  90. /// | `SbiRet::success()` | CSRs synchronized successfully.
  91. /// | `SbiRet::not_supported()` | SBI_NACL_FEAT_SYNC_CSR feature is not available.
  92. /// | `SbiRet::invalid_param()` | `csr_num` is not all-ones bitwise and either: `(csr_num & 0x300) != 0x200` or `csr_num >= 0x1000` or `csr_num` is not implemented by the SBI implementation
  93. /// | `SbiRet::no_shmem()` | Nested acceleration shared memory not available.
  94. fn sync_csr(&self, csr_num: usize) -> SbiRet;
  95. /// Synchronize shared memory HFENCEs.
  96. ///
  97. /// Synchronize HFENCEs in the nested acceleration shared memory. This is an
  98. /// optional function that is only available if the SBI_NACL_FEAT_SYNC_HFENCE
  99. /// feature is available.
  100. ///
  101. /// # Parameters
  102. ///
  103. /// The parameter `entry_index` specifies the set of nested HFENCE entries to be synchronized.
  104. ///
  105. /// If `entry_index` is all-ones bitwise, then all nested HFENCE entries are
  106. /// synchronized.
  107. ///
  108. /// If `entry_index < (3840 / XLEN)` then only a single nested HFENCE entry
  109. /// specified by the `entry_index` parameter is synchronized.
  110. ///
  111. /// # Return Value
  112. ///
  113. /// The possible error codes returned in `SbiRet.error` are shown in the table below:
  114. ///
  115. /// | Return code | Description
  116. /// |:--------------------------|:----------------------------------------------
  117. /// | `SbiRet::success()` | HFENCEs synchronized successfully.
  118. /// | `SbiRet::not_supported()` | SBI_NACL_FEAT_SYNC_HFENCE feature is not available.
  119. /// | `SbiRet::invalid_param()` | `entry_index` is not all-ones bitwise and `entry_index >= (3840 / XLEN)`.
  120. /// | `SbiRet::no_shmem()` | Nested acceleration shared memory not available.
  121. fn sync_hfence(&self, entry_index: usize) -> SbiRet;
  122. /// Synchronize shared memory and emulate SRET.
  123. ///
  124. /// Synchronize CSRs and HFENCEs in the nested acceleration shared memory and
  125. /// emulate the SRET instruction. This is an optional function that is only
  126. /// available if the SBI_NACL_FEAT_SYNC_SRET feature is available.
  127. ///
  128. /// This function is used by supervisor software (or L1 hypervisor) to do
  129. /// a synchronized SRET request, and the SBI implementation (or L0 hypervisor)
  130. /// MUST handle it.
  131. ///
  132. /// # Return Value
  133. ///
  134. /// This function does not return upon success, and the possible error codes returned in
  135. /// `SbiRet.error` upon failure are shown in the table below:
  136. ///
  137. /// | Return code | Description
  138. /// |:--------------------------|:----------------------------------------------
  139. /// | `SbiRet::not_supported()` | SBI_NACL_FEAT_SYNC_SRET feature is not available.
  140. /// | `SbiRet::no_shmem()` | Nested acceleration shared memory not available.
  141. fn sync_sret(&self) -> SbiRet;
  142. /// Function internal to macros. Do not use.
  143. #[doc(hidden)]
  144. #[inline]
  145. fn _rustsbi_probe(&self) -> usize {
  146. sbi_spec::base::UNAVAILABLE_EXTENSION.wrapping_add(1)
  147. }
  148. }
  149. impl<T: Nacl> Nacl for &T {
  150. #[inline]
  151. fn probe_feature(&self, feature_id: u32) -> SbiRet {
  152. T::probe_feature(self, feature_id)
  153. }
  154. #[inline]
  155. fn set_shmem(&self, shmem: SharedPtr<[u8; NATIVE]>, flags: usize) -> SbiRet {
  156. T::set_shmem(self, shmem, flags)
  157. }
  158. #[inline]
  159. fn sync_csr(&self, csr_num: usize) -> SbiRet {
  160. T::sync_csr(self, csr_num)
  161. }
  162. #[inline]
  163. fn sync_hfence(&self, entry_index: usize) -> SbiRet {
  164. T::sync_hfence(self, entry_index)
  165. }
  166. #[inline]
  167. fn sync_sret(&self) -> SbiRet {
  168. T::sync_sret(self)
  169. }
  170. }