Index: kernel/arch/arm32/include/arch/barrier.h
===================================================================
--- kernel/arch/arm32/include/arch/barrier.h	(revision 8ca6f083cb43f60ec03821558bb3bc0c93603d87)
+++ kernel/arch/arm32/include/arch/barrier.h	(revision d5610b97cb04ef50092daf40ac8aaab0770e0199)
@@ -38,4 +38,5 @@
 
 #ifdef KERNEL
+#include <arch/cache.h>
 #include <arch/cp15.h>
 #else
@@ -71,8 +72,16 @@
  * CP15 implementation is mandatory only for armv6+.
  */
+#if defined(PROCESSOR_ARCH_armv6) || defined(PROCESSOR_ARCH_armv7_a)
 #define memory_barrier()  CP15DMB_write(0)
-#define read_barrier()    CP15DSB_write(0)
+#else
+#define memory_barrier()  CP15DSB_write(0)
+#endif
+#define read_barrier()    CP15DSB_write(0) 
 #define write_barrier()   read_barrier()
+#if defined(PROCESSOR_ARCH_armv6) || defined(PROCESSOR_ARCH_armv7_a)
 #define inst_barrier()    CP15ISB_write(0)
+#else
+#define inst_barrier()
+#endif
 #else
 /* Older manuals mention syscalls as a way to implement cache coherency and
@@ -103,12 +112,10 @@
 
 #if defined PROCESSOR_ARCH_armv7_a | defined PROCESSOR_ARCH_armv6 | defined KERNEL
-/* Available on all supported arms,
- * invalidates entire ICache so the written value does not matter. */
 //TODO might be PL1 only on armv5-
 #define smc_coherence(a) \
 do { \
-	DCCMVAU_write((uint32_t)(a));  /* Flush changed memory */\
+	dcache_clean_mva_pou((uintptr_t) a);\
 	write_barrier();               /* Wait for completion */\
-	ICIALLU_write(0);              /* Flush ICache */\
+	icache_invalidate();\
 	inst_barrier();                /* Wait for Inst refetch */\
 } while (0)
Index: kernel/arch/arm32/include/arch/cache.h
===================================================================
--- kernel/arch/arm32/include/arch/cache.h	(revision 8ca6f083cb43f60ec03821558bb3bc0c93603d87)
+++ kernel/arch/arm32/include/arch/cache.h	(revision d5610b97cb04ef50092daf40ac8aaab0770e0199)
@@ -37,4 +37,6 @@
 #define KERN_arm32_CACHE_H_
 
+#include <typedefs.h>
+
 unsigned dcache_levels(void);
 
@@ -43,5 +45,6 @@
 void cpu_dcache_flush(void);
 void cpu_dcache_flush_invalidate(void);
-void icache_invalidate(void);
+extern void icache_invalidate(void);
+extern void dcache_clean_mva_pou(uintptr_t);
 
 #endif
Index: kernel/arch/arm32/include/arch/cp15.h
===================================================================
--- kernel/arch/arm32/include/arch/cp15.h	(revision 8ca6f083cb43f60ec03821558bb3bc0c93603d87)
+++ kernel/arch/arm32/include/arch/cp15.h	(revision d5610b97cb04ef50092daf40ac8aaab0770e0199)
@@ -391,44 +391,114 @@
 CONTROL_REG_GEN_WRITE(HPFAR, c6, 4, c0, 4);
 
-/* Cache maintenance, address translation and other */
-CONTROL_REG_GEN_WRITE(WFI, c7, 0, c0, 4); /* armv6 only */
-CONTROL_REG_GEN_WRITE(ICIALLLUIS, c7, 0, c1, 0);
-CONTROL_REG_GEN_WRITE(BPIALLIS, c7, 0, c1, 6);
-CONTROL_REG_GEN_READ(PAR, c7, 0, c4, 0);
-CONTROL_REG_GEN_WRITE(PAR, c7, 0, c4, 0);
-CONTROL_REG_GEN_READ(PARH, c7, 0, c7, 0);   /* PAE */
-CONTROL_REG_GEN_WRITE(PARH, c7, 0, c7, 0);   /* PAE */
-CONTROL_REG_GEN_WRITE(ICIALLU, c7, 0, c5, 0);
-CONTROL_REG_GEN_WRITE(ICIMVAU, c7, 0, c5, 1);
+/*
+ * Cache maintenance, address translation and other
+ */
+
+#if defined(PROCESSOR_ARCH_armv6) || defined(PROCESSOR_ARCH_armv7_a)
 CONTROL_REG_GEN_WRITE(CP15ISB, c7, 0, c5, 4);
 CONTROL_REG_GEN_WRITE(BPIALL, c7, 0, c5, 6);
 CONTROL_REG_GEN_WRITE(BPIMVA, c7, 0, c5, 7);
