24: Add FS and XS fields, fix incorrect field setting, bump version r=dvc94ch a=Disasm



Co-authored-by: Vadim Kaushan <admin@disasm.info>
This commit is contained in:
bors[bot] 2019-03-28 20:47:36 +00:00
commit 6425cab701
8 changed files with 96 additions and 15 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "riscv" name = "riscv"
version = "0.5.0" version = "0.5.1"
repository = "https://github.com/rust-embedded/riscv" repository = "https://github.com/rust-embedded/riscv"
authors = ["The RISC-V Team <risc-v@teams.rust-embedded.org>"] authors = ["The RISC-V Team <risc-v@teams.rust-embedded.org>"]
categories = ["embedded", "hardware-support", "no-std"] categories = ["embedded", "hardware-support", "no-std"]

4
asm.S
View File

@ -36,7 +36,7 @@ REG_SET_CLEAR(mie, 0x304)
REG_READ(minstret, 0xB02) REG_READ(minstret, 0xB02)
REG_READ(mip, 0x344) REG_READ(mip, 0x344)
REG_READ(misa, 0x301) REG_READ(misa, 0x301)
REG_READ(mstatus, 0x300) REG_READ_WRITE(mstatus, 0x300)
REG_SET_CLEAR(mstatus, 0x300) REG_SET_CLEAR(mstatus, 0x300)
REG_READ_WRITE(mtvec, 0x305) REG_READ_WRITE(mtvec, 0x305)
REG_READ(mvendorid, 0xF11) REG_READ(mvendorid, 0xF11)
@ -49,7 +49,7 @@ REG_READ(sie, 0x104)
REG_SET_CLEAR(sie, 0x104) REG_SET_CLEAR(sie, 0x104)
REG_READ(sip, 0x144) REG_READ(sip, 0x144)
REG_READ_WRITE(sscratch, 0x140) REG_READ_WRITE(sscratch, 0x140)
REG_READ(sstatus, 0x100) REG_READ_WRITE(sstatus, 0x100)
REG_SET_CLEAR(sstatus, 0x100) REG_SET_CLEAR(sstatus, 0x100)
REG_READ(stval, 0x143) REG_READ(stval, 0x143)
REG_READ_WRITE(stvec, 0x105) REG_READ_WRITE(stvec, 0x105)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,37 @@
//! mstatus register //! mstatus register
// TODO: Virtualization, Memory Privilege and Extension Context Fields // TODO: Virtualization, Memory Privilege and Extension Context Fields
use bit_field::BitField;
/// mstatus register /// mstatus register
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Mstatus { pub struct Mstatus {
bits: usize, 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 /// Machine Previous Privilege Mode
pub enum MPP { pub enum MPP {
Machine = 3, Machine = 3,
@ -24,43 +49,43 @@ impl Mstatus {
/// User Interrupt Enable /// User Interrupt Enable
#[inline] #[inline]
pub fn uie(&self) -> bool { pub fn uie(&self) -> bool {
self.bits & (1 << 0) == 1 << 0 self.bits.get_bit(0)
} }
/// Supervisor Interrupt Enable /// Supervisor Interrupt Enable
#[inline] #[inline]
pub fn sie(&self) -> bool { pub fn sie(&self) -> bool {
self.bits & (1 << 1) == 1 << 1 self.bits.get_bit(1)
} }
/// Machine Interrupt Enable /// Machine Interrupt Enable
#[inline] #[inline]
pub fn mie(&self) -> bool { pub fn mie(&self) -> bool {
self.bits & (1 << 3) == 1 << 3 self.bits.get_bit(3)
} }
/// User Previous Interrupt Enable /// User Previous Interrupt Enable
#[inline] #[inline]
pub fn upie(&self) -> bool { pub fn upie(&self) -> bool {
self.bits & (1 << 4) == 1 << 4 self.bits.get_bit(4)
} }
/// Supervisor Previous Interrupt Enable /// Supervisor Previous Interrupt Enable
#[inline] #[inline]
pub fn spie(&self) -> bool { pub fn spie(&self) -> bool {
self.bits & (1 << 5) == 1 << 5 self.bits.get_bit(5)
} }
/// User Previous Interrupt Enable /// User Previous Interrupt Enable
#[inline] #[inline]
pub fn mpie(&self) -> bool { pub fn mpie(&self) -> bool {
self.bits & (1 << 7) == 1 << 7 self.bits.get_bit(7)
} }
/// Supervisor Previous Privilege Mode /// Supervisor Previous Privilege Mode
#[inline] #[inline]
pub fn spp(&self) -> SPP { pub fn spp(&self) -> SPP {
match self.bits & (1 << 8) == (1 << 8) { match self.bits.get_bit(8) {
true => SPP::Supervisor, true => SPP::Supervisor,
false => SPP::User, false => SPP::User,
} }
@ -69,45 +94,95 @@ impl Mstatus {
/// Machine Previous Privilege Mode /// Machine Previous Privilege Mode
#[inline] #[inline]
pub fn mpp(&self) -> MPP { pub fn mpp(&self) -> MPP {
match (self.bits & (0b11 << 11)) >> 11 { match self.bits.get_bits(11..13) {
0b00 => MPP::User, 0b00 => MPP::User,
0b01 => MPP::Supervisor, 0b01 => MPP::Supervisor,
0b11 => MPP::Machine, 0b11 => MPP::Machine,
_ => unreachable!(), _ => 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); read_csr_as!(Mstatus, 0x300, __read_mstatus);
write_csr!(0x300, __write_mstatus);
set!(0x300, __set_mstatus); set!(0x300, __set_mstatus);
clear!(0x300, __clear_mstatus); clear!(0x300, __clear_mstatus);
set_clear_csr!( set_clear_csr!(
/// User Interrupt Enable /// User Interrupt Enable
, set_uie, clear_uie, 1 << 0); , set_uie, clear_uie, 1 << 0);
set_clear_csr!( set_clear_csr!(
/// Supervisor Interrupt Enable /// Supervisor Interrupt Enable
, set_sie, clear_sie, 1 << 1); , set_sie, clear_sie, 1 << 1);
set_clear_csr!( set_clear_csr!(
/// Machine Interrupt Enable /// Machine Interrupt Enable
, set_mie, clear_mie, 1 << 3); , set_mie, clear_mie, 1 << 3);
set_csr!( set_csr!(
/// User Previous Interrupt Enable /// User Previous Interrupt Enable
, set_upie, 1 << 4); , set_upie, 1 << 4);
set_csr!( set_csr!(
/// Supervisor Previous Interrupt Enable /// Supervisor Previous Interrupt Enable
, set_spie, 1 << 5); , set_spie, 1 << 5);
set_csr!( set_csr!(
/// Machine Previous Interrupt Enable /// Machine Previous Interrupt Enable
, set_mpie, 1 << 7); , set_mpie, 1 << 7);
/// Supervisor Previous Privilege Mode /// Supervisor Previous Privilege Mode
#[inline] #[inline]
pub unsafe fn set_spp(spp: SPP) { pub unsafe fn set_spp(spp: SPP) {
_set((spp as usize) << 8); match spp {
SPP::Supervisor => _set(1 << 8),
SPP::User => _clear(1 << 8),
}
} }
/// Machine Previous Privilege Mode /// Machine Previous Privilege Mode
#[inline] #[inline]
pub unsafe fn set_mpp(mpp: MPP) { pub unsafe fn set_mpp(mpp: MPP) {
_set((mpp as usize) << 11); let mut value = _read();
value.set_bits(11..13, mpp as usize);
_write(value);
}
/// Floating-point extension state
#[inline]
pub unsafe fn set_fs(fs: FS) {
let mut value = _read();
value.set_bits(13..15, fs as usize);
_write(value);
} }

View File

@ -105,6 +105,7 @@ impl Sstatus {
} }
read_csr_as!(Sstatus, 0x100, __read_sstatus); read_csr_as!(Sstatus, 0x100, __read_sstatus);
write_csr!(0x100, __write_sstatus);
set!(0x100, __set_sstatus); set!(0x100, __set_sstatus);
clear!(0x100, __clear_sstatus); clear!(0x100, __clear_sstatus);
@ -131,12 +132,17 @@ set_clear_csr!(
#[inline] #[inline]
#[cfg(riscv)] #[cfg(riscv)]
pub unsafe fn set_spp(spp: SPP) { pub unsafe fn set_spp(spp: SPP) {
_set((spp as usize) << 8); match spp {
SPP::Supervisor => _set(1 << 8),
SPP::User => _clear(1 << 8),
}
} }
/// The status of the floating-point unit /// The status of the floating-point unit
#[inline] #[inline]
#[cfg(riscv)] #[cfg(riscv)]
pub unsafe fn set_fs(fs: FS) { pub unsafe fn set_fs(fs: FS) {
_set((fs as usize) << 13); let mut value = _read();
value.set_bits(13..15, fs as usize);
_write(value);
} }