diff options
-rw-r--r-- | src/lib.rs | 5 | ||||
-rw-r--r-- | src/memory.rs | 33 | ||||
-rw-r--r-- | src/simulator.rs | 18 |
3 files changed, 49 insertions, 7 deletions
@@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with rustv. If not, see <http://www.gnu.org/licenses/>. -#![feature(step_by)] +#![feature(braced_empty_structs, step_by)] pub mod isa; pub mod binary; pub mod memory; @@ -28,10 +28,11 @@ fn it_works() { use std::path::Path; match binary::Binary::new_from_hex_file(Path::new("../riscv/kernel.hex")) { Ok(b) => { + let mmu = memory::IdentityMmu::new(); let memory = memory::Memory::new_from_binary(0x2000, b); let memory_ref = Rc::new(RefCell::new(Box::new(memory) as Box<memory::MemoryInterface>)); let cache = Rc::new( RefCell::new( Box::new( memory::DirectMappedCache::new(4, 4, memory_ref.clone())) as Box<memory::MemoryInterface>) ); - let core = simulator::Core::new(cache.clone()); + let core = simulator::Core::new(cache.clone(), Box::new(mmu)); let mut simulator = simulator::Simulator::new(vec![core], memory_ref.clone()); simulator.run(); }, diff --git a/src/memory.rs b/src/memory.rs index 9f14700..92aefd5 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -89,7 +89,38 @@ pub trait MemoryInterface { pub type SharedMemory<'a> = Rc<RefCell<Box<MemoryInterface + 'a>>>; pub trait Mmu { - fn translate(address: isa::Address) -> isa::Address; + fn translate(&self, address: isa::Address) -> isa::Address; +} + +pub struct IdentityMmu {} +pub struct ReverseMmu { + top: isa::Address, +} + +impl IdentityMmu { + pub fn new() -> IdentityMmu { + IdentityMmu {} + } +} + +impl Mmu for IdentityMmu { + fn translate(&self, address: isa::Address) -> isa::Address { + address + } +} + +impl ReverseMmu { + pub fn new(top: isa::Address) -> ReverseMmu { + ReverseMmu { + top: top, + } + } +} + +impl Mmu for ReverseMmu { + fn translate(&self, address: isa::Address) -> isa::Address { + self.top - address + } } pub struct Memory { diff --git a/src/simulator.rs b/src/simulator.rs index 558f2b1..f92d3d2 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -15,18 +15,19 @@ // along with rustv. If not, see <http://www.gnu.org/licenses/>. use isa; -use memory::{MemoryInterface, MemoryError, SharedMemory}; +use memory::{MemoryInterface, MemoryError, Mmu, SharedMemory}; struct RegisterFile { registers: [isa::Word; 32], } -pub struct Core<'a> { +pub struct Core<'a>{ pc: isa::Address, registers: RegisterFile, stall: u32, running: bool, cache: SharedMemory<'a>, + mmu: Box<Mmu + 'a>, } pub struct Simulator<'a> { @@ -74,13 +75,14 @@ impl RegisterFile { impl<'a> Core<'a> { // TODO: take Rc<RefCell<>> to Memory as well? - pub fn new(cache: SharedMemory<'a>) -> Core<'a> { + pub fn new(cache: SharedMemory<'a>, mmu: Box<Mmu + 'a>) -> Core<'a> { Core { pc: 0x1002c, // TODO: hardcoded: fix later registers: RegisterFile::new(), stall: 0, running: true, cache: cache, + mmu: mmu, } } @@ -273,6 +275,8 @@ impl<'a> Core<'a> { let imm = inst.i_imm(); let base = self.registers.read_word(inst.rs1()); let address = ((base as isa::SignedWord) + imm) as isa::Address; + let address = self.mmu.translate(address); + let result = self.cache.borrow_mut().read_word(address); match result { Ok(value) => @@ -300,6 +304,8 @@ impl<'a> Core<'a> { let base = self.registers.read_word(inst.rs1()); let val = self.registers.read_word(inst.rs2()); let address = ((base as isa::SignedWord) + imm) as isa::Address; + let address = self.mmu.translate(address); + let result = self.cache.borrow_mut().write_word(address, val); match result { Ok(()) => (), @@ -371,7 +377,11 @@ impl<'a> Simulator<'a> { continue; } if core.stall > 0 { stall_cycles += 1; } - let inst = self.memory.borrow_mut().read_instruction(core.pc); + + let pc = core.pc; + let pc = core.mmu.translate(pc); + let inst = self.memory.borrow_mut().read_instruction(pc); + if let Some(inst) = inst { core.step(inst); } |