arch: arm64: mpu: Use BR mode to flush the MPU regions

Using BR(background region) during the flushing regions instead of
enabling/disabling the MPU which is a heavy operation.

Signed-off-by: Jaxson Han <jaxson.han@arm.com>
diff --git a/arch/arm64/core/cortex_r/arm_mpu.c b/arch/arm64/core/cortex_r/arm_mpu.c
index f849021..4575959 100644
--- a/arch/arm64/core/cortex_r/arm_mpu.c
+++ b/arch/arm64/core/cortex_r/arm_mpu.c
@@ -222,6 +222,28 @@
 static struct dynamic_region_info sys_dyn_regions[MPU_DYNAMIC_REGION_AREAS_NUM];
 static int sys_dyn_regions_num;
 
+static void arm_core_mpu_background_region_enable(void)
+{
+	uint64_t val;
+
+	val = read_sctlr_el1();
+	val |= SCTLR_BR_BIT;
+	write_sctlr_el1(val);
+	barrier_dsync_fence_full();
+	barrier_isync_fence_full();
+}
+
+static void arm_core_mpu_background_region_disable(void)
+{
+	uint64_t val;
+
+	val = read_sctlr_el1();
+	val &= ~SCTLR_BR_BIT;
+	write_sctlr_el1(val);
+	barrier_dsync_fence_full();
+	barrier_isync_fence_full();
+}
+
 static int dynamic_areas_init(uintptr_t start, size_t size)
 {
 	const struct arm_mpu_region *region;
@@ -474,9 +496,9 @@
 		region_num = (uint8_t)ret2;
 	}
 
-	arm_core_mpu_disable();
+	arm_core_mpu_background_region_enable();
 	ret = flush_dynamic_regions_to_mpu(dyn_regions, region_num);
-	arm_core_mpu_enable();
+	arm_core_mpu_background_region_disable();
 
 out:
 	return ret;
diff --git a/include/zephyr/arch/arm64/cpu.h b/include/zephyr/arch/arm64/cpu.h
index 3b30a80..bd29195 100644
--- a/include/zephyr/arch/arm64/cpu.h
+++ b/include/zephyr/arch/arm64/cpu.h
@@ -52,6 +52,7 @@
 #define SCTLR_C_BIT		BIT(2)
 #define SCTLR_SA_BIT		BIT(3)
 #define SCTLR_I_BIT		BIT(12)
+#define SCTLR_BR_BIT		BIT(17)
 
 #define CPACR_EL1_FPEN_NOTRAP	(0x3 << 20)