222 lines
4.9 KiB
Rust
222 lines
4.9 KiB
Rust
macro impl_csr_read($struct:ident, $repr:ty, $reg:ident, $register:ty) {
|
|
impl tock_registers::interfaces::Readable for $struct {
|
|
type T = $repr;
|
|
type R = $register;
|
|
|
|
#[inline]
|
|
fn get(&self) -> $repr {
|
|
let mut value: $repr;
|
|
unsafe {
|
|
core::arch::asm!(concat!("csrr {0}, ", stringify!($reg)), out(reg) value);
|
|
}
|
|
value
|
|
}
|
|
}
|
|
}
|
|
macro impl_csr_write($struct:ident, $repr:ty, $reg:ident, $register:ty) {
|
|
impl tock_registers::interfaces::Writeable for $struct {
|
|
type T = $repr;
|
|
type R = $register;
|
|
|
|
#[inline]
|
|
fn set(&self, value: $repr) {
|
|
unsafe {
|
|
core::arch::asm!(concat!("csrw ", stringify!($reg), ", {0}"), in(reg) value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub mod satp {
|
|
use tock_registers::register_bitfields;
|
|
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
register_bitfields!(
|
|
u64,
|
|
pub SATP [
|
|
PPN OFFSET(0) NUMBITS(44) [],
|
|
ASID OFFSET(44) NUMBITS(16) [],
|
|
MODE OFFSET(60) NUMBITS(4) [
|
|
Bare = 0,
|
|
Sv39 = 8,
|
|
Sv48 = 9,
|
|
Sv57 = 10,
|
|
Sv64 = 11,
|
|
],
|
|
]
|
|
);
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, satp, SATP::Register);
|
|
impl_csr_write!(Reg, u64, satp, SATP::Register);
|
|
|
|
pub const SATP: Reg = Reg;
|
|
}
|
|
|
|
pub mod stvec {
|
|
use tock_registers::{interfaces::ReadWriteable, register_bitfields};
|
|
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
register_bitfields!(
|
|
u64,
|
|
pub STVEC [
|
|
MODE OFFSET(0) NUMBITS(2) [
|
|
Direct = 0,
|
|
Vectored = 1
|
|
],
|
|
BASE OFFSET(2) NUMBITS(62) [],
|
|
]
|
|
);
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, stvec, STVEC::Register);
|
|
impl_csr_write!(Reg, u64, stvec, STVEC::Register);
|
|
|
|
impl Reg {
|
|
pub fn set_base(&self, base: usize) {
|
|
debug_assert_eq!(base & 0xF, 0);
|
|
let mask = match base & 63 != 0 {
|
|
false => 0,
|
|
true => 0x3 << 62,
|
|
};
|
|
self.modify(STVEC::BASE.val(((base as u64) >> 2) | mask));
|
|
}
|
|
}
|
|
|
|
pub const STVEC: Reg = Reg;
|
|
}
|
|
|
|
pub mod scause {
|
|
use tock_registers::register_bitfields;
|
|
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
register_bitfields!(
|
|
u64,
|
|
pub SCAUSE [
|
|
CODE OFFSET(0) NUMBITS(63) [],
|
|
INTERRUPT OFFSET(63) NUMBITS(1) [],
|
|
]
|
|
);
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, scause, SCAUSE::Register);
|
|
impl_csr_write!(Reg, u64, scause, SCAUSE::Register);
|
|
|
|
pub const SCAUSE: Reg = Reg;
|
|
}
|
|
|
|
pub mod stval {
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, stval, ());
|
|
impl_csr_write!(Reg, u64, stval, ());
|
|
|
|
pub const STVAL: Reg = Reg;
|
|
}
|
|
|
|
pub mod sepc {
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, sepc, ());
|
|
impl_csr_write!(Reg, u64, sepc, ());
|
|
|
|
pub const SEPC: Reg = Reg;
|
|
}
|
|
|
|
pub mod sstatus {
|
|
use tock_registers::register_bitfields;
|
|
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
register_bitfields!(
|
|
u64,
|
|
pub SSTATUS [
|
|
SUM OFFSET(18) NUMBITS(1) [],
|
|
SPP OFFSET(8) NUMBITS(1) [],
|
|
SIE OFFSET(1) NUMBITS(1) [],
|
|
]
|
|
);
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, sstatus, SSTATUS::Register);
|
|
impl_csr_write!(Reg, u64, sstatus, SSTATUS::Register);
|
|
|
|
pub const SSTATUS: Reg = Reg;
|
|
}
|
|
|
|
pub mod sscratch {
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, sscratch, ());
|
|
impl_csr_write!(Reg, u64, sscratch, ());
|
|
|
|
pub const SSCRATCH: Reg = Reg;
|
|
}
|
|
|
|
pub mod sip {
|
|
use tock_registers::register_bitfields;
|
|
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
register_bitfields!(
|
|
u64,
|
|
pub SIP [
|
|
SSIP OFFSET(1) NUMBITS(1) [],
|
|
STIP OFFSET(5) NUMBITS(1) [],
|
|
SEIP OFFSET(9) NUMBITS(1) [],
|
|
]
|
|
);
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, sip, SIP::Register);
|
|
impl_csr_write!(Reg, u64, sip, SIP::Register);
|
|
|
|
pub const SIP: Reg = Reg;
|
|
}
|
|
|
|
pub mod sie {
|
|
use tock_registers::register_bitfields;
|
|
|
|
use super::{impl_csr_read, impl_csr_write};
|
|
|
|
register_bitfields!(
|
|
u64,
|
|
pub SIE [
|
|
SSIE OFFSET(1) NUMBITS(1) [],
|
|
STIE OFFSET(5) NUMBITS(1) [],
|
|
SEIE OFFSET(9) NUMBITS(1) [],
|
|
]
|
|
);
|
|
|
|
pub struct Reg;
|
|
|
|
impl_csr_read!(Reg, u64, sie, SIE::Register);
|
|
impl_csr_write!(Reg, u64, sie, SIE::Register);
|
|
|
|
pub const SIE: Reg = Reg;
|
|
}
|
|
|
|
pub use satp::SATP;
|
|
pub use scause::SCAUSE;
|
|
pub use sepc::SEPC;
|
|
pub use sie::SIE;
|
|
pub use sip::SIP;
|
|
pub use sscratch::SSCRATCH;
|
|
pub use sstatus::SSTATUS;
|
|
pub use stval::STVAL;
|
|
pub use stvec::STVEC;
|