Merge pull request #453 from yatharth-arm/yk/fwu-6

Firmware Update patch stack
diff --git a/Makefile b/Makefile
index 0c3303f..ae9b41b 100644
--- a/Makefile
+++ b/Makefile
@@ -76,6 +76,8 @@
 PSCI_EXTENDED_STATE_ID		:= 0
 # Default FIP file name
 FIP_NAME			:= fip.bin
+# Default FWU_FIP file name
+FWU_FIP_NAME			:= fwu_fip.bin
 # By default, use the -pedantic option in the gcc command line
 DISABLE_PEDANTIC		:= 0
 # Flags to generate the Chain of Trust
@@ -150,6 +152,7 @@
 # target 'certificates' to create them all
 ifneq (${GENERATE_COT},0)
         FIP_DEPS += certificates
+        FWU_FIP_DEPS += fwu_certificates
 endif
 
 
@@ -195,7 +198,8 @@
 				lib/stdlib/std.c			\
 				plat/common/aarch64/platform_helpers.S
 
-INCLUDES		+=	-Iinclude/bl31			\
+INCLUDES		+=	-Iinclude/bl1			\
+				-Iinclude/bl31			\
 				-Iinclude/bl31/services		\
 				-Iinclude/common		\
 				-Iinclude/drivers		\
@@ -320,8 +324,10 @@
         # Common cert_create options
         ifneq (${CREATE_KEYS},0)
                 $(eval CRT_ARGS += -n)
+                $(eval FWU_CRT_ARGS += -n)
                 ifneq (${SAVE_KEYS},0)
                         $(eval CRT_ARGS += -k)
+                        $(eval FWU_CRT_ARGS += -k)
                 endif
         endif
         # Include TBBR makefile (unless the platform indicates otherwise)
@@ -409,6 +415,11 @@
 include bl2/bl2.mk
 endif
 
+ifdef BL2U_SOURCES
+NEED_BL2U := yes
+include bl2u/bl2u.mk
+endif
+
 ifdef BL31_SOURCES
 # When booting an EL3 payload, there is no need to compile the BL31 image nor
 # put it in the FIP.
@@ -423,7 +434,7 @@
 # Build targets
 ################################################################################
 
-.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip certtool
+.PHONY:	all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip fwu_fip certtool
 .SUFFIXES:
 
 all: msg_start
@@ -466,6 +477,12 @@
 $(eval $(call FIP_ADD_IMG,BL33,--bl33))
 endif
 
+ifeq (${NEED_BL2U},yes)
+BL2U_PATH	:= $(if ${BL2U},${BL2U},$(call IMG_BIN,2u))
+$(if ${BL2U}, ,$(eval $(call MAKE_BL,2u)))
+$(eval $(call FWU_FIP_ADD_PAYLOAD,${BL2U_PATH},--bl2u))
+endif
+
 locate-checkpatch:
 ifndef CHECKPATCH
 	$(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/script/checkpatch.pl")
@@ -524,8 +541,24 @@
 	@echo "Built $@ successfully"
 	@echo
 
+ifneq (${GENERATE_COT},0)
+fwu_certificates: ${FWU_CRT_DEPS} ${CRTTOOL}
+	${Q}${CRTTOOL} ${FWU_CRT_ARGS}
+	@echo
+	@echo "Built $@ successfully"
+	@echo "FWU certificates can be found in ${BUILD_PLAT}"
+	@echo
+endif
+
+${BUILD_PLAT}/${FWU_FIP_NAME}: ${FWU_FIP_DEPS} ${FIPTOOL}
+	${Q}${FIPTOOL} --dump ${FWU_FIP_ARGS} $@
+	@echo
+	@echo "Built $@ successfully"
+	@echo
+
 fiptool: ${FIPTOOL}
 fip: ${BUILD_PLAT}/${FIP_NAME}
+fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME}
 
 .PHONY: ${FIPTOOL}
 ${FIPTOOL}:
@@ -551,10 +584,12 @@
 	@echo "  all            Build all individual bootloader binaries"
 	@echo "  bl1            Build the BL1 binary"
 	@echo "  bl2            Build the BL2 binary"
+	@echo "  bl2u           Build the BL2U binary"
 	@echo "  bl31           Build the BL3-1 binary"
 	@echo "  bl32           Build the BL3-2 binary"
 	@echo "  certificates   Build the certificates (requires 'GENERATE_COT=1')"
 	@echo "  fip            Build the Firmware Image Package (FIP)"
+	@echo "  fwu_fip        Build the FWU Firmware Image Package (FIP)"
 	@echo "  checkcodebase  Check the coding style of the entire source tree"
 	@echo "  checkpatch     Check the coding style on changes in the current"
 	@echo "                 branch against BASE_COMMIT (default origin/master)"
diff --git a/bl1/aarch64/bl1_entrypoint.S b/bl1/aarch64/bl1_entrypoint.S
index 83594f2..ce27752 100644
--- a/bl1/aarch64/bl1_entrypoint.S
+++ b/bl1/aarch64/bl1_entrypoint.S
@@ -69,10 +69,14 @@
 
 	/* --------------------------------------------------
 	 * Initialize platform and jump to our c-entry point
-	 * for this type of reset. Panic if it returns
+	 * for this type of reset.
 	 * --------------------------------------------------
 	 */
 	bl	bl1_main
-panic:
-	b	panic
+
+	/* --------------------------------------------------
+	 * Do the transition to next boot image.
+	 * --------------------------------------------------
+	 */
+	b	el3_exit
 endfunc bl1_entrypoint
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S
index 5415d39..9ff6a57 100644
--- a/bl1/aarch64/bl1_exceptions.S
+++ b/bl1/aarch64/bl1_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -31,7 +31,8 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <bl_common.h>
-#include <runtime_svc.h>
+#include <bl1.h>
+#include <context.h>
 
 	.globl	bl1_exceptions
 
@@ -115,10 +116,12 @@
 	/* Enable the SError interrupt */
 	msr	daifclr, #DAIF_ABT_BIT
 
+	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
 	/* Expect only SMC exceptions */
-	mrs	x19, esr_el3
-	ubfx	x20, x19, #ESR_EC_SHIFT, #ESR_EC_LENGTH
-	cmp	x20, #EC_AARCH64_SMC
+	mrs	x30, esr_el3
+	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+	cmp	x30, #EC_AARCH64_SMC
 	b.ne	unexpected_sync_exception
 
 	b	smc_handler64
@@ -179,21 +182,40 @@
 
 
 func smc_handler64
+
+	/* ----------------------------------------------
+	 * Detect if this is a RUN_IMAGE or other SMC.
+	 * ----------------------------------------------
+	 */
+	mov	x30, #BL1_SMC_RUN_IMAGE
+	cmp	x30, x0
+	b.ne	smc_handler
+
+	/* ------------------------------------------------
+	 * Make sure only Secure world reaches here.
+	 * ------------------------------------------------
+	 */
+	mrs	x30, scr_el3
+	tst	x30, #SCR_NS_BIT
+	b.ne	unexpected_sync_exception
+
+	/* ----------------------------------------------
+	 * Handling RUN_IMAGE SMC. First switch back to
+	 * SP_EL0 for the C runtime stack.
+	 * ----------------------------------------------
+	 */
+	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+	msr	spsel, #0
+	mov	sp, x30
+
 	/* ---------------------------------------------------------------------
-	 * Only a single SMC exception from BL2 to ask BL1 to pass EL3 control
-	 * to BL31 is expected here. It expects:
-	 *   - X0 with RUN_IMAGE SMC function ID;
-	 *   - X1 with the address of a entry_point_info_t structure describing
-	 *     the BL31 entrypoint.
+	 * Pass EL3 control to BL31.
+	 * Here it expects X1 with the address of a entry_point_info_t
+	 * structure describing the BL31 entrypoint.
 	 * ---------------------------------------------------------------------
 	 */
-	mov	x19, x0
 	mov	x20, x1
 
-	mov	x0, #RUN_IMAGE
-	cmp	x19, x0
-	b.ne	unexpected_sync_exception
-
 	mov	x0, x20
 	bl	bl1_print_bl31_ep_info
 
@@ -228,3 +250,69 @@
 	bl	plat_report_exception
 	wfi
 	b	unexpected_sync_exception
+
+	/* -----------------------------------------------------
+	 * Save Secure/Normal world context and jump to
+	 * BL1 SMC handler.
+	 * -----------------------------------------------------
+	 */
+smc_handler:
+	/* -----------------------------------------------------
+	 * Save the GP registers x0-x29.
+	 * TODO: Revisit to store only SMCC specified registers.
+	 * -----------------------------------------------------
+	 */
+	bl	save_gp_registers
+
+	/* -----------------------------------------------------
+	 * Populate the parameters for the SMC handler. We
+	 * already have x0-x4 in place. x5 will point to a
+	 * cookie (not used now). x6 will point to the context
+	 * structure (SP_EL3) and x7 will contain flags we need
+	 * to pass to the handler.
+	 * -----------------------------------------------------
+	 */
+	mov	x5, xzr
+	mov	x6, sp
+
+	/* -----------------------------------------------------
+	 * Restore the saved C runtime stack value which will
+	 * become the new SP_EL0 i.e. EL3 runtime stack. It was
+	 * saved in the 'cpu_context' structure prior to the last
+	 * ERET from EL3.
+	 * -----------------------------------------------------
+	 */
+	ldr	x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+
+	/* ---------------------------------------------
+	 * Switch back to SP_EL0 for the C runtime stack.
+	 * ---------------------------------------------
+	 */
+	msr	spsel, #0
+	mov	sp, x12
+
+	/* -----------------------------------------------------
+	 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there
+	 * is a world switch during SMC handling.
+	 * -----------------------------------------------------
+	 */
+	mrs	x16, spsr_el3
+	mrs	x17, elr_el3
+	mrs	x18, scr_el3
+	stp	x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+	str	x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+
+	/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
+	bfi	x7, x18, #0, #1
+
+	/* -----------------------------------------------------
+	 * Go to BL1 SMC handler.
+	 * -----------------------------------------------------
+	 */
+	bl	bl1_smc_handler
+
+	/* -----------------------------------------------------
+	 * Do the transition to next BL image.
+	 * -----------------------------------------------------
+	 */
+	b	el3_exit
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 8e73bef..21e87c7 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions are met:
@@ -32,6 +32,14 @@
 				bl1/aarch64/bl1_arch_setup.c		\
 				bl1/aarch64/bl1_entrypoint.S		\
 				bl1/aarch64/bl1_exceptions.S		\
-				lib/cpus/aarch64/cpu_helpers.S
+				bl1/bl1_context_mgmt.c			\
+				common/aarch64/context.S		\
+				common/context_mgmt.c			\
+				lib/cpus/aarch64/cpu_helpers.S		\
+				plat/common/plat_bl1_common.c
+
+ifeq (${TRUSTED_BOARD_BOOT},1)
+BL1_SOURCES		+=	bl1/bl1_fwu.c
+endif
 
 BL1_LINKERFILE		:=	bl1/bl1.ld.S
