diff options
author | David Li <li.davidm96@gmail.com> | 2016-01-04 19:01:24 -0700 |
---|---|---|
committer | David Li <li.davidm96@gmail.com> | 2016-01-04 19:01:24 -0700 |
commit | db87cd3953eef9ec78c3a17ce6d21055cf879ab8 (patch) | |
tree | 020548b68a01bf57c3f460d90dca7ee49fa1fd72 /src | |
parent | 7c2e626e99c6167444de52fb63509814644a11a3 (diff) |
Enable loading with address translation
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 30 | ||||
-rw-r--r-- | src/memory.rs | 12 |
2 files changed, 27 insertions, 15 deletions
@@ -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); } } |