Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions src/register/mstatus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,155 @@ pub enum SPP {
}

impl Mstatus {
/// Set bit for User Interrupt Enable
#[inline]
pub fn bitset_uie(&mut self, value: bool) {
self.bits.set_bit(0, value);
}

/// Set bit for Supervisor Interrupt Enable
#[inline]
pub fn bitset_sie(&mut self, value: bool) {
self.bits.set_bit(1, value);
}

/// Set bit for Machine Interrupt Enable
#[inline]
pub fn bitset_mie(&mut self, value: bool) {
self.bits.set_bit(3, value);
}

/// Set bit for User Previous Interrupt Enable
#[inline]
pub fn bitset_upie(&mut self, value: bool) {
self.bits.set_bit(4, value);
}

/// Set bit for Supervisor Previous Interrupt Enable
#[inline]
pub fn bitset_spie(&mut self, value: bool) {
self.bits.set_bit(5, value);
}

/// Set bit for Machine Previous Interrupt Enable
#[inline]
pub fn bitset_mpie(&mut self, value: bool) {
self.bits.set_bit(7, value);
}

/// Set bit for Supervisor Previous Privilege Mode
#[inline]
pub fn bitset_spp(&mut self, spp: SPP) {
match spp {
SPP::Supervisor => self.bits.set_bit(8, true),
SPP::User => self.bits.set_bit(8, false),
};
}

/// Set bit for Machine Previous Privilege Mode
#[inline]
pub fn bitset_mpp(&mut self, mpp: MPP) {
match mpp {
MPP::User => self.bits.set_bits(11..13, 0b00),
MPP::Supervisor => self.bits.set_bits(11..13, 0b01),
MPP::Machine => self.bits.set_bits(11..13, 0b11),
};
}

/// Set bit for 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 bitset_fs(&mut self, fs: FS) {
match fs {
FS::Off => self.bits.set_bits(13..15, 0b00),
FS::Initial => self.bits.set_bits(13..15, 0b01),
FS::Clean => self.bits.set_bits(13..15, 0b10),
FS::Dirty => self.bits.set_bits(13..15, 0b11),
};
}

/// Set bit for Additional extension state
///
/// Encodes the status of additional user-mode extensions and associated state.
#[inline]
pub fn bitset_xs(&mut self, xs: XS) {
match xs {
XS::AllOff => self.bits.set_bits(15..17, 0b00),
XS::NoneDirtyOrClean => self.bits.set_bits(15..17, 0b01),
XS::NoneDirtySomeClean => self.bits.set_bits(15..17, 0b10),
XS::SomeDirty => self.bits.set_bits(15..17, 0b11),
};
}

/// Set bit for Modify Memory PRiVilege
#[inline]
pub fn bitset_mprv(&mut self, value: bool) {
self.bits.set_bit(17, value);
}

/// Set bit for Permit Supervisor User Memory access
#[inline]
pub fn bitset_sum(&mut self, value: bool) {
self.bits.set_bit(18, value);
}

/// Set bit for Make eXecutable Readable
#[inline]
pub fn bitset_mxr(&mut self, value: bool) {
self.bits.set_bit(19, value);
}

/// Set bit for 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 bitset_tvm(&mut self, value: bool) {
self.bits.set_bit(20, value);
}

/// Set bit for 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 bitset_tw(&mut self, value: bool) {
self.bits.set_bit(21, value);
}

/// Set bit for 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 bitset_tsr(&mut self, value: bool) {
self.bits.set_bit(22, value);
}

/// Apply the bits into actual mstatus register.
#[inline]
pub fn apply(&self) {
unsafe {
_write(self.bits);
}
}

/*
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.
*/

/// User Interrupt Enable
#[inline]
pub fn uie(&self) -> bool {
Expand Down