macros.rs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. macro_rules! read_csr {
  2. ($csr_number:expr, $asm_fn: ident) => {
  3. /// Reads the CSR
  4. #[inline]
  5. unsafe fn _read() -> usize {
  6. match () {
  7. #[cfg(all(riscv, feature = "inline-asm"))]
  8. () => {
  9. let r: usize;
  10. asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile");
  11. r
  12. }
  13. #[cfg(all(riscv, not(feature = "inline-asm")))]
  14. () => {
  15. extern "C" {
  16. fn $asm_fn() -> usize;
  17. }
  18. $asm_fn()
  19. }
  20. #[cfg(not(riscv))]
  21. () => unimplemented!(),
  22. }
  23. }
  24. };
  25. }
  26. macro_rules! read_csr_rv32 {
  27. ($csr_number:expr, $asm_fn: ident) => {
  28. /// Reads the CSR
  29. #[inline]
  30. unsafe fn _read() -> usize {
  31. match () {
  32. #[cfg(all(riscv32, feature = "inline-asm"))]
  33. () => {
  34. let r: usize;
  35. asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile");
  36. r
  37. }
  38. #[cfg(all(riscv32, not(feature = "inline-asm")))]
  39. () => {
  40. extern "C" {
  41. fn $asm_fn() -> usize;
  42. }
  43. $asm_fn()
  44. }
  45. #[cfg(not(riscv32))]
  46. () => unimplemented!(),
  47. }
  48. }
  49. };
  50. }
  51. macro_rules! read_csr_as {
  52. ($register:ident, $csr_number:expr, $asm_fn: ident) => {
  53. read_csr!($csr_number, $asm_fn);
  54. /// Reads the CSR
  55. #[inline]
  56. pub fn read() -> $register {
  57. $register { bits: unsafe{ _read() } }
  58. }
  59. };
  60. }
  61. macro_rules! read_csr_as_usize {
  62. ($csr_number:expr, $asm_fn: ident) => {
  63. read_csr!($csr_number, $asm_fn);
  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:expr, $asm_fn: ident) => {
  73. read_csr_rv32!($csr_number, $asm_fn);
  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:expr, $asm_fn: ident) => {
  83. /// Writes the CSR
  84. #[inline]
  85. #[allow(unused_variables)]
  86. unsafe fn _write(bits: usize) {
  87. match () {
  88. #[cfg(all(riscv, feature = "inline-asm"))]
  89. () => asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"),
  90. #[cfg(all(riscv, not(feature = "inline-asm")))]
  91. () => {
  92. extern "C" {
  93. fn $asm_fn(bits: usize);
  94. }
  95. $asm_fn(bits);
  96. }
  97. #[cfg(not(riscv))]
  98. () => unimplemented!(),
  99. }
  100. }
  101. };
  102. }
  103. macro_rules! write_csr_rv32 {
  104. ($csr_number:expr, $asm_fn: ident) => {
  105. /// Writes the CSR
  106. #[inline]
  107. #[allow(unused_variables)]
  108. unsafe fn _write(bits: usize) {
  109. match () {
  110. #[cfg(all(riscv32, feature = "inline-asm"))]
  111. () => asm!("csrrw x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"),
  112. #[cfg(all(riscv32, not(feature = "inline-asm")))]
  113. () => {
  114. extern "C" {
  115. fn $asm_fn(bits: usize);
  116. }
  117. $asm_fn(bits);
  118. }
  119. #[cfg(not(riscv32))]
  120. () => unimplemented!(),
  121. }
  122. }
  123. };
  124. }
  125. macro_rules! write_csr_as_usize {
  126. ($csr_number:expr, $asm_fn: ident) => {
  127. write_csr!($csr_number, $asm_fn);
  128. /// Writes the CSR
  129. #[inline]
  130. pub fn write(bits: usize) {
  131. unsafe{ _write(bits) }
  132. }
  133. };
  134. }
  135. macro_rules! write_csr_as_usize_rv32 {
  136. ($csr_number:expr, $asm_fn: ident) => {
  137. write_csr_rv32!($csr_number, $asm_fn);
  138. /// Writes the CSR
  139. #[inline]
  140. pub fn write(bits: usize) {
  141. unsafe{ _write(bits) }
  142. }
  143. };
  144. }
  145. macro_rules! set {
  146. ($csr_number:expr, $asm_fn: ident) => {
  147. /// Set the CSR
  148. #[inline]
  149. #[allow(unused_variables)]
  150. unsafe fn _set(bits: usize) {
  151. match () {
  152. #[cfg(all(riscv, feature = "inline-asm"))]
  153. () => asm!("csrrs x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"),
  154. #[cfg(all(riscv, not(feature = "inline-asm")))]
  155. () => {
  156. extern "C" {
  157. fn $asm_fn(bits: usize);
  158. }
  159. $asm_fn(bits);
  160. }
  161. #[cfg(not(riscv))]
  162. () => unimplemented!(),
  163. }
  164. }
  165. };
  166. }
  167. macro_rules! clear {
  168. ($csr_number:expr, $asm_fn: ident) => {
  169. /// Clear the CSR
  170. #[inline]
  171. #[allow(unused_variables)]
  172. unsafe fn _clear(bits: usize) {
  173. match () {
  174. #[cfg(all(riscv, feature = "inline-asm"))]
  175. () => asm!("csrrc x0, $1, $0" :: "r"(bits), "i"($csr_number) :: "volatile"),
  176. #[cfg(all(riscv, not(feature = "inline-asm")))]
  177. () => {
  178. extern "C" {
  179. fn $asm_fn(bits: usize);
  180. }
  181. $asm_fn(bits);
  182. }
  183. #[cfg(not(riscv))]
  184. () => unimplemented!(),
  185. }
  186. }
  187. };
  188. }
  189. macro_rules! set_csr {
  190. ($(#[$attr:meta])*, $set_field:ident, $e:expr) => {
  191. $(#[$attr])*
  192. #[inline]
  193. pub unsafe fn $set_field() {
  194. _set($e);
  195. }
  196. }
  197. }
  198. macro_rules! clear_csr {
  199. ($(#[$attr:meta])*, $clear_field:ident, $e:expr) => {
  200. $(#[$attr])*
  201. #[inline]
  202. pub unsafe fn $clear_field() {
  203. _clear($e);
  204. }
  205. }
  206. }
  207. macro_rules! set_clear_csr {
  208. ($(#[$attr:meta])*, $set_field:ident, $clear_field:ident, $e:expr) => {
  209. set_csr!($(#[$attr])*, $set_field, $e);
  210. clear_csr!($(#[$attr])*, $clear_field, $e);
  211. }
  212. }
  213. macro_rules! read_composite_csr {
  214. ($hi:expr, $lo:expr) => {
  215. /// Reads the CSR as a 64-bit value
  216. #[inline]
  217. pub fn read64() -> u64 {
  218. match () {
  219. #[cfg(riscv32)]
  220. () => loop {
  221. let hi = $hi;
  222. let lo = $lo;
  223. if hi == $hi {
  224. return ((hi as u64) << 32) | lo as u64;
  225. }
  226. },
  227. #[cfg(not(riscv32))]
  228. () => $lo as u64,
  229. }
  230. }
  231. }
  232. }