瀏覽代碼

Add set_pmp fn in pmpcfg modules, and into_config method for Pmpcfg struct

dkhayes117 3 年之前
父節點
當前提交
726d5164df
共有 1 個文件被更改,包括 92 次插入208 次删除
  1. 92 208
      src/register/pmpcfgx.rs

+ 92 - 208
src/register/pmpcfgx.rs

@@ -4,121 +4,93 @@ use bit_field::BitField;
 /// Permission enum contains all possible permission modes for pmp registers
 #[derive(Clone, Copy, Debug)]
 pub enum Permission {
-    NONE = 0b_000,
-    R = 0b_001,
-    W = 0b_010,
-    RW = 0b_011,
-    X = 0b_100,
-    RX = 0b_101,
-    WX = 0b_110,
-    RWX = 0b_111,
+    NONE = 0b000,
+    R = 0b001,
+    W = 0b010,
+    RW = 0b011,
+    X = 0b100,
+    RX = 0b101,
+    WX = 0b110,
+    RWX = 0b111,
 }
 
 /// Range enum contains all possible addressing modes for pmp registers
 #[derive(Clone, Copy, Debug)]
 pub enum Range {
-    OFF = 0b_00,
-    TOR = 0b_01,
-    NA4 = 0b_10,
-    NAPOT = 0b_11,
+    OFF = 0b00,
+    TOR = 0b01,
+    NA4 = 0b10,
+    NAPOT = 0b11,
 }
 
+/// RV64 Pmpcfg holds the entire register (8 Pmp configurations)
 #[derive(Clone, Copy, Debug)]