diff --git a/bl1/bl1_context_mgmt.c b/bl1/bl1_context_mgmt.c
new file mode 100644
index 0000000..6355190
--- /dev/null
+++ b/bl1/bl1_context_mgmt.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <platform.h>
+
+/*
+ * Following array will be used for context management.
+ * There are 2 instances, for the Secure and Non-Secure contexts.
+ */
+static cpu_context_t bl1_cpu_context[2];
+
+/* Following contains the cpu context pointers. */
+static void *bl1_cpu_context_ptr[2];
+
+
+void *cm_get_context(uint32_t security_state)
+{
+	assert(sec_state_is_valid(security_state));
+	return bl1_cpu_context_ptr[security_state];
+}
+
+void cm_set_context(void *context, uint32_t security_state)
+{
+	assert(sec_state_is_valid(security_state));
+	bl1_cpu_context_ptr[security_state] = context;
+}
+
+/*******************************************************************************
+ * This function prepares the context for Secure/Normal world images.
+ * Normal world images are transitioned to EL2(if supported) else EL1.
+ ******************************************************************************/
+void bl1_prepare_next_image(unsigned int image_id)
+{
+	unsigned int security_state;
+	image_desc_t *image_desc;
+	entry_point_info_t *next_bl_ep;
+
+	/* Get the image descriptor. */
+	image_desc = bl1_plat_get_image_desc(image_id);
+	assert(image_desc);
+
+	/* Get the entry point info. */
+	next_bl_ep = &image_desc->ep_info;
+
+	/* Get the image security state. */
+	security_state = GET_SEC_STATE(next_bl_ep->h.attr);
+
+	/* Setup the Secure/Non-Secure context if not done already. */
+	if (!cm_get_context(security_state))
+		cm_set_context(&bl1_cpu_context[security_state], security_state);
+
+	/* Prepare the SPSR for the next BL image. */
+	if (security_state == SECURE) {
+		next_bl_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+				   DISABLE_ALL_EXCEPTIONS);
+	} else {
+		/* Use EL2 if supported else use EL1. */
+		if (read_id_aa64pfr0_el1() &
+			(ID_AA64PFR0_ELX_MASK << ID_AA64PFR0_EL2_SHIFT)) {
+			next_bl_ep->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+				DISABLE_ALL_EXCEPTIONS);
+		} else {
+			next_bl_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+			   DISABLE_ALL_EXCEPTIONS);
+		}
+	}
+
+	/* Allow platform to make change */
+	bl1_plat_set_ep_info(image_id, next_bl_ep);
+
+	/* Prepare the context for the next BL image. */
+	cm_init_my_context(next_bl_ep);
+	cm_prepare_el3_exit(security_state);
+
+	/* Indicate that image is in execution state. */
+	image_desc->state = IMAGE_STATE_EXECUTED;
+
+	print_entry_point_info(next_bl_ep);
+}
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
new file mode 100644
index 0000000..f8b414e
--- /dev/null
+++ b/bl1/bl1_fwu.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <arch_helpers.h>
+#include <auth_mod.h>
+#include <bl1.h>
+#include <bl_common.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <errno.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <smcc_helpers.h>
+#include <string.h>
+#include "bl1_private.h"
+
+/*
+ * Function declarations.
+ */
+static int bl1_fwu_image_copy(unsigned int image_id,
+			uintptr_t image_addr,
+			unsigned int block_size,
+			unsigned int image_size,
+			unsigned int flags);
+static int bl1_fwu_image_auth(unsigned int image_id,
+			uintptr_t image_addr,
+			unsigned int image_size,
+			unsigned int flags);
+static int bl1_fwu_image_execute(unsigned int image_id,
+			void **handle,
+			unsigned int flags);
+static register_t bl1_fwu_image_resume(unsigned int image_id,
+			register_t image_param,
+			void **handle,
+			unsigned int flags);
+static int bl1_fwu_sec_image_done(void **handle,
+			unsigned int flags);
+__dead2 static void bl1_fwu_done(void *cookie, void *reserved);
+
+/*
+ * This keeps track of last executed secure image id.
+ */
+static unsigned int sec_exec_image_id = INVALID_IMAGE_ID;
+
+/*******************************************************************************
+ * Top level handler for servicing FWU SMCs.
+ ******************************************************************************/
+register_t bl1_fwu_smc_handler(unsigned int smc_fid,
+			register_t x1,
+			register_t x2,
+			register_t x3,
+			register_t x4,
+			void *cookie,
+			void *handle,
+			unsigned int flags)
+{
+
+	switch (smc_fid) {
+	case FWU_SMC_IMAGE_COPY:
+		SMC_RET1(handle, bl1_fwu_image_copy(x1, x2, x3, x4, flags));
+
+	case FWU_SMC_IMAGE_AUTH:
+		SMC_RET1(handle, bl1_fwu_image_auth(x1, x2, x3, flags));
+
+	case FWU_SMC_IMAGE_EXECUTE:
+		SMC_RET1(handle, bl1_fwu_image_execute(x1, &handle, flags));
+
+	case FWU_SMC_IMAGE_RESUME:
+		SMC_RET1(handle, bl1_fwu_image_resume(x1, x2, &handle, flags));
+
+	case FWU_SMC_SEC_IMAGE_DONE:
+		SMC_RET1(handle, bl1_fwu_sec_image_done(&handle, flags));
+
+	case FWU_SMC_UPDATE_DONE:
+		bl1_fwu_done(cookie, NULL);
+		/* We should never return from bl1_fwu_done() */
+
+	default:
+		assert(0);
+		break;
+	}
+
+	SMC_RET0(handle);
+}
+
+/*******************************************************************************
+ * This function is responsible for copying secure images in AP Secure RAM.
+ ******************************************************************************/
+static int bl1_fwu_image_copy(unsigned int image_id,
+			uintptr_t image_src,
+			unsigned int block_size,
+			unsigned int image_size,
+			unsigned int flags)
+{
+	uintptr_t base_addr;
+	meminfo_t *mem_layout;
+
+	/* Get the image descriptor. */
+	image_desc_t *image_desc = bl1_plat_get_image_desc(image_id);
+
+	/* Check if we are in correct state. */
+	if ((!image_desc) ||
+		((image_desc->state != IMAGE_STATE_RESET) &&
+		 (image_desc->state != IMAGE_STATE_COPYING))) {
+		WARN("BL1-FWU: Copy not allowed due to invalid state\n");
+		return -EPERM;
+	}
+
+	/* Only Normal world is allowed to copy a Secure image. */
+	if ((GET_SEC_STATE(flags) == SECURE) ||
+		(GET_SEC_STATE(image_desc->ep_info.h.attr) == NON_SECURE)) {
+		WARN("BL1-FWU: Copy not allowed for Non-Secure "
+			 "image from Secure-world\n");
+		return -EPERM;
+	}
+
+	if ((!image_src) || (!block_size)) {
+		WARN("BL1-FWU: Copy not allowed due to invalid image source"
+			" or block size\n");
+		return -ENOMEM;
+	}
+
+	/* Get the image base address. */
+	base_addr = image_desc->image_info.image_base;
+
+	if (image_desc->state == IMAGE_STATE_COPYING) {
+		/*
+		 * If last block is more than expected then
+		 * clip the block to the required image size.
+		 */
+		if (image_desc->image_info.copied_size + block_size >
+			 image_desc->image_info.image_size) {
+			block_size = image_desc->image_info.image_size -
+				image_desc->image_info.copied_size;
+			WARN("BL1-FWU: Copy argument block_size > remaining image size."
+				" Clipping block_size\n");
+		}
+
+		/* Make sure the image src/size is mapped. */
+		if (bl1_plat_mem_check(image_src, block_size, flags)) {
+			WARN("BL1-FWU: Copy arguments source/size not mapped\n");
+			return -ENOMEM;
+		}
+
+		INFO("BL1-FWU: Continuing image copy in blocks\n");
+
+		/* Copy image for given block size. */
+		base_addr += image_desc->image_info.copied_size;
+		image_desc->image_info.copied_size += block_size;
+		memcpy((void *)base_addr, (const void *)image_src, block_size);
+		flush_dcache_range(base_addr, block_size);
+
+		/* Update the state if last block. */
+		if (image_desc->image_info.copied_size ==
+				image_desc->image_info.image_size) {
+			image_desc->state = IMAGE_STATE_COPIED;
+			INFO("BL1-FWU: Image copy in blocks completed\n");
+		}
+	} else {
+		/* This means image is in RESET state and ready to be copied. */
+		INFO("BL1-FWU: Fresh call to copy an image\n");
+
+		if (!image_size) {
+			WARN("BL1-FWU: Copy not allowed due to invalid image size\n");
+			return -ENOMEM;
+		}
+
+		/*
+		 * If block size is more than total size then
+		 * assume block size as the total image size.
+		 */
+		if (block_size > image_size) {
+			block_size = image_size;
+			WARN("BL1-FWU: Copy argument block_size > image size."
+				" Clipping block_size\n");
+		}
+
+		/* Make sure the image src/size is mapped. */
+		if (bl1_plat_mem_check(image_src, block_size, flags)) {
+			WARN("BL1-FWU: Copy arguments source/size not mapped\n");
+			return -ENOMEM;
+		}
+
+		/* Find out how much free trusted ram remains after BL1 load */
+		mem_layout = bl1_plat_sec_mem_layout();
+		if ((image_desc->image_info.image_base < mem_layout->free_base) ||
+			 (image_desc->image_info.image_base + image_size >
+			  mem_layout->free_base + mem_layout->free_size)) {
+			WARN("BL1-FWU: Memory not available to copy\n");
+			return -ENOMEM;
+		}
+
+		/* Update the image size. */
+		image_desc->image_info.image_size = image_size;
+
+		/* Copy image for given size. */
+		memcpy((void *)base_addr, (const void *)image_src, block_size);
+		flush_dcache_range(base_addr, block_size);
+
+		/* Update the state. */
+		if (block_size == image_size) {
+			image_desc->state = IMAGE_STATE_COPIED;
+			INFO("BL1-FWU: Image is copied successfully\n");
+		} else {
+			image_desc->state = IMAGE_STATE_COPYING;
+			INFO("BL1-FWU: Started image copy in blocks\n");
+		}
+
+		image_desc->image_info.copied_size = block_size;
+	}
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function is responsible for authenticating Normal/Secure images.
+ ******************************************************************************/
+static int bl1_fwu_image_auth(unsigned int image_id,
+			uintptr_t image_src,
+			unsigned int image_size,
+			unsigned int flags)
+{
+	int result;
+	uintptr_t base_addr;
+	unsigned int total_size;
+
+	/* Get the image descriptor. */
+	image_desc_t *image_desc = bl1_plat_get_image_desc(image_id);
+	if (!image_desc)
+		return -EPERM;
+
+	if (GET_SEC_STATE(flags) == SECURE) {
+		if (image_desc->state != IMAGE_STATE_RESET) {
+			WARN("BL1-FWU: Authentication from secure world "
+				"while in invalid state\n");
+			return -EPERM;
+		}
+	} else {
+		if (GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE) {
+			if (image_desc->state != IMAGE_STATE_COPIED) {
+				WARN("BL1-FWU: Authentication of secure image "
+					"from non-secure world while not in copied state\n");
+				return -EPERM;
+			}
+		} else {
+			if (image_desc->state != IMAGE_STATE_RESET) {
+				WARN("BL1-FWU: Authentication of non-secure image "
+					"from non-secure world while in invalid state\n");
+				return -EPERM;
+			}
+		}
+	}
+
+	if (image_desc->state == IMAGE_STATE_COPIED) {
+		/*
+		 * Image is in COPIED state.
+		 * Use the stored address and size.
+		 */
+		base_addr = image_desc->image_info.image_base;
+		total_size = image_desc->image_info.image_size;
+	} else {
+		if ((!image_src) || (!image_size)) {
+			WARN("BL1-FWU: Auth not allowed due to invalid"
+				" image source/size\n");
+			return -ENOMEM;
+		}
+
+		/*
+		 * Image is in RESET state.
+		 * Check the parameters and authenticate the source image in place.
+		 */
+		if (bl1_plat_mem_check(image_src, image_size, flags)) {
+			WARN("BL1-FWU: Authentication arguments source/size not mapped\n");
+			return -ENOMEM;
+		}
+
+		base_addr = image_src;
+		total_size = image_size;
+
+		/* Update the image size in the descriptor. */
+		image_desc->image_info.image_size = total_size;
+	}
+
+	/*
+	 * Authenticate the image.
+	 */
+	INFO("BL1-FWU: Authenticating image_id:%d\n", image_id);
+	result = auth_mod_verify_img(image_id, (void *)base_addr, total_size);
+	if (result != 0) {
+		WARN("BL1-FWU: Authentication Failed err=%d\n", result);
+
+		/*
+		 * Authentication has failed.
+		 * Clear the memory if the image was copied.
+		 * This is to prevent an attack where this contains
+		 * some malicious code that can somehow be executed later.
+		 */
+		if (image_desc->state == IMAGE_STATE_COPIED) {
+			/* Clear the memory.*/
+			memset((void *)base_addr, 0, total_size);
+			flush_dcache_range(base_addr, total_size);
+
+			/* Indicate that image can be copied again*/
+			image_desc->state = IMAGE_STATE_RESET;
+		}
+		return -EAUTH;
+	}
+
+	/* Indicate that image is in authenticated state. */
+	image_desc->state = IMAGE_STATE_AUTHENTICATED;
+
+	/*
+	 * Flush image_info to memory so that other
+	 * secure world images can see changes.
+	 */
+	flush_dcache_range((unsigned long)&image_desc->image_info,
+		sizeof(image_info_t));
+
+	INFO("BL1-FWU: Authentication was successful\n");
+
+	return 0;
+}
+
+/*******************************************************************************
+ * This function is responsible for executing Secure images.
+ ******************************************************************************/
+static int bl1_fwu_image_execute(unsigned int image_id,
+			void **handle,
+			unsigned int flags)
+{
+	/* Get the image descriptor. */
+	image_desc_t *image_desc = bl1_plat_get_image_desc(image_id);
+
+	/*
+	 * Execution is NOT allowed if:
+	 * Caller is from Secure world OR
+	 * Image is Non-Secure OR
+	 * Image is Non-Executable OR
+	 * Image is NOT in AUTHENTICATED state.
+	 */
+	if ((!image_desc) ||
+		(GET_SEC_STATE(flags) == SECURE) ||
+		(GET_SEC_STATE(image_desc->ep_info.h.attr) == NON_SECURE) ||
+		(GET_EXEC_STATE(image_desc->image_info.h.attr) == NON_EXECUTABLE) ||
+		(image_desc->state != IMAGE_STATE_AUTHENTICATED)) {
+		WARN("BL1-FWU: Execution not allowed due to invalid state/args\n");
+		return -EPERM;
+	}
+
+	INFO("BL1-FWU: Executing Secure image\n");
+
+	/* Save NS-EL1 system registers. */
+	cm_el1_sysregs_context_save(NON_SECURE);
+
+	/* Prepare the image for execution. */
+	bl1_prepare_next_image(image_id);
+
+	/* Update the secure image id. */
+	sec_exec_image_id = image_id;
+
+	*handle = cm_get_context(SECURE);
+	return 0;
+}
+
+/*******************************************************************************
+ * This function is responsible for resuming Secure/Non-Secure images.
+ ******************************************************************************/
+static register_t bl1_fwu_image_resume(unsigned int image_id,
+			register_t image_param,
+			void **handle,
+			unsigned int flags)
+{
+	image_desc_t *image_desc;
+	unsigned int resume_sec_state;
+
+	if (GET_SEC_STATE(flags) == SECURE) {
+		/* Get the image descriptor for last executed secure image id. */
+		image_desc = bl1_plat_get_image_desc(sec_exec_image_id);
+
+		if ((!image_desc) || (image_desc->state != IMAGE_STATE_EXECUTED)) {
+			WARN("BL1-FWU: Resume not allowed for secure image "
+				"due to invalid state\n");
+			return -EPERM;
+		}
+
+		/* Update the flags. */
+		image_desc->state = IMAGE_STATE_INTERRUPTED;
+		resume_sec_state = NON_SECURE;
+	} else {
+		/* Get the image descriptor for image id to be resumed. */
+		image_desc = bl1_plat_get_image_desc(image_id);
+
+		/* Make sure image is secure and was interrupted. */
+		if ((!image_desc) ||
+			(GET_SEC_STATE(image_desc->ep_info.h.attr) == NON_SECURE) ||
+			(image_desc->state != IMAGE_STATE_INTERRUPTED)) {
+			WARN("BL1-FWU: Resume not allowed for NS image/ invalid state\n");
+			return -EPERM;
+		}
+
+		/* Update the flags. */
+		image_desc->state = IMAGE_STATE_EXECUTED;
+		resume_sec_state = SECURE;
+	}
+
+	/* Save the EL1 system registers of calling world. */
+	cm_el1_sysregs_context_save(GET_SEC_STATE(flags));
+
+	/* Restore the EL1 system registers of resuming world. */
+	cm_el1_sysregs_context_restore(resume_sec_state);
+
+	/* Update the next context. */
+	cm_set_next_eret_context(resume_sec_state);
+
+	INFO("BL1-FWU: Resuming %s world context\n",
+		(resume_sec_state == SECURE) ? "Secure" : "Normal");
+
+	*handle = cm_get_context(resume_sec_state);
+	return image_param;
+}
+
+/*******************************************************************************
+ * This function is responsible for resuming normal world context.
+ ******************************************************************************/
+static int bl1_fwu_sec_image_done(void **handle, unsigned int flags)
+{
+
+	/* Get the image descriptor for last executed secure image id. */
+	image_desc_t *image_desc = bl1_plat_get_image_desc(sec_exec_image_id);
+
+	/*
+	 * Make sure caller is from secure world
+	 * and the image is in EXECUTED state.
+	 */
+	if ((!image_desc) ||
+		(GET_SEC_STATE(flags) == NON_SECURE) ||
+		(image_desc->state != IMAGE_STATE_EXECUTED)) {
+		WARN("BL1-FWU: Done not allowed for NS caller/ invalid state\n");
+		return -EPERM;
+	}
+
+	/* Update the flags. */
+	image_desc->state = IMAGE_STATE_RESET;
+	sec_exec_image_id = INVALID_IMAGE_ID;
+
+	/*
+	 * Secure world is done so no need to save the context.
+	 * Just restore the Non-Secure context.
+	 */
+	cm_el1_sysregs_context_restore(NON_SECURE);
+
+	/* Update the next context. */
+	cm_set_next_eret_context(NON_SECURE);
+
+	INFO("BL1-FWU: Resuming Normal world context\n");
+
+	*handle = cm_get_context(NON_SECURE);
+	return 0;
+}
+
+/*******************************************************************************
+ * This function provides the opportunity for users to perform any
+ * platform specific handling after the Firmware update is done.
+ ******************************************************************************/
+__dead2 static void bl1_fwu_done(void *cookie, void *reserved)
+{
+	NOTICE("BL1-FWU: *******FWU Process Completed*******\n");
+
+	/*
+	 * Call platform done function.
+	 */
+	bl1_plat_fwu_done(cookie, reserved);
+	assert(0);
+}
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 73f023a..84d5611 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -32,43 +32,22 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <auth_mod.h>
+#include <bl1.h>
 #include <bl_common.h>
 #include <debug.h>
 #include <platform.h>
 #include <platform_def.h>
+#include <smcc_helpers.h>
 #include "bl1_private.h"
+#include <uuid.h>
 
-/*******************************************************************************
- * Runs BL2 from the given entry point. It results in dropping the
- * exception level
- ******************************************************************************/
-static void __dead2 bl1_run_bl2(entry_point_info_t *bl2_ep)
-{
-	/* Check bl2 security state is expected as secure */
-	assert(GET_SECURITY_STATE(bl2_ep->h.attr) == SECURE);
-	/* Check NS Bit is also set as secure */
-	assert(!(read_scr_el3() & SCR_NS_BIT));
-
-	bl1_arch_next_el_setup();
+/* BL1 Service UUID */
+DEFINE_SVC_UUID(bl1_svc_uid,
+	0xfd3967d4, 0x72cb, 0x4d9a, 0xb5, 0x75,
+	0x67, 0x15, 0xd6, 0xf4, 0xbb, 0x4a);
 
-	/* Tell next EL what we want done */
-	bl2_ep->args.arg0 = RUN_IMAGE;
 
-	write_spsr_el3(bl2_ep->spsr);
-	write_elr_el3(bl2_ep->pc);
-
-	NOTICE("BL1: Booting BL2\n");
-	print_entry_point_info(bl2_ep);
-
-	eret(bl2_ep->args.arg0,
-		bl2_ep->args.arg1,
-		bl2_ep->args.arg2,
-		bl2_ep->args.arg3,
-		bl2_ep->args.arg4,
-		bl2_ep->args.arg5,
-		bl2_ep->args.arg6,
-		bl2_ep->args.arg7);
-}
+static void bl1_load_bl2(void);
 
 /*******************************************************************************
  * The next function has a weak definition. Platform specific code can override
@@ -91,7 +70,8 @@
 
 	/* Check that BL1's memory is lying outside of the free memory */
 	assert((BL1_RAM_LIMIT <= bl1_mem_layout->free_base) ||
-	       (BL1_RAM_BASE >= bl1_mem_layout->free_base + bl1_mem_layout->free_size));
+	       (BL1_RAM_BASE >= bl1_mem_layout->free_base +
+				bl1_mem_layout->free_size));
 
 	/* Remove BL1 RW data from the scope of memory visible to BL2 */
 	*bl2_mem_layout = *bl1_mem_layout;
@@ -105,13 +85,13 @@
 
 /*******************************************************************************
  * Function to perform late architectural and platform specific initialization.
- * It also locates and loads the BL2 raw binary image in the trusted DRAM. Only
- * called by the primary cpu after a cold boot.
- * TODO: Add support for alternative image load mechanism e.g using virtio/elf
- * loader etc.
-  ******************************************************************************/
+ * It also queries the platform to load and run next BL image. Only called
+ * by the primary cpu after a cold boot.
+ ******************************************************************************/
 void bl1_main(void)
 {
+	unsigned int image_id;
+
 	/* Announce our arrival */
 	NOTICE(FIRMWARE_WELCOME_STR);
 	NOTICE("BL1: %s\n", version_string);
@@ -119,11 +99,6 @@
 
 	INFO("BL1: RAM 0x%lx - 0x%lx\n", BL1_RAM_BASE, BL1_RAM_LIMIT);
 
-	image_info_t bl2_image_info = { {0} };
-	entry_point_info_t bl2_ep = { {0} };
-	meminfo_t *bl1_tzram_layout;
-	meminfo_t *bl2_tzram_layout = 0x0;
-	int err;
 
 #if DEBUG
 	unsigned long val;
@@ -153,28 +128,65 @@
 	/* Perform remaining generic architectural setup from EL3 */
 	bl1_arch_setup();
 
+#if TRUSTED_BOARD_BOOT
+	/* Initialize authentication module */
+	auth_mod_init();
+#endif /* TRUSTED_BOARD_BOOT */
+
 	/* Perform platform setup in BL1. */
 	bl1_platform_setup();
 
+	/* Get the image id of next image to load and run. */
+	image_id = bl1_plat_get_next_image_id();
+
+	/*
+	 * We currently interpret any image id other than
+	 * BL2_IMAGE_ID as the start of firmware update.
+	 */
+	if (image_id == BL2_IMAGE_ID)
+		bl1_load_bl2();
+	else
+		NOTICE("BL1-FWU: *******FWU Process Started*******\n");
+
+	bl1_prepare_next_image(image_id);
+}
+
+/*******************************************************************************
+ * This function locates and loads the BL2 raw binary image in the trusted SRAM.
+ * Called by the primary cpu after a cold boot.
+ * TODO: Add support for alternative image load mechanism e.g using virtio/elf
+ * loader etc.
+ ******************************************************************************/
+void bl1_load_bl2(void)
+{
+	image_desc_t *image_desc;
+	image_info_t *image_info;
+	entry_point_info_t *ep_info;
+	meminfo_t *bl1_tzram_layout;
+	meminfo_t *bl2_tzram_layout;
+	int err;
+
-	SET_PARAM_HEAD(&bl2_image_info, PARAM_IMAGE_BINARY, VERSION_1, 0);
-	SET_PARAM_HEAD(&bl2_ep, PARAM_EP, VERSION_1, 0);
+	/* Get the image descriptor */
+	image_desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
+	assert(image_desc);
+
+	/* Get the image info */
+	image_info = &image_desc->image_info;
+
+	/* Get the entry point info */
+	ep_info = &image_desc->ep_info;
 
 	/* Find out how much free trusted ram remains after BL1 load */
 	bl1_tzram_layout = bl1_plat_sec_mem_layout();
 
 	INFO("BL1: Loading BL2\n");
 
-#if TRUSTED_BOARD_BOOT
-	/* Initialize authentication module */
-	auth_mod_init();
-#endif /* TRUSTED_BOARD_BOOT */
-
 	/* Load the BL2 image */
 	err = load_auth_image(bl1_tzram_layout,
 			 BL2_IMAGE_ID,
-			 BL2_BASE,
-			 &bl2_image_info,
-			 &bl2_ep);
+			 image_info->image_base,
+			 image_info,
+			 ep_info);
 
 	if (err) {
 		ERROR("Failed to load BL2 firmware.\n");
@@ -191,11 +203,10 @@
 	bl2_tzram_layout = (meminfo_t *) bl1_tzram_layout->free_base;
 	bl1_init_bl2_mem_layout(bl1_tzram_layout, bl2_tzram_layout);
 
-	bl1_plat_set_bl2_ep_info(&bl2_image_info, &bl2_ep);
-	bl2_ep.args.arg1 = (unsigned long)bl2_tzram_layout;
-	bl1_run_bl2(&bl2_ep);
-
-	return;
+	ep_info->args.arg1 = (unsigned long)bl2_tzram_layout;
+	NOTICE("BL1: Booting BL2\n");
+	VERBOSE("BL1: BL2 memory layout address = 0x%llx\n",
+		(unsigned long long) bl2_tzram_layout);
 }
 
 /*******************************************************************************
@@ -216,3 +227,45 @@
 	NOTICE("BL1: Please connect the debugger to continue\n");
 }
 #endif
+
+/*******************************************************************************
+ * Top level handler for servicing BL1 SMCs.
+ ******************************************************************************/
+register_t bl1_smc_handler(unsigned int smc_fid,
+	register_t x1,
+	register_t x2,
+	register_t x3,
+	register_t x4,
+	void *cookie,
+	void *handle,
+	unsigned int flags)
+{
+
+#if TRUSTED_BOARD_BOOT
+	/*
+	 * Dispatch FWU calls to FWU SMC handler and return its return
+	 * value
+	 */
+	if (is_fwu_fid(smc_fid)) {
+		return bl1_fwu_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+			handle, flags);
+	}
+#endif
+
+	switch (smc_fid) {
+	case BL1_SMC_CALL_COUNT:
+		SMC_RET1(handle, BL1_NUM_SMC_CALLS);
+
+	case BL1_SMC_UID:
+		SMC_UUID_RET(handle, bl1_svc_uid);
+
+	case BL1_SMC_VERSION:
+		SMC_RET1(handle, BL1_SMC_MAJOR_VER | BL1_SMC_MINOR_VER);
+
+	default:
+		break;
+	}
+
+	WARN("Unimplemented BL1 SMC Call: 0x%x \n", smc_fid);
+	SMC_RET1(handle, SMC_UNK);
+}
diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h
index 0a8fc45..283bbb9 100644
--- a/bl1/bl1_private.h
+++ b/bl1/bl1_private.h
@@ -31,6 +31,8 @@
 #ifndef __BL1_PRIVATE_H__
 #define __BL1_PRIVATE_H__
 
