From db87cd3953eef9ec78c3a17ce6d21055cf879ab8 Mon Sep 17 00:00:00 2001
From: David Li <li.davidm96@gmail.com>
Date: Mon, 4 Jan 2016 19:01:24 -0700
Subject: Enable loading with address translation

---
 src/lib.rs    | 30 +++++++++++++++++++++---------
 src/memory.rs | 12 ++++++------
 2 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 6418df3..1c41bbf 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -27,6 +27,7 @@ fn test_elfloader() {
     use std::rc::Rc;
     use std::cell::RefCell;
     extern crate elfloader;
+    use memory::{Mmu, MemoryInterface};
 
     let mut f = File::open("../riscv/kernel").unwrap();
     let mut buffer = Vec::new();
@@ -51,15 +52,26 @@ fn test_elfloader() {
     let (data, data_offset) = data.unwrap();
 
     let mmu = memory::IdentityMmu::new();
-    // TODO: make this a method; have it accept a MMU
-    let mut memory = memory::Memory::new(0x8000);
-    memory.write_segment(text, text_offset as usize);
-    memory.write_segment(data, data_offset as usize);
-    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(start, 0x1000, cache.clone(), Box::new(mmu));
-    let core2 = simulator::Core::new(start, 0x3000, cache.clone(), Box::new(memory::IdentityMmu::new()));
-    let mut simulator = simulator::Simulator::new(vec![core, core2], memory_ref.clone());
+    let mmu2 = memory::ReverseMmu::new(0x8000);
+    let mut memory = memory::Memory::new(0x10000);
+    memory.write_segment(&mmu, text, text_offset as usize);
+    memory.write_segment(&mmu, data, data_offset as usize);
+    memory.write_segment(&mmu2, text, text_offset as usize);
+    memory.write_segment(&mmu2, data, data_offset as usize);
+
+    let memory_box = Box::new(memory) as Box<memory::MemoryInterface>;
+    let memory_ref = Rc::new(RefCell::new(memory_box));
+    let cache = memory::DirectMappedCache::new(4, 4, memory_ref.clone());
+    let cache_box = Box::new(cache) as Box<memory::MemoryInterface>;
+    let cache_ref = Rc::new(RefCell::new(cache_box));
+    let core = simulator::Core::new(
+        start, 0x1000,
+        cache_ref.clone(), Box::new(mmu));
+    let core2 = simulator::Core::new(
+        start, 0x3000,
+        cache_ref.clone(), Box::new(mmu2));
+    let cores = vec![core, core2];
+    let mut simulator = simulator::Simulator::new(cores, memory_ref.clone());
     simulator.run();
 }
 
diff --git a/src/memory.rs b/src/memory.rs
index b90170b..b618001 100644
--- a/src/memory.rs
+++ b/src/memory.rs
@@ -160,7 +160,7 @@ pub struct DirectMappedCache<'a> {
     next_level: SharedMemory<'a>,
 }
 
-fn copy_u8_into_u32(src: &[u8], dst: &mut [u32]) {
+fn copy_u8_into_u32<T: Mmu>(mmu: &T, base: usize, src: &[u8], dst: &mut [u32]) {
     for (offset, word) in src.chunks(4).enumerate() {
         let word = if word.len() == 4 {
             (word[0] as u32) |
@@ -181,7 +181,8 @@ fn copy_u8_into_u32(src: &[u8], dst: &mut [u32]) {
             word[0] as u32
         };
 
-        dst[offset] = word;
+        let addr = mmu.translate((base as isa::Address) + ((4 * offset) as isa::Address)) / 4;
+        dst[addr as usize] = word;
     }
 }
 
@@ -204,10 +205,9 @@ impl Memory {
         }
     }
 
-    pub fn write_segment(&mut self, data: &[u8], offset: usize) {
-        let size = self.memory.len();
-        let mut segment = &mut self.memory[(offset / 4)..size];
-        copy_u8_into_u32(data, segment);
+    pub fn write_segment<T: Mmu>(&mut self, mmu: &T,
+                                 data: &[u8], offset: usize) {
+        copy_u8_into_u32(mmu, offset, data, &mut self.memory);
     }
 }
 
-- 
cgit v1.2.3