-pub struct Pmpcfg {
-    pub bits: usize,
+pub struct Pmp {
+    /// raw bits
+    pub byte: u8,
+    /// Current PMP Permission
+    pub permission: Permission,
+    /// Current PMP Range
+    pub range: Range,
+    /// Is PMP locked?
+    pub locked: bool,
 }
 
-/// PmpByte holds the a single pmp configuration
-#[derive(Clone, Copy, Debug)]
-pub struct PmpEntry {
-    pub byte: usize,
-    pub index: usize,
-    pub permission: Option<Permission>,
-    pub range: Option<Range>,
-    pub locked: bool,
+pub struct Pmpcsr {
+    /// Holds the raw contents of the PMP CSR
+    pub bits: usize,
 }
 
-impl Pmpcfg {
+impl Pmpcsr {
+    /// Take the register contents and translate into configurations held in a Pmpcfg struct
+    /// Takes `self` as a parameter and destroys the current Pmpcsr struct
     #[inline]
-    pub fn get_config(&self, index: usize) -> PmpEntry {
+    pub fn into_config(&self, index: usize) -> Pmp {
         #[cfg(riscv32)]
         assert!(index < 4);
 
         #[cfg(riscv64)]
         assert!(index < 8);
 
-        PmpEntry {
-            byte: self.get_byte(index),
-            index,
-            permission: self.get_permission(index),
-            range: self.get_range(index),
-            locked: self.is_locked(index),
-        }
-    }
-
-    /// PmpByte methods to get a pmp configuration attributes
-    pub fn get_byte(&self, index: usize) -> usize {
-        self.bits.get_bits(8 * index..=(8 * index) + 7) as usize
-    }
-
-    #[inline]
-    pub fn is_locked(&self, index: usize) -> bool {
-        self.bits.get_bit(7 + 8 * index)
-    }
-
-    #[inline]
-    pub fn get_permission(&self, index: usize) -> Option<Permission> {
-        match self.bits.get_bits(8 * index..=8 * index + 2) {
-            0 => Some(Permission::NONE),
-            1 => Some(Permission::R),
-            2 => Some(Permission::W),
-            3 => Some(Permission::RW),
-            4 => Some(Permission::X),
-            5 => Some(Permission::RX),
-            6 => Some(Permission::WX),
-            7 => Some(Permission::RWX),
-            _ => unreachable!(),
-        }
-    }
-
-    #[inline]
-    pub fn get_range(&self, index: usize) -> Option<Range> {
-        match self.bits.get_bits(8 * index + 3..=8 * index + 4) {
-            0 => Some(Range::OFF),
-            1 => Some(Range::TOR),
-            2 => Some(Range::NA4),
-            3 => Some(Range::NAPOT),
-            _ => unreachable!(),
+        let byte = self.bits.get_bits(8 * index..=8 * index + 7) as u8;
+        Pmp {
+            byte,
+            permission: match byte.get_bits(0..=2) {
+                0 => Permission::NONE,
+                1 => Permission::R,
+                2 => Permission::W,
+                3 => Permission::RW,
+                4 => Permission::X,
+                5 => Permission::RX,
+                6 => Permission::WX,
+                7 => Permission::RWX,
+                _ => unreachable!(),
+            },
+            range: match byte.get_bits(3..=4) {
+                0 => Range::OFF,
+                1 => Range::TOR,
+                2 => Range::NA4,
+                3 => Range::NAPOT,
+                _ => unreachable!(),
+            },
+            locked: byte.get_bit(7) as bool,
         }
     }
 }
+
 /// Physical memory protection configuration
-/// Pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, or pmp0cfg - pmp7cfg for RV64
-/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
-pub mod pmpcfg0 {
-    use super::{Permission, Pmpcfg, Range};
+/// pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, and pmp0cfg - pmp7cfg for RV64
+mod pmpcfg0 {
+    use super::{Permission, Pmpcsr, Range};
     use bit_field::BitField;
 
-    read_csr_as!(Pmpcfg, 0x3A0, __read_pmpcfg0);
-    write_csr!(0x3A0, __write_pmpcfg0);
+    read_csr_as!(Pmpcsr, 0x3A0, __read_pmpcfg0);
+    write_csr_as_usize!(0x3A0, __write_pmpcfg0);
     set!(0x3A0, __set_pmpcfg0);
     clear!(0x3A0, __clear_pmpcfg0);
 
-    #[inline]
-    pub unsafe fn set_permissions(permission: Permission, index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        let mut value = _read();
-        value.set_bits(8 * index..=8 * index + 2, permission as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_range(range: Range, index: usize) {
+    /// set the configuration for pmp(x)
+    pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
         #[cfg(riscv32)]
         assert!(index < 4);
 
@@ -126,86 +98,48 @@ pub mod pmpcfg0 {
         assert!(index < 8);
 
         let mut value = _read();
-        value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_lock(index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        _set(1 << (7 + index * 8));
+        let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
+        value.set_bits(8 * index..=8 * index + 7, byte);
+        _set(value)
     }
 }
 
 /// Physical memory protection configuration
-/// Pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
-/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
-pub mod pmpcfg1 {
-    use super::{Permission, Pmpcfg, Range};
+/// pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only
+#[cfg(riscv32)]
+mod pmpcfg1 {
+    use super::{Permission, Pmpcsr, Range};
     use bit_field::BitField;
 
-    read_csr_as!(Pmpcfg, 0x3A1, __read_pmpcfg1);
-    write_csr!(0x3A1, __write_pmpcfg1);
+    read_csr_as!(Pmpcsr, 0x3A1, __read_pmpcfg1);
+    write_csr_as_usize_rv32!(0x3A1, __write_pmpcfg1);
     set!(0x3A1, __set_pmpcfg1);
     clear!(0x3A1, __clear_pmpcfg1);
 
-    #[inline]
-    pub unsafe fn set_permissions(permission: Permission, index: usize) {
-        #[cfg(riscv32)]
+    /// set the configuration for pmp(x)
+    pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
         assert!(index < 4);
 
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        let mut value = _read();
-        value.set_bits(8 * index..=8 * index + 2, permission as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_range(range: Range, index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
         let mut value = _read();
-        value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_lock(index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        _set(1 << (7 + index * 8));
+        let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
+        value.set_bits(8 * index..=8 * index + 7, byte);
+        _set(value)
     }
 }
 
 /// Physical memory protection configuration
-/// Pmpcfg0 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
-/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
+/// pmpcfg2 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64
 pub mod pmpcfg2 {
-    use super::{Permission, Pmpcfg, Range};
+    use super::{Permission, Pmpcsr, Range};
     use bit_field::BitField;
 
-    read_csr_as!(Pmpcfg, 0x3A2, __read_pmpcfg2);
-    write_csr!(0x3A2, __write_pmpcfg2);
+    read_csr_as!(Pmpcsr, 0x3A2, __read_pmpcfg2);
+    write_csr_as_usize!(0x3A2, __write_pmpcfg2);
     set!(0x3A2, __set_pmpcfg2);
     clear!(0x3A2, __clear_pmpcfg2);
 
-    #[inline]
-    pub unsafe fn set_permissions(permission: Permission, index: usize) {
+    /// set the configuration for pmp(x)
+    pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
         #[cfg(riscv32)]
         assert!(index < 4);
 
@@ -213,81 +147,31 @@ pub mod pmpcfg2 {
         assert!(index < 8);
 
         let mut value = _read();
-        value.set_bits(8 * index..=8 * index + 2, permission as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_range(range: Range, index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        let mut value = _read();
-        value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_lock(index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        _set(1 << (7 + index * 8));
+        let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
+        value.set_bits(8 * index..=8 * index + 7, byte);
+        _set(value)
     }
 }
 
 /// Physical memory protection configuration
-/// Pmpcfg0 struct contains pmp12cfg - pmp15cfg for RV32 only
-/// get_byte() method retrieves a single pmp<x>cfg held in a PmpByte struct
+/// pmpcfg3 struct contains pmp12cfg - pmp15cfg for RV32 only
+#[cfg(riscv32)]
 pub mod pmpcfg3 {
-    use super::{Permission, Pmpcfg, Range};
+    use super::{Permission, Pmpcsr, Range};
     use bit_field::BitField;
 
-    read_csr_as!(Pmpcfg, 0x3A3, __read_pmpcfg3);
-    write_csr!(0x3A3, __write_pmpcfg3);
+    read_csr_as!(Pmpcsr, 0x3A3, __read_pmpcfg3);
+    write_csr_as_usize_rv32!(0x3A3, __read_pmpcfg3);
     set!(0x3A3, __set_pmpcfg3);
     clear!(0x3A3, __clear_pmpcfg3);
 
-    #[inline]
-    pub unsafe fn set_permissions(permission: Permission, index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        let mut value = _read();
-        value.set_bits(8 * index..=8 * index + 2, permission as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_range(range: Range, index: usize) {
-        #[cfg(riscv32)]
+    /// set the configuration for pmp(x)
+    pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
         assert!(index < 4);
 
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
         let mut value = _read();
-        value.set_bits(8 * index + 3..=8 * index + 4, range as usize);
-        _write(value);
-    }
-
-    #[inline]
-    pub unsafe fn set_lock(index: usize) {
-        #[cfg(riscv32)]
-        assert!(index < 4);
-
-        #[cfg(riscv64)]
-        assert!(index < 8);
-
-        _set(1 << (7 + index * 8));
+        let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
+        value.set_bits(8 * index..=8 * index + 7, byte);
+        _set(value)
     }
 }