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; use std::rc::Rc; use std::cell::RefCell; use docopt::Docopt; use rustv::elfloader; use rustv::isa; use rustv::memory; use rustv::memory::Mmu; use rustv::simulator; use memory_tracker::MemoryTracker; use system::SyscallHandler; const USAGE: &'static str = " cacheracer - A F/OSS implementation of the CS 3410 CacheRacer Usage: cacheracer Options: -h --help Show this screen. --version Show version. "; #[derive(Debug, RustcDecodable)] struct Args { arg_program1: String, arg_program2: String, } fn load_program(memory: &mut memory::Memory, mmu: &T, path: &str) -> isa::Address { let mut f = File::open(path).unwrap(); let mut buffer = Vec::new(); f.read_to_end(&mut buffer).unwrap(); let elf = elfloader::ElfBinary::new("test", &buffer).unwrap(); let start = elf.file_header().entry as isa::Address; for p in elf.section_headers() { let name = elf.section_name(p); if name == ".text" || name == ".sdata" || name == ".rodata" { memory.write_segment(mmu, elf.section_data(p), p.addr as usize); } } start } fn main() { let args: Args = Docopt::new(USAGE) .and_then(|d| d.decode()) .unwrap_or_else(|e| e.exit()); let mmu = memory::IdentityMmu::new(); // 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 memory = MemoryTracker::new(memory, 0x43, 0x42); let memory_ref = Rc::new(RefCell::new(memory)); 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, cache2_ref.clone(), Box::new(mmu2)); let cores = vec![core, core2]; let system = SyscallHandler::new(memory_ref.clone()); let mut simulator = simulator::Simulator::new( cores, memory_ref.clone(), system); // let cycles = 0x1000000; let cycles = 0x1000000; let start = time::precise_time_s(); simulator.run_max(cycles); let end = time::precise_time_s(); 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); }