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 {
($register:ident, $csr_number:expr) => {
read_csr!($csr_number);
@ -28,6 +47,7 @@ macro_rules! read_csr_as {
}
};
}
macro_rules! read_csr_as_usize {
($csr_number:expr) => {
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 {
($csr_number:expr) => {
/// Writes the CSR

View File

@ -136,19 +136,4 @@ impl Mcause {
}
}
/// Reads the CSR
#[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!(),
}
}
read_csr_as!(Mcause, 0x342);

View File

@ -1,18 +1,3 @@
//! mcycle register
/// Reads the CSR
#[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!(),
}
}
read_csr_as_usize!(0xB00);

View File

@ -1,18 +1,3 @@
//! mcycleh register
/// Reads the CSR
#[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!(),
}
}
read_csr_as_usize_rv32!(0xB80);

View File

@ -1,18 +1,3 @@
//! mepc register
/// Reads the CSR
#[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!(),
}
}
read_csr_as_usize!(0x341);

View File

@ -68,71 +68,9 @@ impl Mie {
}
}
/// Reads the CSR
#[inline]
pub fn read() -> Mie {
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);
}
}
read_csr_as!(Mie, 0x304);
set!(0x304);
clear!(0x304);
/// User Software Interrupt Enable
set_clear_csr!(set_usoft, clear_usoft, 1 << 0);

View File

@ -1,18 +1,3 @@
//! minstret register
/// Reads the CSR
#[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!(),
}
}
read_csr_as_usize!(0xB02);

View File

@ -1,18 +1,3 @@
//! minstreth register
/// Reads the CSR
#[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!(),
}
}
read_csr_as_usize_rv32!(0xB82);

View File

@ -68,19 +68,4 @@ impl Mip {
}
}
/// Reads the CSR
#[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!(),
}
}
read_csr_as!(Mip, 0x344);

View File

@ -47,21 +47,13 @@ impl Misa {
}
}
read_csr!(0x301);
/// Reads the CSR
#[inline]
pub fn read() -> Option<Misa> {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0x301, x0" : "=r"(r) ::: "volatile");
}
let r = unsafe{ _read() };
// 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
#[inline]
pub fn read() -> Mstatus {
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);
}
}
read_csr_as!(Mstatus, 0x300);
set!(0x300);
clear!(0x300);
/// User Interrupt Enable
set_clear_csr!(set_uie, clear_uie, 1 << 0);
@ -160,10 +98,10 @@ set_csr!(set_mpie, 1 << 7);
/// Supervisor Previous Privilege Mode
#[inline]
pub unsafe fn set_spp(spp: SPP) {
set((spp as usize) << 8);
_set((spp as usize) << 8);
}
/// Machine Previous Privilege Mode
#[inline]
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
#[inline]
pub fn read() -> Mtvec {
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!(),
}
}
read_csr_as!(Mtvec, 0x305);
write_csr!(0x305);
/// Writes the CSR
#[cfg_attr(not(any(target_arch = "riscv32", target_arch = "riscv64")), allow(unused_variables))]
#[inline]
pub unsafe fn write(addr: usize, mode: TrapMode) {
let bits = addr + mode as usize;
match () {
#[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!(),
}
_write(bits);
}

View File

@ -20,21 +20,13 @@ impl Mvendorid {
}
}
read_csr!(0xF11);
/// Reads the CSR
#[inline]
pub fn read() -> Option<Mvendorid> {
match () {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
() => {
let r: usize;
unsafe {
asm!("csrrs $0, 0xF11, x0" : "=r"(r) ::: "volatile");
}
let r = unsafe{ _read() };
// 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
/// Reads the CSR
#[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!(),
}
}
read_csr_as_usize_rv32!(0xC81);