pmpcfgx.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /// Physical memory protection configuration
  2. pub mod pmpcfg0 {
  3. use bit_field::BitField;
  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. #[derive(Clone, Copy, Debug)]
  16. pub enum Range {
  17. OFF = 0,
  18. TOR = 1,
  19. NA4 = 2,
  20. NAPOT = 3,
  21. }
  22. #[derive(Clone, Copy, Debug)]
  23. pub struct Pmpconfig {
  24. pub permission: Permission,
  25. pub range_type: Range,
  26. pub locked: bool,
  27. }
  28. #[derive(Clone, Copy, Debug)]
  29. pub struct Pmpcfg0 {
  30. bits: usize,
  31. }
  32. impl Pmpcfg0 {
  33. ///Returns the pmp byte associated with the index
  34. #[inline]
  35. pub fn pmp_byte(&self, index: usize) -> usize {
  36. assert!(index < 8);
  37. match index {
  38. 0 => self.bits.get_bits(0..8),
  39. 1 => self.bits.get_bits(8..16),
  40. 2 => self.bits.get_bits(16..24),
  41. 3 => self.bits.get_bits(24..32),
  42. 4 => self.bits.get_bits(32..40),
  43. 5 => self.bits.get_bits(40..48),
  44. 6 => self.bits.get_bits(48..56),
  45. 7 => self.bits.get_bits(56..64),
  46. _ => panic!(),
  47. }
  48. }
  49. #[inline]
  50. fn range(&self, byte: usize) -> Range {
  51. match byte.get_bits(4..6) {
  52. 0 => Range::OFF,
  53. 1 => Range::TOR,
  54. 2 => Range::NA4,
  55. 3 => Range::NAPOT,
  56. _ => panic!(),
  57. }
  58. }
  59. #[inline]
  60. fn permission(&self, byte: usize) -> Permission {
  61. match byte.get_bits(0..4) {
  62. 0 => Permission::NONE,
  63. 1 => Permission::R,
  64. 2 => Permission::W,
  65. 3 => Permission::RW,
  66. 4 => Permission::X,
  67. 5 => Permission::RX,
  68. 6 => Permission::WX,
  69. 7 => Permission::RWX,
  70. _ => panic!(),
  71. }
  72. }
  73. ///Returns pmp[x]cfg configuration structure
  74. #[inline]
  75. pub fn pmp_cfg(&self, index: usize) -> Pmpconfig {
  76. assert!(index < 8);
  77. let byte = self.pmp_byte(index);
  78. let p = self.permission(byte);
  79. let r = self.range(byte);
  80. let l = byte.get_bit(7);
  81. Pmpconfig {
  82. permission: p,
  83. range_type: r,
  84. locked: l,
  85. }
  86. }
  87. }
  88. read_csr_as!(Pmpcfg0, 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. assert!(index < 8);
  95. _set((permission as usize) << (index * 8));
  96. }
  97. #[inline]
  98. pub unsafe fn set_range(range: Range, index: usize) {
  99. assert!(index < 8);
  100. _set((range as usize) << (3 + (index * 8)));
  101. }
  102. #[inline]
  103. pub unsafe fn set_lock(index: usize) {
  104. assert!(index < 8);
  105. _set(1 << (7 + (index * 8)));
  106. }
  107. #[inline]
  108. pub unsafe fn clear_lock(index: usize) {
  109. assert!(index < 8);
  110. _clear(1 << (7 + (index * 8)));
  111. }
  112. }
  113. /// Physical memory protection configuration, RV32 only
  114. pub mod pmpcfg1 {
  115. read_csr_as_usize_rv32!(0x3A1, __read_pmpcfg1);
  116. write_csr_as_usize_rv32!(0x3A1, __write_pmpcfg1);
  117. }
  118. /// Physical memory protection configuration
  119. pub mod pmpcfg2 {
  120. read_csr_as_usize!(0x3A2, __read_pmpcfg2);
  121. write_csr_as_usize!(0x3A2, __write_pmpcfg2);
  122. }
  123. /// Physical memory protection configuration, RV32 only
  124. pub mod pmpcfg3 {
  125. read_csr_as_usize_rv32!(0x3A3, __read_pmpcfg3);
  126. write_csr_as_usize_rv32!(0x3A3, __write_pmpcfg3);
  127. }