build-full.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. use core::cell::RefCell;
  2. use rustsbi::RustSBI;
  3. use sbi_spec::{
  4. binary::{HartMask, Physical, SbiRet, SharedPtr},
  5. nacl::shmem_size::NATIVE,
  6. pmu::shmem_size::SIZE,
  7. };
  8. #[derive(RustSBI)]
  9. struct FullyImplemented {
  10. console: DummyConsole,
  11. cppc: DummyCppc,
  12. hsm: DummyHsm,
  13. ipi: DummyIpi,
  14. nacl: DummyNacl,
  15. pmu: DummyPmu,
  16. reset: DummyReset,
  17. fence: DummyFence,
  18. sta: DummySta,
  19. susp: DummySusp,
  20. timer: DummyTimer,
  21. info: DummyEnvInfo,
  22. }
  23. #[derive(RustSBI)]
  24. struct AlternateName {
  25. dbcn: DummyConsole,
  26. cppc: DummyCppc,
  27. hsm: DummyHsm,
  28. ipi: DummyIpi,
  29. nacl: DummyNacl,
  30. pmu: DummyPmu,
  31. srst: DummyReset,
  32. rfnc: DummyFence,
  33. sta: DummySta,
  34. susp: DummySusp,
  35. time: DummyTimer,
  36. info: DummyEnvInfo,
  37. }
  38. #[derive(RustSBI)]
  39. struct TupleStruct(
  40. #[rustsbi(dbcn)] DummyConsole,
  41. #[rustsbi(cppc)] DummyCppc,
  42. #[rustsbi(hsm)] DummyHsm,
  43. #[rustsbi(ipi)] DummyIpi,
  44. #[rustsbi(nacl)] DummyNacl,
  45. #[rustsbi(pmu)] DummyPmu,
  46. #[rustsbi(srst)] DummyReset,
  47. #[rustsbi(rfnc)] DummyFence,
  48. #[rustsbi(sta)] DummySta,
  49. #[rustsbi(susp)] DummySusp,
  50. #[rustsbi(time)] DummyTimer,
  51. #[rustsbi(info)] DummyEnvInfo,
  52. );
  53. #[cfg(feature = "machine")]
  54. #[derive(RustSBI)]
  55. struct UnitStruct;
  56. #[test]
  57. fn rustsbi_impl_id() {
  58. let sbi = FullyImplemented {
  59. console: DummyConsole,
  60. cppc: DummyCppc,
  61. hsm: DummyHsm,
  62. ipi: DummyIpi,
  63. nacl: DummyNacl,
  64. pmu: DummyPmu,
  65. reset: DummyReset,
  66. fence: DummyFence,
  67. sta: DummySta,
  68. susp: DummySusp,
  69. timer: DummyTimer(RefCell::new(0)),
  70. info: DummyEnvInfo,
  71. };
  72. assert_eq!(sbi.handle_ecall(0x10, 0x1, [0; 6]).value, 4);
  73. let sbi = AlternateName {
  74. dbcn: DummyConsole,
  75. cppc: DummyCppc,
  76. hsm: DummyHsm,
  77. ipi: DummyIpi,
  78. nacl: DummyNacl,
  79. pmu: DummyPmu,
  80. srst: DummyReset,
  81. rfnc: DummyFence,
  82. sta: DummySta,
  83. susp: DummySusp,
  84. time: DummyTimer(RefCell::new(0)),
  85. info: DummyEnvInfo,
  86. };
  87. assert_eq!(sbi.handle_ecall(0x10, 0x1, [0; 6]).value, 4);
  88. let sbi = TupleStruct(
  89. DummyConsole,
  90. DummyCppc,
  91. DummyHsm,
  92. DummyIpi,
  93. DummyNacl,
  94. DummyPmu,
  95. DummyReset,
  96. DummyFence,
  97. DummySta,
  98. DummySusp,
  99. DummyTimer(RefCell::new(0)),
  100. DummyEnvInfo,
  101. );
  102. assert_eq!(sbi.handle_ecall(0x10, 0x1, [0; 6]).value, 4);
  103. }
  104. #[cfg(feature = "machine")]
  105. #[test]
  106. fn unit_struct() {
  107. let sbi = UnitStruct;
  108. assert_eq!(sbi.handle_ecall(0x10, 0x1, [0; 6]).value, 4);
  109. }
  110. #[test]
  111. fn generated_extensions() {
  112. let sbi = FullyImplemented {
  113. console: DummyConsole,
  114. cppc: DummyCppc,
  115. hsm: DummyHsm,
  116. ipi: DummyIpi,
  117. nacl: DummyNacl,
  118. pmu: DummyPmu,
  119. reset: DummyReset,
  120. fence: DummyFence,
  121. sta: DummySta,
  122. susp: DummySusp,
  123. timer: DummyTimer(RefCell::new(0)),
  124. info: DummyEnvInfo,
  125. };
  126. assert_eq!(
  127. sbi.handle_ecall(0x10, 0, [0; 6]),
  128. SbiRet::success(0x02000000)
  129. );
  130. assert_eq!(sbi.handle_ecall(0x10, 1, [0; 6]), SbiRet::success(4));
  131. assert!(sbi.handle_ecall(0x10, 2, [0; 6]).is_ok());
  132. // All SBI 2.0 extensions, including Base, are supported
  133. for eid in [
  134. 0x10, 0x54494d45, 0x735049, 0x52464e43, 0x48534d, 0x53525354, 0x504d55, 0x4442434e,
  135. 0x53555350, 0x4e41434c, 0x535441, 0x43505043,
  136. ] {
  137. assert_eq!(
  138. sbi.handle_ecall(0x10, 3, [eid, 0, 0, 0, 0, 0]),
  139. SbiRet::success(1)
  140. );
  141. }
  142. // All legacy extensions are not supported
  143. for eid in 0x00..=0x08 {
  144. assert_eq!(
  145. sbi.handle_ecall(0x10, 3, [eid, 0, 0, 0, 0, 0]),
  146. SbiRet::success(0)
  147. );
  148. }
  149. assert_eq!(sbi.handle_ecall(0x4442434e, 0, [0; 6]), SbiRet::success(1));
  150. assert_eq!(sbi.handle_ecall(0x4442434e, 1, [0; 6]), SbiRet::success(2));
  151. assert_eq!(sbi.handle_ecall(0x4442434e, 2, [0; 6]), SbiRet::success(3));
  152. assert_eq!(sbi.handle_ecall(0x43505043, 0, [0; 6]), SbiRet::success(4));
  153. assert_eq!(sbi.handle_ecall(0x43505043, 1, [0; 6]), SbiRet::success(5));
  154. assert_eq!(sbi.handle_ecall(0x43505043, 2, [0; 6]), SbiRet::success(6));
  155. assert_eq!(sbi.handle_ecall(0x43505043, 3, [0; 6]), SbiRet::success(7));
  156. assert_eq!(sbi.handle_ecall(0x48534d, 0, [0; 6]), SbiRet::success(8));
  157. assert_eq!(sbi.handle_ecall(0x48534d, 1, [0; 6]), SbiRet::success(9));
  158. assert_eq!(sbi.handle_ecall(0x48534d, 2, [0; 6]), SbiRet::success(10));
  159. assert_eq!(sbi.handle_ecall(0x48534d, 3, [0; 6]), SbiRet::success(11));
  160. assert_eq!(sbi.handle_ecall(0x735049, 0, [0; 6]), SbiRet::success(12));
  161. assert_eq!(sbi.handle_ecall(0x4E41434C, 0, [0; 6]), SbiRet::success(13));
  162. assert_eq!(sbi.handle_ecall(0x4E41434C, 1, [0; 6]), SbiRet::success(14));
  163. assert_eq!(sbi.handle_ecall(0x4E41434C, 2, [0; 6]), SbiRet::success(15));
  164. assert_eq!(sbi.handle_ecall(0x4E41434C, 3, [0; 6]), SbiRet::success(16));
  165. assert_eq!(sbi.handle_ecall(0x4E41434C, 4, [0; 6]), SbiRet::success(17));
  166. assert_eq!(sbi.handle_ecall(0x504D55, 0, [0; 6]), SbiRet::success(18));
  167. assert_eq!(sbi.handle_ecall(0x504D55, 1, [0; 6]), SbiRet::success(19));
  168. assert_eq!(sbi.handle_ecall(0x504D55, 2, [0; 6]), SbiRet::success(20));
  169. assert_eq!(sbi.handle_ecall(0x504D55, 3, [0; 6]), SbiRet::success(21));
  170. assert_eq!(sbi.handle_ecall(0x504D55, 4, [0; 6]), SbiRet::success(22));
  171. assert_eq!(sbi.handle_ecall(0x504D55, 5, [0; 6]), SbiRet::success(23));
  172. assert_eq!(sbi.handle_ecall(0x504D55, 6, [0; 6]), SbiRet::success(24));
  173. assert_eq!(sbi.handle_ecall(0x504D55, 7, [0; 6]), SbiRet::success(25));
  174. // TODO eid and fid of snapshot_set_shmem
  175. assert_eq!(sbi.handle_ecall(0x53525354, 0, [0; 6]), SbiRet::success(26));
  176. assert_eq!(sbi.handle_ecall(0x52464E43, 0, [0; 6]), SbiRet::success(27));
  177. assert_eq!(sbi.handle_ecall(0x52464E43, 1, [0; 6]), SbiRet::success(28));
  178. assert_eq!(sbi.handle_ecall(0x52464E43, 2, [0; 6]), SbiRet::success(29));
  179. assert_eq!(sbi.handle_ecall(0x52464E43, 3, [0; 6]), SbiRet::success(30));
  180. assert_eq!(sbi.handle_ecall(0x52464E43, 4, [0; 6]), SbiRet::success(31));
  181. assert_eq!(sbi.handle_ecall(0x52464E43, 5, [0; 6]), SbiRet::success(32));
  182. assert_eq!(sbi.handle_ecall(0x52464E43, 6, [0; 6]), SbiRet::success(33));
  183. assert_eq!(sbi.handle_ecall(0x535441, 0, [0; 6]), SbiRet::success(34));
  184. assert_eq!(sbi.handle_ecall(0x53555350, 0, [0; 6]), SbiRet::success(35));
  185. assert!(sbi.handle_ecall(0x54494D45, 0, [0; 6]).is_ok());
  186. assert_eq!(sbi.timer.0.take(), 36);
  187. assert_eq!(sbi.handle_ecall(0x10, 4, [0; 6]), SbiRet::success(37));
  188. assert_eq!(sbi.handle_ecall(0x10, 5, [0; 6]), SbiRet::success(38));
  189. assert_eq!(sbi.handle_ecall(0x10, 6, [0; 6]), SbiRet::success(39));
  190. }
  191. struct DummyConsole;
  192. impl rustsbi::Console for DummyConsole {
  193. fn write(&self, _: Physical<&[u8]>) -> SbiRet {
  194. SbiRet::success(1)
  195. }
  196. fn read(&self, _: Physical<&mut [u8]>) -> SbiRet {
  197. SbiRet::success(2)
  198. }
  199. fn write_byte(&self, _: u8) -> SbiRet {
  200. SbiRet::success(3)
  201. }
  202. }
  203. struct DummyCppc;
  204. impl rustsbi::Cppc for DummyCppc {
  205. fn probe(&self, _: u32) -> SbiRet {
  206. SbiRet::success(4)
  207. }
  208. fn read(&self, _: u32) -> SbiRet {
  209. SbiRet::success(5)
  210. }
  211. fn read_hi(&self, _: u32) -> SbiRet {
  212. SbiRet::success(6)
  213. }
  214. fn write(&self, _: u32, _: u64) -> SbiRet {
  215. SbiRet::success(7)
  216. }
  217. }
  218. struct DummyHsm;
  219. impl rustsbi::Hsm for DummyHsm {
  220. fn hart_start(&self, _: usize, _: usize, _: usize) -> SbiRet {
  221. SbiRet::success(8)
  222. }
  223. fn hart_stop(&self) -> SbiRet {
  224. SbiRet::success(9)
  225. }
  226. fn hart_get_status(&self, _: usize) -> SbiRet {
  227. SbiRet::success(10)
  228. }
  229. fn hart_suspend(&self, _: u32, _: usize, _: usize) -> SbiRet {
  230. SbiRet::success(11)
  231. }
  232. }
  233. struct DummyIpi;
  234. impl rustsbi::Ipi for DummyIpi {
  235. fn send_ipi(&self, _: HartMask) -> SbiRet {
  236. SbiRet::success(12)
  237. }
  238. }
  239. struct DummyNacl;
  240. impl rustsbi::Nacl for DummyNacl {
  241. fn probe_feature(&self, _: u32) -> SbiRet {
  242. SbiRet::success(13)
  243. }
  244. fn set_shmem(&self, _: SharedPtr<[u8; NATIVE]>, _: usize) -> SbiRet {
  245. SbiRet::success(14)
  246. }
  247. fn sync_csr(&self, _: usize) -> SbiRet {
  248. SbiRet::success(15)
  249. }
  250. fn sync_hfence(&self, _: usize) -> SbiRet {
  251. SbiRet::success(16)
  252. }
  253. fn sync_sret(&self) -> SbiRet {
  254. SbiRet::success(17)
  255. }
  256. }
  257. struct DummyPmu;
  258. impl rustsbi::Pmu for DummyPmu {
  259. fn num_counters(&self) -> usize {
  260. 18
  261. }
  262. fn counter_get_info(&self, _: usize) -> SbiRet {
  263. SbiRet::success(19)
  264. }
  265. fn counter_config_matching(&self, _: usize, _: usize, _: usize, _: usize, _: u64) -> SbiRet {
  266. SbiRet::success(20)
  267. }
  268. fn counter_start(&self, _: usize, _: usize, _: usize, _: u64) -> SbiRet {
  269. SbiRet::success(21)
  270. }
  271. fn counter_stop(&self, _: usize, _: usize, _: usize) -> SbiRet {
  272. SbiRet::success(22)
  273. }
  274. fn counter_fw_read(&self, _: usize) -> SbiRet {
  275. SbiRet::success(23)
  276. }
  277. fn counter_fw_read_hi(&self, _: usize) -> SbiRet {
  278. SbiRet::success(24)
  279. }
  280. fn snapshot_set_shmem(&self, _: SharedPtr<[u8; SIZE]>, _: usize) -> SbiRet {
  281. SbiRet::success(25)
  282. }
  283. // TODO fn snapshot_set_shmem
  284. }
  285. struct DummyReset;
  286. impl rustsbi::Reset for DummyReset {
  287. fn system_reset(&self, _: u32, _: u32) -> SbiRet {
  288. SbiRet::success(26)
  289. }
  290. }
  291. struct DummyFence;
  292. impl rustsbi::Fence for DummyFence {
  293. fn remote_fence_i(&self, _: HartMask) -> SbiRet {
  294. SbiRet::success(27)
  295. }
  296. fn remote_sfence_vma(&self, _: HartMask, _: usize, _: usize) -> SbiRet {
  297. SbiRet::success(28)
  298. }
  299. fn remote_sfence_vma_asid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet {
  300. SbiRet::success(29)
  301. }
  302. fn remote_hfence_gvma_vmid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet {
  303. SbiRet::success(30)
  304. }
  305. fn remote_hfence_gvma(&self, _: HartMask, _: usize, _: usize) -> SbiRet {
  306. SbiRet::success(31)
  307. }
  308. fn remote_hfence_vvma_asid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet {
  309. SbiRet::success(32)
  310. }
  311. fn remote_hfence_vvma(&self, _: HartMask, _: usize, _: usize) -> SbiRet {
  312. SbiRet::success(33)
  313. }
  314. }
  315. struct DummySta;
  316. impl rustsbi::Sta for DummySta {
  317. fn set_shmem(&self, _: SharedPtr<[u8; 64]>, _: usize) -> SbiRet {
  318. SbiRet::success(34)
  319. }
  320. }
  321. struct DummySusp;
  322. impl rustsbi::Susp for DummySusp {
  323. fn system_suspend(&self, _: u32, _: usize, _: usize) -> SbiRet {
  324. SbiRet::success(35)
  325. }
  326. }
  327. struct DummyTimer(RefCell<u64>);
  328. impl rustsbi::Timer for DummyTimer {
  329. fn set_timer(&self, _: u64) {
  330. self.0.replace(36);
  331. }
  332. }
  333. struct DummyEnvInfo;
  334. impl rustsbi::EnvInfo for DummyEnvInfo {
  335. fn mvendorid(&self) -> usize {
  336. 37
  337. }
  338. fn marchid(&self) -> usize {
  339. 38
  340. }
  341. fn mimpid(&self) -> usize {
  342. 39
  343. }
  344. }