arch: arm: Fix MMU disable function
Use dsb barrier before disabling the mmu to ensure all memory
accesses have completed. Also as per arm reference manual use
isb & dsb barriers for tlb invalidate & mmu enable, disable
functions.
CRs-Fixed: 514600
Change-Id: I7f9a041189cbf87c9b41ebefba07893b2798f037
diff --git a/arch/arm/include/arch/defines.h b/arch/arm/include/arch/defines.h
index 2041f39..d08988e 100644
--- a/arch/arm/include/arch/defines.h
+++ b/arch/arm/include/arch/defines.h
@@ -41,5 +41,12 @@
#endif
#define IS_CACHE_LINE_ALIGNED(addr) !((uint32_t) (addr) & (CACHE_LINE - 1))
+
+#if ARM_ISA_ARMV7
+#define dsb() __asm__ volatile ("dsb" : : : "memory");
+#elif ARM_ISA_ARMV6
+#define dsb() __asm__ volatile ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0): "memory");
+#endif
+
#endif
diff --git a/arch/arm/mmu.c b/arch/arm/mmu.c
index 3fc61bf..2027b41 100644
--- a/arch/arm/mmu.c
+++ b/arch/arm/mmu.c
@@ -25,6 +25,7 @@
#include <compiler.h>
#include <arch.h>
#include <arch/arm.h>
+#include <arch/defines.h>
#include <arch/arm/mmu.h>
#if ARM_WITH_MMU
@@ -94,6 +95,10 @@
void arch_disable_mmu(void)
{
+ /* Ensure all memory access are complete
+ * before disabling MMU
+ */
+ dsb();
arm_write_cr1(arm_read_cr1() & ~(1<<0));
arm_invalidate_tlb();
}
diff --git a/arch/arm/ops.S b/arch/arm/ops.S
index 2581273..6b9d966 100644
--- a/arch/arm/ops.S
+++ b/arch/arm/ops.S
@@ -209,6 +209,12 @@
/* void arm_write_cr1(uint32_t val) */
FUNCTION(arm_write_cr1)
mcr p15, 0, r0, c1, c0, 0
+#if ARM_CPU_CORTEX_A8
+ isb sy
+#elif ARM_CPU_ARM1136
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 4
+#endif
bx lr
/* uint32_t arm_read_cr1_aux(void) */
@@ -235,6 +241,18 @@
FUNCTION(arm_invalidate_tlb)
mov r0, #0
mcr p15, 0, r0, c8, c7, 0
+#if ARM_CPU_CORTEX_A8
+ dsb sy
+#elif ARM_CPU_ARM1136
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4
+#endif
+#if ARM_CPU_CORTEX_A8
+ isb sy
+#elif ARM_CPU_ARM1136
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 4
+#endif
bx lr
/* void arch_switch_stacks_and_call(addr_t call, addr_t stack) */
@@ -252,26 +270,6 @@
#endif
bx lr
-/*void isb(void) */
-FUNCTION(isb)
-#if ARM_CPU_CORTEX_A8
- isb sy
-#elif ARM_CPU_ARM1136
- mov r0, #0
- mcr p15, 0, r0, c7, c5, 4
-#endif
- bx lr
-
-/*void dsb(void) */
-FUNCTION(dsb)
-#if ARM_CPU_CORTEX_A8
- dsb sy
-#elif ARM_CPU_ARM1136
- mov r0, #0
- mcr p15, 0, r0, c7, c10, 4
-#endif
- bx lr
-
/* uint32_t arm_read_cycle_count(void); */
FUNCTION(arm_read_cycle_count)