@@ -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