Add FS and XS fields of mstatus

This commit is contained in:
Vadim Kaushan 2019-03-18 18:08:14 +03:00
parent 32eba6c1ea
commit 4fb81f4860
No known key found for this signature in database
GPG Key ID: A501C5DF67C05C4E
2 changed files with 65 additions and 1 deletions

2
asm.S
View File

@ -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)

View File

@ -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 `f0f31`.
#[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);
}