macro_rules! read_csr {
($csr_number:literal) => {
#[inline]
unsafe fn _read() -> usize {
match () {
#[cfg(riscv)]
() => {
let r: usize;
core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r);
r
}
#[cfg(not(riscv))]
() => unimplemented!(),
}
}
};
}
macro_rules! read_csr_rv32 {
($csr_number:literal) => {
#[inline]
unsafe fn _read() -> usize {
match () {
#[cfg(riscv32)]
() => {
let r: usize;
core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r);
r
}
#[cfg(not(riscv32))]
() => unimplemented!(),
}
}
};
}
macro_rules! read_csr_as {
($register:ident, $csr_number:literal) => {
read_csr!($csr_number);
#[inline]
pub fn read() -> $register {
$register {
bits: unsafe { _read() },
}
}
};
}
macro_rules! read_csr_as_usize {
($csr_number:literal) => {
read_csr!($csr_number);
#[inline]
pub fn read() -> usize {
unsafe { _read() }
}
};
}
macro_rules! read_csr_as_usize_rv32 {
($csr_number:literal) => {
read_csr_rv32!($csr_number);
#[inline]
pub fn read() -> usize {
unsafe { _read() }
}
};
}
macro_rules! write_csr {
($csr_number:literal) => {
#[inline]
#[allow(unused_variables)]
unsafe fn _write(bits: usize) {
match () {
#[cfg(riscv)]
() => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
#[cfg(not(riscv))]
() => unimplemented!(),
}
}
};
}
macro_rules! write_csr_rv32 {
($csr_number:literal) => {
#[inline]
#[allow(unused_variables)]
unsafe fn _write(bits: usize) {
match () {
#[cfg(riscv32)]
() => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
#[cfg(not(riscv32))]
() => unimplemented!(),
}
}
};
}
macro_rules! write_csr_as_usize {
($csr_number:literal) => {
write_csr!($csr_number);
#[inline]
pub fn write(bits: usize) {
unsafe { _write(bits) }
}
};
}
macro_rules! write_csr_as_usize_rv32 {
($csr_number:literal) => {
write_csr_rv32!($csr_number);
#[inline]
pub fn write(bits: usize) {
unsafe { _write(bits) }
}
};
}
macro_rules! set {
($csr_number:literal) => {
#[inline]
#[allow(unused_variables)]
unsafe fn _set(bits: usize) {
match () {
#[cfg(riscv)]
() => core::arch::asm!(concat!("csrrs x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
#[cfg(not(riscv))]
() => unimplemented!(),
}
}
};
}
macro_rules! clear {
($csr_number:literal) => {
#[inline]
#[allow(unused_variables)]
unsafe fn _clear(bits: usize) {
match () {
#[cfg(riscv)]
() => core::arch::asm!(concat!("csrrc x0, ", stringify!($csr_number), ", {0}"), in(reg) bits),
#[cfg(not(riscv))]
() => unimplemented!(),
}
}
};
}
macro_rules! set_csr {
($(#[$attr:meta])*, $set_field:ident, $e:expr) => {
$(#[$attr])*
#[inline]
pub unsafe fn $set_field() {
_set($e);
}
};
}
macro_rules! clear_csr {
($(#[$attr:meta])*, $clear_field:ident, $e:expr) => {
$(#[$attr])*
#[inline]
pub unsafe fn $clear_field() {
_clear($e);
}
};
}
macro_rules! set_clear_csr {
($(#[$attr:meta])*, $set_field:ident, $clear_field:ident, $e:expr) => {
set_csr!($(#[$attr])*, $set_field, $e);
clear_csr!($(#[$attr])*, $clear_field, $e);
}
}
macro_rules! read_composite_csr {
($hi:expr, $lo:expr) => {
#[inline]
pub fn read64() -> u64 {
match () {
#[cfg(riscv32)]
() => loop {
let hi = $hi;
let lo = $lo;
if hi == $hi {
return ((hi as u64) << 32) | lo as u64;
}
},
#[cfg(not(riscv32))]
() => $lo as u64,
}
}
};
}
macro_rules! set_pmp {
() => {
#[inline]
pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) {
#[cfg(riscv32)]
assert!(index < 4);
#[cfg(riscv64)]
assert!(index < 8);
let mut value = _read();
let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize);
value.set_bits(8 * index..=8 * index + 7, byte);
_write(value);
}
};
}
macro_rules! clear_pmp {
() => {
#[inline]
pub unsafe fn clear_pmp(index: usize) {
#[cfg(riscv32)]
assert!(index < 4);
#[cfg(riscv64)]
assert!(index < 8);
let mut value = _read();
value.set_bits(8 * index..=8 * index + 7, 0);
_write(value);
}
};
}