pmpcfgx.rs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  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(4..=5) {
  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. /// Pmpcf0 struct contains pmp0cfg - pmp3cfg for 32-bit arch, or pmp0cfg - pmp7cfg for 64-bit arch
  64. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  65. pub mod pmpcfg0 {
  66. use super::PmpByte;
  67. #[derive(Clone, Copy, Debug)]
  68. pub struct Pmpcfg0 {
  69. pub bits: u32,
  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. read_csr_as!(Pmpcfg0, 0x3A0, __read_pmpcfg0);
  83. write_csr!(0x3A0, __write_pmpcfg0);
  84. set!(0x3A0, __set_pmpcfg0);
  85. clear!(0x3A0, __clear_pmpcfg0);
  86. #[inline]
  87. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  88. #[cfg(riscv32)]
  89. assert!(index < 4);
  90. #[cfg(riscv64)]
  91. assert!(index < 8);
  92. _write((permission as usize) << (index * 8));
  93. }
  94. #[inline]
  95. pub unsafe fn set_range(range: Range, index: usize) {
  96. #[cfg(riscv32)]
  97. assert!(index < 4);
  98. #[cfg(riscv64)]
  99. assert!(index < 8);
  100. _write((range as usize) << (3 + (index * 8)));
  101. }
  102. #[inline]
  103. pub unsafe fn set_lock(index: usize) {
  104. #[cfg(riscv32)]
  105. assert!(index < 4);
  106. #[cfg(riscv64)]
  107. assert!(index < 8);
  108. _set(1 << (7 + (index * 8)));
  109. }
  110. #[inline]
  111. pub unsafe fn clear_lock(index: usize) {
  112. #[cfg(riscv32)]
  113. assert!(index < 4);
  114. #[cfg(riscv64)]
  115. assert!(index < 8);
  116. _clear(1 << (7 + (index * 8)));
  117. }
  118. }
  119. }
  120. /// Physical memory protection configuration, RV32 only
  121. /// Pmpcf1 struct contains pmp4cfg - pmp7cfg for 32-bit arch only
  122. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  123. pub mod pmpcfg1 {
  124. use super::PmpByte;
  125. #[derive(Clone, Copy, Debug)]
  126. pub struct Pmpcfg1 {
  127. pub bits: u32,
  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. read_csr_as_usize_rv32!(0x3A1, __read_pmpcfg1);
  137. write_csr_as_usize_rv32!(0x3A1, __write_pmpcfg1);
  138. #[inline]
  139. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  140. #[cfg(riscv32)]
  141. assert!(index < 4);
  142. #[cfg(riscv64)]
  143. assert!(index < 8);
  144. _write((permission as usize) << (index * 8));
  145. }
  146. #[inline]
  147. pub unsafe fn set_range(range: Range, index: usize) {
  148. #[cfg(riscv32)]
  149. assert!(index < 4);
  150. #[cfg(riscv64)]
  151. assert!(index < 8);
  152. _write((range as usize) << (3 + (index * 8)));
  153. }
  154. #[inline]
  155. pub unsafe fn set_lock(index: usize) {
  156. #[cfg(riscv32)]
  157. assert!(index < 4);
  158. #[cfg(riscv64)]
  159. assert!(index < 8);
  160. _set(1 << (7 + (index * 8)));
  161. }
  162. #[inline]
  163. pub unsafe fn clear_lock(index: usize) {
  164. #[cfg(riscv32)]
  165. assert!(index < 4);
  166. #[cfg(riscv64)]
  167. assert!(index < 8);
  168. _clear(1 << (7 + (index * 8)));
  169. }
  170. }
  171. }
  172. /// Physical memory protection configuration
  173. /// Pmpcf0 struct contains pmp8cfg - pmp11cfg for 32-bit arch, or pmp8cfg - pmp15cfg for 64-bit arch
  174. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  175. pub mod pmpcfg2 {
  176. use super::PmpByte;
  177. #[derive(Clone, Copy, Debug)]
  178. pub struct Pmpcfg2 {
  179. pub bits: u32,
  180. }
  181. impl Pmpcfg2 {
  182. #[inline]
  183. pub fn get_byte(&self, index: usize) -> PmpByte {
  184. PmpByte {
  185. byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
  186. }
  187. }
  188. read_csr_as_usize!(0x3A2, __read_pmpcfg2);
  189. write_csr_as_usize!(0x3A2, __write_pmpcfg2);
  190. #[inline]
  191. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  192. #[cfg(riscv32)]
  193. assert!(index < 4);
  194. #[cfg(riscv64)]
  195. assert!(index < 8);
  196. _write((permission as usize) << (index * 8));
  197. }
  198. #[inline]
  199. pub unsafe fn set_range(range: Range, index: usize) {
  200. #[cfg(riscv32)]
  201. assert!(index < 4);
  202. #[cfg(riscv64)]
  203. assert!(index < 8);
  204. _write((range as usize) << (3 + (index * 8)));
  205. }
  206. #[inline]
  207. pub unsafe fn set_lock(index: usize) {
  208. #[cfg(riscv32)]
  209. assert!(index < 4);
  210. #[cfg(riscv64)]
  211. assert!(index < 8);
  212. _set(1 << (7 + (index * 8)));
  213. }
  214. #[inline]
  215. pub unsafe fn clear_lock(index: usize) {
  216. #[cfg(riscv32)]
  217. assert!(index < 4);
  218. #[cfg(riscv64)]
  219. assert!(index < 8);
  220. _clear(1 << (7 + (index * 8)));
  221. }
  222. }
  223. }
  224. /// Physical memory protection configuration, RV32 only
  225. /// Pmpcf0 struct contains pmp12cfg - pmp15cfg for 32-bit arch only
  226. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  227. pub mod pmpcfg3 {
  228. use super::PmpByte;
  229. #[derive(Clone, Copy, Debug)]
  230. pub struct Pmpcfg3 {
  231. pub bits: u32,
  232. }
  233. impl Pmpcfg3 {
  234. #[inline]
  235. pub fn get_byte(&self, index: usize) -> PmpByte {
  236. PmpByte {
  237. byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
  238. }
  239. }
  240. read_csr_as_usize_rv32!(0x3A3, __read_pmpcfg3);
  241. write_csr_as_usize_rv32!(0x3A3, __write_pmpcfg3);
  242. #[inline]
  243. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  244. #[cfg(riscv32)]
  245. assert!(index < 4);
  246. #[cfg(riscv64)]
  247. assert!(index < 8);
  248. _write((permission as usize) << (index * 8));
  249. }
  250. #[inline]
  251. pub unsafe fn set_range(range: Range, index: usize) {
  252. #[cfg(riscv32)]
  253. assert!(index < 4);
  254. #[cfg(riscv64)]
  255. assert!(index < 8);
  256. _write((range as usize) << (3 + (index * 8)));
  257. }
  258. #[inline]
  259. pub unsafe fn set_lock(index: usize) {
  260. #[cfg(riscv32)]
  261. assert!(index < 4);
  262. #[cfg(riscv64)]
  263. assert!(index < 8);
  264. _set(1 << (7 + (index * 8)));
  265. }
  266. #[inline]
  267. pub unsafe fn clear_lock(index: usize) {
  268. #[cfg(riscv32)]
  269. assert!(index < 4);
  270. #[cfg(riscv64)]
  271. assert!(index < 8);
  272. _clear(1 << (7 + (index * 8)));
  273. }
  274. }
  275. }