+#include <types.h>
+
 /*******************************************************************************
  * Declarations of linker defined symbols which will tell us where BL1 lives
  * in Trusted RAM
@@ -46,4 +48,14 @@
 void bl1_arch_setup(void);
 void bl1_arch_next_el_setup(void);
 
+void bl1_prepare_next_image(unsigned int image_id);
+
+register_t bl1_fwu_smc_handler(unsigned int smc_fid,
+		register_t x1,
+		register_t x2,
+		register_t x3,
+		register_t x4,
+		void *cookie,
+		void *handle,
+		unsigned int flags);
 #endif /* __BL1_PRIVATE_H__ */
diff --git a/bl1/tbbr/tbbr_img_desc.c b/bl1/tbbr/tbbr_img_desc.c
new file mode 100644
index 0000000..42de851
--- /dev/null
+++ b/bl1/tbbr/tbbr_img_desc.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bl1.h>
+#include <bl_common.h>
+#include <platform_def.h>
+
+image_desc_t bl1_tbbr_image_descs[] = {
+    {
+	    .image_id = FWU_CERT_ID,
+	    .image_info.h.attr = SET_EXEC_STATE(NON_EXECUTABLE),
+	    .image_info.image_base = BL2_BASE,
+	    .ep_info.h.attr = SET_SEC_STATE(SECURE),
+    },
+#if NS_BL1U_BASE
+    {
+	    .image_id = NS_BL1U_IMAGE_ID,
+	    .image_info.h.attr = SET_EXEC_STATE(EXECUTABLE),
+	    .image_info.image_base = NS_BL1U_BASE,
+	    .ep_info.h.attr = SET_SEC_STATE(NON_SECURE),
+	    .ep_info.pc = NS_BL1U_BASE,
+    },
+#endif
+#if SCP_BL2U_BASE
+    {
+	    .image_id = SCP_BL2U_IMAGE_ID,
+	    .image_info.h.attr = SET_EXEC_STATE(NON_EXECUTABLE),
+	    .image_info.image_base = SCP_BL2U_BASE,
+	    .ep_info.h.attr = SET_SEC_STATE(SECURE),
+    },
+#endif
+#if BL2U_BASE
+    {
+	    .image_id = BL2U_IMAGE_ID,
+	    .image_info.h.attr = SET_EXEC_STATE(EXECUTABLE),
+	    .image_info.image_base = BL2U_BASE,
+	    .ep_info.h.attr = SET_SEC_STATE(SECURE),
+	    .ep_info.pc = BL2U_BASE,
+    },
+#endif
+#if NS_BL2U_BASE
+    {
+	    .image_id = NS_BL2U_IMAGE_ID,
+	    .image_info.h.attr = SET_EXEC_STATE(NON_EXECUTABLE),
+	    .image_info.image_base = NS_BL2U_BASE,
+	    .ep_info.h.attr = SET_SEC_STATE(NON_SECURE),
+    },
+#endif
+	    BL2_IMAGE_DESC,
+
+    {
+	    .image_id = INVALID_IMAGE_ID,
+    }
+};
diff --git a/bl2/aarch64/bl2_entrypoint.S b/bl2/aarch64/bl2_entrypoint.S
index 1d26229..75eb02a 100644
--- a/bl2/aarch64/bl2_entrypoint.S
+++ b/bl2/aarch64/bl2_entrypoint.S
@@ -39,13 +39,12 @@
 
 func bl2_entrypoint
 	/*---------------------------------------------
-	 * Store the extents of the tzram available to
-	 * BL2 for future use. Use the opcode param to
-	 * allow implement other functions if needed.
+	 * Save from x1 the extents of the tzram
+	 * available to BL2 for future use.
+	 * x0 is not currently used.
 	 * ---------------------------------------------
-	 */
-	mov	x20, x0
-	mov	x21, x1
+ 	 */
+ 	mov	x20, x1
 
 	/* ---------------------------------------------
 	 * Set the exception vector to something sane.
@@ -74,14 +73,6 @@
 	isb
 
 	/* ---------------------------------------------
-	 * Check the opcodes out of paranoia.
-	 * ---------------------------------------------
-	 */
-	mov	x0, #RUN_IMAGE
-	cmp	x0, x20
-	b.ne	_panic
-
-	/* ---------------------------------------------
 	 * Invalidate the RW memory used by the BL2
 	 * image. This includes the data and NOBITS
 	 * sections. This is done to safeguard against
@@ -126,7 +117,7 @@
 	 * specific early arch. setup e.g. mmu setup
 	 * ---------------------------------------------
 	 */
-	mov	x0, x21
+	mov	x0, x20
 	bl	bl2_early_platform_setup
 	bl	bl2_plat_arch_setup
 
diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c
index a3f016f..f475640 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -32,6 +32,7 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <auth_mod.h>
+#include <bl1.h>
 #include <bl_common.h>
 #include <debug.h>
 #include <errno.h>
@@ -281,5 +282,5 @@
 	 * the BL3-2 (if present) and BL3-3 software images will be passed to
 	 * BL3-1 as an argument.
 	 */
-	smc(RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
+	smc(BL1_SMC_RUN_IMAGE, (unsigned long)bl31_ep_info, 0, 0, 0, 0, 0, 0);
 }
diff --git a/bl2u/aarch64/bl2u_entrypoint.S b/bl2u/aarch64/bl2u_entrypoint.S
new file mode 100644
index 0000000..c9aad81
--- /dev/null
+++ b/bl2u/aarch64/bl2u_entrypoint.S
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+
+
+	.globl	bl2u_entrypoint
+
+
+func bl2u_entrypoint
+	/*---------------------------------------------
+	 * Store the extents of the tzram available to
+	 * BL2U and other platform specific information
+	 * for future use. x0 is currently not used.
+	 * ---------------------------------------------
+	 */
+	mov	x20, x1
+	mov	x21, x2
+
+	/* ---------------------------------------------
+	 * Set the exception vector to something sane.
+	 * ---------------------------------------------
+	 */
+	adr	x0, early_exceptions
+	msr	vbar_el1, x0
+	isb
+
+	/* ---------------------------------------------
+	 * Enable the SError interrupt now that the
+	 * exception vectors have been setup.
+	 * ---------------------------------------------
+	 */
+	msr	daifclr, #DAIF_ABT_BIT
+
+	/* ---------------------------------------------
+	 * Enable the instruction cache, stack pointer
+	 * and data access alignment checks
+	 * ---------------------------------------------
+	 */
+	mov	x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
+	mrs	x0, sctlr_el1
+	orr	x0, x0, x1
+	msr	sctlr_el1, x0
+	isb
+
+	/* ---------------------------------------------
+	 * 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.
+	 * ---------------------------------------------
+	 */
+	adr	x0, __RW_START__
+	adr	x1, __RW_END__
+	sub	x1, x1, x0
+	bl	inv_dcache_range
+
+	/* ---------------------------------------------
+	 * Zero out NOBITS sections. There are 2 of them:
+	 *   - the .bss section;
+	 *   - the coherent memory section.
+	 * ---------------------------------------------
+	 */
+	ldr	x0, =__BSS_START__
+	ldr	x1, =__BSS_SIZE__
+	bl	zeromem16
+
+	/* --------------------------------------------
+	 * 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
+
+	/* ---------------------------------------------
+	 * Perform early platform setup & platform
+	 * specific early arch. setup e.g. mmu setup
+	 * ---------------------------------------------
+	 */
+	mov	x0, x20
+	mov	x1, x21
+	bl	bl2u_early_platform_setup
+	bl	bl2u_plat_arch_setup
+
+	/* ---------------------------------------------
+	 * Jump to bl2u_main function.
+	 * ---------------------------------------------
+	 */
+	bl	bl2u_main
+
+_panic:
+	b	_panic
+endfunc bl2u_entrypoint
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
new file mode 100644
index 0000000..ec12077
--- /dev/null
+++ b/bl2u/bl2u.ld.S
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <platform_def.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(bl2u_entrypoint)
+
+MEMORY {
+    RAM (rwx): ORIGIN = BL2U_BASE, LENGTH = BL2U_LIMIT - BL2U_BASE
+}
+
+
+SECTIONS
+{
+    . = BL2U_BASE;
+    ASSERT(. == ALIGN(4096),
+           "BL2U_BASE address is not aligned on a page boundary.")
+
+    ro . : {
+        __RO_START__ = .;
+        *bl2u_entrypoint.o(.text*)
+        *(.text*)
+        *(.rodata*)
+
+        *(.vectors)
+        __RO_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked as
+         * read-only, executable.  No RW data from the next section must
+         * creep in.  Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __RO_END__ = .;
+    } >RAM
+
+    /*
+     * Define a linker symbol to mark start of the RW memory area for this
+     * image.
+     */
+    __RW_START__ = . ;
+
+    .data . : {
+        __DATA_START__ = .;
+        *(.data*)
+        __DATA_END__ = .;
+    } >RAM
+
+    stacks (NOLOAD) : {
+        __STACKS_START__ = .;
+        *(tzfw_normal_stacks)
+        __STACKS_END__ = .;
+    } >RAM
+
+    /*
+     * The .bss section gets initialised to 0 at runtime.
+     * Its base address must be 16-byte aligned.
+     */
+    .bss : ALIGN(16) {
+        __BSS_START__ = .;
+        *(SORT_BY_ALIGNMENT(.bss*))
+        *(COMMON)
+        __BSS_END__ = .;
+    } >RAM
+
+    /*
+     * The xlat_table section is for full, aligned page tables (4K).
+     * Removing them from .bss avoids forcing 4K alignment on
+     * the .bss section and eliminates the unecessary zero init
+     */
+    xlat_table (NOLOAD) : {
+        *(xlat_table)
+    } >RAM
+
+#if USE_COHERENT_MEM
+    /*
+     * The base address of the coherent memory section must be page-aligned (4K)
+     * to guarantee that the coherent data are stored on their own pages and
+     * are not mixed with normal data.  This is required to set up the correct
+     * memory attributes for the coherent data page tables.
+     */
+    coherent_ram (NOLOAD) : ALIGN(4096) {
+        __COHERENT_RAM_START__ = .;
+        *(tzfw_coherent_mem)
+        __COHERENT_RAM_END_UNALIGNED__ = .;
+        /*
+         * Memory page(s) mapped to this section will be marked
+         * as device memory.  No other unexpected data must creep in.
+         * Ensure the rest of the current memory page is unused.
+         */
+        . = NEXT(4096);
+        __COHERENT_RAM_END__ = .;
+    } >RAM
+#endif
+
+    /*
+     * Define a linker symbol to mark end of the RW memory area for this
+     * image.
+     */
+    __RW_END__ = .;
+    __BL2U_END__ = .;
+
+    __BSS_SIZE__ = SIZEOF(.bss);
+
+    ASSERT(. <= BL2U_LIMIT, "BL2U image has exceeded its limit.")
+}
diff --git a/bl2u/bl2u.mk b/bl2u/bl2u.mk
new file mode 100644
index 0000000..aa9de54
--- /dev/null
+++ b/bl2u/bl2u.mk
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# Neither the name of ARM nor the names of its contributors may be used
+# to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+BL2U_SOURCES		+=	bl2u/bl2u_main.c			\
+				bl2u/aarch64/bl2u_entrypoint.S		\
+				common/aarch64/early_exceptions.S
+
+BL2U_LINKERFILE		:=	bl2u/bl2u.ld.S
diff --git a/bl2u/bl2u_main.c b/bl2u/bl2u_main.c
new file mode 100644
index 0000000..515ddfb
--- /dev/null
+++ b/bl2u/bl2u_main.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <auth_mod.h>
+#include <bl_common.h>
+#include <bl1.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * This function is responsible to:
+ * Load SCP_BL2U if platform has defined SCP_BL2U_BASE
+ * Perform platform setup.
+ * Go back to EL3.
+ ******************************************************************************/
+void bl2u_main(void)
+{
+	NOTICE("BL2U: %s\n", version_string);
+	NOTICE("BL2U: %s\n", build_message);
+
+#if SCP_BL2U_BASE
+	int rc;
+	/* Load the subsequent bootloader images */
+	rc = bl2u_plat_handle_scp_bl2u();
+	if (rc) {
+		ERROR("Failed to load SCP_BL2U (%i)\n", rc);
+		panic();
+	}
+#endif
+
+	/* Perform platform setup in BL2U after loading SCP_BL2U */
+	bl2u_platform_setup();
+
+	/*
+	 * Indicate that BL2U is done and resume back to
+	 * normal world via an SMC to BL1.
+	 * x1 could be passed to Normal world,
+	 * so DO NOT pass any secret information.
+	 */
+	smc(FWU_SMC_SEC_IMAGE_DONE, 0, 0, 0, 0, 0, 0, 0);
+	wfi();
+}
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 2835320..dc11e0a 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -36,7 +36,6 @@
 #include <runtime_svc.h>
 
 	.globl	runtime_exceptions
-	.globl	el3_exit
 
 	/* -----------------------------------------------------
 	 * Handle SMC exceptions separately from other sync.
@@ -426,38 +425,7 @@
 #endif
 	blr	x15
 
-	/* -----------------------------------------------------
-	 * This routine assumes that the SP_EL3 is pointing to
-	 * a valid context structure from where the gp regs and
-	 * other special registers can be retrieved.
-	 *
-	 * Keep it in the same section as smc_handler as this
-	 * function uses a fall-through to el3_exit
-	 * -----------------------------------------------------
-	 */
-el3_exit: ; .type el3_exit, %function
-	/* -----------------------------------------------------
-	 * Save the current SP_EL0 i.e. the EL3 runtime stack
-	 * which will be used for handling the next SMC. Then
-	 * switch to SP_EL3
-	 * -----------------------------------------------------
-	 */
-	mov	x17, sp
-	msr	spsel, #1
-	str	x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
-
-	/* -----------------------------------------------------
-	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
-	 * -----------------------------------------------------
-	 */
-	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
-	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-	msr	scr_el3, x18
-	msr	spsr_el3, x16
-	msr	elr_el3, x17
-
-	/* Restore saved general purpose registers and return */
-	b	restore_gp_registers_eret
+	b	el3_exit
 
 smc_unknown:
 	/*
@@ -479,51 +447,3 @@
 	msr	spsel, #1 /* Switch to SP_ELx */
 	bl	report_unhandled_exception
 endfunc smc_handler
-
-	/* -----------------------------------------------------
-	 * The following functions are used to saved and restore
-	 * all the general pupose registers. Ideally we would
-	 * only save and restore the callee saved registers when
-	 * a world switch occurs but that type of implementation
-	 * is more complex. So currently we will always save and
-	 * restore these registers on entry and exit of EL3.
-	 * These are not macros to ensure their invocation fits
-	 * within the 32 instructions per exception vector.
-	 * -----------------------------------------------------
-	 */
-func save_gp_registers
-	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
-	stp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
-	stp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
-	stp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
-	stp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
-	stp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
-	stp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
-	stp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
-	stp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
-	save_x18_to_x29_sp_el0
-	ret
-endfunc save_gp_registers
-
-func restore_gp_registers_eret
-	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
-	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
-
-restore_gp_registers_callee_eret:
-	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
-	ldp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
-	ldp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
-	ldp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
-	ldp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
-	ldp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
-	ldp	x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
-	ldp	x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
-	ldp	x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
-	ldp	x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
-	ldp	x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
-	ldp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
-	ldp	x30, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
-	msr	sp_el0, x17
-	ldp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
-	eret
-endfunc restore_gp_registers_eret
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index a31c1f4..0c2b631 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -29,16 +29,17 @@
 #
 
 BL31_SOURCES		+=	bl31/bl31_main.c				\
