4
0

build-skip.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. use rustsbi::RustSBI;
  2. use sbi_spec::{
  3. binary::{HartMask, Physical, SbiRet},
  4. dbcn::EID_DBCN,
  5. rfnc::EID_RFNC,
  6. };
  7. #[derive(RustSBI)]
  8. struct SkipExtension {
  9. console: DummyConsole,
  10. #[rustsbi(skip)]
  11. fence: DummyFence,
  12. info: DummyEnvInfo,
  13. }
  14. #[derive(RustSBI)]
  15. struct SkipEnvInfo {
  16. console: DummyConsole,
  17. fence: DummyFence,
  18. #[rustsbi(skip)]
  19. info: DummyEnvInfo,
  20. env_info: RealEnvInfo,
  21. }
  22. #[test]
  23. fn rustsbi_skip_extension() {
  24. let sbi = SkipExtension {
  25. console: DummyConsole,
  26. fence: DummyFence,
  27. info: DummyEnvInfo,
  28. };
  29. // 1. Skipped fields are neither used during RustSBI macro generation, ...
  30. assert_eq!(sbi.handle_ecall(EID_DBCN, 0x0, [0; 6]), SbiRet::success(1));
  31. assert_eq!(sbi.handle_ecall(EID_DBCN, 0x1, [0; 6]), SbiRet::success(2));
  32. assert_eq!(sbi.handle_ecall(EID_DBCN, 0x2, [0; 6]), SbiRet::success(3));
  33. assert_eq!(
  34. sbi.handle_ecall(EID_RFNC, 0x0, [0; 6]),
  35. SbiRet::not_supported()
  36. );
  37. assert_eq!(
  38. sbi.handle_ecall(EID_RFNC, 0x1, [0; 6]),
  39. SbiRet::not_supported()
  40. );
  41. assert_eq!(
  42. sbi.handle_ecall(EID_RFNC, 0x2, [0; 6]),
  43. SbiRet::not_supported()
  44. );
  45. // 2. ... nor do they appear in extension detection in Base extension.
  46. // note that it's `assert_ne` - the handle_ecall should not return a success detection with
  47. // value 0 indicating this feature is not supported, ...
  48. assert_ne!(
  49. sbi.handle_ecall(0x10, 0x3, [EID_DBCN, 0, 0, 0, 0, 0]),
  50. SbiRet::success(0)
  51. );
  52. // ... and the `assert_eq` here means extension detection detected successfully that this
  53. // extension is not supported in SBI implementation `SkipExtension`.
  54. assert_eq!(
  55. sbi.handle_ecall(0x10, 0x3, [EID_RFNC, 0, 0, 0, 0, 0]),
  56. SbiRet::success(0)
  57. );
  58. // Additionally, we illustrate here that the skipped fields may be used elsewhere.
  59. let _ = sbi.fence;
  60. }
  61. #[test]
  62. fn rustsbi_skip_env_info() {
  63. let sbi = SkipEnvInfo {
  64. console: DummyConsole,
  65. fence: DummyFence,
  66. info: DummyEnvInfo,
  67. env_info: RealEnvInfo,
  68. };
  69. // The `env_info` instead of `info` field would be used by RustSBI macro; struct
  70. // `RealEnvInfo` would return 11, 12 and 13 for mvendorid, marchid and mimpid.
  71. assert_eq!(sbi.handle_ecall(0x10, 0x4, [0; 6]), SbiRet::success(11));
  72. assert_eq!(sbi.handle_ecall(0x10, 0x5, [0; 6]), SbiRet::success(12));
  73. assert_eq!(sbi.handle_ecall(0x10, 0x6, [0; 6]), SbiRet::success(13));
  74. let _ = sbi.info;
  75. }
  76. // Return values of following trait impls are special values,
  77. // they are used by software to detect if one implementation is used by RustSBI.
  78. struct DummyConsole;
  79. impl rustsbi::Console for DummyConsole {
  80. fn write(&self, _: Physical<&[u8]>) -> SbiRet {
  81. SbiRet::success(1)
  82. }
  83. fn read(&self, _: Physical<&mut [u8]>) -> SbiRet {
  84. SbiRet::success(2)
  85. }
  86. fn write_byte(&self, _: u8) -> SbiRet {
  87. SbiRet::success(3)
  88. }
  89. }
  90. struct DummyFence;
  91. impl rustsbi::Fence for DummyFence {
  92. fn remote_fence_i(&self, _: HartMask) -> SbiRet {
  93. SbiRet::success(4)
  94. }
  95. fn remote_sfence_vma(&self, _: HartMask, _: usize, _: usize) -> SbiRet {
  96. SbiRet::success(5)
  97. }
  98. fn remote_sfence_vma_asid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet {
  99. SbiRet::success(6)
  100. }
  101. fn remote_hfence_gvma_vmid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet {
  102. SbiRet::success(7)
  103. }
  104. fn remote_hfence_gvma(&self, _: HartMask, _: usize, _: usize) -> SbiRet {
  105. SbiRet::success(8)
  106. }
  107. fn remote_hfence_vvma_asid(&self, _: HartMask, _: usize, _: usize, _: usize) -> SbiRet {
  108. SbiRet::success(9)
  109. }
  110. fn remote_hfence_vvma(&self, _: HartMask, _: usize, _: usize) -> SbiRet {
  111. SbiRet::success(10)
  112. }
  113. }
  114. struct DummyEnvInfo;
  115. impl rustsbi::EnvInfo for DummyEnvInfo {
  116. fn mvendorid(&self) -> usize {
  117. unimplemented!()
  118. }
  119. fn marchid(&self) -> usize {
  120. unimplemented!()
  121. }
  122. fn mimpid(&self) -> usize {
  123. unimplemented!()
  124. }
  125. }
  126. struct RealEnvInfo;
  127. impl rustsbi::EnvInfo for RealEnvInfo {
  128. fn mvendorid(&self) -> usize {
  129. 11
  130. }
  131. fn marchid(&self) -> usize {
  132. 12
  133. }
  134. fn mimpid(&self) -> usize {
  135. 13
  136. }
  137. }