aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2016-01-08 10:04:27 -0700
committerDavid Li <li.davidm96@gmail.com>2016-01-08 10:04:27 -0700
commitad805c698cd1c4d68d090f842fb14621c32ee8d6 (patch)
treefd357647c13c461370d34a067b84cc7aac94c7d3 /src/main.rs
parent940a5ae77a1efc8f89fe5b56fe4a4ae34a0e480d (diff)
Refactor into multiple files
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs141
1 files changed, 27 insertions, 114 deletions
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<isa::Word> {
- 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<trap::Trap> {
- 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<T: memory::Mmu>(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);
}