浏览代码

Add supervisor privilege bits defined in 1.10

luojia65 4 年之前
父节点
当前提交
97f1347d4e
共有 2 个文件被更改,包括 77 次插入11 次删除
  1. 74 6
      src/register/mstatus.rs
  2. 3 5
      src/register/sstatus.rs

+ 74 - 6
src/register/mstatus.rs

@@ -1,5 +1,10 @@
 //! mstatus register
-// TODO: Virtualization, Memory Privilege and Extension Context Fields
+// FIXME: in 1.12 spec there will be `SBE` and `MBE` bits.
+// They allows to execute supervisor in given big endian,
+// they would be in a new register `mstatush` in RV32; we should implement `mstatush`
+// at that time.
+// FIXME: `SXL` and `UXL` bits require a structure interpreting XLEN,
+// which would be the best way we implement this using Rust?
 
 use bit_field::BitField;
 use core::mem::size_of;
@@ -136,6 +141,59 @@ impl Mstatus {
         }
     }
 
+    /// Permit Supervisor User Memory access
+    #[inline]
+    pub fn sum(&self) -> bool {
+        self.bits.get_bit(18)
+    }
+
+    /// Make eXecutable Readable
+    #[inline]
+    pub fn mxr(&self) -> bool {
+        self.bits.get_bit(19)
+    }
+
+    /// Trap Virtual Memory
+    ///
+    /// If this bit is set, reads or writes to `satp` CSR or execute `sfence.vma`
+    /// instruction when in S-mode will raise an illegal instruction exception.
+    ///
+    /// TVM is hard-wired to 0 when S-mode is not supported.
+    #[inline]
+    pub fn tvm(&self) -> bool {
+        self.bits.get_bit(20)
+    }
+
+    /// Timeout Wait
+    ///
+    /// Indicates that if WFI instruction should be intercepted. 
+    /// 
+    /// If this bit is set, when WFI is executed in S-mode, and it does not complete 
+    /// within an implementation specific, bounded time limit, the WFI instruction will cause
+    /// an illegal instruction trap; or could always cause trap then the time limit is zero.
+    ///
+    /// TW is hard-wired to 0 when S-mode is not supported.
+    #[inline]
+    pub fn tw(&self) -> bool {
+        self.bits.get_bit(21)
+    }
+
+    /// Trap SRET
+    ///
+    /// Indicates that if SRET instruction should be trapped to raise illegal
+    /// instruction exception.
+    ///
+    /// If S-mode is not supported, TSR bit is hard-wired to 0.
+    #[inline]
+    pub fn tsr(&self) -> bool {
+        self.bits.get_bit(22)
+    }
+
+    /* 
+        FIXME: There are MBE and SBE bits in 1.12; once Privileged Specification version 1.12
+        is ratified, there should be read functions of these bits as well.
+    */
+
     /// Whether either the FS field or XS field
     /// signals the presence of some dirty state
     #[inline]
@@ -152,26 +210,36 @@ clear!(0x300, __clear_mstatus);
 set_clear_csr!(
     /// User Interrupt Enable
     , set_uie, clear_uie, 1 << 0);
-
 set_clear_csr!(
     /// Supervisor Interrupt Enable
     , set_sie, clear_sie, 1 << 1);
-
 set_clear_csr!(
     /// Machine Interrupt Enable
     , set_mie, clear_mie, 1 << 3);
-
 set_csr!(
     /// User Previous Interrupt Enable
     , set_upie, 1 << 4);
-
 set_csr!(
     /// Supervisor Previous Interrupt Enable
     , set_spie, 1 << 5);
-
 set_csr!(
     /// Machine Previous Interrupt Enable
     , set_mpie, 1 << 7);
+set_clear_csr!(
+    /// Permit Supervisor User Memory access
+    , set_sum, clear_sum, 1 << 18);
+set_clear_csr!(
+    /// Make eXecutable Readable
+    , set_mxr, clear_mxr, 1 << 19);
+set_clear_csr!(
+    /// Trap Virtual Memory
+    , set_tvm, clear_tvm, 1 << 20);
+set_clear_csr!(
+    /// Timeout Wait
+    , set_tw, clear_tw, 1 << 21);
+set_clear_csr!(
+    /// Trap SRET
+    , set_tsr, clear_tsr, 1 << 22);
 
 /// Supervisor Previous Privilege Mode
 #[inline]

+ 3 - 5
src/register/sstatus.rs

@@ -113,16 +113,15 @@ set_csr!(
 set_csr!(
     /// Supervisor Previous Interrupt Enable
     , set_spie, 1 << 5);
-set_clear_csr!(
-    /// Make eXecutable Readable
-    , set_mxr, clear_mxr, 1 << 19);
 set_clear_csr!(
     /// Permit Supervisor User Memory access
     , set_sum, clear_sum, 1 << 18);
+set_clear_csr!(
+    /// Make eXecutable Readable
+    , set_mxr, clear_mxr, 1 << 19);
 
 /// Supervisor Previous Privilege Mode
 #[inline]
-#[cfg(riscv)]
 pub unsafe fn set_spp(spp: SPP) {
     match spp {
         SPP::Supervisor => _set(1 << 8),
@@ -132,7 +131,6 @@ pub unsafe fn set_spp(spp: SPP) {
 
 /// The status of the floating-point unit
 #[inline]
-#[cfg(riscv)]
 pub unsafe fn set_fs(fs: FS) {
     let mut value = _read();
     value.set_bits(13..15, fs as usize);