-				bl31/context_mgmt.c				\
 				bl31/cpu_data_array.c				\
 				bl31/runtime_svc.c				\
 				bl31/interrupt_mgmt.c				\
 				bl31/aarch64/bl31_arch_setup.c			\
 				bl31/aarch64/bl31_entrypoint.S			\
-				bl31/aarch64/context.S				\
 				bl31/aarch64/cpu_data.S				\
 				bl31/aarch64/runtime_exceptions.S		\
 				bl31/aarch64/crash_reporting.S			\
+				bl31/bl31_context_mgmt.c			\
+				common/aarch64/context.S			\
+				common/context_mgmt.c				\
 				lib/cpus/aarch64/cpu_helpers.S			\
 				lib/locks/exclusive/spinlock.S			\
 				services/std_svc/std_svc_setup.c		\
diff --git a/bl31/bl31_context_mgmt.c b/bl31/bl31_context_mgmt.c
new file mode 100644
index 0000000..ae24424
--- /dev/null
+++ b/bl31/bl31_context_mgmt.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <bl31.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <cpu_data.h>
+#include <platform.h>
+
+
+/*******************************************************************************
+ * This function returns a pointer to the most recent 'cpu_context' structure
+ * for the calling CPU that was set as the context for the specified security
+ * state. NULL is returned if no such structure has been specified.
+ ******************************************************************************/
+void *cm_get_context(uint32_t security_state)
+{
+	assert(security_state <= NON_SECURE);
+
+	return get_cpu_data(cpu_context[security_state]);
+}
+
+/*******************************************************************************
+ * This function sets the pointer to the current 'cpu_context' structure for the
+ * specified security state for the calling CPU
+ ******************************************************************************/
+void cm_set_context(void *context, uint32_t security_state)
+{
+	assert(security_state <= NON_SECURE);
+
+	set_cpu_data(cpu_context[security_state], context);
+}
+
+/*******************************************************************************
+ * This function returns a pointer to the most recent 'cpu_context' structure
+ * for the CPU identified by `cpu_idx` that was set as the context for the
+ * specified security state. NULL is returned if no such structure has been
+ * specified.
+ ******************************************************************************/
+void *cm_get_context_by_index(unsigned int cpu_idx,
+				unsigned int security_state)
+{
+	assert(sec_state_is_valid(security_state));
+
+	return get_cpu_data_by_index(cpu_idx, cpu_context[security_state]);
+}
+
+/*******************************************************************************
+ * This function sets the pointer to the current 'cpu_context' structure for the
+ * specified security state for the CPU identified by CPU index.
+ ******************************************************************************/
+void cm_set_context_by_index(unsigned int cpu_idx, void *context,
+				unsigned int security_state)
+{
+	assert(sec_state_is_valid(security_state));
+
+	set_cpu_data_by_index(cpu_idx, cpu_context[security_state], context);
+}
+
+#if !ERROR_DEPRECATED
+/*
+ * These context management helpers are deprecated but are maintained for use
+ * by SPDs which have not migrated to the new API. If ERROR_DEPRECATED
+ * is enabled, these are excluded from the build so as to force users to
+ * migrate to the new API.
+ */
+
+/*******************************************************************************
+ * This function returns a pointer to the most recent 'cpu_context' structure
+ * for the CPU identified by MPIDR that was set as the context for the specified
+ * security state. NULL is returned if no such structure has been specified.
+ ******************************************************************************/
+void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state)
+{
+	assert(sec_state_is_valid(security_state));
+
+	return cm_get_context_by_index(platform_get_core_pos(mpidr), security_state);
+}
+
+/*******************************************************************************
+ * This function sets the pointer to the current 'cpu_context' structure for the
+ * specified security state for the CPU identified by MPIDR
+ ******************************************************************************/
+void cm_set_context_by_mpidr(uint64_t mpidr, void *context, uint32_t security_state)
+{
+	assert(sec_state_is_valid(security_state));
+
+	cm_set_context_by_index(platform_get_core_pos(mpidr),
+						 context, security_state);
+}
+
+/*******************************************************************************
+ * The following function provides a compatibility function for SPDs using the
+ * existing cm library routines. This function is expected to be invoked for
+ * initializing the cpu_context for the CPU specified by MPIDR for first use.
+ ******************************************************************************/
+void cm_init_context(unsigned long mpidr, const entry_point_info_t *ep)
+{
+	if ((mpidr & MPIDR_AFFINITY_MASK) ==
+			(read_mpidr_el1() & MPIDR_AFFINITY_MASK))
+		cm_init_my_context(ep);
+	else
+		cm_init_context_by_index(platform_get_core_pos(mpidr), ep);
+}
+#endif
\ No newline at end of file
diff --git a/bl31/aarch64/context.S b/common/aarch64/context.S
similarity index 66%
rename from bl31/aarch64/context.S
rename to common/aarch64/context.S
index a72879b..3d13a80 100644
--- a/bl31/aarch64/context.S
+++ b/common/aarch64/context.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -32,6 +32,17 @@
 #include <asm_macros.S>
 #include <context.h>
 
+	.global	el1_sysregs_context_save
+	.global	el1_sysregs_context_restore
+#if CTX_INCLUDE_FPREGS
+	.global	fpregs_context_save
+	.global	fpregs_context_restore
+#endif
+	.global	save_gp_registers
+	.global	restore_gp_registers_eret
+	.global	restore_gp_registers_callee_eret
+	.global	el3_exit
+
 /* -----------------------------------------------------
  * The following function strictly follows the AArch64
  * PCS to use x9-x17 (temporary caller-saved registers)
@@ -40,7 +51,6 @@
  * the register context will be saved.
  * -----------------------------------------------------
  */
-	.global el1_sysregs_context_save
 func el1_sysregs_context_save
 
 	mrs	x9, spsr_el1
@@ -127,7 +137,6 @@
  * from where the register context will be restored
  * -----------------------------------------------------
  */
-	.global el1_sysregs_context_restore
 func el1_sysregs_context_restore
 
 	ldp	x9, x10, [x0, #CTX_SPSR_EL1]
@@ -225,7 +234,6 @@
  * -----------------------------------------------------
  */
 #if CTX_INCLUDE_FPREGS
-	.global fpregs_context_save
 func fpregs_context_save
 	stp	q0, q1, [x0, #CTX_FP_Q0]
 	stp	q2, q3, [x0, #CTX_FP_Q2]
@@ -269,7 +277,6 @@
  * TODO: Revisit when VFP is used in secure world
  * -----------------------------------------------------
  */
-	.global fpregs_context_restore
 func fpregs_context_restore
 	ldp	q0, q1, [x0, #CTX_FP_Q0]
 	ldp	q2, q3, [x0, #CTX_FP_Q2]
@@ -303,3 +310,92 @@
 	ret
 endfunc fpregs_context_restore
 #endif /* CTX_INCLUDE_FPREGS */
+
+/* -----------------------------------------------------
+ * The following functions are used to save and restore
+ * all the general purpose registers. Ideally we would
+ * only save and restore the callee saved registers when
+ * a world switch occurs but that type of implementation
+ * is more complex. So currently we will always save and
+ * restore these registers on entry and exit of EL3.
+ * These are not macros to ensure their invocation fits
+ * within the 32 instructions per exception vector.
+ * clobbers: x18
+ * -----------------------------------------------------
+ */
+func save_gp_registers
+	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+	stp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+	stp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+	stp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
+	stp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
+	stp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
+	stp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
+	stp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
+	stp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
+	stp	x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
+	stp	x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
+	stp	x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
+	stp	x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
+	stp	x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
+	stp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
+	mrs	x18, sp_el0
+	str	x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]
+	ret
+endfunc save_gp_registers
+
+func restore_gp_registers_eret
+	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
+	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
+	b	restore_gp_registers_callee_eret
+endfunc restore_gp_registers_eret
+
+func restore_gp_registers_callee_eret
+	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
+	ldp	x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
+	ldp	x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
+	ldp	x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
+	ldp	x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
+	ldp	x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
+	ldp	x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
+	ldp	x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
+	ldp	x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
+	ldp	x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
+	ldp	x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
+	ldp	x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
+	ldp	 x30, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+	msr	sp_el0, x17
+	ldp	x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
+	eret
+endfunc	restore_gp_registers_callee_eret
+
+	/* -----------------------------------------------------
+	 * This routine assumes that the SP_EL3 is pointing to
+	 * a valid context structure from where the gp regs and
+	 * other special registers can be retrieved.
+	 * -----------------------------------------------------
+	 */
+func el3_exit
+	/* -----------------------------------------------------
+	 * Save the current SP_EL0 i.e. the EL3 runtime stack
+	 * which will be used for handling the next SMC. Then
+	 * switch to SP_EL3
+	 * -----------------------------------------------------
+	 */
+	mov	x17, sp
+	msr	spsel, #1
+	str	x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+
+	/* -----------------------------------------------------
+	 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
+	 * -----------------------------------------------------
+	 */
+	ldr	x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+	ldp	x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+	msr	scr_el3, x18
+	msr	spsr_el3, x16
+	msr	elr_el3, x17
+
+	/* Restore saved general purpose registers and return */
+	b	restore_gp_registers_eret
+endfunc el3_exit
diff --git a/common/aarch64/early_exceptions.S b/common/aarch64/early_exceptions.S
index 90f5421..780a38f 100644
--- a/common/aarch64/early_exceptions.S
+++ b/common/aarch64/early_exceptions.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -29,7 +29,7 @@
  */
 
 #include <asm_macros.S>
-#include <runtime_svc.h>
+#include <bl_common.h>
 
 	.globl	early_exceptions
 
diff --git a/bl31/context_mgmt.c b/common/context_mgmt.c
similarity index 77%
rename from bl31/context_mgmt.c
rename to common/context_mgmt.c
index 2b619aa..68ec894 100644
--- a/bl31/context_mgmt.c
+++ b/common/context_mgmt.c
@@ -32,14 +32,12 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bl_common.h>
-#include <bl31.h>
 #include <context.h>
 #include <context_mgmt.h>
-#include <cpu_data.h>
 #include <interrupt_mgmt.h>
 #include <platform.h>
 #include <platform_def.h>
-#include <runtime_svc.h>
+#include <smcc_helpers.h>
 #include <string.h>
 
 
@@ -65,105 +63,6 @@
 }
 
 /*******************************************************************************
- * This function returns a pointer to the most recent 'cpu_context' structure
- * for the CPU identified by `cpu_idx` that was set as the context for the
- * specified security state. NULL is returned if no such structure has been
- * specified.
- ******************************************************************************/
-void *cm_get_context_by_index(unsigned int cpu_idx,
-				unsigned int security_state)
-{
-	assert(sec_state_is_valid(security_state));
-
-	return get_cpu_data_by_index(cpu_idx, cpu_context[security_state]);
-}
-
-/*******************************************************************************
- * This function sets the pointer to the current 'cpu_context' structure for the
- * specified security state for the CPU identified by CPU index.
- ******************************************************************************/
-void cm_set_context_by_index(unsigned int cpu_idx, void *context,
-				unsigned int security_state)
-{
-	assert(sec_state_is_valid(security_state));
-
-	set_cpu_data_by_index(cpu_idx, cpu_context[security_state], context);
-}
-
-#if !ERROR_DEPRECATED
-/*
- * These context management helpers are deprecated but are maintained for use
- * by SPDs which have not migrated to the new API. If ERROR_DEPRECATED
- * is enabled, these are excluded from the build so as to force users to
- * migrate to the new API.
- */
-
-/*******************************************************************************
- * This function returns a pointer to the most recent 'cpu_context' structure
- * for the CPU identified by MPIDR that was set as the context for the specified
- * security state. NULL is returned if no such structure has been specified.
- ******************************************************************************/
-void *cm_get_context_by_mpidr(uint64_t mpidr, uint32_t security_state)
-{
-	assert(sec_state_is_valid(security_state));
-
-	return cm_get_context_by_index(platform_get_core_pos(mpidr), security_state);
-}
-
-/*******************************************************************************
- * This function sets the pointer to the current 'cpu_context' structure for the
- * specified security state for the CPU identified by MPIDR
- ******************************************************************************/
-void cm_set_context_by_mpidr(uint64_t mpidr, void *context, uint32_t security_state)
-{
-	assert(sec_state_is_valid(security_state));
-
-	cm_set_context_by_index(platform_get_core_pos(mpidr),
-						 context, security_state);
-}
-
-/*******************************************************************************
- * The following function provides a compatibility function for SPDs using the
- * existing cm library routines. This function is expected to be invoked for
- * initializing the cpu_context for the CPU specified by MPIDR for first use.
- ******************************************************************************/
-void cm_init_context(unsigned long mpidr, const entry_point_info_t *ep)
-{
-	if ((mpidr & MPIDR_AFFINITY_MASK) ==
-			(read_mpidr_el1() & MPIDR_AFFINITY_MASK))
-		cm_init_my_context(ep);
-	else
-		cm_init_context_by_index(platform_get_core_pos(mpidr), ep);
-}
-#endif
-
-/*******************************************************************************
- * This function is used to program the context that's used for exception
- * return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for
- * the required security state
- ******************************************************************************/
-static inline void cm_set_next_context(void *context)
-{
-#if DEBUG
-	uint64_t sp_mode;
-
-	/*
-	 * Check that this function is called with SP_EL0 as the stack
-	 * pointer
-	 */
-	__asm__ volatile("mrs	%0, SPSel\n"
-			 : "=r" (sp_mode));
-
-	assert(sp_mode == MODE_SP_EL0);
-#endif
-
-	__asm__ volatile("msr	spsel, #1\n"
-			 "mov	sp, %0\n"
-			 "msr	spsel, #0\n"
-			 : : "r" (context));
-}
-
-/*******************************************************************************
  * The following function initializes the cpu_context 'ctx' for
  * first use, and sets the initial entrypoint state as specified by the
  * entry_point_info structure.
@@ -212,7 +111,13 @@
 	if (EP_GET_ST(ep->h.attr))
 		scr_el3 |= SCR_ST_BIT;
 
+#if IMAGE_BL31
+	/*
+	 * IRQ/FIQ bits only need setting if interrupt routing
+	 * model has been set up for BL31.
+	 */
 	scr_el3 |= get_scr_el3_from_routing_model(security_state);
+#endif
 
 	/*
 	 * Set up SCTLR_ELx for the target exception level:
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index 79a8965..71634a1 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -89,6 +89,12 @@
 		AUTH_PARAM_HASH, BL32_HASH_OID);
 static auth_param_type_desc_t bl33_hash = AUTH_PARAM_TYPE_DESC(
 		AUTH_PARAM_HASH, BL33_HASH_OID);
+static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, SCP_BL2U_HASH_OID);
+static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, BL2U_HASH_OID);
+static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
+		AUTH_PARAM_HASH, NS_BL2U_HASH_OID);
 
 /*
  * TBBR Chain of trust definition
@@ -438,6 +444,99 @@
 				}
 			}
 		}
+	},
+	/*
+	 * FWU auth descriptor.
+	 */
+	[FWU_CERT_ID] = {
+		.img_id = FWU_CERT_ID,
+		.img_type = IMG_CERT,
+		.parent = NULL,
+		.img_auth_methods = {
+			[0] = {
+				.type = AUTH_METHOD_SIG,
+				.param.sig = {
+					.pk = &subject_pk,
+					.sig = &sig,
+					.alg = &sig_alg,
+					.data = &raw_data,
+				}
+			}
+		},
+		.authenticated_data = {
+			[0] = {
+				.type_desc = &scp_bl2u_hash,
+				.data = {
+					.ptr = (void *)plat_bl30_hash_buf,
+					.len = (unsigned int)HASH_DER_LEN
+				}
+			},
+			[1] = {
+				.type_desc = &bl2u_hash,
+				.data = {
+					.ptr = (void *)plat_bl2_hash_buf,
+					.len = (unsigned int)HASH_DER_LEN
+				}
+			},
+			[2] = {
+				.type_desc = &ns_bl2u_hash,
+				.data = {
+					.ptr = (void *)plat_bl33_hash_buf,
+					.len = (unsigned int)HASH_DER_LEN
+				}
+			}
+		}
+	},
+	/*
+	 * SCP_BL2U
+	 */
+	[SCP_BL2U_IMAGE_ID] = {
+		.img_id = SCP_BL2U_IMAGE_ID,
+		.img_type = IMG_RAW,
+		.parent = &cot_desc[FWU_CERT_ID],
+		.img_auth_methods = {
+			[0] = {
+				.type = AUTH_METHOD_HASH,
+				.param.hash = {
+					.data = &raw_data,
+					.hash = &scp_bl2u_hash,
+				}
+			}
+		}
+	},
+	/*
+	 * BL2U
+	 */
+	[BL2U_IMAGE_ID] = {
+		.img_id = BL2U_IMAGE_ID,
+		.img_type = IMG_RAW,
+		.parent = &cot_desc[FWU_CERT_ID],
+		.img_auth_methods = {
+			[0] = {
+				.type = AUTH_METHOD_HASH,
+				.param.hash = {
+					.data = &raw_data,
+					.hash = &bl2u_hash,
+				}
+			}
+		}
+	},
+	/*
+	 * NS_BL2U
+	 */
+	[NS_BL2U_IMAGE_ID] = {
+		.img_id = NS_BL2U_IMAGE_ID,
+		.img_type = IMG_RAW,
+		.parent = &cot_desc[FWU_CERT_ID],
+		.img_auth_methods = {
+			[0] = {
+				.type = AUTH_METHOD_HASH,
+				.param.hash = {
+					.data = &raw_data,
+					.hash = &ns_bl2u_hash,
+				}
+			}
+		}
 	}
 };
 
diff --git a/include/bl1/bl1.h b/include/bl1/bl1.h
new file mode 100644
index 0000000..9fb3cb2
--- /dev/null
+++ b/include/bl1/bl1.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BL1_FWU_H__
+#define __BL1_FWU_H__
+
+#include <bl_common.h>
+
+/*
+ * Defines for BL1 SMC function ids.
+ */
+#define BL1_SMC_CALL_COUNT		0x0
+#define BL1_SMC_UID			0x1
+/* SMC #0x2 reserved */
+#define BL1_SMC_VERSION			0x3
+
+/*
+ * Corresponds to the function ID of the SMC that
+ * the BL1 exception handler service to execute BL31.
+ */
+#define BL1_SMC_RUN_IMAGE		0x4
+
+/*
+ * BL1 SMC version
+ */
+#define BL1_SMC_MAJOR_VER		0x0
+#define BL1_SMC_MINOR_VER		0x1
+
+/*
+ * Defines for FWU SMC function ids.
+ */
+
+#define FWU_SMC_IMAGE_COPY		0x10
+#define FWU_SMC_IMAGE_AUTH		0x11
+#define FWU_SMC_IMAGE_EXECUTE		0x12
+#define FWU_SMC_IMAGE_RESUME		0x13
+#define FWU_SMC_SEC_IMAGE_DONE		0x14
+#define FWU_SMC_UPDATE_DONE		0x15
+
+/*
+ * Number of FWU calls (above) implemented
+ */
+#define FWU_NUM_SMC_CALLS		6
+
+#if TRUSTED_BOARD_BOOT
+# define BL1_NUM_SMC_CALLS		(FWU_NUM_SMC_CALLS + 4)
+#else
+# define BL1_NUM_SMC_CALLS		4
+#endif
+
+/*
+ * The macros below are used to identify FWU
+ * calls from the SMC function ID
+ */
+#define FWU_SMC_FID_START		FWU_SMC_IMAGE_COPY
+#define FWU_SMC_FID_END			FWU_SMC_UPDATE_DONE
+#define is_fwu_fid(_fid) \
+    ((_fid >= FWU_SMC_FID_START) && (_fid <= FWU_SMC_FID_END))
+
+#ifndef __ASSEMBLY__
+#include <cassert.h>
+
+/*
+ * Check if the total number of FWU SMC calls are as expected.
+ */
+CASSERT(FWU_NUM_SMC_CALLS == 	\
+		(FWU_SMC_FID_END - FWU_SMC_FID_START + 1),\
+		assert_FWU_NUM_SMC_CALLS_mismatch);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __BL1_FWU_H__ */
diff --git a/include/bl1/tbbr/tbbr_img_desc.h b/include/bl1/tbbr/tbbr_img_desc.h
new file mode 100644
index 0000000..56f3507
--- /dev/null
+++ b/include/bl1/tbbr/tbbr_img_desc.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __TBBR_IMG_DESC_H__
+#define __TBBR_IMG_DESC_H__
+
+#include <bl_common.h>
+
+extern image_desc_t bl1_tbbr_image_descs[];
+
+#endif /* __TBBR_IMG_DESC_H__ */
diff --git a/include/bl31/runtime_svc.h b/include/bl31/runtime_svc.h
index f112418..30ba29f 100644
--- a/include/bl31/runtime_svc.h
+++ b/include/bl31/runtime_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -31,74 +31,9 @@
 #ifndef __RUNTIME_SVC_H__
 #define __RUNTIME_SVC_H__
 
-/*******************************************************************************
- * Bit definitions inside the function id as per the SMC calling convention
- ******************************************************************************/
-#define FUNCID_TYPE_SHIFT		31
-#define FUNCID_CC_SHIFT			30
-#define FUNCID_OEN_SHIFT		24
-#define FUNCID_NUM_SHIFT		0
-
-#define FUNCID_TYPE_MASK		0x1
-#define FUNCID_CC_MASK			0x1
-#define FUNCID_OEN_MASK			0x3f
-#define FUNCID_NUM_MASK			0xffff
-
-#define FUNCID_TYPE_WIDTH		1
-#define FUNCID_CC_WIDTH			1
-#define FUNCID_OEN_WIDTH		6
-#define FUNCID_NUM_WIDTH		16
-
-#define GET_SMC_CC(id)			((id >> FUNCID_CC_SHIFT) & \
-					 FUNCID_CC_MASK)
-#define GET_SMC_TYPE(id)		((id >> FUNCID_TYPE_SHIFT) & \
-					 FUNCID_TYPE_MASK)
-
-#define SMC_64				1
-#define SMC_32				0
-#define SMC_UNK				0xffffffff
-#define SMC_TYPE_FAST			1
-#define SMC_TYPE_STD			0
-#define SMC_PREEMPTED		0xfffffffe
-/*******************************************************************************
- * Owning entity number definitions inside the function id as per the SMC
- * calling convention
- ******************************************************************************/
-#define OEN_ARM_START			0
-#define OEN_ARM_END			0
-#define OEN_CPU_START			1
-#define OEN_CPU_END			1
-#define OEN_SIP_START			2
-#define OEN_SIP_END			2
-#define OEN_OEM_START			3
-#define OEN_OEM_END			3
-#define OEN_STD_START			4	/* Standard Calls */
-#define OEN_STD_END			4
-#define OEN_TAP_START			48	/* Trusted Applications */
-#define OEN_TAP_END			49
-#define OEN_TOS_START			50	/* Trusted OS */
-#define OEN_TOS_END			63
-#define OEN_LIMIT			64
+#include <bl_common.h>		/* to include exception types */
+#include <smcc_helpers.h>	/* to include SMCC definitions */
 
