|
1 | 1 | //! mstatus register
|
2 | 2 | // TODO: Virtualization, Memory Privilege and Extension Context Fields
|
3 | 3 |
|
| 4 | +use bit_field::BitField; |
| 5 | + |
4 | 6 | /// mstatus register
|
5 | 7 | #[derive(Clone, Copy, Debug)]
|
6 | 8 | pub struct Mstatus {
|
7 | 9 | bits: usize,
|
8 | 10 | }
|
9 | 11 |
|
| 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 | + |
10 | 35 | /// Machine Previous Privilege Mode
|
11 | 36 | pub enum MPP {
|
12 | 37 | Machine = 3,
|
@@ -76,10 +101,40 @@ impl Mstatus {
|
76 | 101 | _ => unreachable!(),
|
77 | 102 | }
|
78 | 103 | }
|
| 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 | + } |
79 | 133 | }
|
80 | 134 |
|
81 | 135 |
|
82 | 136 | read_csr_as!(Mstatus, 0x300, __read_mstatus);
|
| 137 | +write_csr!(0x300, __write_mstatus); |
83 | 138 | set!(0x300, __set_mstatus);
|
84 | 139 | clear!(0x300, __clear_mstatus);
|
85 | 140 |
|
@@ -111,3 +166,12 @@ pub unsafe fn set_spp(spp: SPP) {
|
111 | 166 | pub unsafe fn set_mpp(mpp: MPP) {
|
112 | 167 | _set((mpp as usize) << 11);
|
113 | 168 | }
|
| 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