use crate::arch::csr::Csrs;
use crate::isa::csr;
#[test]
fn trap_delegation_medeleg() {
let mut csrs = Csrs::default();
let deleg = (1 << 8) | (1 << 13);
csrs.write(csr::MEDELEG, deleg);
assert_eq!(csrs.read(csr::MEDELEG), deleg);
}
#[test]
fn trap_delegation_mideleg() {
let mut csrs = Csrs::default();
csrs.write(csr::MIDELEG, csr::MIP_STIP);
assert_eq!(csrs.read(csr::MIDELEG), csr::MIP_STIP);
}
#[test]
fn mtvec_direct_mode() {
let mut csrs = Csrs::default();
let mtvec = 0x8000_0000;
csrs.write(csr::MTVEC, mtvec);
assert_eq!(csrs.read(csr::MTVEC), mtvec);
assert_eq!(csrs.read(csr::MTVEC) & 0x3, 0, "Mode should be direct (0)");
}
#[test]
fn mtvec_vectored_mode() {
let mut csrs = Csrs::default();
let mtvec = 0x8000_0001;
csrs.write(csr::MTVEC, mtvec);
assert_eq!(csrs.read(csr::MTVEC) & 0x3, 1, "Mode should be vectored (1)");
}
#[test]
fn stvec_configuration() {
let mut csrs = Csrs::default();
csrs.write(csr::STVEC, 0x8000_0100);
assert_eq!(csrs.read(csr::STVEC), 0x8000_0100);
}
#[test]
fn mstatus_interrupt_enable_bits() {
let mut csrs = Csrs::default();
csrs.write(csr::MSTATUS, csr::MSTATUS_MIE | csr::MSTATUS_SIE);
let mstatus = csrs.read(csr::MSTATUS);
assert_ne!(mstatus & csr::MSTATUS_MIE, 0, "MIE should be set");
assert_ne!(mstatus & csr::MSTATUS_SIE, 0, "SIE should be set");
}
#[test]
fn mstatus_previous_mode_mpp() {
let mut csrs = Csrs::default();
csrs.write(csr::MSTATUS, 1 << csr::MSTATUS_MPP_SHIFT);
let mpp = (csrs.read(csr::MSTATUS) >> csr::MSTATUS_MPP_SHIFT) & csr::MSTATUS_MPP_MASK;
assert_eq!(mpp, 1, "MPP should be Supervisor (1)");
}
#[test]
fn mstatus_fs_field() {
let mut csrs = Csrs::default();
csrs.write(csr::MSTATUS, csr::MSTATUS_FS_DIRTY);
assert_eq!(csrs.read(csr::MSTATUS) & csr::MSTATUS_FS, csr::MSTATUS_FS_DIRTY);
}
#[test]
fn medeleg_mideleg_combined() {
let mut csrs = Csrs::default();
csrs.write(csr::MEDELEG, (1 << 8) | (1 << 13));
csrs.write(csr::MIDELEG, csr::MIP_SSIP | csr::MIP_STIP | csr::MIP_SEIP);
let edeleg = csrs.read(csr::MEDELEG);
let ideleg = csrs.read(csr::MIDELEG);
assert_ne!(edeleg & (1 << 8), 0, "User ecall should be delegated");
assert_ne!(ideleg & csr::MIP_STIP, 0, "S-mode timer should be delegated");
}