-/*******************************************************************************
- * Constants to indicate type of exception to the common exception handler.
- ******************************************************************************/
-#define SYNC_EXCEPTION_SP_EL0		0x0
-#define IRQ_SP_EL0			0x1
-#define FIQ_SP_EL0			0x2
-#define SERROR_SP_EL0			0x3
-#define SYNC_EXCEPTION_SP_ELX		0x4
-#define IRQ_SP_ELX			0x5
-#define FIQ_SP_ELX			0x6
-#define SERROR_SP_ELX			0x7
-#define SYNC_EXCEPTION_AARCH64		0x8
-#define IRQ_AARCH64			0x9
-#define FIQ_AARCH64			0xa
-#define SERROR_AARCH64			0xb
-#define SYNC_EXCEPTION_AARCH32		0xc
-#define IRQ_AARCH32			0xd
-#define FIQ_AARCH32			0xe
-#define SERROR_AARCH32			0xf
 
 /*******************************************************************************
  * Structure definition, typedefs & constants for the runtime service framework
@@ -122,68 +57,9 @@
 
 #ifndef __ASSEMBLY__
 
-#include <cassert.h>
-#include <context.h>
-#include <stdint.h>
-
-/* Various flags passed to SMC handlers */
-#define SMC_FROM_SECURE		(0 << 0)
-#define SMC_FROM_NON_SECURE	(1 << 0)
-
-#define is_caller_non_secure(_f)	(!!(_f & SMC_FROM_NON_SECURE))
-#define is_caller_secure(_f)		(!(is_caller_non_secure(_f)))
-
 /* Prototype for runtime service initializing function */
 typedef int32_t (*rt_svc_init_t)(void);
 
-/* Convenience macros to return from SMC handler */
-#define SMC_RET0(_h)	{ \
-	return (uint64_t) (_h);		\
-}
-#define SMC_RET1(_h, _x0)	{ \
-	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X0, (_x0)); \
-	SMC_RET0(_h);						\
-}
-#define SMC_RET2(_h, _x0, _x1)	{ \
-	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X1, (_x1)); \
-	SMC_RET1(_h, (_x0)); \
-}
-#define SMC_RET3(_h, _x0, _x1, _x2)	{ \
-	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X2, (_x2)); \
-	SMC_RET2(_h, (_x0), (_x1)); \
-}
-#define SMC_RET4(_h, _x0, _x1, _x2, _x3)	{ \
-	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X3, (_x3)); \
-	SMC_RET3(_h, (_x0), (_x1), (_x2)); \
-}
-
-
-/*
- * Convenience macros to access general purpose registers using handle provided
- * to SMC handler. These takes the offset values defined in context.h
- */
-#define SMC_GET_GP(_h, _g) \
-	read_ctx_reg(get_gpregs_ctx(_h), (_g));
-#define SMC_SET_GP(_h, _g, _v) \
-	write_ctx_reg(get_gpregs_ctx(_h), (_g), (_v));
-
-/*
- * Convenience macros to access EL3 context registers using handle provided to
- * SMC handler. These takes the offset values defined in context.h
- */
-#define SMC_GET_EL3(_h, _e) \
-	read_ctx_reg(get_el3state_ctx(_h), (_e));
-#define SMC_SET_EL3(_h, _e, _v) \
-	write_ctx_reg(get_el3state_ctx(_h), (_e), (_v));
-
-/* The macro below is used to identify a Standard Service SMC call */
-#define is_std_svc_call(_fid)		((((_fid) >> FUNCID_OEN_SHIFT) & \
-					   FUNCID_OEN_MASK) == OEN_STD_START)
-
-/* The macro below is used to identify a valid Fast SMC call */
-#define is_valid_fast_smc(_fid)		((!(((_fid) >> 16) & 0xff)) && \
-					   (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST))
-
 /*
  * Prototype for runtime service SMC handler function. x0 (SMC Function ID) to
  * x4 are as passed by the caller. Rest of the arguments to SMC and the context
@@ -247,28 +123,6 @@
 					((call_type & FUNCID_TYPE_MASK) \
 					 << FUNCID_OEN_WIDTH))
 
-
-/*
- * Macro to define UUID for services. Apart from defining and initializing a
- * uuid_t structure, this macro verifies that the first word of the defined UUID
- * does not equal SMC_UNK. This is to ensure that the caller won't mistake the
- * returned UUID in x0 for an invalid SMC error return
- */
-#define DEFINE_SVC_UUID(_name, _tl, _tm, _th, _cl, _ch, \
-		_n0, _n1, _n2, _n3, _n4, _n5) \
-	CASSERT(_tl != SMC_UNK, invalid_svc_uuid);\
-	static const uuid_t _name = { \
-		_tl, _tm, _th, _cl, _ch, \
-		{ _n0, _n1, _n2, _n3, _n4, _n5 } \
-	}
-
-/* Return a UUID in the SMC return registers */
-#define SMC_UUID_RET(_h, _uuid) \
-	SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
-			 ((const uint32_t *) &(_uuid))[1], \
-			 ((const uint32_t *) &(_uuid))[2], \
-			 ((const uint32_t *) &(_uuid))[3])
-
 /*******************************************************************************
  * Function & variable prototypes
  ******************************************************************************/
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index c9a7a3d..b7cb95a 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -45,14 +45,6 @@
 #define TOP	0x1
 #define BOTTOM	!TOP
 
-/******************************************************************************
- * Opcode passed in x0 to tell next EL that we want to run an image.
- * Corresponds to the function ID of the only SMC that the BL1 exception
- * handlers service. That's why the chosen value is the first function ID of
- * the ARM SMC64 range.
- *****************************************************************************/
-#define RUN_IMAGE	0xC0000000
-
 /*******************************************************************************
  * Constants that allow assembler code to access members of and the
  * 'entry_point_info' structure at their correct offsets.
@@ -60,11 +52,41 @@
 #define ENTRY_POINT_INFO_PC_OFFSET	0x08
 #define ENTRY_POINT_INFO_ARGS_OFFSET	0x18
 
-#define PARAM_EP_SECURITY_MASK    0x1
+/* The following are used to set/get image attributes. */
+#define EXECUTABLE			(0x1)
+#define NON_EXECUTABLE			(0x0)
+#define PARAM_EP_EXECUTE_MASK		(0x1)
+#define PARAM_EP_EXECUTE_SHIFT		(0x1)
+#define PARAM_EP_SECURITY_MASK		(0x1)
+#define PARAM_EP_SECURITY_SHIFT		(0x0)
+
 #define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK)
 #define SET_SECURITY_STATE(x, security) \
 			((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security))
 
+#define GET_EXEC_STATE(x)    \
+    (((x) >> PARAM_EP_EXECUTE_SHIFT) & PARAM_EP_EXECUTE_MASK)
+
+#define SET_EXEC_STATE(x)    \
+    (((x) & PARAM_EP_EXECUTE_MASK) << PARAM_EP_EXECUTE_SHIFT)
+
+#define GET_SEC_STATE(x)    \
+    (((x) >> PARAM_EP_SECURITY_SHIFT) & PARAM_EP_SECURITY_MASK)
+
+#define SET_SEC_STATE(x)    \
+    (((x) & PARAM_EP_SECURITY_MASK) << PARAM_EP_SECURITY_SHIFT)
+
+/*
+ * The following are used for image state attributes.
+ * Image can only be in one of the following state.
+ */
+#define IMAGE_STATE_RESET			0
+#define IMAGE_STATE_COPIED			1
+#define IMAGE_STATE_COPYING			2
+#define IMAGE_STATE_AUTHENTICATED		3
+#define IMAGE_STATE_EXECUTED			4
+#define IMAGE_STATE_INTERRUPTED			5
+
 #define EP_EE_MASK	0x2
 #define EP_EE_LITTLE	0x0
 #define EP_EE_BIG	0x2
@@ -83,6 +105,8 @@
 
 #define VERSION_1		0x01
 
+#define INVALID_IMAGE_ID		(0xFFFFFFFF)
+
 #define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
 	(_p)->h.type = (uint8_t)(_type); \
 	(_p)->h.version = (uint8_t)(_ver); \
@@ -90,6 +114,26 @@
 	(_p)->h.attr = (uint32_t)(_attr) ; \
 	} while (0)
 
+/*******************************************************************************
+ * Constants to indicate type of exception to the common exception handler.
+ ******************************************************************************/
+#define SYNC_EXCEPTION_SP_EL0		0x0
+#define IRQ_SP_EL0			0x1
+#define FIQ_SP_EL0			0x2
+#define SERROR_SP_EL0			0x3
+#define SYNC_EXCEPTION_SP_ELX		0x4
+#define IRQ_SP_ELX			0x5
+#define FIQ_SP_ELX			0x6
+#define SERROR_SP_ELX			0x7
+#define SYNC_EXCEPTION_AARCH64		0x8
+#define IRQ_AARCH64			0x9
+#define FIQ_AARCH64			0xa
+#define SERROR_AARCH64			0xb
+#define SYNC_EXCEPTION_AARCH32		0xc
+#define IRQ_AARCH32			0xd
+#define FIQ_AARCH32			0xe
+#define SERROR_AARCH32			0xf
+
 #ifndef __ASSEMBLY__
 #include <cdefs.h> /* For __dead2 */
 #include <cassert.h>
@@ -106,6 +150,8 @@
 extern unsigned long __RO_END__;
 #if IMAGE_BL2
 extern unsigned long __BL2_END__;
+#elif IMAGE_BL2U
+extern unsigned long __BL2U_END__;
 #elif IMAGE_BL31
 extern unsigned long __BL31_END__;
 #elif IMAGE_BL32
@@ -177,8 +223,24 @@
 	param_header_t h;
 	uintptr_t image_base;   /* physical address of base of image */
 	uint32_t image_size;    /* bytes read from image file */
+	uint32_t copied_size;	/* image size copied in blocks */
 } image_info_t;
 
+/*****************************************************************************
+ * The image descriptor struct definition.
+ *****************************************************************************/
+typedef struct image_desc {
+	/* Contains unique image id for the image. */
+	unsigned int image_id;
+	image_info_t image_info;
+	entry_point_info_t ep_info;
+	/*
+	 * This member contains Image state information.
+	 * Refer IMAGE_STATE_XXX defined above.
+	 */
+	unsigned int state;
+} image_desc_t;
+
 /*******************************************************************************
  * This structure represents the superset of information that can be passed to
  * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
diff --git a/include/bl31/context.h b/include/common/context.h
similarity index 100%
rename from include/bl31/context.h
rename to include/common/context.h
diff --git a/include/bl31/context_mgmt.h b/include/common/context_mgmt.h
similarity index 77%
rename from include/bl31/context_mgmt.h
rename to include/common/context_mgmt.h
index 1ef4076..141b348 100644
--- a/include/bl31/context_mgmt.h
+++ b/include/common/context_mgmt.h
@@ -31,9 +31,9 @@
 #ifndef __CM_H__
 #define __CM_H__
 
+#include <arch.h>
+#include <bl_common.h>
 #include <common_def.h>
-#include <cpu_data.h>
-#include <stdint.h>
 
 /*******************************************************************************
  * Forward declarations
@@ -46,7 +46,6 @@
 void cm_init(void);
 void *cm_get_context_by_mpidr(uint64_t mpidr,
 			      uint32_t security_state) __warn_deprecated;
-static inline void *cm_get_context(uint32_t security_state);
 void cm_set_context_by_mpidr(uint64_t mpidr,
 			     void *context,
 			     uint32_t security_state) __warn_deprecated;
@@ -55,7 +54,9 @@
 void cm_set_context_by_index(unsigned int cpu_idx,
 			     void *context,
 			     unsigned int security_state);
-static inline void cm_set_context(void *context, uint32_t security_state);
+void *cm_get_context(uint32_t security_state);
+void cm_set_context(void *context, uint32_t security_state);
+inline void cm_set_next_context(void *context);
 void cm_init_context(uint64_t mpidr,
 		     const struct entry_point_info *ep) __warn_deprecated;
 void cm_init_my_context(const struct entry_point_info *ep);
@@ -76,27 +77,28 @@
 /* Inline definitions */
 
 /*******************************************************************************
- * This function returns a pointer to the most recent 'cpu_context' structure
- * for the calling CPU that was set as the context for the specified security
- * state. NULL is returned if no such structure has been specified.
+ * This function is used to program the context that's used for exception
+ * return. This initializes the SP_EL3 to a pointer to a 'cpu_context' set for
+ * the required security state
  ******************************************************************************/
