AArch32: Add BL2U support

Add support for firmware upgrade on AArch32.
This patch has been tested on the FVP models.

NOTE: Firmware upgrade on Juno AArch32 is not currently supported.

Change-Id: I1ca8078214eaf86b46463edd14740120af930aec
Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
Co-Authored-By: Yatharth Kochar <yatharth.kochar@arm.com>
diff --git a/Makefile b/Makefile
index 78860b3..ddf8756 100644
--- a/Makefile
+++ b/Makefile
@@ -396,13 +396,13 @@
 include bl2/bl2.mk
 endif
 
-# For AArch32, BL31 is not applicable, and BL2U is not supported at present.
-ifneq (${ARCH},aarch32)
 ifdef BL2U_SOURCES
 NEED_BL2U := yes
 include bl2u/bl2u.mk
 endif
 
+# For AArch32, BL31 is not currently supported.
+ifneq (${ARCH},aarch32)
 ifdef BL31_SOURCES
 # When booting an EL3 payload, there is no need to compile the BL31 image nor
 # put it in the FIP.
diff --git a/bl2u/aarch32/bl2u_entrypoint.S b/bl2u/aarch32/bl2u_entrypoint.S
new file mode 100644
index 0000000..1fa669e
--- /dev/null
+++ b/bl2u/aarch32/bl2u_entrypoint.S
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+
+
+	.globl	bl2u_vector_table
+	.globl	bl2u_entrypoint
+
+
+vector_base bl2u_vector_table
+	b	bl2u_entrypoint
+	b	report_exception	/* Undef */
+	b	report_exception	/* SVC call */
+	b	report_exception	/* Prefetch abort */
+	b	report_exception	/* Data abort */
+	b	report_exception	/* Reserved */
+	b	report_exception	/* IRQ */
+	b	report_exception	/* FIQ */
+
+
+func bl2u_entrypoint
+	/*---------------------------------------------
+	 * Save from r1 the extents of the trusted ram
+	 * available to BL2U for future use.
+	 * r0 is not currently used.
+	 * ---------------------------------------------
+	 */
+	mov	r11, r1
+	mov	r12, r2
+
+	/* ---------------------------------------------
+	 * Set the exception vector to something sane.
+	 * ---------------------------------------------
+	 */
+	ldr	r0, =bl2u_vector_table
+	stcopr	r0, VBAR
+	isb
+
+	/* -----------------------------------------------------
+	 * Enable the instruction cache
+	 * -----------------------------------------------------
+	 */
+	ldcopr	r0, SCTLR
+	orr	r0, r0, #SCTLR_I_BIT
+	stcopr	r0, SCTLR
+	isb
+
+	/* ---------------------------------------------
+	 * Since BL2U executes after BL1, it is assumed
+	 * here that BL1 has already has done the
+	 * necessary register initializations.
+	 * ---------------------------------------------
+	 */
+
+	/* ---------------------------------------------
+	 * Invalidate the RW memory used by the BL2U
+	 * image. This includes the data and NOBITS
+	 * sections. This is done to safeguard against
+	 * possible corruption of this memory by dirty
+	 * cache lines in a system cache as a result of
+	 * use by an earlier boot loader stage.
+	 * ---------------------------------------------
+	 */
+	ldr	r0, =__RW_START__
+	ldr	r1, =__RW_END__
+	sub	r1, r1, r0
+	bl	inv_dcache_range
+
+	/* ---------------------------------------------
+	 * Zero out NOBITS sections. There are 2 of them:
+	 *   - the .bss section;
+	 *   - the coherent memory section.
+	 * ---------------------------------------------
+	 */
+	ldr	r0, =__BSS_START__
+	ldr	r1, =__BSS_SIZE__
+	bl	zeromem
+
+	/* --------------------------------------------
+	 * Allocate a stack whose memory will be marked
+	 * as Normal-IS-WBWA when the MMU is enabled.
+	 * There is no risk of reading stale stack
+	 * memory after enabling the MMU as only the
+	 * primary cpu is running at the moment.
+	 * --------------------------------------------
+	 */
+	bl	plat_set_my_stack
+
+	/* ---------------------------------------------
+	 * Initialize the stack protector canary before
+	 * any C code is called.
+	 * ---------------------------------------------
+	 */
+#if STACK_PROTECTOR_ENABLED
+	bl	update_stack_protector_canary
+#endif
+
+	/* ---------------------------------------------
+	 * Perform early platform setup & platform
+	 * specific early arch. setup e.g. mmu setup
+	 * ---------------------------------------------
+	 */
+	mov	r0, r11
+	mov	r1, r12
+	bl	bl2u_early_platform_setup
+	bl	bl2u_plat_arch_setup
+
+	/* ---------------------------------------------
+	 * Jump to main function.
+	 * ---------------------------------------------
+	 */
+	bl	bl2u_main
+
+	/* ---------------------------------------------
+	 * Should never reach this point.
+	 * ---------------------------------------------
+	 */
+	no_ret	plat_panic_handler
+
+endfunc bl2u_entrypoint
diff --git a/bl2u/bl2u.mk b/bl2u/bl2u.mk
index 7780f49..b4d7634 100644
--- a/bl2u/bl2u.mk
+++ b/bl2u/bl2u.mk
@@ -5,8 +5,11 @@
 #
 
 BL2U_SOURCES		+=	bl2u/bl2u_main.c			\
