Index: boot/arch/arm32/include/mm.h
===================================================================
--- boot/arch/arm32/include/mm.h	(revision b55877d41311cafdacbe0aa0189cc1695c1f3311)
+++ boot/arch/arm32/include/mm.h	(revision b5a3b50c5e0e757d7f292db4541d06a2e1c042d6)
@@ -47,7 +47,14 @@
 /** Describe "section" page table entry (one-level paging with 1 MB sized pages). */
 #define PTE_DESCRIPTOR_SECTION  0x02
+/** Shift of memory address in section descriptor */
+#define PTE_SECTION_SHIFT  20
 
 /** Page table access rights: user - no access, kernel - read/write. */
 #define PTE_AP_USER_NO_KERNEL_RW  0x01
+
+/** Start of memory mapped I/O area for GTA02 */
+#define GTA02_IOMEM_START  0x48000000
+/** End of memory mapped I/O area for GTA02 */
+#define GTA02_IOMEM_END  0x60000000
 
 /* Page table level 0 entry - "section" format is used
Index: boot/arch/arm32/src/asm.S
===================================================================
--- boot/arch/arm32/src/asm.S	(revision b55877d41311cafdacbe0aa0189cc1695c1f3311)
+++ boot/arch/arm32/src/asm.S	(revision b5a3b50c5e0e757d7f292db4541d06a2e1c042d6)
@@ -60,3 +60,40 @@
 	# before passing control to the copied code.
 	#
+
+#if defined(MACHINE_gta02)
+
+#define CP15_C1_IC		12
+#define CP15_C1_DC		2
+#define CP15_C7_SEG_SHIFT	5
+#define CP15_C7_SEG_SIZE	3
+#define CP15_C7_IDX_SHIFT	26
+
+	# Disable I-cache and D-cache before the kernel is started.
+	mrc	p15, 0, r4, c1, c0, 0
+	bic	r4, r4, #(1 << CP15_C1_DC)
+	bic	r4, r4, #(1 << CP15_C1_IC)
+	mcr	p15, 0, r4, c1, c0, 0
+
+	# Now clean D-cache to guarantee coherency between I-cache and D-cache.
+
+	# D-cache clean and invalidate procedure.
+	# See ARM920T TRM pages 2-17, 4-17.
+
+	# Initialize segment
+	mov	r4, #0
+	# Initialize index
+1:	mov	r5, #0
+2:	orr	r6, r4, r5
+	# Clean and invalidate a single line
+	mcr	p15, 0, r6, c7, c10, 2
+	# Increment index
+	add	r5, r5, #(1 << CP15_C7_IDX_SHIFT)
+	cmp	r5, #0
+	bne	2b
+	# Increment segment
+	add	r4, #(1 << CP15_C7_SEG_SHIFT)
+	tst	r4, #(1 << (CP15_C7_SEG_SHIFT + CP15_C7_SEG_SIZE))
+	beq	1b
+#endif
+
 	mov pc, r0
Index: boot/arch/arm32/src/mm.c
===================================================================
--- boot/arch/arm32/src/mm.c	(revision b55877d41311cafdacbe0aa0189cc1695c1f3311)
+++ boot/arch/arm32/src/mm.c	(revision b5a3b50c5e0e757d7f292db4541d06a2e1c042d6)
@@ -38,4 +38,27 @@
 #include <arch/mm.h>
 
+/** Check if caching can be enabled for a given memory section.
+ *
+ * Memory areas used for I/O are excluded from caching.
+ * At the moment caching is enabled only on GTA02.
+ *
+ * @param section	The section number.
+ *
+ * @return	1 if the given section can be mapped as cacheable, 0 otherwise.
+*/
+static inline int section_cacheable(pfn_t section)
+{
+#ifdef MACHINE_gta02
+	unsigned long address = section << PTE_SECTION_SHIFT;
+
+	if (address >= GTA02_IOMEM_START && address < GTA02_IOMEM_END)
+		return 0;
+	else
+		return 1;
+#else
+	return 0;
+#endif
+}
+
 /** Initialize "section" page table entry.
  *
@@ -55,5 +78,5 @@
 	pte->descriptor_type = PTE_DESCRIPTOR_SECTION;
 	pte->bufferable = 1;
-	pte->cacheable = 0;
+	pte->cacheable = section_cacheable(frame);
 	pte->xn = 0;
 	pte->domain = 0;
@@ -123,6 +146,12 @@
 		"ldr r1, =0x00000005\n"
 #else
+#ifdef MACHINE_gta02
+		/* Mask to enable paging (bit 0),
+		   D-cache (bit 2), I-cache (bit 12) */
+		"ldr r1, =0x00001005\n"
+#else
 		/* Mask to enable paging */
 		"ldr r1, =0x00000001\n"
+#endif
 #endif
 		"orr r0, r0, r1\n"
