forward.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. use crate::{Console, Cppc, EnvInfo, Fence, Hsm, Ipi, Nacl, Pmu, Reset, Sta, Susp, Timer};
  2. use sbi_spec::{
  3. binary::{HartMask, Physical, SbiRet, SharedPtr},
  4. nacl::shmem_size::NATIVE,
  5. };
  6. /// Forwards SBI calls onto current supervisor environment.
  7. ///
  8. /// If crate feature `forward` is enabled, this structure implements all RustSBI extensions
  9. /// by forwarding the calls into current supervisor environment. This is done by `sbi-rt`
  10. /// crate; thus `Forward` is only available when it's running in RISC-V SBI environments.
  11. ///
  12. /// `Forward` implements all RustSBI traits, but is only effective if `#[cfg(feature = "forward")]`
  13. /// is enabled. Otherwise, struct `Forward` is `unimplemented!()` on SBI calls.
  14. ///
  15. /// # Examples
  16. ///
  17. /// This structure can be used as a structure field in `#[derive(RustSBI)]`, with helper
  18. /// macro `#[rustsbi(extension_1, extension_2, ...)]` annotating what extensions should be
  19. /// forwarded to `sbi-rt` in the structure.
  20. ///
  21. /// ```rust
  22. /// use rustsbi::{Forward, RustSBI};
  23. ///
  24. /// // Forwards fence, timer and console extensions, but the hsm extension
  25. /// // is still handled by the `hsm` field variable.
  26. /// #[derive(RustSBI)]
  27. /// struct VmSBI {
  28. /// hsm: VmHsm,
  29. /// #[rustsbi(fence, timer, console, info)]
  30. /// forward: Forward,
  31. /// }
  32. ///
  33. /// # use sbi_spec::binary::SbiRet;
  34. /// # struct VmHsm;
  35. /// # impl rustsbi::Hsm for VmHsm {
  36. /// # fn hart_start(&self, _: usize, _: usize, _: usize) -> SbiRet { unimplemented!() }
  37. /// # fn hart_stop(&self) -> SbiRet { unimplemented!() }
  38. /// # fn hart_get_status(&self, _: usize) -> SbiRet { unimplemented!() }
  39. /// # }
  40. /// ```
  41. #[derive(Debug, Clone)]
  42. pub struct Forward;
  43. impl Console for Forward {
  44. #[inline]
  45. fn write(&self, bytes: Physical<&[u8]>) -> SbiRet {
  46. match () {
  47. #[cfg(feature = "forward")]
  48. () => sbi_rt::console_write(bytes),
  49. #[cfg(not(feature = "forward"))]
  50. () => {
  51. let _ = bytes;
  52. unimplemented!()
  53. }
  54. }
  55. }
  56. #[inline]
  57. fn read(&self, bytes: Physical<&mut [u8]>) -> SbiRet {
  58. match () {
  59. #[cfg(feature = "forward")]
  60. () => sbi_rt::console_read(bytes),
  61. #[cfg(not(feature = "forward"))]
  62. () => {
  63. let _ = bytes;
  64. unimplemented!()
  65. }
  66. }
  67. }
  68. #[inline]
  69. fn write_byte(&self, byte: u8) -> SbiRet {
  70. match () {
  71. #[cfg(feature = "forward")]
  72. () => sbi_rt::console_write_byte(byte),
  73. #[cfg(not(feature = "forward"))]
  74. () => {
  75. let _ = byte;
  76. unimplemented!()
  77. }
  78. }
  79. }
  80. }
  81. impl Cppc for Forward {
  82. #[inline]
  83. fn probe(&self, reg_id: u32) -> SbiRet {
  84. match () {
  85. #[cfg(feature = "forward")]
  86. () => sbi_rt::cppc_probe(reg_id),
  87. #[cfg(not(feature = "forward"))]
  88. () => {
  89. let _ = reg_id;
  90. unimplemented!()
  91. }
  92. }
  93. }
  94. #[inline]
  95. fn read(&self, reg_id: u32) -> SbiRet {
  96. match () {
  97. #[cfg(feature = "forward")]
  98. () => sbi_rt::cppc_read(reg_id),
  99. #[cfg(not(feature = "forward"))]
  100. () => {
  101. let _ = reg_id;
  102. unimplemented!()
  103. }
  104. }
  105. }
  106. #[inline]
  107. fn read_hi(&self, reg_id: u32) -> SbiRet {
  108. match () {
  109. #[cfg(feature = "forward")]
  110. () => sbi_rt::cppc_read_hi(reg_id),
  111. #[cfg(not(feature = "forward"))]
  112. () => {
  113. let _ = reg_id;
  114. unimplemented!()
  115. }
  116. }
  117. }
  118. #[inline]
  119. fn write(&self, reg_id: u32, val: u64) -> SbiRet {
  120. match () {
  121. #[cfg(feature = "forward")]
  122. () => sbi_rt::cppc_write(reg_id, val),
  123. #[cfg(not(feature = "forward"))]
  124. () => {
  125. let _ = (reg_id, val);
  126. unimplemented!()
  127. }
  128. }
  129. }
  130. }
  131. impl Fence for Forward {
  132. #[inline]
  133. fn remote_fence_i(&self, hart_mask: HartMask) -> SbiRet {
  134. match () {
  135. #[cfg(feature = "forward")]
  136. () => sbi_rt::remote_fence_i(hart_mask),
  137. #[cfg(not(feature = "forward"))]
  138. () => {
  139. let _ = hart_mask;
  140. unimplemented!()
  141. }
  142. }
  143. }
  144. #[inline]
  145. fn remote_sfence_vma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  146. match () {
  147. #[cfg(feature = "forward")]
  148. () => sbi_rt::remote_sfence_vma(hart_mask, start_addr, size),
  149. #[cfg(not(feature = "forward"))]
  150. () => {
  151. let _ = (hart_mask, start_addr, size);
  152. unimplemented!()
  153. }
  154. }
  155. }
  156. #[inline]
  157. fn remote_sfence_vma_asid(
  158. &self,
  159. hart_mask: HartMask,
  160. start_addr: usize,
  161. size: usize,
  162. asid: usize,
  163. ) -> SbiRet {
  164. match () {
  165. #[cfg(feature = "forward")]
  166. () => sbi_rt::remote_sfence_vma_asid(hart_mask, start_addr, size, asid),
  167. #[cfg(not(feature = "forward"))]
  168. () => {
  169. let _ = (hart_mask, start_addr, size, asid);
  170. unimplemented!()
  171. }
  172. }
  173. }
  174. #[inline]
  175. fn remote_hfence_gvma_vmid(
  176. &self,
  177. hart_mask: HartMask,
  178. start_addr: usize,
  179. size: usize,
  180. vmid: usize,
  181. ) -> SbiRet {
  182. match () {
  183. #[cfg(feature = "forward")]
  184. () => sbi_rt::remote_hfence_gvma_vmid(hart_mask, start_addr, size, vmid),
  185. #[cfg(not(feature = "forward"))]
  186. () => {
  187. let _ = (hart_mask, start_addr, size, vmid);
  188. unimplemented!()
  189. }
  190. }
  191. }
  192. #[inline]
  193. fn remote_hfence_gvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  194. match () {
  195. #[cfg(feature = "forward")]
  196. () => sbi_rt::remote_hfence_gvma(hart_mask, start_addr, size),
  197. #[cfg(not(feature = "forward"))]
  198. () => {
  199. let _ = (hart_mask, start_addr, size);
  200. unimplemented!()
  201. }
  202. }
  203. }
  204. #[inline]
  205. fn remote_hfence_vvma_asid(
  206. &self,
  207. hart_mask: HartMask,
  208. start_addr: usize,
  209. size: usize,
  210. asid: usize,
  211. ) -> SbiRet {
  212. match () {
  213. #[cfg(feature = "forward")]
  214. () => sbi_rt::remote_hfence_vvma_asid(hart_mask, start_addr, size, asid),
  215. #[cfg(not(feature = "forward"))]
  216. () => {
  217. let _ = (hart_mask, start_addr, size, asid);
  218. unimplemented!()
  219. }
  220. }
  221. }
  222. #[inline]
  223. fn remote_hfence_vvma(&self, hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet {
  224. match () {
  225. #[cfg(feature = "forward")]
  226. () => sbi_rt::remote_hfence_vvma(hart_mask, start_addr, size),
  227. #[cfg(not(feature = "forward"))]
  228. () => {
  229. let _ = (hart_mask, start_addr, size);
  230. unimplemented!()
  231. }
  232. }
  233. }
  234. }
  235. impl Hsm for Forward {
  236. #[inline]
  237. fn hart_start(&self, hartid: usize, start_addr: usize, opaque: usize) -> SbiRet {
  238. match () {
  239. #[cfg(feature = "forward")]
  240. () => sbi_rt::hart_start(hartid, start_addr, opaque),
  241. #[cfg(not(feature = "forward"))]
  242. () => {
  243. let _ = (hartid, start_addr, opaque);
  244. unimplemented!()
  245. }
  246. }
  247. }
  248. #[inline]
  249. fn hart_stop(&self) -> SbiRet {
  250. match () {
  251. #[cfg(feature = "forward")]
  252. () => sbi_rt::hart_stop(),
  253. #[cfg(not(feature = "forward"))]
  254. () => {
  255. unimplemented!()
  256. }
  257. }
  258. }
  259. #[inline]
  260. fn hart_get_status(&self, hartid: usize) -> SbiRet {
  261. match () {
  262. #[cfg(feature = "forward")]
  263. () => sbi_rt::hart_get_status(hartid),
  264. #[cfg(not(feature = "forward"))]
  265. () => {
  266. let _ = hartid;
  267. unimplemented!()
  268. }
  269. }
  270. }
  271. #[inline]
  272. fn hart_suspend(&self, suspend_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
  273. match () {
  274. #[cfg(feature = "forward")]
  275. () => sbi_rt::hart_suspend(suspend_type, resume_addr, opaque),
  276. #[cfg(not(feature = "forward"))]
  277. () => {
  278. let _ = (suspend_type, resume_addr, opaque);
  279. unimplemented!()
  280. }
  281. }
  282. }
  283. }
  284. impl Ipi for Forward {
  285. #[inline]
  286. fn send_ipi(&self, hart_mask: HartMask) -> SbiRet {
  287. match () {
  288. #[cfg(feature = "forward")]
  289. () => sbi_rt::send_ipi(hart_mask),
  290. #[cfg(not(feature = "forward"))]
  291. () => {
  292. let _ = hart_mask;
  293. unimplemented!()
  294. }
  295. }
  296. }
  297. }
  298. impl Nacl for Forward {
  299. #[inline]
  300. fn probe_feature(&self, feature_id: u32) -> SbiRet {
  301. match () {
  302. #[cfg(feature = "forward")]
  303. () => sbi_rt::nacl_probe_feature(feature_id),
  304. #[cfg(not(feature = "forward"))]
  305. () => {
  306. let _ = feature_id;
  307. unimplemented!()
  308. }
  309. }
  310. }
  311. #[inline]
  312. fn set_shmem(&self, shmem: SharedPtr<[u8; NATIVE]>, flags: usize) -> SbiRet {
  313. match () {
  314. #[cfg(feature = "forward")]
  315. () => sbi_rt::nacl_set_shmem(shmem, flags),
  316. #[cfg(not(feature = "forward"))]
  317. () => {
  318. let _ = (shmem, flags);
  319. unimplemented!()
  320. }
  321. }
  322. }
  323. #[inline]
  324. fn sync_csr(&self, csr_num: usize) -> SbiRet {
  325. match () {
  326. #[cfg(feature = "forward")]
  327. () => sbi_rt::nacl_sync_csr(csr_num),
  328. #[cfg(not(feature = "forward"))]
  329. () => {
  330. let _ = csr_num;
  331. unimplemented!()
  332. }
  333. }
  334. }
  335. #[inline]
  336. fn sync_hfence(&self, entry_index: usize) -> SbiRet {
  337. match () {
  338. #[cfg(feature = "forward")]
  339. () => sbi_rt::nacl_sync_hfence(entry_index),
  340. #[cfg(not(feature = "forward"))]
  341. () => {
  342. let _ = entry_index;
  343. unimplemented!()
  344. }
  345. }
  346. }
  347. #[inline]
  348. fn sync_sret(&self) -> SbiRet {
  349. match () {
  350. #[cfg(feature = "forward")]
  351. () => sbi_rt::nacl_sync_sret(),
  352. #[cfg(not(feature = "forward"))]
  353. () => unimplemented!(),
  354. }
  355. }
  356. }
  357. impl Pmu for Forward {
  358. #[inline]
  359. fn num_counters(&self) -> usize {
  360. match () {
  361. #[cfg(feature = "forward")]
  362. () => sbi_rt::pmu_num_counters(),
  363. #[cfg(not(feature = "forward"))]
  364. () => unimplemented!(),
  365. }
  366. }
  367. #[inline]
  368. fn counter_get_info(&self, counter_idx: usize) -> SbiRet {
  369. match () {
  370. #[cfg(feature = "forward")]
  371. () => sbi_rt::pmu_counter_get_info(counter_idx),
  372. #[cfg(not(feature = "forward"))]
  373. () => {
  374. let _ = counter_idx;
  375. unimplemented!()
  376. }
  377. }
  378. }
  379. #[inline]
  380. fn counter_config_matching(
  381. &self,
  382. counter_idx_base: usize,
  383. counter_idx_mask: usize,
  384. config_flags: usize,
  385. event_idx: usize,
  386. event_data: u64,
  387. ) -> SbiRet {
  388. match () {
  389. #[cfg(feature = "forward")]
  390. () => sbi_rt::pmu_counter_config_matching(
  391. counter_idx_base,
  392. counter_idx_mask,
  393. config_flags,
  394. event_idx,
  395. event_data,
  396. ),
  397. #[cfg(not(feature = "forward"))]
  398. () => {
  399. let _ = (
  400. counter_idx_base,
  401. counter_idx_mask,
  402. config_flags,
  403. event_idx,
  404. event_data,
  405. );
  406. unimplemented!()
  407. }
  408. }
  409. }
  410. #[inline]
  411. fn counter_start(
  412. &self,
  413. counter_idx_base: usize,
  414. counter_idx_mask: usize,
  415. start_flags: usize,
  416. initial_value: u64,
  417. ) -> SbiRet {
  418. match () {
  419. #[cfg(feature = "forward")]
  420. () => sbi_rt::pmu_counter_start(
  421. counter_idx_base,
  422. counter_idx_mask,
  423. start_flags,
  424. initial_value,
  425. ),
  426. #[cfg(not(feature = "forward"))]
  427. () => {
  428. let _ = (
  429. counter_idx_base,
  430. counter_idx_mask,
  431. start_flags,
  432. initial_value,
  433. );
  434. unimplemented!()
  435. }
  436. }
  437. }
  438. #[inline]
  439. fn counter_stop(
  440. &self,
  441. counter_idx_base: usize,
  442. counter_idx_mask: usize,
  443. stop_flags: usize,
  444. ) -> SbiRet {
  445. match () {
  446. #[cfg(feature = "forward")]
  447. () => sbi_rt::pmu_counter_stop(counter_idx_base, counter_idx_mask, stop_flags),
  448. #[cfg(not(feature = "forward"))]
  449. () => {
  450. let _ = (counter_idx_base, counter_idx_mask, stop_flags);
  451. unimplemented!()
  452. }
  453. }
  454. }
  455. #[inline]
  456. fn counter_fw_read(&self, counter_idx: usize) -> SbiRet {
  457. match () {
  458. #[cfg(feature = "forward")]
  459. () => sbi_rt::pmu_counter_fw_read(counter_idx),
  460. #[cfg(not(feature = "forward"))]
  461. () => {
  462. let _ = counter_idx;
  463. unimplemented!()
  464. }
  465. }
  466. }
  467. #[inline]
  468. fn counter_fw_read_hi(&self, counter_idx: usize) -> SbiRet {
  469. match () {
  470. #[cfg(feature = "forward")]
  471. () => sbi_rt::pmu_counter_fw_read_hi(counter_idx),
  472. #[cfg(not(feature = "forward"))]
  473. () => {
  474. let _ = counter_idx;
  475. unimplemented!()
  476. }
  477. }
  478. }
  479. }
  480. impl Reset for Forward {
  481. #[inline]
  482. fn system_reset(&self, reset_type: u32, reset_reason: u32) -> SbiRet {
  483. match () {
  484. #[cfg(feature = "forward")]
  485. () => sbi_rt::system_reset(reset_type, reset_reason),
  486. #[cfg(not(feature = "forward"))]
  487. () => {
  488. let _ = (reset_type, reset_reason);
  489. unimplemented!()
  490. }
  491. }
  492. }
  493. }
  494. impl Sta for Forward {
  495. #[inline]
  496. fn set_shmem(&self, shmem: SharedPtr<[u8; 64]>, flags: usize) -> SbiRet {
  497. match () {
  498. #[cfg(feature = "forward")]
  499. () => sbi_rt::sta_set_shmem(shmem, flags),
  500. #[cfg(not(feature = "forward"))]
  501. () => {
  502. let _ = (shmem, flags);
  503. unimplemented!()
  504. }
  505. }
  506. }
  507. }
  508. impl Susp for Forward {
  509. #[inline]
  510. fn system_suspend(&self, sleep_type: u32, resume_addr: usize, opaque: usize) -> SbiRet {
  511. match () {
  512. #[cfg(feature = "forward")]
  513. () => sbi_rt::system_suspend(sleep_type, resume_addr, opaque),
  514. #[cfg(not(feature = "forward"))]
  515. () => {
  516. let _ = (sleep_type, resume_addr, opaque);
  517. unimplemented!()
  518. }
  519. }
  520. }
  521. }
  522. impl Timer for Forward {
  523. #[inline]
  524. fn set_timer(&self, stime_value: u64) {
  525. match () {
  526. #[cfg(feature = "forward")]
  527. () => sbi_rt::set_timer(stime_value),
  528. #[cfg(not(feature = "forward"))]
  529. () => {
  530. let _ = stime_value;
  531. unimplemented!()
  532. }
  533. };
  534. }
  535. }
  536. impl EnvInfo for Forward {
  537. #[inline]
  538. fn mvendorid(&self) -> usize {
  539. match () {
  540. #[cfg(feature = "forward")]
  541. () => sbi_rt::get_mvendorid(),
  542. #[cfg(not(feature = "forward"))]
  543. () => unimplemented!(),
  544. }
  545. }
  546. #[inline]
  547. fn marchid(&self) -> usize {
  548. match () {
  549. #[cfg(feature = "forward")]
  550. () => sbi_rt::get_marchid(),
  551. #[cfg(not(feature = "forward"))]
  552. () => unimplemented!(),
  553. }
  554. }
  555. #[inline]
  556. fn mimpid(&self) -> usize {
  557. match () {
  558. #[cfg(feature = "forward")]
  559. () => sbi_rt::get_mimpid(),
  560. #[cfg(not(feature = "forward"))]
  561. () => unimplemented!(),
  562. }
  563. }
  564. }