-void *cm_get_context(uint32_t security_state)
+inline void cm_set_next_context(void *context)
 {
-	assert(security_state <= NON_SECURE);
+#if DEBUG
+	uint64_t sp_mode;
 
-	return get_cpu_data(cpu_context[security_state]);
-}
+	/*
+	 * Check that this function is called with SP_EL0 as the stack
+	 * pointer
+	 */
+	__asm__ volatile("mrs	%0, SPSel\n"
+			 : "=r" (sp_mode));
 
-/*******************************************************************************
- * This function sets the pointer to the current 'cpu_context' structure for the
- * specified security state for the calling CPU
- ******************************************************************************/
-void cm_set_context(void *context, uint32_t security_state)
-{
-	assert(security_state <= NON_SECURE);
+	assert(sp_mode == MODE_SP_EL0);
+#endif
 
-	set_cpu_data(cpu_context[security_state], context);
+	__asm__ volatile("msr	spsel, #1\n"
+			 "mov	sp, %0\n"
+			 "msr	spsel, #0\n"
+			 : : "r" (context));
 }
-
-
 #endif /* __CM_H__ */
diff --git a/include/common/el3_common_macros.S b/include/common/el3_common_macros.S
index 87e172e..0514e2a 100644
--- a/include/common/el3_common_macros.S
+++ b/include/common/el3_common_macros.S
@@ -247,13 +247,11 @@
 #endif
 	.endif /* _init_c_runtime */
 
-#if IMAGE_BL31
 	/* ---------------------------------------------------------------------
 	 * Use SP_EL0 for the C runtime stack.
 	 * ---------------------------------------------------------------------
 	 */
 	msr	spsel, #0
-#endif /* IMAGE_BL31 */
 
 	/* ---------------------------------------------------------------------
 	 * Allocate a stack whose memory will be marked as Normal-IS-WBWA when
diff --git a/include/common/firmware_image_package.h b/include/common/firmware_image_package.h
index 8fb669e..daa043a 100644
--- a/include/common/firmware_image_package.h
+++ b/include/common/firmware_image_package.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -39,6 +39,14 @@
 
 
 /* ToC Entry UUIDs */
+#define UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U \
+	{0x03279265, 0x742f, 0x44e6, 0x8d, 0xff, {0x57, 0x9a, 0xc1, 0xff, 0x06, 0x10} }
+#define UUID_TRUSTED_UPDATE_FIRMWARE_BL2U \
+	{0x37ebb360, 0xe5c1, 0x41ea, 0x9d, 0xf3, {0x19, 0xed, 0xa1, 0x1f, 0x68, 0x01} }
+#define UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U \
+	{0x111d514f, 0xe52b, 0x494e, 0xb4, 0xc5, {0x83, 0xc2, 0xf7, 0x15, 0x84, 0x0a} }
+#define UUID_TRUSTED_FWU_CERT \
+	{0xb28a4071, 0xd618, 0x4c87, 0x8b, 0x2e, {0xc6, 0xdc, 0xcd, 0x50, 0xf0, 0x96} }
 #define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \
 	{0x0becf95f, 0x224d, 0x4d3e, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} }
 #define UUID_SCP_FIRMWARE_BL30 \
diff --git a/include/common/smcc_helpers.h b/include/common/smcc_helpers.h
new file mode 100644
index 0000000..6a07b01
--- /dev/null
+++ b/include/common/smcc_helpers.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SMCC_HELPERS_H__
+#define __SMCC_HELPERS_H__
+
+/*******************************************************************************
+ * Bit definitions inside the function id as per the SMC calling convention
+ ******************************************************************************/
+#define FUNCID_TYPE_SHIFT		31
+#define FUNCID_CC_SHIFT			30
+#define FUNCID_OEN_SHIFT		24
+#define FUNCID_NUM_SHIFT		0
+
+#define FUNCID_TYPE_MASK		0x1
+#define FUNCID_CC_MASK			0x1
+#define FUNCID_OEN_MASK			0x3f
+#define FUNCID_NUM_MASK			0xffff
+
+#define FUNCID_TYPE_WIDTH		1
+#define FUNCID_CC_WIDTH			1
+#define FUNCID_OEN_WIDTH		6
+#define FUNCID_NUM_WIDTH		16
+
+#define GET_SMC_CC(id)			((id >> FUNCID_CC_SHIFT) & \
+					 FUNCID_CC_MASK)
+#define GET_SMC_TYPE(id)		((id >> FUNCID_TYPE_SHIFT) & \
+					 FUNCID_TYPE_MASK)
+
+#define SMC_64				1
+#define SMC_32				0
+#define SMC_UNK				0xffffffff
+#define SMC_TYPE_FAST			1
+#define SMC_TYPE_STD			0
+#define SMC_PREEMPTED		0xfffffffe
+/*******************************************************************************
+ * Owning entity number definitions inside the function id as per the SMC
+ * calling convention
+ ******************************************************************************/
+#define OEN_ARM_START			0
+#define OEN_ARM_END			0
+#define OEN_CPU_START			1
+#define OEN_CPU_END			1
+#define OEN_SIP_START			2
+#define OEN_SIP_END			2
+#define OEN_OEM_START			3
+#define OEN_OEM_END			3
+#define OEN_STD_START			4	/* Standard Calls */
+#define OEN_STD_END			4
+#define OEN_TAP_START			48	/* Trusted Applications */
+#define OEN_TAP_END			49
+#define OEN_TOS_START			50	/* Trusted OS */
+#define OEN_TOS_END			63
+#define OEN_LIMIT			64
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <context.h>
+#include <stdint.h>
+
+/* Various flags passed to SMC handlers */
+#define SMC_FROM_SECURE		(0 << 0)
+#define SMC_FROM_NON_SECURE	(1 << 0)
+
+#define is_caller_non_secure(_f)	(!!(_f & SMC_FROM_NON_SECURE))
+#define is_caller_secure(_f)		(!(is_caller_non_secure(_f)))
+
+/* Convenience macros to return from SMC handler */
+#define SMC_RET0(_h)	{ \
+	return (uint64_t) (_h);		\
+}
+#define SMC_RET1(_h, _x0)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X0, (_x0)); \
+	SMC_RET0(_h);						\
+}
+#define SMC_RET2(_h, _x0, _x1)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X1, (_x1)); \
+	SMC_RET1(_h, (_x0)); \
+}
+#define SMC_RET3(_h, _x0, _x1, _x2)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X2, (_x2)); \
+	SMC_RET2(_h, (_x0), (_x1)); \
+}
+#define SMC_RET4(_h, _x0, _x1, _x2, _x3)	{ \
+	write_ctx_reg(get_gpregs_ctx(_h), CTX_GPREG_X3, (_x3)); \
+	SMC_RET3(_h, (_x0), (_x1), (_x2)); \
+}
+
+/*
+ * Convenience macros to access general purpose registers using handle provided
+ * to SMC handler. These takes the offset values defined in context.h
+ */
+#define SMC_GET_GP(_h, _g) \
+	read_ctx_reg(get_gpregs_ctx(_h), (_g));
+#define SMC_SET_GP(_h, _g, _v) \
+	write_ctx_reg(get_gpregs_ctx(_h), (_g), (_v));
+
+/*
+ * Convenience macros to access EL3 context registers using handle provided to
+ * SMC handler. These takes the offset values defined in context.h
+ */
+#define SMC_GET_EL3(_h, _e) \
+	read_ctx_reg(get_el3state_ctx(_h), (_e));
+#define SMC_SET_EL3(_h, _e, _v) \
+	write_ctx_reg(get_el3state_ctx(_h), (_e), (_v));
+
+/* The macro below is used to identify a Standard Service SMC call */
+#define is_std_svc_call(_fid)		((((_fid) >> FUNCID_OEN_SHIFT) & \
+					   FUNCID_OEN_MASK) == OEN_STD_START)
+
+/* The macro below is used to identify a valid Fast SMC call */
+#define is_valid_fast_smc(_fid)		((!(((_fid) >> 16) & 0xff)) && \
+					   (GET_SMC_TYPE(_fid) == SMC_TYPE_FAST))
+
+/*
+ * Macro to define UUID for services. Apart from defining and initializing a
+ * uuid_t structure, this macro verifies that the first word of the defined UUID
+ * does not equal SMC_UNK. This is to ensure that the caller won't mistake the
+ * returned UUID in x0 for an invalid SMC error return
+ */
+#define DEFINE_SVC_UUID(_name, _tl, _tm, _th, _cl, _ch, \
+		_n0, _n1, _n2, _n3, _n4, _n5) \
+	CASSERT(_tl != SMC_UNK, invalid_svc_uuid);\
+	static const uuid_t _name = { \
+		_tl, _tm, _th, _cl, _ch, \
+		{ _n0, _n1, _n2, _n3, _n4, _n5 } \
+	}
+
+/* Return a UUID in the SMC return registers */
+#define SMC_UUID_RET(_h, _uuid) \
+	SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
+			 ((const uint32_t *) &(_uuid))[1], \
+			 ((const uint32_t *) &(_uuid))[2], \
+			 ((const uint32_t *) &(_uuid))[3])
+
+#endif /*__ASSEMBLY__*/
+#endif /* __SMCC_HELPERS_H__ */
diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h
index c43c395..fabe0b9 100644
--- a/include/common/tbbr/tbbr_img_def.h
+++ b/include/common/tbbr/tbbr_img_def.h
@@ -63,4 +63,19 @@
 #define BL32_CERT_ID			14
 #define BL33_CERT_ID			15
 
+/* Non-Trusted ROM Firmware NS_BL1U */
+#define NS_BL1U_IMAGE_ID		16
+
+/* Trusted FWU Certificate */
+#define FWU_CERT_ID			17
+
+/* Trusted FWU SCP Firmware SCP_BL2U */
+#define SCP_BL2U_IMAGE_ID		18
+
+/* Trusted FWU Boot Firmware BL2U */
+#define BL2U_IMAGE_ID			19
+
+/* Non-Trusted FWU Firmware NS_BL2U */
+#define NS_BL2U_IMAGE_ID		20
+
 #endif /* __TBBR_IMG_DEF_H__ */
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h
index 3abf235..b4e4313 100644
--- a/include/plat/arm/board/common/board_arm_def.h
+++ b/include/plat/arm/board/common/board_arm_def.h
@@ -53,6 +53,8 @@
 # else
 #  define PLATFORM_STACK_SIZE 0x400
 # endif
+#elif IMAGE_BL2U
+# define PLATFORM_STACK_SIZE 0x200
 #elif IMAGE_BL31
 # define PLATFORM_STACK_SIZE 0x400
 #elif IMAGE_BL32
@@ -65,10 +67,18 @@
  */
 #if IMAGE_BL1
 # if PLAT_fvp
-#  define PLAT_ARM_MMAP_ENTRIES		7
+#  if TRUSTED_BOARD_BOOT
+#   define PLAT_ARM_MMAP_ENTRIES	8
+#  else
+#   define PLAT_ARM_MMAP_ENTRIES	7
+#  endif	/* TRUSTED_BOARD_BOOT */
 # else
-#  define PLAT_ARM_MMAP_ENTRIES		6
-# endif
+#  if TRUSTED_BOARD_BOOT
+#   define PLAT_ARM_MMAP_ENTRIES	7
+#  else
+#   define PLAT_ARM_MMAP_ENTRIES	6
+#  endif	/* TRUSTED_BOARD_BOOT */
+# endif		/* PLAT_ */
 #endif
 #if IMAGE_BL2
 # if PLAT_fvp
@@ -77,6 +87,13 @@
 #  define PLAT_ARM_MMAP_ENTRIES		8
 # endif
 #endif
+#if IMAGE_BL2U
+# if PLAT_fvp
+#  define PLAT_ARM_MMAP_ENTRIES		3
+# else
+#  define PLAT_ARM_MMAP_ENTRIES		4
+#endif
+#endif
 #if IMAGE_BL31
 #define PLAT_ARM_MMAP_ENTRIES		5
 #endif
@@ -88,12 +105,22 @@
  * Platform specific page table and MMU setup constants
  */
 #if IMAGE_BL1
-# if PLAT_juno
-#  define MAX_XLAT_TABLES		2
+# if TRUSTED_BOARD_BOOT
+#  define MAX_XLAT_TABLES		4
 # else
+#  if PLAT_juno
+#   define MAX_XLAT_TABLES		2
+#  else
+#   define MAX_XLAT_TABLES		3
+#  endif /* PLAT_ */
+# endif	/* TRUSTED_BOARD_BOOT */
+#elif IMAGE_BL2
+# if PLAT_juno
 #  define MAX_XLAT_TABLES		3
+# else
+#  define MAX_XLAT_TABLES		4
 # endif /* PLAT_ */
-#elif IMAGE_BL2
+#elif IMAGE_BL2U
 # if PLAT_juno
 #  define MAX_XLAT_TABLES		3
 # else
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 5c03feb..4a50c1c 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -310,6 +310,14 @@
 # error "Unsupported ARM_TSP_RAM_LOCATION_ID value"
 #endif
 
+/*******************************************************************************
+ * FWU Images: NS_BL1U, BL2U & NS_BL2U defines.
+ ******************************************************************************/
+#define BL2U_BASE			BL2_BASE
+#define BL2U_LIMIT			BL31_BASE
+#define NS_BL2U_BASE			ARM_NS_DRAM1_BASE
+#define NS_BL1U_BASE			(V2M_FLASH0_BASE + 0x03EB8000)
+
 /*
  * ID of the secure physical generic timer interrupt used by the TSP.
  */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index f0b3ff6..bcb2e2b 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -165,6 +165,12 @@
 uint32_t arm_get_spsr_for_bl32_entry(void);
 uint32_t arm_get_spsr_for_bl33_entry(void);
 
+/* BL2U utility functions */
+void arm_bl2u_early_platform_setup(struct meminfo *mem_layout,
+				void *plat_info);
+void arm_bl2u_platform_setup(void);
+void arm_bl2u_plat_arch_setup(void);
+
 /* BL3-1 utility functions */
 void arm_bl31_early_platform_setup(bl31_params_t *from_bl2,
 				void *plat_params_from_bl2);
@@ -174,6 +180,8 @@
 /* TSP utility functions */
 void arm_tsp_early_platform_setup(void);
 
+/* FIP TOC validity check */
+int arm_io_is_toc_valid(void);
 
 /*
  * Mandatory functions required in ARM standard platforms
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 99491f8..3fa4c15 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -50,6 +50,10 @@
 #define NSRAM_BASE			0x2e000000
 #define NSRAM_SIZE			0x00008000
 
+/* System Security Control Registers */
+#define SSC_REG_BASE			0x2a420000
+#define SSC_GPRETN			(SSC_REG_BASE + 0x030)
+
 /* The slave_bootsecure controls access to GPU, DMC and CS. */
 #define CSS_NIC400_SLAVE_BOOTSECURE	8
 
@@ -112,6 +116,8 @@
  */
 #define BL30_BASE			BL31_BASE
 
+#define SCP_BL2U_BASE			BL31_BASE
+
 #define PLAT_ARM_SHARED_RAM_CACHED	MHU_PAYLOAD_CACHED
 
 /* Load address of Non-Secure Image for CSS platform ports */
diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h
index 43c69cc..4175b14 100644
--- a/include/plat/common/common_def.h
+++ b/include/plat/common/common_def.h
@@ -30,6 +30,9 @@
 #ifndef __COMMON_DEF_H__
 #define __COMMON_DEF_H__
 
+#include <bl_common.h>
+#include <platform_def.h>
+
 /******************************************************************************
  * Required platform porting definitions that are expected to be common to
  * all platforms
@@ -74,5 +77,14 @@
  */
 #define __warn_deprecated	__attribute__ ((deprecated))
 
+#define BL2_IMAGE_DESC {				\
+	.image_id = BL2_IMAGE_ID,			\
+	.image_info.h.version = VERSION_1,		\
+	.image_info.h.attr = SET_EXEC_STATE(EXECUTABLE),\
+	.image_info.image_base = BL2_BASE,		\
+	.ep_info.h.attr = SET_SEC_STATE(SECURE),	\
+	.ep_info.pc = BL2_BASE				\
+}
+
 #endif /* __COMMON_DEF_H__ */
 
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index de9848b..9fbc172 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -43,6 +43,7 @@
 struct image_info;
 struct entry_point_info;
 struct bl31_params;
+struct image_desc;
 
 /*******************************************************************************
  * plat_get_rotpk_info() flags
@@ -92,11 +93,11 @@
 struct meminfo *bl1_plat_sec_mem_layout(void);
 
 /*
- * This function allows the platform to change the entrypoint information for
- * BL2, after BL1 has loaded BL2 into memory but before BL2 is executed.
+ * The following function is mandatory when the
+ * firmware update feature is used.
  */
-void bl1_plat_set_bl2_ep_info(struct image_info *image,
-			      struct entry_point_info *ep);
+int bl1_plat_mem_check(uintptr_t mem_base, unsigned int mem_size,
+		unsigned int flags);
 
 /*******************************************************************************
  * Optional BL1 functions (may be overridden)
@@ -104,6 +105,25 @@
 void bl1_init_bl2_mem_layout(const struct meminfo *bl1_mem_layout,
 			     struct meminfo *bl2_mem_layout);
 
+/*
+ * The following functions are used for image loading process in BL1.
+ */
+void bl1_plat_set_ep_info(unsigned int image_id,
+		struct entry_point_info *ep_info);
+/*
+ * The following functions are mandatory when firmware update
+ * feature is used and optional otherwise.
+ */
+unsigned int bl1_plat_get_next_image_id(void);
+struct image_desc *bl1_plat_get_image_desc(unsigned int image_id);
+
+/*
+ * The following functions are used by firmware update
+ * feature and may optionally be overridden.
+ */
+__dead2 void bl1_plat_fwu_done(void *cookie, void *reserved);
+
+
 /*******************************************************************************
  * Mandatory BL2 functions
  ******************************************************************************/
