Read bytes for debug display without touching cache stats or LRU state. Routes by address: ROM and MMIO are read directly (non-destructive). RAM is read through the L1/L2/L3 cache hierarchy.
(&self, addr: u64, len: usize)
| 213 | &mut self, |
| 214 | addr: u64, |
| 215 | before: Option<( |
| 216 | crate::memory::cache::CacheStats, |
| 217 | crate::memory::cache::CacheStats, |
| 218 | crate::memory::cache::CacheStats, |
| 219 | )>, |
| 220 | ) { |
| 221 | // Disabled = historical one-cycle model: never accumulate, so multi-access |
| 222 | // windows (page walks, misaligned splits) add no stall cycles. |
| 223 | if !self.memory_latency.enabled { |
| 224 | return; |
| 225 | } |
| 226 | let cycles = if addr < RAM_BASE { |
| 227 | self.memory_latency.uncached |
| 228 | } else if let Some((l1_before, l2_before, l3_before)) = before { |
| 229 | let (l1_after, l2_after, l3_after) = self.get_cache_stats(); |
| 230 | if cache_misses(&l3_after) > cache_misses(&l3_before) { |
| 231 | self.memory_latency.dram |
| 232 | } else if cache_misses(&l2_after) > cache_misses(&l2_before) { |
| 233 | self.memory_latency.l3_hit |
| 234 | } else if cache_misses(&l1_after) > cache_misses(&l1_before) { |
| 235 | self.memory_latency.l2_hit |
| 236 | } else { |
| 237 | self.memory_latency.l1_hit |
| 238 | } |
| 239 | } else { |
| 240 | 1 |
| 241 | }; |
| 242 | self.access_latency_cycles = self.access_latency_cycles.saturating_add(cycles.max(1)); |
| 243 | } |
| 244 | |
| 245 | fn stats_before_access( |
| 246 | &self, |
| 247 | addr: u64, |
| 248 | ) -> Option<( |
nothing calls this directly
no test coverage detected