Skip to content

Commit 4fb81f4

Browse files
committed
Add FS and XS fields of mstatus
1 parent 32eba6c commit 4fb81f4

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

asm.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ REG_SET_CLEAR(mie, 0x304)
3636
REG_READ(minstret, 0xB02)
3737
REG_READ(mip, 0x344)
3838
REG_READ(misa, 0x301)
39-
REG_READ(mstatus, 0x300)
39+
REG_READ_WRITE(mstatus, 0x300)
4040
REG_SET_CLEAR(mstatus, 0x300)
4141
REG_READ_WRITE(mtvec, 0x305)
4242
REG_READ(mvendorid, 0xF11)

src/register/mstatus.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,37 @@
11
//! mstatus register
22
// TODO: Virtualization, Memory Privilege and Extension Context Fields
33

4+
use bit_field::BitField;
5+
46
/// mstatus register
57
#[derive(Clone, Copy, Debug)]
68
pub struct Mstatus {
79
bits: usize,
810
}
911

12+
/// Additional extension state
13+
pub enum XS {
14+
/// All off
15+
AllOff = 0,
16+
17+
/// None dirty or clean, some on
18+
NoneDirtyOrClean = 1,
19+
20+
/// None dirty, some clean
21+
NoneDirtySomeClean = 2,
22+
23+
/// Some dirty
24+
SomeDirty = 3,
25+
}
26+
27+
/// Floating-point extension state
28+
pub enum FS {
29+
Off = 0,
30+
Initial = 1,
31+
Clean = 2,
32+
Dirty = 3,
33+
}
34+
1035
/// Machine Previous Privilege Mode
1136
pub enum MPP {
1237
Machine = 3,
@@ -76,10 +101,40 @@ impl Mstatus {
76101
_ => unreachable!(),
77102
}
78103
}
104+
105+
/// Floating-point extension state
106+
///
107+
/// Encodes the status of the floating-point unit,
108+
/// including the CSR `fcsr` and floating-point data registers `f0–f31`.
109+
#[inline]
110+
pub fn fs(&self) -> FS {
111+
match self.bits.get_bits(13..15) {
112+
0b00 => FS::Off,
113+
0b01 => FS::Initial,
114+
0b10 => FS::Clean,
115+
0b11 => FS::Dirty,
116+
_ => unreachable!(),
117+
}
118+
}
119+
120+
/// Additional extension state
121+
///
122+
/// Encodes the status of additional user-mode extensions and associated state.
123+
#[inline]
124+
pub fn xs(&self) -> XS {
125+
match self.bits.get_bits(15..17) {
126+
0b00 => XS::AllOff,
127+
0b01 => XS::NoneDirtyOrClean,
128+
0b10 => XS::NoneDirtySomeClean,
129+
0b11 => XS::SomeDirty,
130+
_ => unreachable!(),
131+
}
132+
}
79133
}
80134

81135

82136
read_csr_as!(Mstatus, 0x300, __read_mstatus);
137+
write_csr!(0x300, __write_mstatus);
83138
set!(0x300, __set_mstatus);
84139
clear!(0x300, __clear_mstatus);
85140

@@ -111,3 +166,12 @@ pub unsafe fn set_spp(spp: SPP) {
111166
pub unsafe fn set_mpp(mpp: MPP) {
112167
_set((mpp as usize) << 11);
113168
}
169+
170+
/// Floating-point extension state
171+
#[inline]
172+
pub unsafe fn set_fs(fs: FS) {
173+
let mut value = _read();
174+
value &= !(0b11 << 13);
175+
value |= (fs as usize) << 13;
176+
_write(value);
177+
}

0 commit comments

Comments
 (0)