CSR
This commit is contained in:
@@ -23,6 +23,39 @@ pub struct CPUState {
|
|||||||
pub pc: rv32::Word,
|
pub pc: rv32::Word,
|
||||||
pub trap: rv32::Word,
|
pub trap: rv32::Word,
|
||||||
pub bus: Rc<RefCell<Bus>>,
|
pub bus: Rc<RefCell<Bus>>,
|
||||||
|
// 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 {
|
pub struct CPU {
|
||||||
@@ -43,6 +76,24 @@ impl CPU {
|
|||||||
pc: 0,
|
pc: 0,
|
||||||
trap: 0,
|
trap: 0,
|
||||||
bus,
|
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,
|
instruction_decoder,
|
||||||
extensions,
|
extensions,
|
||||||
@@ -70,19 +121,27 @@ impl CPU {
|
|||||||
self.state.bus.borrow_mut().load_32(self.state.pc)
|
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> {
|
pub fn exec(&mut self) -> Result<(), String> {
|
||||||
while self.state.pc - DRAM_BASE < ram::DRAM_SIZE as u32 {
|
while self.state.pc - DRAM_BASE < ram::DRAM_SIZE as u32 {
|
||||||
// fetch
|
self.step()?;
|
||||||
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.dump_reg();
|
self.dump_reg();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
0
src/ext/a/mod.rs
Normal file
0
src/ext/a/mod.rs
Normal file
0
src/ext/m/mod.rs
Normal file
0
src/ext/m/mod.rs
Normal file
Reference in New Issue
Block a user