-
+#endif
+
+#if !defined(PROCESSOR_arm920t)
+CONTROL_REG_GEN_WRITE(DCISW, c7, 0, c6, 2);
+#endif
+
+#if defined(PROCESSOR_arm920t) || !defined(PROCESSOR_ARCH_armv4)
+CONTROL_REG_GEN_WRITE(DCCSW, c7, 0, c10, 2);
+#endif
+
+CONTROL_REG_GEN_WRITE(CP15DSB, c7, 0, c10, 4);
+
+#if defined(PROCESSOR_ARCH_armv6) || defined(PROCESSOR_ARCH_armv7_a)
+CONTROL_REG_GEN_WRITE(CP15DMB, c7, 0, c10, 5);
+#endif
+
+#if defined(PROCESSOR_arm920t) || !defined(PROCESSOR_ARCH_armv4)
+CONTROL_REG_GEN_WRITE(DCCISW, c7, 0, c14, 2);
+#endif
+
+#if defined(PROCESSOR_ARCH_armv7_a)
+CONTROL_REG_GEN_WRITE(ICIALLLUIS, c7, 0, c1, 0);
+CONTROL_REG_GEN_WRITE(BPIALLIS, c7, 0, c1, 6);
+CONTROL_REG_GEN_READ(PAR, c7, 0, c4, 0); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(PAR, c7, 0, c4, 0); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ICIALLU, c7, 0, c5, 0);
+CONTROL_REG_GEN_WRITE(ICIMVAU, c7, 0, c5, 1);
 CONTROL_REG_GEN_WRITE(DCIMVAC, c7, 0, c6, 1);
-CONTROL_REG_GEN_WRITE(DCISW, c7, 0, c6, 2);
-
-CONTROL_REG_GEN_WRITE(ATS1CPR, c7, 0, c8, 0);
-CONTROL_REG_GEN_WRITE(ATS1CPW, c7, 0, c8, 1);
-CONTROL_REG_GEN_WRITE(ATS1CUR, c7, 0, c8, 2);
-CONTROL_REG_GEN_WRITE(ATS1CUW, c7, 0, c8, 3);
-CONTROL_REG_GEN_WRITE(ATS12NSOPR, c7, 0, c8, 4);
-CONTROL_REG_GEN_WRITE(ATS12NSOPW, c7, 0, c8, 5);
-CONTROL_REG_GEN_WRITE(ATS12NSOUR, c7, 0, c8, 6);
-CONTROL_REG_GEN_WRITE(ATS12NSOUW, c7, 0, c8, 7);
-
-
+CONTROL_REG_GEN_READ(PARH, c7, 0, c7, 0); /* PAE */
+CONTROL_REG_GEN_WRITE(PARH, c7, 0, c7, 0); /* PAE */
+CONTROL_REG_GEN_WRITE(ATS1CPR, c7, 0, c8, 0); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS1CPW, c7, 0, c8, 1); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS1CUR, c7, 0, c8, 2); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS1CUW, c7, 0, c8, 3); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS12NSOPR, c7, 0, c8, 4); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS12NSOPW, c7, 0, c8, 5); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS12NSOUR, c7, 0, c8, 6); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS12NSOUW, c7, 0, c8, 7); /* Security Extensions */
+CONTROL_REG_GEN_WRITE(ATS1HR, c7, 4, c8, 0); /* Virtualization Extensions */
+CONTROL_REG_GEN_WRITE(ATS1HW, c7, 4, c8, 1); /* Virtualization Extensions */
 CONTROL_REG_GEN_WRITE(DCCMVAC, c7, 0, c10, 1);
-CONTROL_REG_GEN_WRITE(DCCSW, c7, 0, c10, 2);
-CONTROL_REG_GEN_WRITE(CP15DSB, c7, 0, c10, 4);
-CONTROL_REG_GEN_WRITE(CP15DMB, c7, 0, c10, 5);
 CONTROL_REG_GEN_WRITE(DCCMVAU, c7, 0, c11, 1);
-
-CONTROL_REG_GEN_WRITE(PFI, c7, 0, c13, 1); /* armv6 only */
-
 CONTROL_REG_GEN_WRITE(DCCIMVAC, c7, 0, c14, 1);
