Skip to content

Commit b15a60e

Browse files
committed
Revert "Fix #15: Implement a proper CSR file"
This reverts commit d90d8a7. For reasons yet to be determined, the reverted commit broke WASM (it hung)
1 parent 5622735 commit b15a60e

File tree

4 files changed

+87
-150
lines changed

4 files changed

+87
-150
lines changed

TODO.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44

55
- Fix boot with the newest kernels (it hangs, unknown why)
66

7-
- CSR handling is still a bit suspect; the access checks looks
8-
broken. Need to cross check the read/write CSR behavior against
9-
Dromajo
7+
- CSR handling is still a bit suspect
8+
The access checks looks broken and we shouldn't have a CSR array but instead
9+
individually implement CSR registers we support and trap access to everything else.
10+
need to cross check the read/write CSR behavior against Dromajo
1011

1112
- Go though all explicit usage of cpu.f[] and look for mistakes
1213

1314
- Pass all of riscv-test (status: debug, svnapot, and lots of FP.
14-
Might punt on debug and svnapot for now)
15+
Might punt on debug and svnapot)
1516

1617
- Pass all of riscof
1718

src/cpu.rs

Lines changed: 80 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub struct Cpu {
140140

141141
// Supervisor and CSR
142142
pub cycle: u64,
143-
csr: csr::CsrFile,
143+
csr: Box<[u64]>, // XXX this should be replaced with individual registers
144144
reservation: Option<u64>,
145145

146146
// Wait-For-Interrupt; relax and await further instruction
@@ -297,13 +297,17 @@ impl Cpu {
297297
cycle: 0,
298298
wfi: false,
299299
pc: 0,
300-
csr: CsrFile::new(),
300+
csr: vec![0; 4096].into_boxed_slice(), // XXX MUST GO AWAY SOON
301301
mmu,
302302
reservation: None,
303303
flush_icache: false,
304304
decode_dag: dag_decoder::new(&patterns),
305305
};
306-
log::trace!("FDT is {} entries", cpu.decode_dag.len());
306+
log::info!("FDT is {} entries", cpu.decode_dag.len());
307+
cpu.csr[Csr::Misa as usize] = 1 << 63; // RV64
308+
for c in "SUIMAFDC".bytes() {
309+
cpu.csr[Csr::Misa as usize] |= 1 << (c as usize - 65);
310+
}
307311
cpu.mmu.mstatus = 2 << MSTATUS_UXL_SHIFT | 2 << MSTATUS_SXL_SHIFT | 3 << MSTATUS_MPP_SHIFT;
308312
cpu.write_x(x(11), 0x1020); // start of DTB (XXX could put that elsewhere);
309313
cpu
@@ -387,7 +391,7 @@ impl Cpu {
387391
fn step_cpu(&mut self, uop_cache: &mut IntMap<u64, Uop>) -> Result<(), Exception> {
388392
self.cycle = self.cycle.wrapping_add(1);
389393
if self.wfi {
390-
if self.mmu.mip & self.csr.mie != 0 {
394+
if self.mmu.mip & self.read_csr_raw(Csr::Mie) != 0 {
391395
self.wfi = false;
392396
}
393397
return Ok(());
@@ -456,7 +460,7 @@ impl Cpu {
456460
use self::Trap::SupervisorExternalInterrupt;
457461
use self::Trap::SupervisorSoftwareInterrupt;
458462
use self::Trap::SupervisorTimerInterrupt;
459-
let minterrupt = self.mmu.mip & self.csr.mie;
463+
let minterrupt = self.mmu.mip & self.read_csr_raw(Csr::Mie);
460464
if minterrupt == 0 {
461465
return;
462466
}
@@ -498,16 +502,16 @@ impl Cpu {
498502
// First, determine which privilege mode should handle the trap.
499503
// @TODO: Check if this logic is correct
500504
let mdeleg = if is_interrupt {
501-
self.csr.mideleg
505+
self.read_csr_raw(Csr::Mideleg)
502506
} else {
503-
self.csr.medeleg
507+
self.read_csr_raw(Csr::Medeleg)
504508
};
505509
let sdeleg = if is_interrupt {
506-
self.csr.sideleg
510+
self.read_csr_raw(Csr::Sideleg)
507511
} else {
508-
self.csr.sedeleg
512+
self.read_csr_raw(Csr::Sedeleg)
509513
};
510-
let pos = cause & 63;
514+
let pos = cause & 0xffff;
511515

512516
let new_priv_mode = if (mdeleg >> pos) & 1 == 0 {
513517
PrivMode::M
@@ -524,11 +528,11 @@ impl Cpu {
524528
let current_status = match self.mmu.prv {
525529
PrivMode::M => self.read_csr_raw(Csr::Mstatus),
526530
PrivMode::S => self.read_csr_raw(Csr::Sstatus),
527-
PrivMode::U => self.csr.ustatus,
531+
PrivMode::U => self.read_csr_raw(Csr::Ustatus),
528532
};
529533

530534
let ie = match new_priv_mode {
531-
PrivMode::M => self.csr.mie,
535+
PrivMode::M => self.read_csr_raw(Csr::Mie),
532536
PrivMode::S => self.read_csr_raw(Csr::Sie),
533537
PrivMode::U => self.read_csr_raw(Csr::Uie),
534538
};
@@ -638,15 +642,16 @@ impl Cpu {
638642
PrivMode::S => Csr::Stval,
639643
PrivMode::U => Csr::Utval,
640644
};
641-
self.pc = match self.mmu.prv {
642-
PrivMode::M => self.read_csr_raw(Csr::Mtvec),
643-
PrivMode::S => self.read_csr_raw(Csr::Stvec),
644-
PrivMode::U => self.read_csr_raw(Csr::Utvec),
645+
let csr_tvec_address = match self.mmu.prv {
646+
PrivMode::M => Csr::Mtvec,
647+
PrivMode::S => Csr::Stvec,
648+
PrivMode::U => Csr::Utvec,
645649
};
646650

647651
self.write_csr_raw(csr_epc_address, insn_addr);
648652
self.write_csr_raw(csr_cause_address, cause);
649653
self.write_csr_raw(csr_tval_address, exc.tval);
654+
self.pc = self.read_csr_raw(csr_tvec_address);
650655

651656
// Add 4 * cause if tvec has vector type address
652657
if self.pc & 3 != 0 {
@@ -718,7 +723,6 @@ impl Cpu {
718723
if self.mmu.prv == S && self.mmu.mstatus & MSTATUS_TVM != 0 {
719724
return illegal;
720725
}
721-
return Ok(self.mmu.satp);
722726
}
723727
_ => {}
724728
}
@@ -727,6 +731,7 @@ impl Cpu {
727731

728732
#[allow(clippy::cast_sign_loss)]
729733
fn write_csr(&mut self, csrno: u16, value: u64) -> Result<(), Exception> {
734+
let mut value = value;
730735
let illegal = Err(Exception {
731736
trap: Trap::IllegalInstruction,
732737
tval: 0,
@@ -742,6 +747,10 @@ impl Cpu {
742747
}
743748

744749
match csr {
750+
Csr::Mstatus => {
751+
let mask = MSTATUS_MASK & !(MSTATUS_VS | MSTATUS_UXL_MASK | MSTATUS_SXL_MASK);
752+
value = value & mask | self.mmu.mstatus & !mask;
753+
}
745754
Csr::Fflags | Csr::Frm | Csr::Fcsr => self.check_float_access_and_dirty(0)?,
746755
Csr::Cycle => {
747756
log::info!("** deny cycle writing");
@@ -759,9 +768,6 @@ impl Cpu {
759768
log::warn!("wrote illegal value {value:x} to satp");
760769
return illegal;
761770
}
762-
763-
self.mmu.satp = value;
764-
return Ok(());
765771
}
766772
_ => {}
767773
}
@@ -774,96 +780,82 @@ impl Cpu {
774780
#[allow(clippy::cast_sign_loss)]
775781
fn read_csr_raw(&self, csr: Csr) -> u64 {
776782
match csr {
777-
Csr::Cycle | Csr::Mcycle | Csr::Minstret => self.cycle,
778-
Csr::Fcsr => self.read_fcsr(),
779783
Csr::Fflags => u64::from(self.read_fflags()),
780784
Csr::Frm => self.read_frm() as u64,
781-
Csr::Mcause => self.csr.mcause,
782-
Csr::Medeleg => self.csr.medeleg,
783-
Csr::Mepc => self.csr.mepc,
784-
Csr::Mhartid => self.csr.mhartid,
785-
Csr::Mideleg => self.csr.mideleg,
786-
Csr::Mie => self.csr.mie,
787-
Csr::Mip => self.mmu.mip,
788-
Csr::Misa => self.csr.misa,
789-
Csr::Mscratch => self.csr.mscratch,
790-
Csr::Mstatus => {
791-
let mut mstatus = self.mmu.mstatus;
792-
mstatus &= !MSTATUS_FS;
793-
mstatus |= u64::from(self.fs) << MSTATUS_FS_SHIFT;
785+
Csr::Fcsr => self.read_fcsr(),
786+
Csr::Sstatus => {
787+
let mut sstatus = self.mmu.mstatus;
788+
sstatus &= !MSTATUS_FS;
789+
sstatus |= u64::from(self.fs) << MSTATUS_FS_SHIFT;
790+
sstatus &= 0x8000_0003_000d_e162;
794791
if self.fs == 3 {
795-
mstatus |= 1 << 63;
792+
sstatus |= 1 << 63;
796793
}
797-
mstatus
794+
sstatus
798795
}
799-
Csr::Mtval => self.csr.mtval,
800-
Csr::Mtvec => self.csr.mtvec,
801-
Csr::Satp => self.mmu.satp,
802-
Csr::Scause => self.csr.scause,
803-
Csr::Sedeleg => self.csr.sedeleg,
804-
Csr::Sepc => self.csr.sepc,
805-
Csr::Sideleg => self.csr.sideleg,
806-
Csr::Sie => self.csr.mie & self.csr.mideleg,
807-
Csr::Sip => self.mmu.mip & self.csr.mideleg,
808-
Csr::Sscratch => self.csr.sscratch,
809-
Csr::Sstatus => {
796+
Csr::Mstatus => {
810797
let mut mstatus = self.mmu.mstatus;
811798
mstatus &= !MSTATUS_FS;
812799
mstatus |= u64::from(self.fs) << MSTATUS_FS_SHIFT;
813-
mstatus &= 0x8000_0003_000d_e162;
814800
if self.fs == 3 {
815801
mstatus |= 1 << 63;
816802
}
817803
mstatus
818804
}
819-
Csr::Stval => self.csr.stval,
820-
Csr::Stvec => self.csr.stvec,
805+
Csr::Sie => self.csr[Csr::Mie as usize] & self.csr[Csr::Mideleg as usize],
806+
Csr::Sip => self.mmu.mip & self.csr[Csr::Mideleg as usize],
807+
Csr::Mip => self.mmu.mip,
821808
Csr::Time => self.mmu.get_clint().read_mtime(),
822-
Csr::Ustatus => self.csr.ustatus,
823-
_ => 0,
809+
Csr::Cycle | Csr::Mcycle | Csr::Minstret => self.cycle,
810+
Csr::Satp => self.mmu.satp,
811+
_ => self.csr[csr as usize],
824812
}
825813
}
826814

827815
fn write_csr_raw(&mut self, csr: Csr, value: u64) {
828816
match csr {
829-
Csr::Mcycle => self.cycle = value,
830-
Csr::Fcsr => self.write_fcsr(value),
817+
Csr::Misa => {} // Not writable
831818
Csr::Fflags => self.write_fflags((value & 31) as u8),
832819
Csr::Frm => self.write_frm(
833820
FromPrimitive::from_u64(value & 7).unwrap_or(RoundingMode::RoundNearestEven),
834821
),
835-
Csr::Mcause => self.csr.mcause = value,
836-
Csr::Medeleg => self.csr.medeleg = value,
837-
Csr::Mepc => self.csr.mepc = value,
838-
Csr::Mhartid => self.csr.mhartid = value,
839-
Csr::Mideleg => self.csr.mideleg = value & 0x222,
840-
Csr::Mie => self.csr.mie = value,
841-
Csr::Mip => self.mmu.mip = value,
842-
Csr::Mscratch => self.csr.mscratch = value,
843-
Csr::Mstatus => {
844-
let mask = MSTATUS_MASK & !(MSTATUS_VS | MSTATUS_UXL_MASK | MSTATUS_SXL_MASK);
845-
self.mmu.mstatus = value & mask | self.mmu.mstatus & !mask;
846-
self.fs = ((value >> MSTATUS_FS_SHIFT) & 3) as u8;
847-
}
848-
Csr::Mtval => self.csr.mtval = value,
849-
Csr::Mtvec => self.csr.mtvec = value,
850-
Csr::Scause => self.csr.scause = value,
851-
Csr::Sedeleg => self.csr.sedeleg = value,
852-
Csr::Sepc => self.csr.sepc = value,
853-
Csr::Sideleg => self.csr.sideleg = value,
854-
Csr::Sie => self.csr.mie = self.csr.mie & !0x222 | value & 0x222,
855-
Csr::Sip => self.mmu.mip = value & 0x222 | self.mmu.mip & !0x222,
856-
Csr::Sscratch => self.csr.sscratch = value,
822+
Csr::Fcsr => self.write_fcsr(value),
857823
Csr::Sstatus => {
858824
self.mmu.mstatus &= !0x8000_0003_000d_e162;
859825
self.mmu.mstatus |= value & 0x8000_0003_000d_e162;
860826
self.fs = ((value >> MSTATUS_FS_SHIFT) & 3) as u8;
861827
}
862-
Csr::Stval => self.csr.stval = value,
863-
Csr::Stvec => self.csr.stvec = value,
864-
Csr::Time => self.mmu.get_mut_clint().write_mtime(value), // XXX SHOULD trap
865-
Csr::Ustatus => self.csr.ustatus = value,
866-
_ => log::warn!("We are ignoring writes to {csr:?}"),
828+
Csr::Sie => {
829+
self.csr[Csr::Mie as usize] &= !0x222;
830+
self.csr[Csr::Mie as usize] |= value & 0x222;
831+
}
832+
Csr::Sip => {
833+
let mask = 0x222;
834+
self.mmu.mip = value & mask | self.mmu.mip & !mask;
835+
}
836+
Csr::Mip => {
837+
let mask = !0; // XXX 0x555 was too restrictive?? Stopped Ubuntu booting
838+
self.mmu.mip = value & mask | self.mmu.mip & !mask;
839+
}
840+
Csr::Mideleg => {
841+
self.csr[Csr::Mideleg as usize] = value & 0x222;
842+
}
843+
Csr::Mstatus => {
844+
self.mmu.mstatus = value;
845+
self.fs = ((value >> MSTATUS_FS_SHIFT) & 3) as u8;
846+
}
847+
Csr::Time => {
848+
// XXX This should trap actually
849+
self.mmu.get_mut_clint().write_mtime(value);
850+
}
851+
Csr::Satp => {
852+
self.mmu.satp = value;
853+
self.mmu.clear_page_cache();
854+
}
855+
/* Csr::Cycle | */ Csr::Mcycle => self.cycle = value,
856+
_ => {
857+
self.csr[csr as usize] = value;
858+
}
867859
}
868860
}
869861

@@ -3858,10 +3850,10 @@ mod test_cpu {
38583850
fn decode_sh2add() {
38593851
let cpu = create_cpu();
38603852
// 10894: 20e74633 sh2add a2,a4,a4
3861-
let Some(inst) = decode(&cpu.decode_dag, 0x20e74633) else {
3862-
panic!("Failed to decode");
3863-
};
3864-
assert_eq!(inst.name, "SH2ADD");
3853+
match decode(&cpu.decode_dag, 0x20e74633) {
3854+
Some(inst) => assert_eq!(inst.name, "SH2ADD"),
3855+
_err => panic!("Failed to decode"),
3856+
}
38653857
}
38663858

38673859
#[test]
@@ -3970,7 +3962,7 @@ mod test_cpu {
39703962
assert_eq!(MEMORY_BASE + 4, cpu.read_pc());
39713963
}
39723964
// Machine timer interrupt
3973-
cpu.csr.mie = MIP_MTIP;
3965+
cpu.write_csr_raw(Csr::Mie, MIP_MTIP);
39743966
cpu.mmu.mip |= MIP_MTIP;
39753967
cpu.write_csr_raw(Csr::Mstatus, 0x8);
39763968
cpu.write_csr_raw(Csr::Mtvec, 0x0);
@@ -3993,7 +3985,7 @@ mod test_cpu {
39933985
cpu.update_pc(MEMORY_BASE);
39943986

39953987
// Machine timer interrupt but mie in mstatus is not enabled yet
3996-
cpu.csr.mie = MIP_MTIP;
3988+
cpu.write_csr_raw(Csr::Mie, MIP_MTIP);
39973989
cpu.mmu.mip |= MIP_MTIP;
39983990
cpu.write_csr_raw(Csr::Mtvec, handler_vector);
39993991

0 commit comments

Comments
 (0)