mmu: remove unnecessary flushes from remap_section

This commit is contained in:
2026-01-13 13:48:28 +08:00
parent 7a4da4df48
commit 3b5359297c
2 changed files with 19 additions and 10 deletions

View File

@@ -11,6 +11,14 @@ pub fn tlbiall() {
}
}
/// Invalidate TLB for given MVA
#[inline(always)]
pub fn tlbimva(mva: u32) {
unsafe {
asm!("mcr p15, 0, {}, c8, c7, 1", in(reg) mva);
}
}
/// Invalidate I-Cache
#[inline(always)]
pub fn iciallu() {

View File

@@ -407,14 +407,20 @@ impl L1Table {
let index = (virtual_addr >> 20) as usize;
let entry = &mut self.table[index];
if entry.0 & 0x000f_ffff == new_physical_base {
// don't waste time with flushing caches if there's no change
if entry.0 & !0x000f_ffff == new_physical_base {
return;
}
let section = entry.get_section();
*entry = L1Entry::from_section(new_physical_base, section);
self.flush_mmu_and_caches();
// L1 I-cache cache is VIPT and 1MB page sizes guarantee different tags
// L1 D-cache and L2 cache is PIPT, unaffected by virtual memory changes
// thus flushing caches are unnecessary, we just
// invalidate the updated TLB entry and the branch predictor
tlbimva(virtual_addr);
bpiall();
dsb();
isb();
}
pub fn update<T, F, R>(&mut self, ptr: *const T, f: F) -> R
@@ -425,13 +431,6 @@ impl L1Table {
let result = f(&mut section);
entry.set_section(section);
self.flush_mmu_and_caches();
result
}
#[inline(always)]
fn flush_mmu_and_caches(&self) {
// Flush L1Dcache
dcciall();
// // TODO: L2?
@@ -447,6 +446,8 @@ impl L1Table {
dsb();
// synchronize context on this processor
isb();
result
}
}