Refactoring: use new macros for M-mode CSRs

This commit is contained in:
Vadim Kaushan 2018-12-21 22:49:23 +01:00
parent 8bffbd7291
commit 921aa2bbec
14 changed files with 64 additions and 311 deletions

View File

@ -17,6 +17,25 @@ macro_rules! read_csr {
}; };
} }
macro_rules! read_csr_rv32 {
($csr_number:expr) => {
/// Reads the CSR
#[inline]
#[cfg(target_arch = "riscv32")]
unsafe fn _read() -> usize {
let r: usize;
asm!("csrrs $0, $1, x0" : "=r"(r) : "i"($csr_number) :: "volatile");
r
}
#[inline]
#[cfg(not(target_arch = "riscv32"))]
unsafe fn _read() -> usize {
unimplemented!()
}
};
}
macro_rules! read_csr_as { macro_rules! read_csr_as {
($register:ident, $csr_number:expr) => { ($register:ident, $csr_number:expr) => {
read_csr!($csr_number); read_csr!($csr_number);
@ -28,6 +47,7 @@ macro_rules! read_csr_as {
} }
}; };
} }
macro_rules! read_csr_as_usize { macro_rules! read_csr_as_usize {
($csr_number:expr) => { ($csr_number:expr) => {
read_csr!($csr_number); read_csr!($csr_number);
@ -40,6 +60,18 @@ macro_rules! read_csr_as_usize {
}; };
} }
macro_rules! read_csr_as_usize_rv32 {
($csr_number:expr) => {
read_csr_rv32!($csr_number);
/// Reads the CSR
#[inline]
pub fn read() -> usize {
unsafe{ _read() }
}
};
}
macro_rules! write_csr { macro_rules! write_csr {
($csr_number:expr) => { ($csr_number:expr) => {
/// Writes the CSR /// Writes the CSR

View File

@ -136,19 +136,4 @@ impl Mcause {
} }
} }
/// Reads the CSR read_csr_as!(Mcause, 0x342);
#[inline]
pub fn read() -> Mcause {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0x342, x0" : "=r"(r) ::: "volatile");
}
Mcause { bits: r }
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}

View File

@ -1,18 +1,3 @@
//! mcycle register //! mcycle register
/// Reads the CSR read_csr_as_usize!(0xB00);
#[inline]
pub fn read() -> usize {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0xB00, x0" : "=r"(r) ::: "volatile");
}
r
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}

View File

@ -1,18 +1,3 @@
//! mcycleh register //! mcycleh register
/// Reads the CSR read_csr_as_usize_rv32!(0xB80);
#[inline]
pub fn read() -> usize {
match () {
#[cfg(target_arch = "riscv32")]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0xB80, x0" : "=r"(r) ::: "volatile");
}
r
}
#[cfg(not(target_arch = "riscv32"))]
() => unimplemented!(),
}
}

View File

@ -1,18 +1,3 @@
//! mepc register //! mepc register
/// Reads the CSR read_csr_as_usize!(0x341);
#[inline]
pub fn read() -> usize {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0x341, x0" : "=r"(r) ::: "volatile");
}
r
},
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}

View File

@ -68,71 +68,9 @@ impl Mie {
} }
} }
/// Reads the CSR read_csr_as!(Mie, 0x304);
#[inline] set!(0x304);
pub fn read() -> Mie { clear!(0x304);
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0x304, x0" : "=r"(r) ::: "volatile");
}
Mie { bits: r }
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}
/// Sets the CSR
#[cfg_attr(not(any(target_arch = "riscv32", target_arch = "riscv64")), allow(unused_variables))]
#[inline]
unsafe fn set(bits: usize) {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => asm!("csrrs x0, 0x304, $0" :: "r"(bits) :: "volatile"),
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}
/// Clears the CSR
#[cfg_attr(not(any(target_arch = "riscv32", target_arch = "riscv64")), allow(unused_variables))]
#[inline]
unsafe fn clear(bits: usize) {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => asm!("csrrc x0, 0x304, $0" :: "r"(bits) :: "volatile"),
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}
macro_rules! set_csr {
($set_field:ident, $e:expr) => {
#[inline]
pub unsafe fn $set_field() {
set($e);
}
}
}
macro_rules! clear_csr {
($clear_field:ident, $e:expr) => {
#[inline]
pub unsafe fn $clear_field() {
clear($e);
}
}
}
macro_rules! set_clear_csr {
($set_field:ident, $clear_field:ident, $e:expr) => {
set_csr!($set_field, $e);
clear_csr!($clear_field, $e);
}
}
/// User Software Interrupt Enable /// User Software Interrupt Enable
set_clear_csr!(set_usoft, clear_usoft, 1 << 0); set_clear_csr!(set_usoft, clear_usoft, 1 << 0);

View File

@ -1,18 +1,3 @@
//! minstret register //! minstret register
/// Reads the CSR read_csr_as_usize!(0xB02);
#[inline]
pub fn read() -> usize {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0xB02, x0" : "=r"(r) ::: "volatile");
}
r
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}

View File

