diff options
-rw-r--r-- | TODO.md | 2 | ||||
-rw-r--r-- | src/main.rs | 18 | ||||
-rw-r--r-- | src/shareable_cache.rs | 46 |
3 files changed, 38 insertions, 28 deletions
@@ -19,7 +19,7 @@ https://git.lidavidm.me/cacheracer/. - [ ] Make sure `ReverseMmu` maps addresses correctly (i.e. 0x0 should map to an actual array element) -- [ ] Sneak attack/retreat needs to be per-core +- [x] Sneak attack/retreat needs to be per-core - [ ] Implement global data structures - [ ] Player status - [ ] Core status diff --git a/src/main.rs b/src/main.rs index 2f607a6..e6b6385 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,15 +86,16 @@ fn main() { let cache2 = memory::DirectMappedCache::new(2, 64, memory_ref.clone()); let cache2_ref = Rc::new(RefCell::new(cache2)); - let (cache1, cache2) = ShareableCache::new(cache_ref.clone(), cache2_ref.clone()); - let mut core_caches = vec![]; let mut cores = vec![]; + let mut core_caches = vec![]; + for i in 0..4 { - let c1 = Rc::new(RefCell::new(cache1.clone())); - core_caches.push(c1.clone()); + let core_cache = Rc::new(RefCell::new( + ShareableCache::new(i, cache_ref.clone(), cache2_ref.clone()))); + core_caches.push(core_cache.clone()); let mut core = simulator::Core::new( - i, start1, (0x100000 * (i + 1)) as u32, c1, + i, start1, (0x100000 * (i + 1)) as u32, core_cache, Box::new(memory::IdentityMmu::new()) ); core.registers().write_word(isa::Register::X10, i as isa::Word); @@ -102,10 +103,11 @@ fn main() { } for i in 4..8 { - let c2 = Rc::new(RefCell::new(cache2.clone())); - core_caches.push(c2.clone()); + let core_cache = Rc::new(RefCell::new( + ShareableCache::new(i, cache2_ref.clone(), cache_ref.clone()))); + core_caches.push(core_cache.clone()); let mut core = simulator::Core::new( - i, start2, (0x100000 * (i + 1)) as u32, c2, + i, start2, (0x100000 * (i + 1)) as u32, core_cache, Box::new(memory::ReverseMmu::new(0x4000000)) ); core.registers().write_word(isa::Register::X10, i as isa::Word); diff --git a/src/shareable_cache.rs b/src/shareable_cache.rs index 09d514f..9f558cd 100644 --- a/src/shareable_cache.rs +++ b/src/shareable_cache.rs @@ -3,8 +3,8 @@ use rustv::memory::{MemoryInterface, Result, SharedMemory}; /// A cache that can be used as two separate caches or one /// set-associative cache. -#[derive(Clone)] pub struct ShareableCache<'a> { + core_id: usize, primary: SharedMemory<'a>, secondary: SharedMemory<'a>, secondary_enabled: bool, @@ -12,20 +12,16 @@ pub struct ShareableCache<'a> { } impl<'a> ShareableCache<'a> { - pub fn new(cache1: SharedMemory<'a>, cache2: SharedMemory<'a>) - -> (ShareableCache<'a>, - ShareableCache<'a>) { - (ShareableCache { + pub fn new(core_id: usize, + cache1: SharedMemory<'a>, cache2: SharedMemory<'a>) + -> ShareableCache<'a> { + ShareableCache { + core_id: core_id, primary: cache1.clone(), secondary: cache2.clone(), secondary_enabled: false, use_secondary: false, - }, ShareableCache { - primary: cache2.clone(), - secondary: cache1.clone(), - secondary_enabled: false, - use_secondary: false, - }) + } } pub fn enable_secondary(&mut self) { @@ -36,6 +32,19 @@ impl<'a> ShareableCache<'a> { pub fn disable_secondary(&mut self) { self.secondary_enabled = false; } + + fn address_accessible(&self, address: isa::Address) -> (bool, bool) { + // Use scopes to make sure these borrows end before the + // branches of the if statement begin + let primary_accessible = { + self.primary.borrow().is_address_accessible(address) + }; + let secondary_accessible = { + self.secondary.borrow().is_address_accessible(address) + }; + + (primary_accessible, secondary_accessible) + } } impl<'a> MemoryInterface for ShareableCache<'a> { @@ -58,10 +67,13 @@ impl<'a> MemoryInterface for ShareableCache<'a> { fn read_word(&mut self, address: isa::Address) -> Result<isa::Word> { if self.secondary_enabled { - if self.primary.borrow().is_address_accessible(address) { + let (primary_accessible, secondary_accessible) = + self.address_accessible(address); + + if primary_accessible { self.primary.borrow_mut().read_word(address) } - else if self.secondary.borrow().is_address_accessible(address) { + else if secondary_accessible { self.secondary.borrow_mut().read_word(address) } else { @@ -81,12 +93,8 @@ impl<'a> MemoryInterface for ShareableCache<'a> { fn write_word(&mut self, address: isa::Address, value: isa::Word) -> Result<()> { if self.secondary_enabled { - let primary_accessible = { - self.primary.borrow().is_address_accessible(address) - }; - let secondary_accessible = { - self.secondary.borrow().is_address_accessible(address) - }; + let (primary_accessible, secondary_accessible) = + self.address_accessible(address); if primary_accessible { self.primary.borrow_mut().write_word(address, value) |