Browse Source

Add FS and XS fields of mstatus

Vadim Kaushan 6 years ago
parent
commit
4fb81f4860
2 changed files with 65 additions and 1 deletions
  1. 1 1
      asm.S
  2. 64 0
      src/register/mstatus.rs

+ 1 - 1
asm.S

@@ -36,7 +36,7 @@ REG_SET_CLEAR(mie, 0x304)
 REG_READ(minstret, 0xB02)
 REG_READ(mip, 0x344)
 REG_READ(misa, 0x301)
-REG_READ(mstatus, 0x300)
+REG_READ_WRITE(mstatus, 0x300)
 REG_SET_CLEAR(mstatus, 0x300)
 REG_READ_WRITE(mtvec, 0x305)
 REG_READ(mvendorid, 0xF11)

+ 64 - 0
src/register/mstatus.rs

@@ -1,12 +1,37 @@
 //! mstatus register
 // TODO: Virtualization, Memory Privilege and Extension Context Fields
 
+use bit_field::BitField;
+
 /// mstatus register
 #[derive(Clone, Copy, Debug)]
 pub struct Mstatus {
     bits: usize,
 }
 
+/// Additional extension state
+pub enum XS {
+    /// All off
+    AllOff = 0,
+
+    /// None dirty or clean, some on
+    NoneDirtyOrClean = 1,
+
+    /// None dirty, some clean
+    NoneDirtySomeClean = 2,
+
+    /// Some dirty
+    SomeDirty = 3,
+}
+
+/// Floating-point extension state
+pub enum FS {
+    Off = 0,
+    Initial = 1,
+    Clean = 2,
+    Dirty = 3,
+}
+
 /// Machine Previous Privilege Mode
 pub enum MPP {
     Machine = 3,
@@ -76,10 +101,40 @@ impl Mstatus {
             _ => unreachable!(),
         }
     }
+
+    /// Floating-point extension state
+    ///
+    /// Encodes the status of the floating-point unit,
+    /// including the CSR `fcsr` and floating-point data registers `f0–f31`.
+    #[inline]
+    pub fn fs(&self) -> FS {
+        match self.bits.get_bits(13..15) {
+            0b00 => FS::Off,
+            0b01 => FS::Initial,
+            0b10 => FS::Clean,
+            0b11 => FS::Dirty,
+            _ => unreachable!(),
+        }
+    }
+
+    /// Additional extension state
+    ///
+    /// Encodes the status of additional user-mode extensions and associated state.
+    #[inline]
+    pub fn xs(&self) -> XS {
+        match self.bits.get_bits(15..17) {
+            0b00 => XS::AllOff,
+            0b01 => XS::NoneDirtyOrClean,
+            0b10 => XS::NoneDirtySomeClean,
+            0b11 => XS::SomeDirty,
+            _ => unreachable!(),
+        }
+    }
 }
 
 
 read_csr_as!(Mstatus, 0x300, __read_mstatus);
+write_csr!(0x300, __write_mstatus);
 set!(0x300, __set_mstatus);
 clear!(0x300, __clear_mstatus);
 
@@ -111,3 +166,12 @@ pub unsafe fn set_spp(spp: SPP) {
 pub unsafe fn set_mpp(mpp: MPP) {
     _set((mpp as usize) << 11);
 }
+
+/// Floating-point extension state
+#[inline]
+pub unsafe fn set_fs(fs: FS) {
+    let mut value = _read();
+    value &= !(0b11 << 13);
+    value |= (fs as usize) << 13;
+    _write(value);
+}