From 01f161fa1ac86e75524bf038e51a236f0dfb22a6 Mon Sep 17 00:00:00 2001
From: David Li
Date: Sun, 3 Jan 2016 13:47:01 -0700
Subject: Add MMU to core
---
src/lib.rs | 5 +++--
src/memory.rs | 33 ++++++++++++++++++++++++++++++++-
src/simulator.rs | 18 ++++++++++++++----
3 files changed, 49 insertions(+), 7 deletions(-)
(limited to 'src')
diff --git a/src/lib.rs b/src/lib.rs
index 66afe2a..5dda62e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with rustv. If not, see .
-#![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));
let cache = Rc::new( RefCell::new( Box::new( memory::DirectMappedCache::new(4, 4, memory_ref.clone())) as Box) );
- 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>>;
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 .
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,
}
pub struct Simulator<'a> {
@@ -74,13 +75,14 @@ impl RegisterFile {
impl<'a> Core<'a> {
// TODO: take Rc> to Memory as well?
- pub fn new(cache: SharedMemory<'a>) -> Core<'a> {
+ pub fn new(cache: SharedMemory<'a>, mmu: Box) -> 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);
}
--
cgit v1.2.3