Skip to content

Commit 6425cab

Browse files
bors[bot]Disasm
andcommitted
Merge #24
24: Add FS and XS fields, fix incorrect field setting, bump version r=dvc94ch a=Disasm Co-authored-by: Vadim Kaushan <[email protected]>
2 parents 32eba6c + 6bfccad commit 6425cab

File tree

8 files changed

+96
-15
lines changed

8 files changed

+96
-15
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "riscv"
3-
version = "0.5.0"
3+
version = "0.5.1"
44
repository = "https://github.com/rust-embedded/riscv"
55
authors = ["The RISC-V Team <[email protected]>"]
66
categories = ["embedded", "hardware-support", "no-std"]

asm.S

Lines changed: 2 additions & 2 deletions
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)
@@ -49,7 +49,7 @@ REG_READ(sie, 0x104)
4949
REG_SET_CLEAR(sie, 0x104)
5050
REG_READ(sip, 0x144)
5151
REG_READ_WRITE(sscratch, 0x140)
52-
REG_READ(sstatus, 0x100)
52+
REG_READ_WRITE(sstatus, 0x100)
5353
REG_SET_CLEAR(sstatus, 0x100)
5454
REG_READ(stval, 0x143)
5555
REG_READ_WRITE(stvec, 0x105)

bin/riscv32imac-unknown-none-elf.a

272 Bytes
Binary file not shown.

bin/riscv32imc-unknown-none-elf.a

272 Bytes
Binary file not shown.

bin/riscv64gc-unknown-none-elf.a

352 Bytes
Binary file not shown.

bin/riscv64imac-unknown-none-elf.a

352 Bytes
Binary file not shown.

src/register/mstatus.rs

Lines changed: 85 additions & 10 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,
@@ -24,43 +49,43 @@ impl Mstatus {
2449
/// User Interrupt Enable
2550
#[inline]
2651
pub fn uie(&self) -> bool {
27-
self.bits & (1 << 0) == 1 << 0
52+
self.bits.get_bit(0)
2853
}
2954

3055
/// Supervisor Interrupt Enable
3156
#[inline]
3257
pub fn sie(&self) -> bool {
33-
self.bits & (1 << 1) == 1 << 1
58+
self.bits.get_bit(1)
3459
}
3560

3661
/// Machine Interrupt Enable
3762
#[inline]
3863
pub fn mie(&self) -> bool {
39-
self.bits & (1 << 3) == 1 << 3
64+
self.bits.get_bit(3)
4065
}
4166

4267
/// User Previous Interrupt Enable
4368
#[inline]
4469
pub fn upie(&self) -> bool {
45-
self.bits & (1 << 4) == 1 << 4
70+
self.bits.get_bit(4)
4671
}
4772

4873
/// Supervisor Previous Interrupt Enable
4974
#[inline]
5075
pub fn spie(&self) -> bool {
51-
self.bits & (1 << 5) == 1 << 5
76+
self.bits.get_bit(5)
5277
}
5378

5479
/// User Previous Interrupt Enable
5580
#[inline]
5681
pub fn mpie(&self) -> bool {
57-
self.bits & (1 << 7) == 1 << 7
82+
self.bits.get_bit(7)
5883
}
5984

6085
/// Supervisor Previous Privilege Mode
6186
#[inline]
6287
pub fn spp(&self) -> SPP {
63-
match self.bits & (1 << 8) == (1 << 8) {
88+
match self.bits.get_bit(8) {
6489
true => SPP::Supervisor,
6590
false => SPP::User,
6691
}
@@ -69,45 +94,95 @@ impl Mstatus {
6994
/// Machine Previous Privilege Mode
7095
#[inline]
7196
pub fn mpp(&self) -> MPP {
72-
match (self.bits & (0b11 << 11)) >> 11 {
97+
match self.bits.get_bits(11..13) {
7398
0b00 => MPP::User,
7499
0b01 => MPP::Supervisor,
75100
0b11 => MPP::Machine,
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

86141
set_clear_csr!(
87142
/// User Interrupt Enable
88143
, set_uie, clear_uie, 1 << 0);
144+
89145
set_clear_csr!(
90146
/// Supervisor Interrupt Enable
91147
, set_sie, clear_sie, 1 << 1);
148+
92149
set_clear_csr!(
93150
/// Machine Interrupt Enable
94151
, set_mie, clear_mie, 1 << 3);
152+
95153
set_csr!(
96154
/// User Previous Interrupt Enable
97155
, set_upie, 1 << 4);
156+
98157
set_csr!(
99158
/// Supervisor Previous Interrupt Enable
100159
, set_spie, 1 << 5);
160+
101161
set_csr!(
102162
/// Machine Previous Interrupt Enable
103163
, set_mpie, 1 << 7);
164+
104165
/// Supervisor Previous Privilege Mode
105166
#[inline]
106167
pub unsafe fn set_spp(spp: SPP) {
107-
_set((spp as usize) << 8);
168+
match spp {
169+
SPP::Supervisor => _set(1 << 8),
170+
SPP::User => _clear(1 << 8),
171+
}
108172
}
173+
109174
/// Machine Previous Privilege Mode
110175
#[inline]
111176
pub unsafe fn set_mpp(mpp: MPP) {
112-
_set((mpp as usize) << 11);
177+
let mut value = _read();
178+
value.set_bits(11..13, mpp as usize);
179+
_write(value);
180+
}
181+
182+
/// Floating-point extension state
183+
#[inline]
184+
pub unsafe fn set_fs(fs: FS) {
185+
let mut value = _read();
186+
value.set_bits(13..15, fs as usize);
187+
_write(value);
113188
}

src/register/sstatus.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ impl Sstatus {
105105
}
106106

107107
read_csr_as!(Sstatus, 0x100, __read_sstatus);
108+
write_csr!(0x100, __write_sstatus);
108109
set!(0x100, __set_sstatus);
109110
clear!(0x100, __clear_sstatus);
110111

@@ -131,12 +132,17 @@ set_clear_csr!(
131132
#[inline]
132133
#[cfg(riscv)]
133134
pub unsafe fn set_spp(spp: SPP) {
134-
_set((spp as usize) << 8);
135+
match spp {
136+
SPP::Supervisor => _set(1 << 8),
137+
SPP::User => _clear(1 << 8),
138+
}
135139
}
136140

137141
/// The status of the floating-point unit
138142
#[inline]
139143
#[cfg(riscv)]
140144
pub unsafe fn set_fs(fs: FS) {
141-
_set((fs as usize) << 13);
145+
let mut value = _read();
146+
value.set_bits(13..15, fs as usize);
147+
_write(value);
142148
}

0 commit comments

Comments
 (0)