@@ -173,6 +193,23 @@
  ******************************************************************************/
 
 /*******************************************************************************
+ * Mandatory BL2U functions.
+ ******************************************************************************/
+void bl2u_early_platform_setup(struct meminfo *mem_layout,
+		void *plat_info);
+void bl2u_plat_arch_setup(void);
+void bl2u_platform_setup(void);
+
+/*******************************************************************************
+ * Conditionally mandatory BL2U functions for CSS platforms.
+ ******************************************************************************/
+/*
+ * This function is used to perform any platform-specific actions required to
+ * handle the BL2U_SCP firmware.
+ */
+int bl2u_plat_handle_scp_bl2u(void);
+
+/*******************************************************************************
  * Mandatory BL3-1 functions
  ******************************************************************************/
 void bl31_early_platform_setup(struct bl31_params *from_bl2,
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 9ab6e64..08cb4b1 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -28,6 +28,22 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
+# This table is used in converting lower case to upper case.
+uppercase_table:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
+
+# Internal macro used for converting lower case to upper case.
+#   $(1) = upper case table
+#   $(2) = String to convert
+define uppercase_internal
+$(if $(1),$$(subst $(firstword $(1)),$(call uppercase_internal,$(wordlist 2,$(words $(1)),$(1)),$(2))),$(2))
+endef
+
+# A macro for converting a string to upper case
+#   $(1) = String to convert
+define uppercase
+$(eval uppercase_result:=$(call uppercase_internal,$(uppercase_table),$(1)))$(uppercase_result)
+endef
+
 # Convenience function for adding build definitions
 # $(eval $(call add_define,FOO)) will have:
 # -DFOO if $(FOO) is empty; -DFOO=$(FOO) otherwise
@@ -82,7 +98,7 @@
     $(eval $(if $(3),FIP_DEPS += $(3)))
 endef
 
-# CERT_ADD_CMD_OPT adds a new command line option to the cert_create invokation
+# CERT_ADD_CMD_OPT adds a new command line option to the cert_create invocation
 #   $(1) = parameter filename
 #   $(2) = cert_create command line option for the specified parameter
 #   $(3) = input parameter (false if empty)
@@ -107,6 +123,38 @@
 	$$(if $(value $(1)),,$$(error "Platform '${PLAT}' requires $(1). Please set $(1) to point to the right file"))
 endef
 
+# FWU_FIP_ADD_PAYLOAD appends the command line arguments required by the FIP tool
+# to package a new FWU payload. Optionally, it  adds the dependency on this payload
+#   $(1) = payload filename (e.g. ns_bl2u.bin)
+#   $(2) = command line option for the specified payload (e.g. --ns_bl2u)
+#   $(3) = fip target dependency (optional) (e.g. ns_bl2u)
+define FWU_FIP_ADD_PAYLOAD
+    $(eval $(if $(3),FWU_FIP_DEPS += $(3)))
+    $(eval FWU_FIP_ARGS += $(2) $(1))
+endef
+
+# FWU_CERT_ADD_CMD_OPT adds a new command line option to the cert_create invocation
+#   $(1) = parameter filename
+#   $(2) = cert_create command line option for the specified parameter
+#   $(3) = input parameter (false if empty)
+define FWU_CERT_ADD_CMD_OPT
+    $(eval $(if $(3),FWU_CRT_DEPS += $(1)))
+    $(eval FWU_CRT_ARGS += $(2) $(1))
+endef
+
+# FWU_FIP_ADD_IMG allows the platform to pack a binary image in the FWU FIP
+#   $(1) build option to specify the image filename (BL2U, NS_BL2U, etc)
+#   $(2) command line option for the fip_create tool (bl2u, ns_bl2u, etc)
+# Example:
+#   $(eval $(call FWU_FIP_ADD_IMG,BL2U,--bl2u))
+define FWU_FIP_ADD_IMG
+    FWU_CRT_DEPS += check_$(1)
+    FWU_FIP_DEPS += check_$(1)
+    $(call FWU_FIP_ADD_PAYLOAD,$(value $(1)),$(2))
+
+check_$(1):
+	$$(if $(value $(1)),,$$(error "Platform '${PLAT}' requires $(1). Please set $(1) to point to the right file"))
+endef
 
 ################################################################################
 # Auxiliary macros to build TF images from sources
@@ -123,7 +171,7 @@
 endef
 
 # List of rules that involve building things
-BUILD_TARGETS := all bl1 bl2 bl31 bl32 certificates fip
+BUILD_TARGETS := all bl1 bl2 bl2u bl31 bl32 certificates fip
 
 # Does the list of goals specified on the command line include a build target?
 ifneq ($(call match_goals,${BUILD_TARGETS}),)
@@ -134,15 +182,16 @@
 # MAKE_C builds a C source file and generates the dependency file
 #   $(1) = output directory
 #   $(2) = source file (%.c)
-#   $(3) = BL stage (2, 30, 31, 32, 33)
+#   $(3) = BL stage (2, 2u, 30, 31, 32, 33)
 define MAKE_C
 
 $(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
 $(eval PREREQUISITES := $(patsubst %.o,%.d,$(OBJ)))
+$(eval IMAGE := IMAGE_BL$(call uppercase,$(3)))
 
 $(OBJ): $(2)
 	@echo "  CC      $$<"
-	$$(Q)$$(CC) $$(CFLAGS) -DIMAGE_BL$(3) -c $$< -o $$@
+	$$(Q)$$(CC) $$(CFLAGS) -D$(IMAGE) -c $$< -o $$@
 
 
 $(PREREQUISITES): $(2)
@@ -160,15 +209,16 @@
 # MAKE_S builds an assembly source file and generates the dependency file
 #   $(1) = output directory
 #   $(2) = assembly file (%.S)
-#   $(3) = BL stage (2, 30, 31, 32, 33)
+#   $(3) = BL stage (2, 2u, 30, 31, 32, 33)
 define MAKE_S
 
 $(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
 $(eval PREREQUISITES := $(patsubst %.o,%.d,$(OBJ)))
+$(eval IMAGE := IMAGE_BL$(call uppercase,$(3)))
 
 $(OBJ): $(2)
 	@echo "  AS      $$<"
-	$$(Q)$$(AS) $$(ASFLAGS) -DIMAGE_BL$(3) -c $$< -o $$@
+	$$(Q)$$(AS) $$(ASFLAGS) -D$(IMAGE) -c $$< -o $$@
 
 $(PREREQUISITES): $(2)
 	@echo "  DEPS    $$@"
@@ -243,20 +293,22 @@
 
 # MAKE_BL macro defines the targets and options to build each BL image.
 # Arguments:
-#   $(1) = BL stage (2, 30, 31, 32, 33)
+#   $(1) = BL stage (2, 2u, 30, 31, 32, 33)
 #   $(2) = In FIP (false if empty)
 define MAKE_BL
         $(eval BUILD_DIR  := ${BUILD_PLAT}/bl$(1))
-        $(eval SOURCES    := $(BL$(1)_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
+        $(eval BL_SOURCES := $(BL$(call uppercase,$(1))_SOURCES))
+        $(eval SOURCES    := $(BL_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES))
         $(eval OBJS       := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
         $(eval LINKERFILE := $(call IMG_LINKERFILE,$(1)))
         $(eval MAPFILE    := $(call IMG_MAPFILE,$(1)))
         $(eval ELF        := $(call IMG_ELF,$(1)))
         $(eval DUMP       := $(call IMG_DUMP,$(1)))
         $(eval BIN        := $(call IMG_BIN,$(1)))
+        $(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE))
 
         $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
-        $(eval $(call MAKE_LD,$(LINKERFILE),$(BL$(1)_LINKERFILE)))
+        $(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE)))
 
 $(BUILD_DIR):
 	$$(Q)mkdir -p "$$@"
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 2ec72b9..bf0d296 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -56,16 +56,22 @@
 
 # Certificate generation tool default parameters
 TRUSTED_KEY_CERT	:=	${BUILD_PLAT}/trusted_key.crt
+FWU_CERT		:=	${BUILD_PLAT}/fwu_cert.crt
 
 # Add Trusted Key certificate to the fip_create and cert_create command line options
 $(eval $(call FIP_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert))
 $(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_KEY_CERT},--trusted-key-cert))
 
+# Add fwu certificate to the fip_create and cert_create command line options
+$(eval $(call FWU_FIP_ADD_PAYLOAD,${FWU_CERT},--fwu-cert))
+$(eval $(call FWU_CERT_ADD_CMD_OPT,${FWU_CERT},--fwu-cert))
+
 # Add the keys to the cert_create command line options (private keys are NOT
 # packed in the FIP). Developers can use their own keys by specifying the proper
 # build option in the command line when building the Trusted Firmware
 $(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg)))
 $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
+$(if ${ROT_KEY},$(eval $(call FWU_CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
 $(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key)))
 $(if ${NON_TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${NON_TRUSTED_WORLD_KEY},--non-trusted-world-key)))
 
@@ -114,3 +120,17 @@
     $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/bl33.crt,--bl33-cert))
     $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/bl33_key.crt,--bl33-key-cert))
 endif
+
+# Add the BL2U image
+$(if ${BL2U},$(eval $(call FWU_CERT_ADD_CMD_OPT,${BL2U},--bl2u,true)),\
+     $(eval $(call FWU_CERT_ADD_CMD_OPT,$(call IMG_BIN,2u),--bl2u,true)))
+
+# Add the SCP_BL2U image
+ifneq (${SCP_BL2U},)
+    $(eval $(call FWU_CERT_ADD_CMD_OPT,${SCP_BL2U},--scp_bl2u,true))
+endif
+
+# Add the NS_BL2U image
+ifneq (${NS_BL2U},)
+    $(eval $(call FWU_CERT_ADD_CMD_OPT,${NS_BL2U},--ns_bl2u,true))
+endif
diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c
index 7bf0273..62253f8 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -42,6 +42,9 @@
 	V2M_MAP_IOFPGA,
 	CSS_MAP_DEVICE,
 	SOC_CSS_MAP_DEVICE,
+#if TRUSTED_BOARD_BOOT
+	ARM_MAP_NS_DRAM1,
+#endif
 	{0}
 };
 #endif
@@ -57,6 +60,14 @@
 	{0}
 };
 #endif
+#if IMAGE_BL2U
+const mmap_region_t plat_arm_mmap[] = {
+	ARM_MAP_SHARED_RAM,
+	CSS_MAP_DEVICE,
+	SOC_CSS_MAP_DEVICE,
+	{0}
+};
+#endif
 #if IMAGE_BL31
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
diff --git a/plat/arm/board/fvp/aarch64/fvp_common.c b/plat/arm/board/fvp/aarch64/fvp_common.c
index e089405..305505d 100644
--- a/plat/arm/board/fvp/aarch64/fvp_common.c
+++ b/plat/arm/board/fvp/aarch64/fvp_common.c
@@ -82,6 +82,9 @@
 	MAP_DEVICE0,
 	MAP_DEVICE1,
 	MAP_DEVICE2,
+#if TRUSTED_BOARD_BOOT
+	ARM_MAP_NS_DRAM1,
+#endif
 	{0}
 };
 #endif
@@ -98,6 +101,13 @@
 	{0}
 };
 #endif
+#if IMAGE_BL2U
+const mmap_region_t plat_arm_mmap[] = {
+	MAP_DEVICE0,
+	V2M_MAP_IOFPGA,
+	{0}
+};
+#endif
 #if IMAGE_BL31
 const mmap_region_t plat_arm_mmap[] = {
 	ARM_MAP_SHARED_RAM,
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index 33712d1..91bc9c4 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -29,6 +29,7 @@
  */
 
 #include <plat_arm.h>
+#include <tbbr_img_def.h>
 #include "fvp_private.h"
 
 
@@ -52,3 +53,16 @@
 	 */
 	fvp_cci_enable();
 }
+
+/*******************************************************************************
+ * The following function checks if Firmware update is needed,
+ * by checking if TOC in FIP image is valid or not.
+ ******************************************************************************/
+unsigned int bl1_plat_get_next_image_id(void)
+{
+	if (!arm_io_is_toc_valid())
+		return NS_BL1U_IMAGE_ID;
+
+	return BL2_IMAGE_ID;
+}
+
diff --git a/plat/arm/board/fvp/fvp_bl2u_setup.c b/plat/arm/board/fvp/fvp_bl2u_setup.c
new file mode 100644
index 0000000..b26f0e0
--- /dev/null
+++ b/plat/arm/board/fvp/fvp_bl2u_setup.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <plat_arm.h>
+#include "fvp_def.h"
+#include "fvp_private.h"
+
+void bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
+{
+	arm_bl2u_early_platform_setup(mem_layout, plat_info);
+
+	/* Initialize the platform config for future decision making */
+	fvp_config_setup();
+}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index b6f0739..cb5f5d7 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -83,6 +83,9 @@
 				plat/arm/board/fvp/fvp_io_storage.c		\
 				plat/arm/board/fvp/fvp_security.c
 
+BL2U_SOURCES		+=	plat/arm/board/fvp/fvp_bl2u_setup.c		\
+				plat/arm/board/fvp/fvp_security.c
+
 BL31_SOURCES		+=	lib/cpus/aarch64/aem_generic.S			\
 				lib/cpus/aarch64/cortex_a53.S			\
 				lib/cpus/aarch64/cortex_a57.S			\
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
new file mode 100644
index 0000000..61a5738
--- /dev/null
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bl_common.h>
+#include <errno.h>
+#include <platform.h>
+#include <plat_arm.h>
+#include <tbbr_img_def.h>
+#include <v2m_def.h>
+
+#define RESET_REASON_WDOG_RESET		(0x2)
+
+/*******************************************************************************
+ * The following function checks if Firmware update is needed,
+ * by checking if TOC in FIP image is valid or watchdog reset happened.
+ ******************************************************************************/
+unsigned int bl1_plat_get_next_image_id(void)
+{
+	unsigned int *reset_flags_ptr = (unsigned int *)SSC_GPRETN;
+	unsigned int *nv_flags_ptr = (unsigned int *)
+			(V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS);
+	/*
+	 * Check if TOC is invalid or watchdog reset happened.
+	 */
+	if ((arm_io_is_toc_valid() != 1) ||
+		((*reset_flags_ptr & RESET_REASON_WDOG_RESET) &&
+		((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT))))
+		return NS_BL1U_IMAGE_ID;
+
+	return BL2_IMAGE_ID;
+}
+
+/*******************************************************************************
+ * On JUNO update the arg2 with address of SCP_BL2U image info.
+ ******************************************************************************/
+void bl1_plat_set_ep_info(unsigned int image_id,
+		entry_point_info_t *ep_info)
+{
+	if (image_id == BL2U_IMAGE_ID) {
+		image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID);
+		ep_info->args.arg2 = (unsigned long)&image_desc->image_info;
+	}
+}
+
+/*******************************************************************************
+ * On Juno clear SYS_NVFLAGS and wait for watchdog reset.
+ ******************************************************************************/
+__dead2 void bl1_plat_fwu_done(void *cookie, void *rsvd_ptr)
+{
+	unsigned int *nv_flags_clr = (unsigned int *)
+			(V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR);
+	unsigned int *nv_flags_ptr = (unsigned int *)
+			(V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS);
+
+	/* Clear the NV flags register. */
+	*nv_flags_clr = *nv_flags_ptr;
+
+	while (1)
+		wfi();
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 0212fdd..fae30e7 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -41,11 +41,14 @@
 BL1_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
 				lib/cpus/aarch64/cortex_a72.S		\
+				plat/arm/board/juno/juno_bl1_setup.c	\
 				plat/arm/board/juno/juno_err.c
 
 BL2_SOURCES		+=	plat/arm/board/juno/juno_security.c	\
 				plat/arm/board/juno/juno_err.c
 
+BL2U_SOURCES		+=	plat/arm/board/juno/juno_security.c
+
 BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
 				lib/cpus/aarch64/cortex_a72.S		\
diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c
new file mode 100644
index 0000000..9a0d93a
--- /dev/null
+++ b/plat/arm/common/arm_bl1_fwu.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <errno.h>
+#include <plat_arm.h>
+#include <tbbr_img_desc.h>
+
+
+/* Struct to keep track of usable memory */
+typedef struct bl1_mem_info{
+	uintptr_t mem_base;
+	unsigned int mem_size;
+} bl1_mem_info_t;
+
+bl1_mem_info_t fwu_addr_map_secure[] = {
+	{
+		.mem_base = ARM_SHARED_RAM_BASE,
+		.mem_size = ARM_SHARED_RAM_SIZE
+	},
+	{
+		.mem_size = 0
+	}
+};
+
+bl1_mem_info_t fwu_addr_map_non_secure[] = {
+	{
+		.mem_base = ARM_NS_DRAM1_BASE,
+		.mem_size = ARM_NS_DRAM1_SIZE
+	},
+	{
+		.mem_base = V2M_FLASH0_BASE,
+		.mem_size = V2M_FLASH0_SIZE
+	},
+	{
+		.mem_size = 0
+	}
+};
+
+int bl1_plat_mem_check(uintptr_t mem_base,
+		unsigned int mem_size,
+		unsigned int flags)
+{
+	unsigned int index = 0;
+	bl1_mem_info_t *mmap;
+
+	assert(mem_base);
+	assert(mem_size);
+
+	/*
+	 * Check the given image source and size.
+	 */
+	if (GET_SEC_STATE(flags) == SECURE)
+		mmap = fwu_addr_map_secure;
+	else
+		mmap = fwu_addr_map_non_secure;
+
+	while (mmap[index].mem_size) {
+		if ((mem_base >= mmap[index].mem_base) &&
+			((mem_base + mem_size)
+			<= (mmap[index].mem_base +
+			mmap[index].mem_size)))
+			return 0;
+
+		index++;
+	}
+
+	return -ENOMEM;
+}
+
+/*******************************************************************************
+ * This function does linear search for image_id and returns image_desc.
+ ******************************************************************************/
+image_desc_t *bl1_plat_get_image_desc(unsigned int image_id)
+{
+	unsigned int index = 0;
+
+	while (bl1_tbbr_image_descs[index].image_id != INVALID_IMAGE_ID) {
+		if (bl1_tbbr_image_descs[index].image_id == image_id)
+			return &bl1_tbbr_image_descs[index];
+		index++;
+	}
+
+	return NULL;
+}
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 79c7d94..d0a4c0b 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -57,7 +57,6 @@
 #pragma weak bl1_plat_arch_setup
 #pragma weak bl1_platform_setup
 #pragma weak bl1_plat_sec_mem_layout
-#pragma weak bl1_plat_set_bl2_ep_info
 
 
 /* Data structure which holds the extents of the trusted SRAM for BL1*/
@@ -169,16 +168,3 @@
 	sev();
 #endif
 }
