aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md2
-rw-r--r--src/main.rs18
-rw-r--r--src/shareable_cache.rs46
3 files changed, 38 insertions, 28 deletions
diff --git a/TODO.md b/TODO.md
index 2aca194..b5afe53 100644
--- a/TODO.md
+++ b/TODO.md
@@ -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)