-				bl2u/aarch64/bl2u_entrypoint.S		\
-				common/aarch64/early_exceptions.S	\
-				plat/common/aarch64/platform_up_stack.S
+				bl2u/${ARCH}/bl2u_entrypoint.S		\
+				plat/common/${ARCH}/platform_up_stack.S
+
+ifeq (${ARCH},aarch64)
+BL2U_SOURCES		+=	common/aarch64/early_exceptions.S
+endif
 
 BL2U_LINKERFILE		:=	bl2u/bl2u.ld.S
diff --git a/bl2u/bl2u_main.c b/bl2u/bl2u_main.c
index 2504668..820da10 100644
--- a/bl2u/bl2u_main.c
+++ b/bl2u/bl2u_main.c
@@ -42,6 +42,15 @@
 
 	console_flush();
 
+#ifdef AARCH32
+	/*
+	 * For AArch32 state BL1 and BL2U share the MMU setup.
+	 * Given that BL2U does not map BL1 regions, MMU needs
+	 * to be disabled in order to go back to BL1.
+	 */
+	disable_mmu_icache_secure();
+#endif /* AARCH32 */
+
 	/*
 	 * Indicate that BL2U is done and resume back to
 	 * normal world via an SMC to BL1.
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 23e7867..ea30954 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -311,9 +311,15 @@
  * FWU Images: NS_BL1U, BL2U & NS_BL2U defines.
  ******************************************************************************/
 #define BL2U_BASE			BL2_BASE
-#if ARM_BL31_IN_DRAM
+#if ARM_BL31_IN_DRAM || defined(AARCH32)
+/*
+ * For AArch32 BL31 is not applicable.
+ * For AArch64 BL31 is loaded in the DRAM.
+ * BL2U extends up to BL1.
+ */
 #define BL2U_LIMIT			BL1_RW_BASE
 #else
+/* BL2U extends up to BL31. */
 #define BL2U_LIMIT			BL31_BASE
 #endif
 #define NS_BL2U_BASE			ARM_NS_DRAM1_BASE
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index d09a00d..5dc9eea 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -68,7 +68,11 @@
 			      BL_COHERENT_RAM_END
 #endif
 		);
+#ifdef AARCH32
+	enable_mmu_secure(0);
+#else
 	enable_mmu_el1(0);
+#endif
 }
 
 void bl2u_plat_arch_setup(void)