-
-/*******************************************************************************
- * Before calling this function BL2 is loaded in memory and its entrypoint
- * is set by load_image. This is a placeholder for the platform to change
- * the entrypoint of BL2 and set SPSR and security state.
- * On ARM standard platforms we only set the security state of the entrypoint
- ******************************************************************************/
-void bl1_plat_set_bl2_ep_info(image_info_t *bl2_image,
-				entry_point_info_t *bl2_ep)
-{
-	SET_SECURITY_STATE(bl2_ep->h.attr, SECURE);
-	bl2_ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
-}
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
new file mode 100644
index 0000000..5b7354b
--- /dev/null
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <arm_def.h>
+#include <bl_common.h>
+#include <console.h>
+#include <platform_def.h>
+#include <plat_arm.h>
+#include <string.h>
+
+
+/*
+ * The next 2 constants identify the extents of the code & RO data region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __RO_START__ and __RO_END__ linker symbols refer to page-aligned addresses.
+ */
+#define BL2U_RO_BASE (unsigned long)(&__RO_START__)
+#define BL2U_RO_LIMIT (unsigned long)(&__RO_END__)
+
+#if USE_COHERENT_MEM
+/*
+ * The next 2 constants identify the extents of the coherent memory region.
+ * These addresses are used by the MMU setup code and therefore they must be
+ * page-aligned.  It is the responsibility of the linker script to ensure that
+ * __COHERENT_RAM_START__ and __COHERENT_RAM_END__ linker symbols refer to
+ * page-aligned addresses.
+ */
+#define BL2U_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
+#define BL2U_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
+#endif
+
+/* Weak definitions may be overridden in specific ARM standard platform */
+#pragma weak bl2u_platform_setup
+#pragma weak bl2u_early_platform_setup
+#pragma weak bl2u_plat_arch_setup
+
+/*
+ * Perform ARM standard platform setup for BL2U
+ */
+void arm_bl2u_platform_setup(void)
+{
+	/* Initialize the secure environment */
+	plat_arm_security_setup();
+}
+
+void bl2u_platform_setup(void)
+{
+	arm_bl2u_platform_setup();
+}
+
+void arm_bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PLAT_ARM_BOOT_UART_BASE, PLAT_ARM_BOOT_UART_CLK_IN_HZ,
+			ARM_CONSOLE_BAUDRATE);
+}
+
+/*******************************************************************************
+ * BL1 can pass platform dependent information to BL2U in x1.
+ * In case of ARM CSS platforms x1 contains SCP_BL2U image info.
+ * In case of ARM FVP platforms x1 is not used.
+ * In both cases, x0 contains the extents of the memory available to BL2U
+ ******************************************************************************/
+void bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
+{
+	arm_bl2u_early_platform_setup(mem_layout, plat_info);
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only initializes the mmu in a quick and dirty way.
+ * The memory that is used by BL2U is only mapped.
+ ******************************************************************************/
+void arm_bl2u_plat_arch_setup(void)
+{
+	arm_configure_mmu_el1(BL2U_RO_LIMIT,
+			      BL31_LIMIT,
+			      BL2U_RO_BASE,
+			      BL2U_RO_LIMIT
+#if USE_COHERENT_MEM
+			      ,
+			      BL2U_COHERENT_RAM_BASE,
+			      BL2U_COHERENT_RAM_LIMIT
+#endif
+		);
+}
+
+void bl2u_plat_arch_setup(void)
+{
+	arm_bl2u_plat_arch_setup();
+}
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 1336e23..4ac12d9 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -106,6 +106,11 @@
 				plat/arm/common/arm_security.c			\
 				plat/common/aarch64/platform_up_stack.S
 
+BL2U_SOURCES		+=	drivers/arm/tzc400/tzc400.c			\
+				plat/arm/common/arm_bl2u_setup.c		\
+				plat/arm/common/arm_security.c			\
+				plat/common/aarch64/platform_up_stack.S
+
 BL31_SOURCES		+=	drivers/arm/cci/cci.c				\
 				drivers/arm/ccn/ccn.c				\
 				drivers/arm/tzc400/tzc400.c			\
@@ -127,9 +132,16 @@
 				drivers/auth/img_parser_mod.c			\
 				drivers/auth/tbbr/tbbr_cot.c			\
 
-    BL1_SOURCES		+=	${AUTH_SOURCES}
+    PLAT_INCLUDES	+=	-Iinclude/bl1/tbbr
+
+    BL1_SOURCES		+=	${AUTH_SOURCES}			\
+				bl1/tbbr/tbbr_img_desc.c	\
+				plat/arm/common/arm_bl1_fwu.c
+
     BL2_SOURCES		+=	${AUTH_SOURCES}
 
+    $(eval $(call FWU_FIP_ADD_IMG,NS_BL2U,--ns_bl2u))
+
     MBEDTLS_KEY_ALG	:=	${KEY_ALG}
 
     # We expect to locate the *.mk files under the directories specified below
diff --git a/plat/arm/common/arm_io_storage.c b/plat/arm/common/arm_io_storage.c
index ae67cde..f7e99e9 100644
--- a/plat/arm/common/arm_io_storage.c
+++ b/plat/arm/common/arm_io_storage.c
@@ -308,3 +308,17 @@
 
 	return result;
 }
+
+/*
+ * See if a Firmware Image Package is available,
+ * by checking if TOC is valid or not.
+ */
+int arm_io_is_toc_valid(void)
+{
+	int result;
+
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+
+	return (result == 0);
+}
+
diff --git a/plat/arm/css/common/css_bl1_setup.c b/plat/arm/css/common/css_bl1_setup.c
new file mode 100644
index 0000000..2abed3b
--- /dev/null
+++ b/plat/arm/css/common/css_bl1_setup.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <soc_css.h>
+
+void bl1_platform_setup(void)
+{
+	arm_bl1_platform_setup();
+	/*
+	 * Do ARM CSS SoC security setup.
+	 * BL1 needs to enable normal world access to memory.
+	 */
+	soc_css_security_setup();
+}
+
diff --git a/plat/arm/css/common/css_bl2u_setup.c b/plat/arm/css/common/css_bl2u_setup.c
new file mode 100644
index 0000000..878b6fa
--- /dev/null
+++ b/plat/arm/css/common/css_bl2u_setup.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include "css_scp_bootloader.h"
+
+/* Weak definition may be overridden in specific CSS based platform */
+#pragma weak bl2u_plat_handle_scp_bl2u
+
+/* Data structure which holds the SCP_BL2U image info for BL2U */
+static image_info_t scp_bl2u_image_info;
+
+/*******************************************************************************
+ * BL1 can pass platform dependent information to BL2U in x1.
+ * In case of ARM CSS platforms x1 contains SCP_BL2U image info.
+ * In case of ARM FVP platforms x1 is not used.
+ * In both cases, x0 contains the extents of the memory available to BL2U
+ ******************************************************************************/
+void bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
+{
+	if (!plat_info)
+		panic();
+
+	arm_bl2u_early_platform_setup(mem_layout, plat_info);
+
+	scp_bl2u_image_info = *(image_info_t *)plat_info;
+}
+
+/*******************************************************************************
+ * Transfer SCP_BL2U from Trusted RAM using the SCP Download protocol.
+ ******************************************************************************/
+int bl2u_plat_handle_scp_bl2u(void)
+{
+	int ret;
+
+	INFO("BL2U: Initiating SCP_BL2U transfer to SCP\n");
+
+	ret = scp_bootloader_transfer((void *)scp_bl2u_image_info.image_base,
+		scp_bl2u_image_info.image_size);
+
+	if (ret == 0)
+		INFO("BL2U: SCP_BL2U transferred to SCP\n");
+	else
+		ERROR("BL2U: SCP_BL2U transfer failure\n");
+
+	return ret;
+}
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index 6394197..49fedc3 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -34,18 +34,26 @@
 
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/css/common/aarch64/css_helpers.S
 
-#BL1_SOURCES		+=
+BL1_SOURCES		+=	plat/arm/css/common/css_bl1_setup.c
 
 BL2_SOURCES		+=	plat/arm/css/common/css_bl2_setup.c		\
 				plat/arm/css/common/css_mhu.c			\
 				plat/arm/css/common/css_scp_bootloader.c	\
 				plat/arm/css/common/css_scpi.c
 
+BL2U_SOURCES		+=	plat/arm/css/common/css_bl2u_setup.c		\
+				plat/arm/css/common/css_mhu.c			\
+				plat/arm/css/common/css_scp_bootloader.c	\
+				plat/arm/css/common/css_scpi.c
+
 BL31_SOURCES		+=	plat/arm/css/common/css_mhu.c			\
 				plat/arm/css/common/css_pm.c			\
 				plat/arm/css/common/css_scpi.c			\
 				plat/arm/css/common/css_topology.c
 
+ifneq (${TRUSTED_BOARD_BOOT},0)
+$(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp_bl2u))
+endif
 
 ifneq (${RESET_TO_BL31},0)
   $(error "Using BL3-1 as the reset vector is not supported on CSS platforms. \
diff --git a/plat/arm/soc/common/soc_css.mk b/plat/arm/soc/common/soc_css.mk
index d8a99a8..7ae8fdb 100644
--- a/plat/arm/soc/common/soc_css.mk
+++ b/plat/arm/soc/common/soc_css.mk
@@ -32,9 +32,10 @@
 
 #PLAT_BL_COMMON_SOURCES	+=
 
-
-#BL1_SOURCES		+=
+BL1_SOURCES		+=	plat/arm/soc/common/soc_css_security.c
 
 BL2_SOURCES		+=	plat/arm/soc/common/soc_css_security.c
 
+BL2U_SOURCES		+=	plat/arm/soc/common/soc_css_security.c
+
 BL31_SOURCES		+=	plat/arm/soc/common/soc_css_security.c
diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c
new file mode 100644
index 0000000..aee9440
--- /dev/null
+++ b/plat/common/plat_bl1_common.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <errno.h>
+#include <platform_def.h>
+
+/*
+ * The following platform functions are weakly defined. They
+ * are default implementations that allow BL1 to compile in
+ * absence of real definitions. The Platforms may override
+ * with more complex definitions.
+ */
+#pragma weak bl1_plat_get_next_image_id
+#pragma weak bl1_plat_set_ep_info
+#pragma weak bl1_plat_get_image_desc
+#pragma weak bl1_plat_fwu_done
+
+
+unsigned int bl1_plat_get_next_image_id(void)
+{
+	/* BL2 load will be done by default. */
+	return BL2_IMAGE_ID;
+}
+
+void bl1_plat_set_ep_info(unsigned int image_id,
+		entry_point_info_t *ep_info)
+{
+
+}
+
+/*
+ * Following is the default definition that always
+ * returns BL2 image details.
+ */
+image_desc_t *bl1_plat_get_image_desc(unsigned int image_id)
+{
+	static image_desc_t bl2_img_desc = BL2_IMAGE_DESC;
+	return &bl2_img_desc;
+}
+
+__dead2 void bl1_plat_fwu_done(void *cookie, void *rsvd_ptr)
+{
+	while (1)
+		wfi();
+}
+
+/*
+ * The Platforms must override with real definition.
+ */
+#pragma weak bl1_plat_mem_check
+
+int bl1_plat_mem_check(uintptr_t mem_base, unsigned int mem_size,
+		unsigned int flags)
+{
+	assert(0);
+	return -ENOMEM;
+}
diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h
index 3c65473..0ede365 100644
--- a/tools/cert_create/include/ext.h
+++ b/tools/cert_create/include/ext.h
@@ -72,6 +72,8 @@
 	X509V3_EXT_METHOD method; /* This field may be used to define a custom
 				   * function to print the contents of the
 				   * extension */
+
+	int optional;	/* This field may be used optionally to exclude an image */
 } ext_t;
 
 enum {
diff --git a/tools/cert_create/include/tbbr/tbb_cert.h b/tools/cert_create/include/tbbr/tbb_cert.h
index 21626c7..2bc3be6 100644
--- a/tools/cert_create/include/tbbr/tbb_cert.h
+++ b/tools/cert_create/include/tbbr/tbb_cert.h
@@ -46,7 +46,8 @@
 	BL32_KEY_CERT,
 	BL32_CERT,
 	BL33_KEY_CERT,
-	BL33_CERT
+	BL33_CERT,
+	FWU_CERT
 };
 
 #endif /* TBB_CERT_H_ */
diff --git a/tools/cert_create/include/tbbr/tbb_ext.h b/tools/cert_create/include/tbbr/tbb_ext.h
index 03b12d7..ecbe866 100644
--- a/tools/cert_create/include/tbbr/tbb_ext.h
+++ b/tools/cert_create/include/tbbr/tbb_ext.h
@@ -46,7 +46,10 @@
 	BL32_CONTENT_CERT_PK_EXT,
 	BL32_HASH_EXT,
 	BL33_CONTENT_CERT_PK_EXT,
-	BL33_HASH_EXT
+	BL33_HASH_EXT,
+	SCP_BL2U_HASH_EXT,
+	BL2U_HASH_EXT,
+	NS_BL2U_HASH_EXT
 };
 
 #endif /* TBB_EXT_H_ */
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index b7ad33f..de15ef6 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -217,8 +217,11 @@
 				}
 				break;
 			case EXT_TYPE_HASH:
-				/* Binary image must be specified */
-				if (ext->data.fn == NULL) {
+				/*
+				 * Binary image must be specified
+				 * unless it is explicitly made optional.
+				 */
+				if ((!ext->optional) && (ext->data.fn == NULL)) {
 					ERROR("Image for '%s' not specified\n",
 					      ext->ln);
 					exit(1);
@@ -410,12 +413,20 @@
 				break;
 			case EXT_TYPE_HASH:
 				if (ext->data.fn == NULL) {
-					break;
-				}
-				if (!sha_file(ext->data.fn, md)) {
-					ERROR("Cannot calculate hash of %s\n",
-						ext->data.fn);
-					exit(1);
+					if (ext->optional) {
+						/* Include a hash filled with zeros */
+						memset(md, 0x0, SHA256_DIGEST_LENGTH);
+					} else {
+						/* Do not include this hash in the certificate */
+						break;
+					}
+				} else {
+					/* Calculate the hash of the file */
+					if (!sha_file(ext->data.fn, md)) {
+						ERROR("Cannot calculate hash of %s\n",
+							ext->data.fn);
+						exit(1);
+					}
 				}
 				CHECK_NULL(cert_ext, ext_new_hash(ext_nid,
 						EXT_CRIT, md_info, md,
diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c
index 770bd6a..59a1cd9 100644
--- a/tools/cert_create/src/tbbr/tbb_cert.c
+++ b/tools/cert_create/src/tbbr/tbb_cert.c
@@ -160,6 +160,20 @@
 			BL33_HASH_EXT
 		},
 		.num_ext = 1
+	},
+	[FWU_CERT] = {
+		.id = FWU_CERT,
+		.opt = "fwu-cert",
+		.fn = NULL,
+		.cn = "FWU Certificate",
+		.key = ROT_KEY,
+		.issuer = FWU_CERT,
+		.ext = {
+			SCP_BL2U_HASH_EXT,
+			BL2U_HASH_EXT,
+			NS_BL2U_HASH_EXT
+		},
+		.num_ext = 3
 	}
 };
 
diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c
index c39c9e6..b0af6f1 100644
--- a/tools/cert_create/src/tbbr/tbb_ext.c
+++ b/tools/cert_create/src/tbbr/tbb_ext.c
@@ -145,6 +145,33 @@
 		.ln = "Non-Trusted World (BL33) hash (SHA256)",
 		.asn1_type = V_ASN1_OCTET_STRING,
 		.type = EXT_TYPE_HASH
+	},
+	[SCP_BL2U_HASH_EXT] = {
+		.oid = SCP_BL2U_HASH_OID,
+		.opt = "scp_bl2u",
+		.sn = "SCPFWUpdateConfig",
+		.ln = "SCP Firmware Update Config (SCP_BL2U) hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[BL2U_HASH_EXT] = {
+		.oid = BL2U_HASH_OID,
+		.opt = "bl2u",
+		.sn = "APFWUpdateConfig",
+		.ln = "AP Firmware Update Config (BL2U) hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
+	},
+	[NS_BL2U_HASH_EXT] = {
+		.oid = NS_BL2U_HASH_OID,
+		.opt = "ns_bl2u",
+		.sn = "FWUpdaterHash",
+		.ln = "Firmware Updater (NS_BL2U) hash (SHA256)",
+		.asn1_type = V_ASN1_OCTET_STRING,
+		.type = EXT_TYPE_HASH,
+		.optional = 1
 	}
 };
 
diff --git a/tools/fip_create/fip_create.c b/tools/fip_create/fip_create.c
index c6869f9..5713184 100644
--- a/tools/fip_create/fip_create.c
+++ b/tools/fip_create/fip_create.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -55,6 +55,14 @@
 
 /* The images used depends on the platform. */
 static entry_lookup_list_t toc_entry_lookup_list[] = {
+	{ "SCP Firmware Updater Configuration FWU SCP_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U,
+	  "scp_bl2u", NULL, FLAG_FILENAME },
+	{ "AP Firmware Updater Configuration BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U,
+	  "bl2u", NULL, FLAG_FILENAME },
+	{ "Firmware Updater NS_BL2U", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U,
+	  "ns_bl2u", NULL, FLAG_FILENAME },
+	{ "Non-Trusted Firmware Updater certificate", UUID_TRUSTED_FWU_CERT,
+	  "fwu-cert", NULL, FLAG_FILENAME},
 	{ "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2,
 	  "bl2", NULL, FLAG_FILENAME },
 	{ "SCP Firmware BL3-0", UUID_SCP_FIRMWARE_BL30,