pmpcfgx.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 = 0b000,
  7. R = 0b001,
  8. W = 0b010,
  9. RW = 0b011,
  10. X = 0b100,
  11. RX = 0b101,
  12. WX = 0b110,
  13. RWX = 0b111,
  14. }
  15. /// Range enum contains all possible addressing modes for pmp registers
  16. #[derive(Clone, Copy, Debug)]
  17. pub enum Range {
  18. OFF = 0b00,
  19. TOR = 0b01,
  20. NA4 = 0b10,
  21. NAPOT = 0b11,
  22. }
  23. /// Pmp struct holds a readable configuration of a single pmp
  24. #[derive(Clone, Copy, Debug)]
  25. pub struct Pmp {
  26. /// raw bits
  27. pub byte: u8,
  28. /// Current PMP Permission
  29. pub permission: Permission,
  30. /// Current PMP Range
  31. pub range: Range,
  32. /// Is PMP locked?
  33. pub locked: bool,
  34. }
  35. pub struct Pmpcsr {
  36. /// Holds the raw contents of the PMP CSR Register
  37. pub bits: usize,
  38. }
  39. impl Pmpcsr {
  40. /// Take the register contents and translates into a Pmp configuration struct
  41. #[inline]
  42. pub fn into_config(&self, index: usize) -> Pmp {
  43. #[cfg(riscv32)]
  44. assert!(index < 4);
  45. #[cfg(riscv64)]
  46. assert!(index < 8);
  47. let byte = self.bits.get_bits(8 * index..=8 * index + 7) as u8;
  48. Pmp {
  49. byte,
  50. permission: match byte.get_bits(0..=2) {
  51. 0 => Permission::NONE,
  52. 1 => Permission::R,
  53. 2 => Permission::W,
  54. 3 => Permission::RW,
  55. 4 => Permission::X,
  56. 5 => Permission::RX,
  57. 6 => Permission::WX,
  58. 7 => Permission::RWX,
  59. _ => unreachable!(),
  60. },
  61. range: match byte.get_bits(3..=4) {
  62. 0 => Range::OFF,
  63. 1 => Range::TOR,
  64. 2 => Range::NA4,
  65. 3 => Range::NAPOT,
  66. _ => unreachable!(),
  67. },
  68. locked: byte.get_bit(7) as bool,
  69. }
  70. }
  71. }
  72. /// Physical memory protection configuration
  73. /// pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, and pmp0cfg - pmp7cfg for RV64
  74. pub mod pmpcfg0 {
  75. use super::{Permission, Pmpcsr, Range};
  76. use bit_field::BitField;
  77. read_csr_as!(Pmpcsr, 0x3A0, __read_pmpcfg0);
  78. write_csr_as_usize!(0x3A0, __write_pmpcfg0);
  79. set_pmp!(Range,Permission);
  80. clear_pmp!();
  81. }
  82. /// Physical memory protection configuration
  83. /// pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
  84. #[cfg(riscv32)]
  85. pub mod pmpcfg1 {
  86. use super::{Permission, Pmpcsr, Range};
  87. use bit_field::BitField;
  88. read_csr_as!(Pmpcsr, 0x3A1, __read_pmpcfg1);
  89. write_csr_as_usize_rv32!(0x3A1, __write_pmpcfg1);
  90. set_pmp!(Range,Permission);
  91. clear_pmp!();
  92. }
  93. /// Physical memory protection configuration
  94. /// pmpcfg2 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
  95. pub mod pmpcfg2 {
  96. use super::{Permission, Pmpcsr, Range};
  97. use bit_field::BitField;
  98. read_csr_as!(Pmpcsr, 0x3A2, __read_pmpcfg2);
  99. write_csr_as_usize!(0x3A2, __write_pmpcfg2);
  100. set_pmp!(Range,Permission);
  101. clear_pmp!();
  102. }
  103. /// Physical memory protection configuration
  104. /// pmpcfg3 struct contains pmp12cfg - pmp15cfg for RV32 only
  105. #[cfg(riscv32)]
  106. pub mod pmpcfg3 {
  107. use super::{Permission, Pmpcsr, Range};
  108. use bit_field::BitField;
  109. read_csr_as!(Pmpcsr, 0x3A3, __read_pmpcfg3);
  110. write_csr_as_usize_rv32!(0x3A3, __write_pmpcfg3);
  111. set_pmp!(Range,Permission);
  112. clear_pmp!();
  113. }