pmpcfgx.rs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /// Physical memory protection configuration
  2. use bit_field::BitField;
  3. /// Permission enum contains all possible permission modes for pmp registers
  4. #[derive(Clone, Copy, Debug)]
  5. pub enum Permission {
  6. NONE = 0,
  7. R = 1,
  8. W = 2,
  9. RW = 3,
  10. X = 4,
  11. RX = 5,
  12. WX = 6,
  13. RWX = 7,
  14. }
  15. /// Range enum contains all possible addressing modes for pmp registers
  16. #[derive(Clone, Copy, Debug)]
  17. pub enum Range {
  18. OFF = 0,
  19. TOR = 1,
  20. NA4 = 2,
  21. NAPOT = 3,
  22. }
  23. /// PmpByte holds the a single pmp configuration
  24. #[derive(Clone, Copy, Debug)]
  25. pub struct PmpByte {
  26. pub byte: u8,
  27. //permission: Option<Permission>,
  28. //range: Option<Range>,
  29. //locked: bool
  30. }
  31. /// PmpByte methods to get a pmp configuration attributes
  32. impl PmpByte {
  33. #[inline]
  34. pub fn is_locked(&self) -> bool {
  35. self.byte.get_bit(7)
  36. }
  37. #[inline]
  38. pub fn get_range(&self) -> Option<Range> {
  39. match self.byte.get_bits(3..=4) {
  40. 0 => Some(Range::OFF),
  41. 1 => Some(Range::TOR),
  42. 2 => Some(Range::NA4),
  43. 3 => Some(Range::NAPOT),
  44. _ => unreachable!(),
  45. }
  46. }
  47. #[inline]
  48. pub fn get_permission(&self) -> Option<Permission> {
  49. match self.byte.get_bits(0..=2) {
  50. 0 => Some(Permission::NONE),
  51. 1 => Some(Permission::R),
  52. 2 => Some(Permission::W),
  53. 3 => Some(Permission::RW),
  54. 4 => Some(Permission::X),
  55. 5 => Some(Permission::RX),
  56. 6 => Some(Permission::WX),
  57. 7 => Some(Permission::RWX),
  58. _ => unreachable!(),
  59. }
  60. }
  61. }
  62. /// Physical memory protection configuration
  63. /// Pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, or pmp0cfg - pmp7cfg for RV64
  64. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  65. pub mod pmpcfg0 {
  66. use super::{BitField, Permission, PmpByte, Range};
  67. #[derive(Clone, Copy, Debug)]
  68. pub struct Pmpcfg0 {
  69. pub bits: usize,
  70. }
  71. impl Pmpcfg0 {
  72. #[inline]
  73. pub fn get_byte(&self, index: usize) -> PmpByte {
  74. #[cfg(riscv32)]
  75. assert!(index < 4);
  76. #[cfg(riscv64)]
  77. assert!(index < 8);
  78. PmpByte {
  79. byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
  80. }
  81. }
  82. }
  83. read_csr_as!(Pmpcfg0, 0x3A0, __read_pmpcfg0);
  84. write_csr!(0x3A0, __write_pmpcfg0);
  85. set!(0x3A0, __set_pmpcfg0);
  86. clear!(0x3A0, __clear_pmpcfg0);
  87. #[inline]
  88. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  89. #[cfg(riscv32)]
  90. assert!(index < 4);
  91. #[cfg(riscv64)]
  92. assert!(index < 8);
  93. _set((permission as usize) << (index * 8));
  94. }
  95. #[inline]
  96. pub unsafe fn set_range(range: Range, index: usize) {
  97. #[cfg(riscv32)]
  98. assert!(index < 4);
  99. #[cfg(riscv64)]
  100. assert!(index < 8);
  101. _set((range as usize) << (3 + (index * 8)));
  102. }
  103. #[inline]
  104. pub unsafe fn set_lock(index: usize) {
  105. #[cfg(riscv32)]
  106. assert!(index < 4);
  107. #[cfg(riscv64)]
  108. assert!(index < 8);
  109. _set(1 << (7 + (index * 8)));
  110. }
  111. #[inline]
  112. pub unsafe fn clear_lock(index: usize) {
  113. #[cfg(riscv32)]
  114. assert!(index < 4);
  115. #[cfg(riscv64)]
  116. assert!(index < 8);
  117. _clear(1 << (7 + (index * 8)));
  118. }
  119. }
  120. /// Physical memory protection configuration
  121. /// Pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
  122. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  123. pub mod pmpcfg1 {
  124. use super::{BitField, Permission, PmpByte, Range};
  125. #[derive(Clone, Copy, Debug)]
  126. pub struct Pmpcfg1 {
  127. pub bits: usize,
  128. }
  129. impl Pmpcfg1 {
  130. #[inline]
  131. pub fn get_byte(&self, index: usize) -> PmpByte {
  132. PmpByte {
  133. byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
  134. }
  135. }
  136. }
  137. read_csr_as!(Pmpcfg1, 0x3A1, __read_pmpcfg1);
  138. write_csr!(0x3A1, __write_pmpcfg1);
  139. set!(0x3A1, __set_pmpcfg1);
  140. clear!(0x3A1, __clear_pmpcfg1);
  141. #[inline]
  142. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  143. #[cfg(riscv32)]
  144. assert!(index < 4);
  145. #[cfg(riscv64)]
  146. assert!(index < 8);
  147. _set((permission as usize) << (index * 8));
  148. }
  149. #[inline]
  150. pub unsafe fn set_range(range: Range, index: usize) {
  151. #[cfg(riscv32)]
  152. assert!(index < 4);
  153. #[cfg(riscv64)]
  154. assert!(index < 8);
  155. _set((range as usize) << (3 + (index * 8)));
  156. }
  157. #[inline]
  158. pub unsafe fn set_lock(index: usize) {
  159. #[cfg(riscv32)]
  160. assert!(index < 4);
  161. #[cfg(riscv64)]
  162. assert!(index < 8);
  163. _set(1 << (7 + (index * 8)));
  164. }
  165. #[inline]
  166. pub unsafe fn clear_lock(index: usize) {
  167. #[cfg(riscv32)]
  168. assert!(index < 4);
  169. #[cfg(riscv64)]
  170. assert!(index < 8);
  171. _clear(1 << (7 + (index * 8)));
  172. }
  173. }
  174. /// Physical memory protection configuration
  175. /// Pmpcfg0 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
  176. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  177. pub mod pmpcfg2 {
  178. use super::{BitField, Permission, PmpByte, Range};
  179. #[derive(Clone, Copy, Debug)]
  180. pub struct Pmpcfg2 {
  181. pub bits: usize,
  182. }
  183. impl Pmpcfg2 {
  184. #[inline]
  185. pub fn get_byte(&self, index: usize) -> PmpByte {
  186. PmpByte {
  187. byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
  188. }
  189. }
  190. }
  191. read_csr_as!(Pmpcfg2, 0x3A2, __read_pmpcfg2);
  192. write_csr!(0x3A2, __write_pmpcfg2);
  193. set!(0x3A2, __set_pmpcfg2);
  194. clear!(0x3A2, __clear_pmpcfg2);
  195. #[inline]
  196. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  197. #[cfg(riscv32)]
  198. assert!(index < 4);
  199. #[cfg(riscv64)]
  200. assert!(index < 8);
  201. _set((permission as usize) << (index * 8));
  202. }
  203. #[inline]
  204. pub unsafe fn set_range(range: Range, index: usize) {
  205. #[cfg(riscv32)]
  206. assert!(index < 4);
  207. #[cfg(riscv64)]
  208. assert!(index < 8);
  209. _set((range as usize) << (3 + (index * 8)));
  210. }
  211. #[inline]
  212. pub unsafe fn set_lock(index: usize) {
  213. #[cfg(riscv32)]
  214. assert!(index < 4);
  215. #[cfg(riscv64)]
  216. assert!(index < 8);
  217. _set(1 << (7 + (index * 8)));
  218. }
  219. #[inline]
  220. pub unsafe fn clear_lock(index: usize) {
  221. #[cfg(riscv32)]
  222. assert!(index < 4);
  223. #[cfg(riscv64)]
  224. assert!(index < 8);
  225. _clear(1 << (7 + (index * 8)));
  226. }
  227. }
  228. /// Physical memory protection configuration
  229. /// Pmpcfg0 struct contains pmp12cfg - pmp15cfg for RV32 only
  230. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  231. pub mod pmpcfg3 {
  232. use super::{BitField, Permission, PmpByte, Range};
  233. #[derive(Clone, Copy, Debug)]
  234. pub struct Pmpcfg3 {
  235. pub bits: usize,
  236. }
  237. impl Pmpcfg3 {
  238. #[inline]
  239. pub fn get_byte(&self, index: usize) -> PmpByte {
  240. PmpByte {
  241. byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
  242. }
  243. }
  244. }
  245. read_csr_as!(Pmpcfg3, 0x3A3, __read_pmpcfg3);
  246. write_csr!(0x3A3, __write_pmpcfg3);
  247. set!(0x3A3, __set_pmpcfg3);
  248. clear!(0x3A3, __clear_pmpcfg3);
  249. #[inline]
  250. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  251. #[cfg(riscv32)]
  252. assert!(index < 4);
  253. #[cfg(riscv64)]
  254. assert!(index < 8);
  255. _set((permission as usize) << (index * 8));
  256. }
  257. #[inline]
  258. pub unsafe fn set_range(range: Range, index: usize) {
  259. #[cfg(riscv32)]
  260. assert!(index < 4);
  261. #[cfg(riscv64)]
  262. assert!(index < 8);
  263. _set((range as usize) << (3 + (index * 8)));
  264. }
  265. #[inline]
  266. pub unsafe fn set_lock(index: usize) {
  267. #[cfg(riscv32)]
  268. assert!(index < 4);
  269. #[cfg(riscv64)]
  270. assert!(index < 8);
  271. _set(1 << (7 + (index * 8)));
  272. }
  273. #[inline]
  274. pub unsafe fn clear_lock(index: usize) {
  275. #[cfg(riscv32)]
  276. assert!(index < 4);
  277. #[cfg(riscv64)]
  278. assert!(index < 8);
  279. _clear(1 << (7 + (index * 8)));
  280. }
  281. }