use crate::arch::csr::Csrs;
use crate::isa::csr;
use crate::isa::csr::CsrAddr;
#[test]
fn csr_default_all_zero() {
let csrs = Csrs::default();
assert_eq!(csrs.mstatus, 0);
assert_eq!(csrs.misa, 0);
assert_eq!(csrs.mie, 0);
assert_eq!(csrs.mip, 0);
assert_eq!(csrs.mepc, 0);
assert_eq!(csrs.mcause, 0);
assert_eq!(csrs.mtval, 0);
assert_eq!(csrs.mscratch, 0);
assert_eq!(csrs.mtvec, 0);
assert_eq!(csrs.satp, 0);
}
#[test]
fn csr_write_and_read_mstatus() {
let mut csrs = Csrs::default();
csrs.write(csr::MSTATUS, 0x0000_0000_000A_0000);
assert_eq!(csrs.read(csr::MSTATUS), 0x0000_0000_000A_0000);
}
#[test]
fn csr_write_and_read_misa() {
let mut csrs = Csrs::default();
csrs.write(csr::MISA, csr::MISA_DEFAULT_RV64IMAFDC);
assert_eq!(csrs.read(csr::MISA), csr::MISA_DEFAULT_RV64IMAFDC);
}
#[test]
fn csr_write_and_read_mie() {
let mut csrs = Csrs::default();
csrs.write(csr::MIE, csr::MIE_MTIE | csr::MIE_MSIP);
assert_eq!(csrs.read(csr::MIE), csr::MIE_MTIE | csr::MIE_MSIP);
}
#[test]
fn csr_write_and_read_mip() {
let mut csrs = Csrs::default();
csrs.write(csr::MIP, csr::MIP_MTIP);
assert_eq!(csrs.read(csr::MIP), csr::MIP_MTIP);
}
#[test]
fn csr_write_and_read_mepc() {
let mut csrs = Csrs::default();
csrs.write(csr::MEPC, 0x8000_1234);
assert_eq!(csrs.read(csr::MEPC), 0x8000_1234);
}
#[test]
fn csr_write_and_read_mcause() {
let mut csrs = Csrs::default();
csrs.write(csr::MCAUSE, 0x8000_0000_0000_0007); assert_eq!(csrs.read(csr::MCAUSE), 0x8000_0000_0000_0007);
}
#[test]
fn csr_write_and_read_supervisor_csrs() {
let mut csrs = Csrs::default();
csrs.write(csr::SSTATUS, 0x22);
csrs.write(csr::SIE, 0x222);
csrs.write(csr::STVEC, 0x8000_0000);
csrs.write(csr::SSCRATCH, 0xDEAD);
csrs.write(csr::SEPC, 0x1000);
csrs.write(csr::SCAUSE, 15);
csrs.write(csr::STVAL, 0xBEEF);
csrs.write(csr::SIP, 0x2);
assert_eq!(csrs.read(csr::SSTATUS), 0x22);
assert_eq!(csrs.read(csr::SIE), 0x222);
assert_eq!(csrs.read(csr::STVEC), 0x8000_0000);
assert_eq!(csrs.read(csr::SSCRATCH), 0xDEAD);
assert_eq!(csrs.read(csr::SEPC), 0x1000);
assert_eq!(csrs.read(csr::SCAUSE), 15);
assert_eq!(csrs.read(csr::STVAL), 0xBEEF);
assert_eq!(csrs.read(csr::SIP), 0x2);
}
#[test]
fn csr_satp_mode_sv39_preserved() {
let mut csrs = Csrs::default();
let sv39_satp = (csr::SATP_MODE_SV39 << csr::SATP_MODE_SHIFT) | 0x12345;
csrs.write(csr::SATP, sv39_satp);
let read_back = csrs.read(csr::SATP);
let mode = (read_back >> csr::SATP_MODE_SHIFT) & csr::SATP_MODE_MASK;
assert_eq!(mode, csr::SATP_MODE_SV39);
assert_eq!(read_back & csr::SATP_PPN_MASK, 0x12345);
}
#[test]
fn csr_satp_mode_bare_preserved() {
let mut csrs = Csrs::default();
let bare_satp = csr::SATP_MODE_BARE << csr::SATP_MODE_SHIFT;
csrs.write(csr::SATP, bare_satp);
let read_back = csrs.read(csr::SATP);
let mode = (read_back >> csr::SATP_MODE_SHIFT) & csr::SATP_MODE_MASK;
assert_eq!(mode, csr::SATP_MODE_BARE);
}
#[test]
fn csr_satp_invalid_mode_becomes_bare() {
let mut csrs = Csrs::default();
let invalid_satp = (5u64 << csr::SATP_MODE_SHIFT) | 0xABC;
csrs.write(csr::SATP, invalid_satp);
let read_back = csrs.read(csr::SATP);
let mode = (read_back >> csr::SATP_MODE_SHIFT) & csr::SATP_MODE_MASK;
assert_eq!(mode, csr::SATP_MODE_BARE, "Invalid mode should become Bare");
}
#[test]
fn csr_unknown_address_returns_zero() {
let csrs = Csrs::default();
assert_eq!(csrs.read(CsrAddr::from_u32(0x999)), 0);
}
#[test]
fn csr_write_unknown_address_is_ignored() {
let mut csrs = Csrs::default();
csrs.write(CsrAddr::from_u32(0x999), 0xDEAD);
assert_eq!(csrs.read(CsrAddr::from_u32(0x999)), 0);
}
#[test]
fn csr_counter_csrs() {
let mut csrs = Csrs::default();
csrs.write(csr::MCYCLE, 400);
csrs.write(csr::MINSTRET, 500);
assert_eq!(csrs.read(csr::CYCLE), 400);
assert_eq!(csrs.read(csr::MCYCLE), 400);
assert_eq!(csrs.read(csr::INSTRET), 500);
assert_eq!(csrs.read(csr::MINSTRET), 500);
}
#[test]
fn csr_clone() {
let mut csrs = Csrs::default();
csrs.write(csr::MSTATUS, 0xABCD);
let cloned = csrs.clone();
assert_eq!(cloned.read(csr::MSTATUS), 0xABCD);
}