diff options
| author | Casey Connolly <[email protected]> | 2026-06-08 19:13:50 +0200 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-06-17 09:55:00 -0600 |
| commit | 76c90926087cd586f151c5ebd557589e1306b45c (patch) | |
| tree | 1d549ec68ffcd28246f2807281bb52b7f65bce87 | |
| parent | 41b6b904b58577c4aa7100e2850af0429e964283 (diff) | |
armv8: mmu: commonize the set_one_region() loop
This loop is duplicated 3 times, put it into its own function and call
it instead. This simplifies the logic in a few functions.
Reviewed-by: Ilias Apalodimas <[email protected]>
Signed-off-by: Casey Connolly <[email protected]>
| -rw-r--r-- | arch/arm/cpu/armv8/cache_v8.c | 94 |
1 files changed, 28 insertions, 66 deletions
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 91c55591a1d..01f72c3d0ec 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -1033,6 +1033,28 @@ static u64 set_one_region(u64 start, u64 size, u64 attrs, bool flag, int level) return 0; } +static void set_regions(u64 start, u64 size, u64 attrs, bool flag) +{ + int level; + u64 r; + + /* + * Loop through the address range until we find a page granule that fits + * our alignment constraints, then set it to the new cache attributes + */ + while (size > 0) { + for (level = 1; level < 4; level++) { + r = set_one_region(start, size, attrs, flag, level); + if (r) { + /* PTE successfully replaced */ + size -= r; + start += r; + break; + } + } + } +} + void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, enum dcache_option option) { @@ -1052,26 +1074,7 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, */ __asm_switch_ttbr(gd->arch.tlb_emerg); - /* - * Loop through the address range until we find a page granule that fits - * our alignment constraints, then set it to the new cache attributes - */ - while (size > 0) { - int level; - u64 r; - - for (level = 1; level < 4; level++) { - /* Set d-cache attributes only */ - r = set_one_region(start, size, attrs, false, level); - if (r) { - /* PTE successfully replaced */ - size -= r; - start += r; - break; - } - } - - } + set_regions(start, size, attrs, false); /* We're done modifying page tables, switch back to our primary ones */ __asm_switch_ttbr(gd->arch.tlb_addr); @@ -1083,29 +1086,9 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, flush_dcache_range(real_start, real_start + real_size); } -void mmu_change_region_attr_nobreak(phys_addr_t addr, size_t siz, u64 attrs) +void mmu_change_region_attr_nobreak(phys_addr_t addr, size_t size, u64 attrs) { - int level; - u64 r, size, start; - - /* - * Loop through the address range until we find a page granule that fits - * our alignment constraints and set the new permissions - */ - start = addr; - size = siz; - while (size > 0) { - for (level = 1; level < 4; level++) { - /* Set PTE to new attributes */ - r = set_one_region(start, size, attrs, true, level); - if (r) { - /* PTE successfully updated */ - size -= r; - start += r; - break; - } - } - } + set_regions(addr, size, attrs, true); flush_dcache_range(gd->arch.tlb_addr, gd->arch.tlb_addr + gd->arch.tlb_size); __asm_invalidate_tlb_all(); @@ -1116,36 +1099,15 @@ void mmu_change_region_attr_nobreak(phys_addr_t addr, size_t siz, u64 attrs) * The procecess is break-before-make. The target region will be marked as * invalid during the process of changing. */ -void mmu_change_region_attr(phys_addr_t addr, size_t siz, u64 attrs) +void mmu_change_region_attr(phys_addr_t addr, size_t size, u64 attrs) { - int level; - u64 r, size, start; - - start = addr; - size = siz; - /* - * Loop through the address range until we find a page granule that fits - * our alignment constraints, then set it to "invalid". - */ - while (size > 0) { - for (level = 1; level < 4; level++) { - /* Set PTE to fault */ - r = set_one_region(start, size, PTE_TYPE_FAULT, true, - level); - if (r) { - /* PTE successfully invalidated */ - size -= r; - start += r; - break; - } - } - } + set_regions(addr, size, PTE_TYPE_FAULT, true); flush_dcache_range(gd->arch.tlb_addr, gd->arch.tlb_addr + gd->arch.tlb_size); __asm_invalidate_tlb_all(); - mmu_change_region_attr_nobreak(addr, siz, attrs); + mmu_change_region_attr_nobreak(addr, size, attrs); } int pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm) |
