pmpcfgx.rs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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. #[derive(Clone, Copy, Debug)]
  24. pub struct Pmpcfg {
  25. pub bits: usize,
  26. }
  27. impl Pmpcfg {
  28. #[inline]
  29. pub fn get_byte(&self, index: usize) -> PmpByte {
  30. #[cfg(riscv32)]
  31. assert!(index < 4);
  32. #[cfg(riscv64)]
  33. assert!(index < 8);
  34. PmpByte {
  35. byte: self.bits.get_bits(8 * index..8 * (index + 1)) as u8,
  36. }
  37. }
  38. }
  39. /// PmpByte holds the a single pmp configuration
  40. #[derive(Clone, Copy, Debug)]
  41. pub struct PmpByte {
  42. pub byte: u8,
  43. //permission: Option<Permission>,
  44. //range: Option<Range>,
  45. //locked: bool
  46. }
  47. /// PmpByte methods to get a pmp configuration attributes
  48. impl PmpByte {
  49. #[inline]
  50. pub fn is_locked(&self) -> bool {
  51. self.byte.get_bit(7)
  52. }
  53. #[inline]
  54. pub fn get_range(&self) -> Option<Range> {
  55. match self.byte.get_bits(3..=4) {
  56. 0 => Some(Range::OFF),
  57. 1 => Some(Range::TOR),
  58. 2 => Some(Range::NA4),
  59. 3 => Some(Range::NAPOT),
  60. _ => unreachable!(),
  61. }
  62. }
  63. #[inline]
  64. pub fn get_permission(&self) -> Option<Permission> {
  65. match self.byte.get_bits(0..=2) {
  66. 0 => Some(Permission::NONE),
  67. 1 => Some(Permission::R),
  68. 2 => Some(Permission::W),
  69. 3 => Some(Permission::RW),
  70. 4 => Some(Permission::X),
  71. 5 => Some(Permission::RX),
  72. 6 => Some(Permission::WX),
  73. 7 => Some(Permission::RWX),
  74. _ => unreachable!(),
  75. }
  76. }
  77. }
  78. /// Physical memory protection configuration
  79. /// Pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, or pmp0cfg - pmp7cfg for RV64
  80. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  81. pub mod pmpcfg0 {
  82. use super::{Permission, Pmpcfg, Range};
  83. read_csr_as!(Pmpcfg, 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. }
  112. /// Physical memory protection configuration
  113. /// Pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
  114. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  115. pub mod pmpcfg1 {
  116. use super::{Permission, Pmpcfg, Range};
  117. read_csr_as!(Pmpcfg, 0x3A1, __read_pmpcfg1);
  118. write_csr!(0x3A1, __write_pmpcfg1);
  119. set!(0x3A1, __set_pmpcfg1);
  120. clear!(0x3A1, __clear_pmpcfg1);
  121. #[inline]
  122. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  123. #[cfg(riscv32)]
  124. assert!(index < 4);
  125. #[cfg(riscv64)]
  126. assert!(index < 8);
  127. _set((permission as usize) << (index * 8));
  128. }
  129. #[inline]
  130. pub unsafe fn set_range(range: Range, index: usize) {
  131. #[cfg(riscv32)]
  132. assert!(index < 4);
  133. #[cfg(riscv64)]
  134. assert!(index < 8);
  135. _set((range as usize) << (3 + (index * 8)));
  136. }
  137. #[inline]
  138. pub unsafe fn set_lock(index: usize) {
  139. #[cfg(riscv32)]
  140. assert!(index < 4);
  141. #[cfg(riscv64)]
  142. assert!(index < 8);
  143. _set(1 << (7 + (index * 8)));
  144. }
  145. }
  146. /// Physical memory protection configuration
  147. /// Pmpcfg0 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
  148. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  149. pub mod pmpcfg2 {
  150. use super::{Permission, Pmpcfg, Range};
  151. read_csr_as!(Pmpcfg, 0x3A2, __read_pmpcfg2);
  152. write_csr!(0x3A2, __write_pmpcfg2);
  153. set!(0x3A2, __set_pmpcfg2);
  154. clear!(0x3A2, __clear_pmpcfg2);
  155. #[inline]
  156. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  157. #[cfg(riscv32)]
  158. assert!(index < 4);
  159. #[cfg(riscv64)]
  160. assert!(index < 8);
  161. _set((permission as usize) << (index * 8));
  162. }
  163. #[inline]
  164. pub unsafe fn set_range(range: Range, index: usize) {
  165. #[cfg(riscv32)]
  166. assert!(index < 4);
  167. #[cfg(riscv64)]
  168. assert!(index < 8);
  169. _set((range as usize) << (3 + (index * 8)));
  170. }
  171. #[inline]
  172. pub unsafe fn set_lock(index: usize) {
  173. #[cfg(riscv32)]
  174. assert!(index < 4);
  175. #[cfg(riscv64)]
  176. assert!(index < 8);
  177. _set(1 << (7 + (index * 8)));
  178. }
  179. }
  180. /// Physical memory protection configuration
  181. /// Pmpcfg0 struct contains pmp12cfg - pmp15cfg for RV32 only
  182. /// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
  183. pub mod pmpcfg3 {
  184. use super::{Permission, Pmpcfg, Range};
  185. read_csr_as!(Pmpcfg, 0x3A3, __read_pmpcfg3);
  186. write_csr!(0x3A3, __write_pmpcfg3);
  187. set!(0x3A3, __set_pmpcfg3);
  188. clear!(0x3A3, __clear_pmpcfg3);
  189. #[inline]
  190. pub unsafe fn set_permissions(permission: Permission, index: usize) {
  191. #[cfg(riscv32)]
  192. assert!(index < 4);
  193. #[cfg(riscv64)]
  194. assert!(index < 8);
  195. _set((permission as usize) << (index * 8));
  196. }
  197. #[inline]
  198. pub unsafe fn set_range(range: Range, index: usize) {
  199. #[cfg(riscv32)]
  200. assert!(index < 4);
  201. #[cfg(riscv64)]
  202. assert!(index < 8);
  203. _set((range as usize) << (3 + (index * 8)));
  204. }
  205. #[inline]
  206. pub unsafe fn set_lock(index: usize) {
  207. #[cfg(riscv32)]
  208. assert!(index < 4);
  209. #[cfg(riscv64)]
  210. assert!(index < 8);
  211. _set(1 << (7 + (index * 8)));
  212. }
  213. }