diff --git a/src/device.rs b/src/device.rs index 70beeef..298952e 100644 --- a/src/device.rs +++ b/src/device.rs @@ -310,8 +310,8 @@ impl Device { is_event: false, instrs: [cop0::reserved; 32], instrs2: [cop0::reserved; 32], - tlb_lut_w: vec![], - tlb_lut_r: vec![], + tlb_lut_w: rustc_hash::FxHashMap::default(), + tlb_lut_r: rustc_hash::FxHashMap::default(), tlb_entries: [tlb::TlbEntry { mask: 0, vpn2: 0, diff --git a/src/device/cop0.rs b/src/device/cop0.rs index 0dd83d1..87521bd 100644 --- a/src/device/cop0.rs +++ b/src/device/cop0.rs @@ -100,10 +100,8 @@ pub struct Cop0 { pub instrs: [fn(&mut device::Device, u32); 32], #[serde(skip, default = "savestates::default_instructions")] pub instrs2: [fn(&mut device::Device, u32); 32], - #[serde(skip)] - pub tlb_lut_r: Vec, - #[serde(skip)] - pub tlb_lut_w: Vec, + pub tlb_lut_r: rustc_hash::FxHashMap, + pub tlb_lut_w: rustc_hash::FxHashMap, pub tlb_entries: [device::tlb::TlbEntry; 32], pub is_event: bool, } @@ -371,7 +369,6 @@ pub fn init(device: &mut device::Device) { ]; map_instructions(device); - device::tlb::init(device); // taken from VR4300 manual device.cpu.cop0.regs[COP0_RANDOM_REG] = 0b00000000000000000000000000011111; diff --git a/src/device/tlb.rs b/src/device/tlb.rs index 1c57000..4f4d48f 100644 --- a/src/device/tlb.rs +++ b/src/device/tlb.rs @@ -30,23 +30,6 @@ pub struct TlbEntry { pub phys_odd: u64, } -pub fn init(device: &mut device::Device) { - device.cpu.cop0.tlb_lut_r.resize( - 0x100000, - device::tlb::TlbLut { - address: 0, - cached: false, - }, - ); - device.cpu.cop0.tlb_lut_w.resize( - 0x100000, - device::tlb::TlbLut { - address: 0, - cached: false, - }, - ); -} - pub fn read(device: &mut device::Device, index: u64) { if index > 31 { return; @@ -166,15 +149,13 @@ fn tlb_unmap(device: &mut device::Device, index: u64) { if e.v_even != 0 { let mut i = e.start_even; while i < e.end_even { - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = 0; - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = false; + device.cpu.cop0.tlb_lut_r.remove(&(i >> 12)); i += 0x1000 } if e.d_even != 0 { let mut i = e.start_even; while i < e.end_even { - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = 0; - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = false; + device.cpu.cop0.tlb_lut_w.remove(&(i >> 12)); i += 0x1000 } } @@ -183,22 +164,20 @@ fn tlb_unmap(device: &mut device::Device, index: u64) { if e.v_odd != 0 { let mut i = e.start_odd; while i < e.end_odd { - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = 0; - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = false; + device.cpu.cop0.tlb_lut_r.remove(&(i >> 12)); i += 0x1000 } if e.d_odd != 0 { let mut i = e.start_odd; while i < e.end_odd { - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = 0; - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = false; + device.cpu.cop0.tlb_lut_w.remove(&(i >> 12)); i += 0x1000 } } } } -pub fn tlb_map(device: &mut device::Device, index: u64) { +fn tlb_map(device: &mut device::Device, index: u64) { let e = &device.cpu.cop0.tlb_entries[index as usize]; if e.v_even != 0 @@ -208,17 +187,25 @@ pub fn tlb_map(device: &mut device::Device, index: u64) { { let mut i = e.start_even; while i < e.end_even { - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = - 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF); - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = e.c_even != 2; + device.cpu.cop0.tlb_lut_r.insert( + i >> 12, + device::tlb::TlbLut { + address: 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF), + cached: e.c_even != 2, + }, + ); i += 0x1000 } if e.d_even != 0 { let mut i = e.start_even; while i < e.end_even { - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = - 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF); - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = e.c_even != 2; + device.cpu.cop0.tlb_lut_w.insert( + i >> 12, + device::tlb::TlbLut { + address: 0x80000000 | (e.phys_even + (i - e.start_even) + 0xFFF), + cached: e.c_even != 2, + }, + ); i += 0x1000 } } @@ -231,17 +218,25 @@ pub fn tlb_map(device: &mut device::Device, index: u64) { { let mut i = e.start_odd; while i < e.end_odd { - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].address = - 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF); - device.cpu.cop0.tlb_lut_r[(i >> 12) as usize].cached = e.c_odd != 2; + device.cpu.cop0.tlb_lut_r.insert( + i >> 12, + device::tlb::TlbLut { + address: 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF), + cached: e.c_odd != 2, + }, + ); i += 0x1000 } if e.d_odd != 0 { let mut i = e.start_odd; while i < e.end_odd { - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].address = - 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF); - device.cpu.cop0.tlb_lut_w[(i >> 12) as usize].cached = e.c_odd != 2; + device.cpu.cop0.tlb_lut_w.insert( + i >> 12, + device::tlb::TlbLut { + address: 0x80000000 | (e.phys_odd + (i - e.start_odd) + 0xFFF), + cached: e.c_odd != 2, + }, + ); i += 0x1000 } } @@ -256,19 +251,17 @@ pub fn get_physical_address( address &= 0xffffffff; if access_type == device::memory::AccessType::Write { - if device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].address != 0 { + if let Some(lut) = device.cpu.cop0.tlb_lut_w.get(&(address >> 12)) { return ( - (device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].address & 0x1FFFF000) - | (address & 0xFFF), - device.cpu.cop0.tlb_lut_w[(address >> 12) as usize].cached, + (lut.address & 0x1FFFF000) | (address & 0xFFF), + lut.cached, false, ); } - } else if device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].address != 0 { + } else if let Some(lut) = device.cpu.cop0.tlb_lut_r.get(&(address >> 12)) { return ( - (device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].address & 0x1FFFF000) - | (address & 0xFFF), - device.cpu.cop0.tlb_lut_r[(address >> 12) as usize].cached, + (lut.address & 0x1FFFF000) | (address & 0xFFF), + lut.cached, false, ); } diff --git a/src/savestates.rs b/src/savestates.rs index 59156d7..e0f2edb 100644 --- a/src/savestates.rs +++ b/src/savestates.rs @@ -247,11 +247,6 @@ pub fn load_savestate(device: &mut device::Device, rewind: bool) { } } - device::tlb::init(device); - for i in 0..32 { - device::tlb::tlb_map(device, i); - } - device::pif::connect_pif_channels(device); for i in 0..4 { if let Some(handler) = device.pif.channels[i].pak_handler {