diff --git a/src/cpu/mod.rs b/src/cpu/mod.rs index c5ffd37..7ca784c 100644 --- a/src/cpu/mod.rs +++ b/src/cpu/mod.rs @@ -23,6 +23,39 @@ pub struct CPUState { pub pc: rv32::Word, pub trap: rv32::Word, pub bus: Rc>, + // for simplicities sake we will just put CSRs here, in the CPU. + // in reality they are part of the system and should be in the system module + // + // We will also manage them outside of the extensions interface, as they are + // not really extensions, but part of the base spec. + // + // We will also not implement all of them, just the ones we need for the Linux + // TODO: Do all of the CSRs exist on each hart? Or are they per hart? + mstatus: rv32::Word, // Machine status reg to disable interrupts + + // Timers + cyclel: rv32::Word, // Lower 32 bits of the cycle counter + cycleh: rv32::Word, // Upper 32 bits of the cycle counter + timel: rv32::Word, // Lower 32 bits of the timer + timeh: rv32::Word, // Upper 32 bits of the timer + timecmpl: rv32::Word, // Lower 32 bits of the timer compare register + timecmph: rv32::Word, // Upper 32 bits of the timer compare register + + // Machine Information Registers + mvendorid: rv32::Word, // Vendor ID of the hart + marchid: rv32::Word, // Architecture ID of the hart + mimpid: rv32::Word, // Implementation ID of the hart + mhartid: rv32::Word, // Hardware thread ID of the hart + + // Machine Trap Stuffs + mscratch: rv32::Word, // Scratch register for machine trap handlers + mtvec: rv32::Word, // Address of trap handler + mie: rv32::Word, // Machine interrupt enable + mip: rv32::Word, // Machine interrupt pending + + mepc: rv32::Word, // Machine exception program counter + mtval: rv32::Word, // Machine trap value + mcause: rv32::Word, // Machine trap cause } pub struct CPU { @@ -43,6 +76,24 @@ impl CPU { pc: 0, trap: 0, bus, + mstatus: 0, + cyclel: 0, + cycleh: 0, + timel: 0, + timeh: 0, + timecmpl: 0, + timecmph: 0, + mvendorid: 0, + marchid: 0, + mimpid: 0, + mhartid: 0, + mscratch: 0, + mtvec: 0, + mie: 0, + mip: 0, + mepc: 0, + mtval: 0, + mcause: 0, }, instruction_decoder, extensions, @@ -70,19 +121,27 @@ impl CPU { self.state.bus.borrow_mut().load_32(self.state.pc) } + pub fn step(&mut self) -> Result<(), String> { + // CSR stuff before fetch execute + // + + // TODO: We can execute multiple instructions per cycle + let inst = self.fetch(); + println!("VM > Fetched 0x{:08x}: 0x{:08x}", self.state.pc, inst); + self.state.x[0] = 0x00000000; + + self.state.pc = self.state.pc + rv32::WORD as u32; + + self.instruction_decoder + .borrow_mut() + .decode_exec_inst(inst, &mut self.state)?; + + Ok(()) + } + pub fn exec(&mut self) -> Result<(), String> { while self.state.pc - DRAM_BASE < ram::DRAM_SIZE as u32 { - // fetch - let inst = self.fetch(); - println!("VM > Fetched 0x{:08x}: 0x{:08x}", self.state.pc, inst); - self.state.x[0] = 0x00000000; - - self.state.pc = self.state.pc + rv32::WORD as u32; - - self.instruction_decoder - .borrow_mut() - .decode_exec_inst(inst, &mut self.state)?; - + self.step()?; self.dump_reg(); } Ok(()) diff --git a/src/ext/a/mod.rs b/src/ext/a/mod.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/ext/m/mod.rs b/src/ext/m/mod.rs new file mode 100644 index 0000000..e69de29