From ad805c698cd1c4d68d090f842fb14621c32ee8d6 Mon Sep 17 00:00:00 2001 From: David Li Date: Fri, 8 Jan 2016 10:04:27 -0700 Subject: Refactor into multiple files --- src/main.rs | 141 ++++++++++++------------------------------------------------ 1 file changed, 27 insertions(+), 114 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 722efdb..50cc8ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,11 @@ extern crate docopt; extern crate rustc_serialize; extern crate rustv; +extern crate time; + +mod memory_tracker; +mod shareable_cache; +mod system; use std::fs::File; use std::io::Read; @@ -12,12 +17,11 @@ use docopt::Docopt; use rustv::elfloader; use rustv::isa; use rustv::memory; -use rustv::memory::MemoryInterface; use rustv::memory::Mmu; -use rustv::register_file; use rustv::simulator; -use rustv::syscall; -use rustv::trap; + +use memory_tracker::MemoryTracker; +use system::SyscallHandler; const USAGE: &'static str = " cacheracer - A F/OSS implementation of the CS 3410 CacheRacer @@ -36,102 +40,7 @@ struct Args { arg_program2: String, } -struct MemoryTracker { - memory: memory::Memory, - program1_byte: u8, - program2_byte: u8, - program1: usize, - program2: usize, -} - -impl memory::MemoryInterface for MemoryTracker { - fn latency(&self) -> u32 { - self.memory.latency() - } - - fn step(&mut self) { - self.memory.step(); - } - - fn read_word(&mut self, address: isa::Address) -> memory::Result { - self.memory.read_word(address) - } - - fn write_word(&mut self, address: isa::Address, value: isa::Word) -> memory::Result<()> { - let original = self.memory.read_word(address); - let result = self.memory.write_word(address, value); - - if let Ok(original) = original { - if let Ok(()) = result { - let p1b = self.program1_byte as u32; - let mut p1orig = 0; - let mut p1new = 0; - if original & 0xFF == p1b { p1orig += 1; } - if (original >> 8) & 0xFF == p1b { p1orig += 1; } - if (original >> 8) & 0xFF == p1b { p1orig += 1; } - if (original >> 8) & 0xFF == p1b { p1orig += 1; } - - if value & 0xFF == p1b { p1new += 1; } - if (value >> 8) & 0xFF == p1b { p1new += 1; } - if (value >> 8) & 0xFF == p1b { p1new += 1; } - if (value >> 8) & 0xFF == p1b { p1new += 1; } - - self.program1 += p1new - p1orig; - - let p2b = self.program2_byte as u32; - let mut p2orig = 0; - let mut p2new = 0; - if original & 0xFF == p2b { p2orig += 1; } - if (original >> 8) & 0xFF == p2b { p2orig += 1; } - if (original >> 8) & 0xFF == p2b { p2orig += 1; } - if (original >> 8) & 0xFF == p2b { p2orig += 1; } - - if value & 0xFF == p2b { p2new += 1; } - if (value >> 8) & 0xFF == p2b { p2new += 1; } - if (value >> 8) & 0xFF == p2b { p2new += 1; } - if (value >> 8) & 0xFF == p2b { p2new += 1; } - - self.program2 += p2new - p2orig; - } - } - - result - } -} - -struct SyscallHandler<'a> { - memory: memory::SharedMemory<'a>, -} - -impl<'a> syscall::SyscallHandler for SyscallHandler<'a> { - fn syscall(&mut self, registers: &mut register_file::RegisterFile) -> Option { - println!("Syscall number {}", registers.read_word(isa::Register::X10)); - let mut base = registers.read_word(isa::Register::X11); - let mut string = vec![]; - loop { - let c = self.memory.borrow_mut().read_byte(base); - - if let Ok(0x00) = c { - break; - } - else if let Ok(c) = c { - string.push(c); - } - - base += 1; - } - - let result = std::str::from_utf8(&string); - if let Ok(string) = result { - println!("{}", string); - } - else { - println!("Error printing string: {:?}", result); - } - None - } -} fn load_program(memory: &mut memory::Memory, mmu: &T, path: &str) -> isa::Address { @@ -159,36 +68,40 @@ fn main() { .unwrap_or_else(|e| e.exit()); let mmu = memory::IdentityMmu::new(); - let mmu2 = memory::ReverseMmu::new(0x8000); - let mut memory = memory::Memory::new(0x10000); + // TODO: account for word-vs-byte addressed. Use newtype pattern? + let mmu2 = memory::ReverseMmu::new(0x4000000); + let mut memory = memory::Memory::new(0x400000); let start1 = load_program(&mut memory, &mmu, &args.arg_program1); let start2 = load_program(&mut memory, &mmu2, &args.arg_program2); - let mut memory = MemoryTracker { - memory: memory, - program1_byte: 0x43, - program2_byte: 0x42, - program1: 0, - program2: 0, - }; + let memory = MemoryTracker::new(memory, 0x43, 0x42); let memory_ref = Rc::new(RefCell::new(memory)); - let cache = memory::DirectMappedCache::new(4, 4, memory_ref.clone()); + let cache = memory::DirectMappedCache::new(4, 64, memory_ref.clone()); let cache_ref = Rc::new(RefCell::new(cache)); + let cache2 = memory::DirectMappedCache::new(4, 64, memory_ref.clone()); + let cache2_ref = Rc::new(RefCell::new(cache2)); + let core = simulator::Core::new( start1, 0x1000, cache_ref.clone(), Box::new(mmu)); let core2 = simulator::Core::new( start2, 0x1000, - cache_ref.clone(), Box::new(mmu2)); + cache2_ref.clone(), Box::new(mmu2)); let cores = vec![core, core2]; - let system = SyscallHandler { memory: memory_ref.clone(), }; + let system = SyscallHandler::new(memory_ref.clone()); let mut simulator = simulator::Simulator::new( cores, memory_ref.clone(), system); - simulator.run(); + // let cycles = 0x1000000; + let cycles = 0x1000000; + let start = time::precise_time_s(); + simulator.run_max(cycles); + let end = time::precise_time_s(); - println!("Program 1 bytes written: {}", memory_ref.borrow().program1); - println!("Program 2 bytes written: {}", memory_ref.borrow().program2); + println!("{} cycles in {:04} seconds ({} cycles/sec)", cycles, end - start, (cycles as f64) / (end - start)); + let (p1, p2) = memory_ref.borrow().score(); + println!("Program 1 bytes written: {}", p1); + println!("Program 2 bytes written: {}", p2); } -- cgit v1.2.3