-CONTROL_REG_GEN_WRITE(DCCISW, c7, 0, c14, 2);
-
-CONTROL_REG_GEN_WRITE(ATS1HR, c7, 4, c8, 0);
-CONTROL_REG_GEN_WRITE(ATS1HW, c7, 4, c8, 1);
+#else
+
+#if defined(PROCESSOR_arm920t) || !defined(PROCESSOR_ARCH_armv4)
+CONTROL_REG_GEN_WRITE(WFI, c7, 0, c0, 4);
+#endif
+
+CONTROL_REG_GEN_WRITE(ICIALL, c7, 0, c5, 0);
+CONTROL_REG_GEN_WRITE(ICIMVA, c7, 0, c5, 1);
+
+#if !defined(PROCESSOR_ARCH_armv4)
+CONTROL_REG_GEN_WRITE(ICISW, c7, 0, c5, 2);
+#endif
+
+CONTROL_REG_GEN_WRITE(DCIALL, c7, 0, c6, 0);
+CONTROL_REG_GEN_WRITE(DCIMVA, c7, 0, c6, 1);
+CONTROL_REG_GEN_WRITE(CIALL, c7, 0, c7, 0);
+CONTROL_REG_GEN_WRITE(CIMVA, c7, 0, c7, 1);
+
+#if !defined(PROCESSOR_ARCH_armv4)
+CONTROL_REG_GEN_WRITE(CISW, c7, 0, c7, 2);
+#endif
+
+#if defined(PROCESSOR_ARCH_armv4) || defined(PROCESSOR_ARCH_armv6)
+CONTROL_REG_GEN_WRITE(DCCALL, c7, 0, c10, 0);
+#endif
+
+CONTROL_REG_GEN_WRITE(DCCMVA, c7, 0, c10, 1);
+
+#if defined(PROCESSOR_ARCH_armv4) || defined(PROCESSOR_ARCH_armv6)
+CONTROL_REG_GEN_WRITE(CCALL, c7, 0, c11, 0);
+#endif
+
+CONTROL_REG_GEN_WRITE(CCMVA, c7, 0, c11, 1);
+
+#if !defined(PROCESSOR_ARCH_armv4)
+CONTROL_REG_GEN_WRITE(CCSW, c7, 0, c11, 2);
+#endif
+
+#if defined(PROCESSOR_arm920t) || !defined(PROCESSOR_ARCH_armv4)
+CONTROL_REG_GEN_WRITE(PFIMVA, c7, 0, c13, 1);
+#endif
+
+#if defined(PROCESSOR_ARCH_armv4) || defined(PROCESSOR_ARCH_armv6)
+CONTROL_REG_GEN_WRITE(DCCIALL, c7, 0, c14, 0);
+#endif
+
+CONTROL_REG_GEN_WRITE(DCCIMVA, c7, 0, c14, 1);
+
+#if defined(PROCESSOR_ARCH_armv4) || defined(PROCESSOR_ARCH_armv6)
+CONTROL_REG_GEN_WRITE(CCIALL, c7, 0, c15, 0);
+#endif
+
+CONTROL_REG_GEN_WRITE(CCIMVA, c7, 0, c15, 1);
+
+#if defined(PROCESSOR_ARCH_armv5) || defined(PROCESSOR_ARCH_armv6)
+CONTROL_REG_GEN_WRITE(CCISW, c7, 0, c15, 2);
+#endif
+
+#endif
 
 /* TLB maintenance */
Index: kernel/arch/arm32/include/arch/mm/page_armv4.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page_armv4.h	(revision 8ca6f083cb43f60ec03821558bb3bc0c93603d87)
+++ kernel/arch/arm32/include/arch/mm/page_armv4.h	(revision d5610b97cb04ef50092daf40ac8aaab0770e0199)
@@ -123,5 +123,5 @@
 do { \
 	for (unsigned i = 0; i < count; ++i) \
-		DCCMVAU_write((uintptr_t)(pt + i)); \
+		dcache_clean_mva_pou((uintptr_t)(pt + i)); \
 	read_barrier(); \
 } while (0)
Index: kernel/arch/arm32/include/arch/mm/page_armv6.h
===================================================================
--- kernel/arch/arm32/include/arch/mm/page_armv6.h	(revision 8ca6f083cb43f60ec03821558bb3bc0c93603d87)
+++ kernel/arch/arm32/include/arch/mm/page_armv6.h	(revision d5610b97cb04ef50092daf40ac8aaab0770e0199)
@@ -156,8 +156,7 @@
 do { \
 	for (unsigned i = 0; i < count; ++i) \
-		DCCMVAU_write((uintptr_t)(pt + i)); \
+		dcache_clean_mva_pou((uintptr_t)(pt + i)); \
 	read_barrier(); \
 } while (0)
-
 
 /** Returns level 0 page table entry flags.
Index: kernel/arch/arm32/src/cpu/cpu.c
===================================================================
--- kernel/arch/arm32/src/cpu/cpu.c	(revision 8ca6f083cb43f60ec03821558bb3bc0c93603d87)
+++ kernel/arch/arm32/src/cpu/cpu.c	(revision d5610b97cb04ef50092daf40ac8aaab0770e0199)
@@ -322,5 +322,33 @@
 void icache_invalidate(void)
 {
+#if defined(PROCESSOR_ARCH_armv7_a)
 	ICIALLU_write(0);
+#else
+	ICIALL_write(0);
+#endif
+}
+
+#if !defined(PROCESSOR_ARCH_armv7_a)
+static bool cache_is_unified(void)
+{
+	if (MIDR_read() != CTR_read()) {
+		/* We have the CTR register */
+		return (CTR_read() & CTR_SEP_FLAG) != CTR_SEP_FLAG;
+	} else {
+		panic("Unknown cache type");
+	}
+}
+#endif
+
+void dcache_clean_mva_pou(uintptr_t mva)
+{
+#if defined(PROCESSOR_ARCH_armv7_a)
+	DCCMVAU_write(mva);
+#else
+	if (cache_is_unified())
+		CCMVA_write(mva);
+	else
+		DCCMVA_write(mva);
+#endif
 }
 
