macros.rs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. macro_rules! read_csr {
  2. ($csr_number:literal) => {
  3. /// Reads the CSR
  4. #[inline]
  5. unsafe fn _read() -> usize {
  6. match () {
  7. #[cfg(riscv)]
  8. () => {
  9. let r: usize;
  10. core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r);
  11. r
  12. }
  13. #[cfg(not(riscv))]
  14. () => unimplemented!(),
  15. }
  16. }
  17. };
  18. }
  19. macro_rules! read_csr_rv32 {
  20. ($csr_number:literal) => {
  21. /// Reads the CSR
  22. #[inline]
  23. unsafe fn _read() -> usize {
  24. match () {
  25. #[cfg(riscv32)]
  26. () => {
  27. let r: usize;
  28. core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r);
  29. r
  30. }
  31. #[cfg(not(riscv32))]
  32. () => unimplemented!(),
  33. }
  34. }
  35. };
  36. }
  37. macro_rules! read_csr_as {
  38. ($register:ident, $csr_number:literal) => {
  39. read_csr!($csr_number);
  40. /// Reads the CSR
  41. #[inline]
  42. pub fn read() -> $register {
  43. $register {
  44. bits: unsafe { _read() },
  45. }
  46. }
  47. };
  48. }
  49. macro_rules! read_csr_as_rv32 {
  50. ($register:ident, $csr_number:literal) => {
  51. read_csr_rv32!($csr_number);
  52. /// Reads the CSR
  53. #[inline]
  54. pub fn read() -> $register {
  55. $register {
  56. bits: unsafe { _read() },
  57. }
  58. }
  59. };
  60. }
  61. macro_rules! read_csr_as_usize {
  62. ($csr_number:literal) => {
  63. read_csr!($csr_number);
  64. /// Reads the CSR
  65. #[inline]
  66. pub fn read() -> usize {
  67. unsafe { _read() }
  68. }
  69. };
  70. }
  71. macro_rules! read_csr_as_usize_rv32 {
  72. ($csr_number:literal) => {
  73. read_csr_rv32!($csr_number);
  74. /// Reads the CSR
  75. #[inline]
  76. pub fn read() -> usize {
  77. unsafe { _read() }
  78. }
  79. };
  80. }
  81. macro_rules! write_csr {
  82. ($csr_number:literal) => {
  83. /// Writes the CSR
  84. #[inline]
  85. #[allow(unused_variables)]
  86. unsafe fn _write(bits: usize) {
  87. match () {
  88. #[cfg(riscv)]
  89. () => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
  90. #[cfg(not(riscv))]
  91. () => unimplemented!(),
  92. }
  93. }
  94. };
  95. }
  96. macro_rules! write_csr_rv32 {
  97. ($csr_number:literal) => {
  98. /// Writes the CSR
  99. #[inline]
  100. #[allow(unused_variables)]
  101. unsafe fn _write(bits: usize) {
  102. match () {
  103. #[cfg(riscv32)]
  104. () => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
  105. #[cfg(not(riscv32))]
  106. () => unimplemented!(),
  107. }
  108. }
  109. };
  110. }
  111. macro_rules! write_csr_as_usize {
  112. ($csr_number:literal) => {
  113. write_csr!($csr_number);
  114. /// Writes the CSR
  115. #[inline]
  116. pub fn write(bits: usize) {
  117. unsafe { _write(bits) }
  118. }
  119. };
  120. }
  121. macro_rules! write_csr_as_usize_rv32 {
  122. ($csr_number:literal) => {
  123. write_csr_rv32!($csr_number);
  124. /// Writes the CSR
  125. #[inline]
  126. pub fn write(bits: usize) {
  127. unsafe { _write(bits) }
  128. }
  129. };
  130. }
  131. macro_rules! set {
  132. ($csr_number:literal) => {
  133. /// Set the CSR
  134. #[inline]
  135. #[allow(unused_variables)]
  136. unsafe fn _set(bits: usize) {
  137. match () {
  138. #[cfg(riscv)]
  139. () => core::arch::asm!(concat!("csrrs x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
  140. #[cfg(not(riscv))]
  141. () => unimplemented!(),
  142. }
  143. }
  144. };
  145. }
  146. macro_rules! set_rv32 {
  147. ($csr_number:literal) => {
  148. /// Set the CSR
  149. #[inline]
  150. #[allow(unused_variables)]
  151. unsafe fn _set(bits: usize) {
  152. match () {
  153. #[cfg(riscv32)]
  154. () => core::arch::asm!(concat!("csrrs x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
  155. #[cfg(not(riscv32))]
  156. () => unimplemented!(),
  157. }
  158. }
  159. };
  160. }
  161. macro_rules! clear {
  162. ($csr_number:literal) => {
  163. /// Clear the CSR
  164. #[inline]
  165. #[allow(unused_variables)]
  166. unsafe fn _clear(bits: usize) {
  167. match () {
  168. #[cfg(riscv)]
  169. () => core::arch::asm!(concat!("csrrc x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
  170. #[cfg(not(riscv))]
  171. () => unimplemented!(),
  172. }
  173. }
  174. };
  175. }
  176. macro_rules! clear_rv32 {
  177. ($csr_number:literal) => {
  178. /// Clear the CSR
  179. #[inline]
  180. #[allow(unused_variables)]
  181. unsafe fn _clear(bits: usize) {
  182. match () {
  183. #[cfg(riscv32)]
  184. () => core::arch::asm!(concat!("csrrc x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
  185. #[cfg(not(riscv32))]
  186. () => unimplemented!(),
  187. }
  188. }
  189. };
  190. }
  191. macro_rules! set_csr {
  192. ($(#[$attr:meta])*, $set_field:ident, $e:expr) => {
  193. $(#[$attr])*
  194. #[inline]
  195. pub unsafe fn $set_field() {
  196. _set($e);
  197. }
  198. };
  199. }
  200. macro_rules! clear_csr {
  201. ($(#[$attr:meta])*, $clear_field:ident, $e:expr) => {
  202. $(#[$attr])*
  203. #[inline]
  204. pub unsafe fn $clear_field() {
  205. _clear($e);
  206. }
  207. };
  208. }
  209. macro_rules! set_clear_csr {
  210. ($(#[$attr:meta])*, $set_field:ident, $clear_field:ident, $e:expr) => {
  211. set_csr!($(#[$attr])*, $set_field, $e);
  212. clear_csr!($(#[$attr])*, $clear_field, $e);
  213. }
  214. }
  215. macro_rules! read_composite_csr {
  216. ($hi:expr, $lo:expr) => {
  217. /// Reads the CSR as a 64-bit value
  218. #[inline]
  219. pub fn read64() -> u64 {
  220. match () {
  221. #[cfg(riscv32)]
  222. () => loop {
  223. let hi = $hi;
  224. let lo = $lo;
  225. if hi == $hi {
  226. return ((hi as u64) << 32) | lo as u64;
  227. }
  228. },
  229. #[cfg(not(riscv32))]
  230. () => $lo as u64,
  231. }
  232. }
  233. };
  234. }
  235. macro_rules! set_pmp {
  236. () => {
  237. /// Set the pmp configuration corresponding to the index
  238. #[inline]
  239. pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
  240. #[cfg(riscv32)]
  241. assert!(index < 4);
  242. #[cfg(riscv64)]
  243. assert!(index < 8);
  244. let mut value = _read();
  245. value &= !(0xFF << (8 * index)); // clear previous value
  246. let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
  247. value |= byte << (8 * index);
  248. _write(value);
  249. }
  250. };
  251. }
  252. macro_rules! clear_pmp {
  253. () => {
  254. /// Clear the pmp configuration corresponding to the index
  255. #[inline]
  256. pub unsafe fn clear_pmp(index: usize) {
  257. #[cfg(riscv32)]
  258. assert!(index < 4);
  259. #[cfg(riscv64)]
  260. assert!(index < 8);
  261. let mut value = _read();
  262. value &= !(0xFF << (8 * index)); // clear previous value
  263. _write(value);
  264. }
  265. };
  266. }