summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorCasey Connolly <[email protected]>2026-06-08 19:13:50 +0200
committerTom Rini <[email protected]>2026-06-17 09:55:00 -0600
commit76c90926087cd586f151c5ebd557589e1306b45c (patch)
tree1d549ec68ffcd28246f2807281bb52b7f65bce87 /arch
parent41b6b904b58577c4aa7100e2850af0429e964283 (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]>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/cpu/armv8/cache_v8.c94
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)