pmpcfgx.rs 7.4 KB

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