@ -1,18 +1,3 @@
//! minstreth register //! minstreth register
/// Reads the CSR read_csr_as_usize_rv32!(0xB82);
#[inline]
pub fn read() -> usize {
match () {
#[cfg(target_arch = "riscv32")]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0xB82, x0" : "=r"(r) ::: "volatile");
}
r
},
#[cfg(not(target_arch = "riscv32"))]
() => unimplemented!(),
}
}

View File

@ -68,19 +68,4 @@ impl Mip {
} }
} }
/// Reads the CSR read_csr_as!(Mip, 0x344);
#[inline]
pub fn read() -> Mip {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0x344, x0" : "=r"(r) ::: "volatile");
}
Mip { bits: r }
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}

View File

@ -47,21 +47,13 @@ impl Misa {
} }
} }
read_csr!(0x301);
/// Reads the CSR /// Reads the CSR
#[inline] #[inline]
pub fn read() -> Option<Misa> { pub fn read() -> Option<Misa> {
match () { let r = unsafe{ _read() };
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] // When misa is hardwired to zero it means that the misa csr
() => { // isn't implemented.
let r: usize; NonZeroUsize::new(r).map(|bits| Misa { bits })
unsafe {
asm!("csrrs $0, 0x301, x0" : "=r"(r) ::: "volatile");
}
// When misa is hardwired to zero it means that the misa csr
// isn't implemented.
NonZeroUsize::new(r).map(|bits| Misa { bits })
},
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
} }

View File

@ -79,71 +79,9 @@ impl Mstatus {
} }
/// Reads the CSR read_csr_as!(Mstatus, 0x300);
#[inline] set!(0x300);
pub fn read() -> Mstatus { clear!(0x300);
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0x300, x0" : "=r"(r) ::: "volatile");
}
Mstatus { bits: r }
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}
/// Sets the CSR
#[cfg_attr(not(any(target_arch = "riscv32", target_arch = "riscv64")), allow(unused_variables))]
#[inline]
unsafe fn set(bits: usize) {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => asm!("csrrs x0, 0x300, $0" :: "r"(bits) :: "volatile"),
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}
/// Clears the CSR
#[cfg_attr(not(any(target_arch = "riscv32", target_arch = "riscv64")), allow(unused_variables))]
#[inline]
unsafe fn clear(bits: usize) {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => asm!("csrrc x0, 0x300, $0" :: "r"(bits) :: "volatile"),
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}
macro_rules! set_csr {
($set_field:ident, $e:expr) => {
#[inline]
pub unsafe fn $set_field() {
set($e);
}
}
}
macro_rules! clear_csr {
($clear_field:ident, $e:expr) => {
#[inline]
pub unsafe fn $clear_field() {
clear($e);
}
}
}
macro_rules! set_clear_csr {
($set_field:ident, $clear_field:ident, $e:expr) => {
set_csr!($set_field, $e);
clear_csr!($clear_field, $e);
}
}
/// User Interrupt Enable /// User Interrupt Enable
set_clear_csr!(set_uie, clear_uie, 1 << 0); set_clear_csr!(set_uie, clear_uie, 1 << 0);
@ -160,10 +98,10 @@ set_csr!(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); _set((spp as usize) << 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); _set((mpp as usize) << 11);
} }

View File

@ -34,32 +34,13 @@ impl Mtvec {
} }
} }
/// Reads the CSR read_csr_as!(Mtvec, 0x305);
#[inline]
pub fn read() -> Mtvec { write_csr!(0x305);
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0x305, x0" : "=r"(r) ::: "volatile");
}
Mtvec { bits: r }
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
}
/// Writes the CSR /// Writes the CSR
#[cfg_attr(not(any(target_arch = "riscv32", target_arch = "riscv64")), allow(unused_variables))]
#[inline] #[inline]
pub unsafe fn write(addr: usize, mode: TrapMode) { pub unsafe fn write(addr: usize, mode: TrapMode) {
let bits = addr + mode as usize; let bits = addr + mode as usize;
match () { _write(bits);
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => asm!("csrrw x0, 0x305, $0" :: "r"(bits) :: "volatile"),
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
} }

View File

@ -20,21 +20,13 @@ impl Mvendorid {
} }
} }
read_csr!(0xF11);
/// Reads the CSR /// Reads the CSR
#[inline] #[inline]
pub fn read() -> Option<Mvendorid> { pub fn read() -> Option<Mvendorid> {
match () { let r = unsafe{ _read() };
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] // When mvendorid is hardwired to zero it means that the mvendorid
() => { // csr isn't implemented.
let r: usize; NonZeroUsize::new(r).map(|bits| Mvendorid { bits })
unsafe {
asm!("csrrs $0, 0xF11, x0" : "=r"(r) ::: "volatile");
}
// When mvendorid is hardwired to zero it means that the mvendorid
// csr isn't implemented.
NonZeroUsize::new(r).map(|bits| Mvendorid { bits })
}
#[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
() => unimplemented!(),
}
} }

View File

@ -1,18 +1,3 @@
//! timeh register //! timeh register
/// Reads the CSR read_csr_as_usize_rv32!(0xC81);
#[inline]
pub fn read() -> usize {
match () {
#[cfg(target_arch = "riscv32")]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0xC81, x0" : "=r"(r) ::: "volatile");
}
r
}
#[cfg(not(target_arch = "riscv32"))]
() => unimplemented!(),
}
}