Merge pull request #1168 from matt2048/master

Replace macro ASM_ASSERTION with macro ENABLE_ASSERTIONS
diff --git a/Makefile b/Makefile
index 9ab37ac..fe75798 100644
--- a/Makefile
+++ b/Makefile
@@ -126,20 +126,28 @@
 NM			:=	${CROSS_COMPILE}nm
 PP			:=	${CROSS_COMPILE}gcc -E
 
+ifeq (${ARM_ARCH_MAJOR},7)
+target32-directive	= 	-target arm-none-eabi
+# Will set march32-directive from platform configuration
+else
+target32-directive	= 	-target armv8a-none-eabi
+march32-directive	= 	-march=armv8-a
+endif
+
 ifeq ($(notdir $(CC)),armclang)
-TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi -march=armv8-a
+TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi $(march32-directive)
 TF_CFLAGS_aarch64	=	-target aarch64-arm-none-eabi -march=armv8-a
 else ifneq ($(findstring clang,$(notdir $(CC))),)
-TF_CFLAGS_aarch32	=	-target armv8a-none-eabi
+TF_CFLAGS_aarch32	=	$(target32-directive)
 TF_CFLAGS_aarch64	=	-target aarch64-elf
 else
-TF_CFLAGS_aarch32	=	-march=armv8-a
+TF_CFLAGS_aarch32	=	$(march32-directive)
 TF_CFLAGS_aarch64	=	-march=armv8-a
 endif
 
 TF_CFLAGS_aarch64	+=	-mgeneral-regs-only -mstrict-align
 
-ASFLAGS_aarch32		=	-march=armv8-a
+ASFLAGS_aarch32		=	$(march32-directive)
 ASFLAGS_aarch64		=	-march=armv8-a
 
 CPPFLAGS		=	${DEFINES} ${INCLUDES} -nostdinc		\
@@ -189,6 +197,7 @@
 				-Iinclude/lib/cpus/${ARCH}		\
 				-Iinclude/lib/el3_runtime		\
 				-Iinclude/lib/el3_runtime/${ARCH}	\
+				-Iinclude/lib/extensions		\
 				-Iinclude/lib/pmf			\
 				-Iinclude/lib/psci			\
 				-Iinclude/lib/xlat_tables		\
@@ -262,6 +271,10 @@
 
 $(eval $(call MAKE_PREREQ_DIR,${BUILD_PLAT}))
 
+ifeq (${ARM_ARCH_MAJOR},7)
+include make_helpers/armv7-a-cpus.mk
+endif
+
 # Platform compatibility is not supported in AArch32
 ifneq (${ARCH},aarch32)
 # If the platform has not defined ENABLE_PLAT_COMPAT, then enable it by default
@@ -370,6 +383,17 @@
         NEED_SCP_BL2		:=	yes
 endif
 
+# For AArch32, BL31 is not currently supported.
+ifneq (${ARCH},aarch32)
+    ifdef BL31_SOURCES
+        # When booting an EL3 payload, there is no need to compile the BL31 image nor
+        # put it in the FIP.
+        ifndef EL3_PAYLOAD_BASE
+            NEED_BL31 := yes
+        endif
+    endif
+endif
+
 # Process TBB related flags
 ifneq (${GENERATE_COT},0)
         # Common cert_create options
@@ -421,17 +445,11 @@
 include bl2u/bl2u.mk
 endif
 
-# For AArch32, BL31 is not currently supported.
-ifneq (${ARCH},aarch32)
+ifeq (${NEED_BL31},yes)
 ifdef BL31_SOURCES
-# When booting an EL3 payload, there is no need to compile the BL31 image nor
-# put it in the FIP.
-ifndef EL3_PAYLOAD_BASE
-NEED_BL31 := yes
 include bl31/bl31.mk
 endif
 endif
-endif
 
 ################################################################################
 # Build options checks
@@ -443,6 +461,7 @@
 $(eval $(call assert_boolean,CTX_INCLUDE_FPREGS))
 $(eval $(call assert_boolean,DEBUG))
 $(eval $(call assert_boolean,DISABLE_PEDANTIC))
+$(eval $(call assert_boolean,ENABLE_AMU))
 $(eval $(call assert_boolean,ENABLE_ASSERTIONS))
 $(eval $(call assert_boolean,ENABLE_PLAT_COMPAT))
 $(eval $(call assert_boolean,ENABLE_PMF))
@@ -482,6 +501,7 @@
 $(eval $(call add_define,COLD_BOOT_SINGLE_CPU))
 $(eval $(call add_define,CTX_INCLUDE_AARCH32_REGS))
 $(eval $(call add_define,CTX_INCLUDE_FPREGS))
+$(eval $(call add_define,ENABLE_AMU))
 $(eval $(call add_define,ENABLE_ASSERTIONS))
 $(eval $(call add_define,ENABLE_PLAT_COMPAT))
 $(eval $(call add_define,ENABLE_PMF))
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 336c295..ebd0e71 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -46,6 +46,14 @@
 				services/std_svc/sdei/sdei_state.c
 endif
 
+ifeq (${ENABLE_SPE_FOR_LOWER_ELS},1)
+BL31_SOURCES		+=	lib/extensions/spe/spe.c
+endif
+
+ifeq (${ENABLE_AMU},1)
+BL31_SOURCES		+=	lib/extensions/amu/aarch64/amu.c
+endif
+
 BL31_LINKERFILE		:=	bl31/bl31.ld.S
 
 # Flag used to indicate if Crash reporting via console should be included
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index cd9fe5c..b2b7953 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -30,6 +30,16 @@
 		stcopr	\reg, SCR
 	.endm
 
+	.macro clrex_on_monitor_entry
+#if (ARM_ARCH_MAJOR == 7)
+	/*
+	 * ARMv7 architectures need to clear the exclusive access when
+	 * entering Monitor mode.
+	 */
+	clrex
+#endif
+	.endm
+
 vector_base sp_min_vector_table
 	b	sp_min_entrypoint
 	b	plat_panic_handler	/* Undef */
@@ -147,6 +157,8 @@
 
 	smcc_save_gp_mode_regs
 
+	clrex_on_monitor_entry
+
 	/*
 	 * `sp` still points to `smc_ctx_t`. Save it to a register
 	 * and restore the C runtime stack pointer to `sp`.
@@ -203,11 +215,7 @@
 
 	smcc_save_gp_mode_regs
 
-	/*
-	 * AArch32 architectures need to clear the exclusive access when
-	 * entering Monitor mode.
-	 */
-	clrex
+	clrex_on_monitor_entry
 
 	/* load run-time stack */
 	mov	r2, sp
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index fc44d524..9325973 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -110,6 +110,10 @@
         __DATA_END__ = .;
     } >RAM
 
+#ifdef BL32_PROGBITS_LIMIT
+    ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.")
+#endif
+
     stacks (NOLOAD) : {
         __STACKS_START__ = .;
         *(tzfw_normal_stacks)
diff --git a/bl32/sp_min/sp_min.mk b/bl32/sp_min/sp_min.mk
index 39588ce..56489a3 100644
--- a/bl32/sp_min/sp_min.mk
+++ b/bl32/sp_min/sp_min.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -22,6 +22,10 @@
 BL32_SOURCES		+=	lib/pmf/pmf_main.c
 endif
 
+ifeq (${ENABLE_AMU}, 1)
+BL32_SOURCES		+=	lib/extensions/amu/aarch32/amu.c
+endif
+
 BL32_LINKERFILE	:=	bl32/sp_min/sp_min.ld.S
 
 # Include the platform-specific SP_MIN Makefile
diff --git a/common/aarch32/debug.S b/common/aarch32/debug.S
index 583ee4a..f506356 100644
--- a/common/aarch32/debug.S
+++ b/common/aarch32/debug.S
@@ -71,7 +71,15 @@
 assert_msg1:
 	.asciz "ASSERT: File "
 assert_msg2:
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	/******************************************************************
+	 * Virtualization comes with the UDIV/SDIV instructions. If missing
+	 * write file line number in hexadecimal format.
+	 ******************************************************************/
+	.asciz " Line 0x"
+#else
 	.asciz " Line "
+#endif
 
 /* ---------------------------------------------------------------------------
  * Assertion support in assembly.
@@ -113,6 +121,13 @@
 	bne	1f
 	mov	r4, r6
 
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	/******************************************************************
+	 * Virtualization comes with the UDIV/SDIV instructions. If missing
+	 * write file line number in hexadecimal format.
+	 ******************************************************************/
+	bl	asm_print_hex
+#else
 	/* Print line number in decimal */
 	mov	r6, #10			/* Divide by 10 after every loop iteration */
 	ldr	r5, =MAX_DEC_DIVISOR
@@ -124,6 +139,7 @@
 	udiv	r5, r5, r6			/* Reduce divisor */
 	cmp	r5, #0
 	bne	dec_print_loop
+#endif
 
 	bl	plat_crash_console_flush
 
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index c0ece0b..405964d 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -2519,6 +2519,35 @@
    table entries for a given stage of translation for a particular translation
    regime.
 
+ARMv7
+~~~~~
+
+This Architecture Extension is targeted when ``ARM_ARCH_MAJOR`` == 7.
+
+There are several ARMv7 extensions available. Obviously the TrustZone
+extension is mandatory to support the ARM Trusted Firmware bootloader
+and runtime services.
+
+Platform implementing an ARMv7 system can to define from its target
+Cortex-A architecture through ``ARM_CORTEX_A<X> = yes`` in their
+``plaform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
+Cortex-A15 target.
+
+Platform can also set ``ARM_WITH_NEON=yes`` to enable neon support.
+Note that using neon at runtime has constraints on non secure wolrd context.
+The trusted firmware does not yet provide VFP context management.
+
+Directive ``ARM_CORTEX_A<x>`` and ``ARM_WITH_NEON`` are used to set
+the toolchain  target architecture directive.
+
+Platform may choose to not define straight the toolchain target architecture
+directive by defining ``MARCH32_DIRECTIVE``.
+I.e:
+
+::
+
+   MARCH32_DIRECTIVE := -mach=armv7-a
+
 Code Structure
 --------------
 
diff --git a/docs/plantuml/sdei_explicit_dispatch.puml b/docs/plantuml/sdei_explicit_dispatch.puml
index 51214f5..c80fcd1 100644
--- a/docs/plantuml/sdei_explicit_dispatch.puml
+++ b/docs/plantuml/sdei_explicit_dispatch.puml
@@ -9,7 +9,7 @@
 autonumber "<b>[#]</b>"
 participant "SDEI client" as EL2
 participant EL3
-participant SEL1
+participant "Secure Partition" as SP
 
 activate EL2
 EL2->EL3: **SDEI_EVENT_REGISTER**(ev, handler, ...)
@@ -24,11 +24,11 @@
 EL3<--]: **CRITICAL EVENT**
 activate EL3 #red
 note over EL3: Critical event triage
-EL3->SEL1: dispatch
-activate SEL1 #salmon
-note over SEL1: Critical event handling
-SEL1->EL3: done
-deactivate SEL1
+EL3->SP: dispatch
+activate SP #salmon
+note over SP: Critical event handling
+SP->EL3: done
+deactivate SP
 EL3-->EL3: sdei_dispatch_event(ev)
 note over EL3: Prepare SDEI dispatch
 EL3->EL2: dispatch
diff --git a/docs/plantuml/sdei_explicit_dispatch.svg b/docs/plantuml/sdei_explicit_dispatch.svg
index b33944e..182df0a 100644
--- a/docs/plantuml/sdei_explicit_dispatch.svg
+++ b/docs/plantuml/sdei_explicit_dispatch.svg
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="767px" preserveAspectRatio="none" style="width:692px;height:767px;" version="1.1" viewBox="0 0 692 767" width="692px" zoomAndPan="magnify"><defs><filter height="300%" id="f13jg8eb0anesb" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#f13jg8eb0anesb)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593.5" x2="593.5" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593.5" x2="593.5" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593.5" x2="593.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593.5" x2="593.5" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593.5" x2="593.5" y1="717.2969" y2="727.2969"/><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="22.9951">SDEI client</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="746.292">SDEI client</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="22.9951">EL3</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="746.292">EL3</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="48" x="567.5" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="34" x="574.5" y="22.9951">SEL1</text><rect fill="#FEFECE" filter="url(#f13jg8eb0anesb)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="48" x="567.5" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="34" x="574.5" y="746.292">SEL1</text><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#f13jg8eb0anesb)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#f13jg8eb0anesb)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#f13jg8eb0anesb)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><polygon fill="#A80036" points="368.5,65.2969,378.5,69.2969,368.5,73.2969,372.5,69.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="69.2969" y2="69.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="64.3638">[1]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="164" x="98.5" y="64.3638">SDEI_EVENT_REGISTER</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="101" x="262.5" y="64.3638">(ev, handler, ...)</text><polygon fill="#A80036" points="77.5,94.4297,67.5,98.4297,77.5,102.4297,73.5,98.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="98.4297" y2="98.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="93.4966">[2]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="93.4966">success</text><polygon fill="#A80036" points="368.5,123.5625,378.5,127.5625,368.5,131.5625,372.5,127.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="127.5625" y2="127.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="122.6294">[3]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="151" x="98.5" y="122.6294">SDEI_EVENT_ENABLE</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="25" x="249.5" y="122.6294">(ev)</text><polygon fill="#A80036" points="77.5,152.6953,67.5,156.6953,77.5,160.6953,73.5,156.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="156.6953" y2="156.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="151.7622">[4]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="151.7622">success</text><polygon fill="#A80036" points="368.5,181.8281,378.5,185.8281,368.5,189.8281,372.5,185.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="185.8281" y2="185.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="180.895">[5]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="129" x="98.5" y="180.895">SDEI_PE_UNMASK</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="10" x="227.5" y="180.895">()</text><polygon fill="#A80036" points="77.5,210.9609,67.5,214.9609,77.5,218.9609,73.5,214.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="214.9609" y2="214.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="210.0278">[6]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="8" x="108.5" y="210.0278">1</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="142" x="256.5" y="247.3042">&lt;&lt;Business as usual&gt;&gt;</text><polygon fill="#A80036" points="396.5,280.8984,386.5,284.8984,396.5,288.8984,392.5,284.8984" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="390.5" x2="680" y1="284.8984" y2="284.8984"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="279.9653">[7]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="116" x="427.5" y="279.9653">CRITICAL EVENT</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="306,298.0313,306,323.0313,451,323.0313,451,308.0313,441,298.0313,306,298.0313" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="441" x2="441" y1="298.0313" y2="308.0313"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="451" x2="441" y1="308.0313" y2="308.0313"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="124" x="312" y="315.0981">Critical event triage</text><polygon fill="#A80036" points="576.5,349.1641,586.5,353.1641,576.5,357.1641,580.5,353.1641" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="385.5" x2="582.5" y1="353.1641" y2="353.1641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="392.5" y="348.231">[8]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="417.5" y="348.231">dispatch</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="510,366.2969,510,391.2969,672,391.2969,672,376.2969,662,366.2969,510,366.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="662" x2="662" y1="366.2969" y2="376.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="672" x2="662" y1="376.2969" y2="376.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="516" y="383.3638">Critical event handling</text><polygon fill="#A80036" points="396.5,417.4297,386.5,421.4297,396.5,425.4297,392.5,421.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="390.5" x2="592.5" y1="421.4297" y2="421.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="416.4966">[9]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="32" x="427.5" y="416.4966">done</text><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="385.5" x2="427.5" y1="450.6953" y2="450.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="427.5" x2="427.5" y1="450.6953" y2="463.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="386.5" x2="427.5" y1="463.6953" y2="463.6953"/><polygon fill="#A80036" points="396.5,459.6953,386.5,463.6953,396.5,467.6953,392.5,463.6953" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="392.5" y="445.6294">[10]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="155" x="426.5" y="445.6294">sdei_dispatch_event(ev)</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="297,476.6953,297,501.6953,460,501.6953,460,486.6953,450,476.6953,297,476.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="450" x2="450" y1="476.6953" y2="486.6953"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="460" x2="450" y1="486.6953" y2="486.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="142" x="303" y="493.7622">Prepare SDEI dispatch</text><polygon fill="#A80036" points="82.5,527.8281,72.5,531.8281,82.5,535.8281,78.5,531.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="76.5" x2="374.5" y1="531.8281" y2="531.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="88.5" y="526.895">[11]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="122.5" y="526.895">dispatch</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="8,544.9609,8,569.9609,111,569.9609,111,554.9609,101,544.9609,8,544.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="101" x2="101" y1="544.9609" y2="554.9609"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="111" x2="101" y1="554.9609" y2="554.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="82" x="14" y="562.0278">SDEI handler</text><polygon fill="#A80036" points="363.5,596.0938,373.5,600.0938,363.5,604.0938,367.5,600.0938" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="369.5" y1="600.0938" y2="600.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="73.5" y="595.1606">[12]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="184" x="107.5" y="595.1606">SDEI_EVENT_COMPLETE()</text><polygon fill="#FBFB77" filter="url(#f13jg8eb0anesb)" points="291,613.2266,291,638.2266,466,638.2266,466,623.2266,456,613.2266,291,613.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="456" x2="456" y1="613.2266" y2="623.2266"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="466" x2="456" y1="623.2266" y2="623.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="154" x="297" y="630.2935">Complete SDEI dispatch</text><polygon fill="#A80036" points="77.5,664.3594,67.5,668.3594,77.5,672.3594,73.5,668.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="668.3594" y2="668.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="83.5" y="663.4263">[13]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="117.5" y="663.4263">resumes preempted execution</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="190" x="232.5" y="700.7026">&lt;&lt;Normal execution resumes&gt;&gt;</text></g></svg>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="767px" preserveAspectRatio="none" style="width:692px;height:767px;" version="1.1" viewBox="0 0 692 767" width="692px" zoomAndPan="magnify"><defs><filter height="300%" id="fueepysa066oi" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#fueepysa066oi)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="61" x2="61" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="61" x2="61" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="380" x2="380" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="380" x2="380" y1="717.2969" y2="727.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593" x2="593" y1="38.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593" x2="593" y1="223.0938" y2="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593" x2="593" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 1.0,4.0;" x1="593" x2="593" y1="676.4922" y2="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="593" x2="593" y1="717.2969" y2="727.2969"/><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="22.9951">SDEI client</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="87" x="16" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="73" x="23" y="746.292">SDEI client</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="22.9951">EL3</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="39" x="359" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="25" x="366" y="746.292">EL3</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="123" x="530" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="109" x="537" y="22.9951">Secure Partition</text><rect fill="#FEFECE" filter="url(#fueepysa066oi)" height="30.2969" style="stroke: #A80036; stroke-width: 1.5;" width="123" x="530" y="726.2969"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="109" x="537" y="746.292">Secure Partition</text><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="174.7969" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="48.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="48.2969" y2="223.0938"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="66.5" y1="48.2969" y2="48.2969"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="412.5938" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="263.8984"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="263.8984" y2="676.4922"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="263.8984" y2="676.4922"/><rect fill="#FFFFFF" filter="url(#fueepysa066oi)" height="1" style="stroke: #FFFFFF; stroke-width: 1.0;" width="10" x="56.5" y="717.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="56.5" x2="56.5" y1="717.2969" y2="718.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="66.5" y1="717.2969" y2="718.2969"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="61.5" y="531.8281"/><rect fill="#FF0000" filter="url(#fueepysa066oi)" height="383.4609" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="375.5" y="284.8984"/><rect fill="#FA8072" filter="url(#fueepysa066oi)" height="68.2656" style="stroke: #A80036; stroke-width: 1.0;" width="10" x="588.5" y="353.1641"/><polygon fill="#A80036" points="368.5,65.2969,378.5,69.2969,368.5,73.2969,372.5,69.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="69.2969" y2="69.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="64.3638">[1]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="164" x="98.5" y="64.3638">SDEI_EVENT_REGISTER</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="101" x="262.5" y="64.3638">(ev, handler, ...)</text><polygon fill="#A80036" points="77.5,94.4297,67.5,98.4297,77.5,102.4297,73.5,98.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="98.4297" y2="98.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="93.4966">[2]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="93.4966">success</text><polygon fill="#A80036" points="368.5,123.5625,378.5,127.5625,368.5,131.5625,372.5,127.5625" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="127.5625" y2="127.5625"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="122.6294">[3]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="151" x="98.5" y="122.6294">SDEI_EVENT_ENABLE</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="25" x="249.5" y="122.6294">(ev)</text><polygon fill="#A80036" points="77.5,152.6953,67.5,156.6953,77.5,160.6953,73.5,156.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="156.6953" y2="156.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="151.7622">[4]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="51" x="108.5" y="151.7622">success</text><polygon fill="#A80036" points="368.5,181.8281,378.5,185.8281,368.5,189.8281,372.5,185.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="374.5" y1="185.8281" y2="185.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="73.5" y="180.895">[5]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="129" x="98.5" y="180.895">SDEI_PE_UNMASK</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="10" x="227.5" y="180.895">()</text><polygon fill="#A80036" points="77.5,210.9609,67.5,214.9609,77.5,218.9609,73.5,214.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="214.9609" y2="214.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="83.5" y="210.0278">[6]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="8" x="108.5" y="210.0278">1</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="142" x="256.5" y="247.3042">&lt;&lt;Business as usual&gt;&gt;</text><polygon fill="#A80036" points="396.5,280.8984,386.5,284.8984,396.5,288.8984,392.5,284.8984" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="390.5" x2="680" y1="284.8984" y2="284.8984"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="279.9653">[7]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="116" x="427.5" y="279.9653">CRITICAL EVENT</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="306,298.0313,306,323.0313,451,323.0313,451,308.0313,441,298.0313,306,298.0313" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="441" x2="441" y1="298.0313" y2="308.0313"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="451" x2="441" y1="308.0313" y2="308.0313"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="124" x="312" y="315.0981">Critical event triage</text><polygon fill="#A80036" points="576.5,349.1641,586.5,353.1641,576.5,357.1641,580.5,353.1641" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="385.5" x2="582.5" y1="353.1641" y2="353.1641"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="392.5" y="348.231">[8]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="417.5" y="348.231">dispatch</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="510,366.2969,510,391.2969,672,391.2969,672,376.2969,662,366.2969,510,366.2969" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="662" x2="662" y1="366.2969" y2="376.2969"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="672" x2="662" y1="376.2969" y2="376.2969"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="141" x="516" y="383.3638">Critical event handling</text><polygon fill="#A80036" points="396.5,417.4297,386.5,421.4297,396.5,425.4297,392.5,421.4297" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="390.5" x2="592.5" y1="421.4297" y2="421.4297"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="21" x="402.5" y="416.4966">[9]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="32" x="427.5" y="416.4966">done</text><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="385.5" x2="427.5" y1="450.6953" y2="450.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="427.5" x2="427.5" y1="450.6953" y2="463.6953"/><line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 2.0,2.0;" x1="386.5" x2="427.5" y1="463.6953" y2="463.6953"/><polygon fill="#A80036" points="396.5,459.6953,386.5,463.6953,396.5,467.6953,392.5,463.6953" style="stroke: #A80036; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="392.5" y="445.6294">[10]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="155" x="426.5" y="445.6294">sdei_dispatch_event(ev)</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="297,476.6953,297,501.6953,460,501.6953,460,486.6953,450,476.6953,297,476.6953" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="450" x2="450" y1="476.6953" y2="486.6953"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="460" x2="450" y1="486.6953" y2="486.6953"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="142" x="303" y="493.7622">Prepare SDEI dispatch</text><polygon fill="#A80036" points="82.5,527.8281,72.5,531.8281,82.5,535.8281,78.5,531.8281" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="76.5" x2="374.5" y1="531.8281" y2="531.8281"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="88.5" y="526.895">[11]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="122.5" y="526.895">dispatch</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="8,544.9609,8,569.9609,111,569.9609,111,554.9609,101,544.9609,8,544.9609" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="101" x2="101" y1="544.9609" y2="554.9609"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="111" x2="101" y1="554.9609" y2="554.9609"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="82" x="14" y="562.0278">SDEI handler</text><polygon fill="#A80036" points="363.5,596.0938,373.5,600.0938,363.5,604.0938,367.5,600.0938" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="66.5" x2="369.5" y1="600.0938" y2="600.0938"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="73.5" y="595.1606">[12]</text><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="184" x="107.5" y="595.1606">SDEI_EVENT_COMPLETE()</text><polygon fill="#FBFB77" filter="url(#fueepysa066oi)" points="291,613.2266,291,638.2266,466,638.2266,466,623.2266,456,613.2266,291,613.2266" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="456" x2="456" y1="613.2266" y2="623.2266"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="466" x2="456" y1="623.2266" y2="623.2266"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="154" x="297" y="630.2935">Complete SDEI dispatch</text><polygon fill="#A80036" points="77.5,664.3594,67.5,668.3594,77.5,672.3594,73.5,668.3594" style="stroke: #A80036; stroke-width: 1.0;"/><line style="stroke: #A80036; stroke-width: 1.0;" x1="71.5" x2="379.5" y1="668.3594" y2="668.3594"/><text fill="#000000" font-family="sans-serif" font-size="13" font-weight="bold" lengthAdjust="spacingAndGlyphs" textLength="30" x="83.5" y="663.4263">[13]</text><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="197" x="117.5" y="663.4263">resumes preempted execution</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="190" x="232.5" y="700.7026">&lt;&lt;Normal execution resumes&gt;&gt;</text></g></svg>
\ No newline at end of file
diff --git a/docs/sdei.rst b/docs/sdei.rst
index 0731a5a..a67b724 100644
--- a/docs/sdei.rst
+++ b/docs/sdei.rst
@@ -232,13 +232,20 @@
 
 At a later point in time, a critical event [#critical-event]_ is trapped into
 EL3 [7]. EL3 performs a first-level triage of the event, and decides to dispatch
-to Secure EL1 for further handling [8]. The dispatch completes, but intends to
-involve Non-secure world in further handling, and therefore decides to
-explicitly dispatch an event [10] (which the client had already registered for
-[1]). The rest of the sequence is similar to that in the `general SDEI
-dispatch`_: the requested event is dispatched to the client (assuming all the
-conditions are met), and when the handler completes, the preempted execution
-resumes.
+to a Secure Partition [#secpart]_ for further handling [8]. The dispatch
+completes, but intends to involve Non-secure world in further handling, and
+therefore decides to explicitly dispatch an event [10] (which the client had
+already registered for [1]). The rest of the sequence is similar to that in the
+`general SDEI dispatch`_: the requested event is dispatched to the client
+(assuming all the conditions are met), and when the handler completes, the
+preempted execution resumes.
+
+.. [#critical-event] Examples of critical event are *SError*, *Synchronous
+                     External Abort*, *Fault Handling interrupt*, or *Error
+                     Recovery interrupt* from one of RAS nodes in the system.
+
+.. [#secpart] Dispatching to Secure Partition involves *Secure Partition
+              Manager*, which isn't depicted in the sequence.
 
 Conditions for event dispatch
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -295,10 +302,6 @@
    context is resumed (as indicated by the ``preempted_sec_state`` parameter of
    the API).
 
-.. [#critical-event] Examples of critical event are *SError*, *Synchronous
-                     External Abort*, *Fault Handling interrupt*, or *Error
-                     Recovery interrupt* from one of RAS nodes in the system.
-
 Porting requirements
 --------------------
 
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 172e793..138ed8b 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -219,7 +219,8 @@
 
 -  ``ARM_ARCH_MAJOR``: The major version of ARM Architecture to target when
    compiling ARM Trusted Firmware. Its value must be numeric, and defaults to
-   8 . See also, *ARMv8 Architecture Extensions* in `Firmware Design`_.
+   8 . See also, *ARMv8 Architecture Extensions* and
+   *ARMv7 Architecture Extensions* in `Firmware Design`_.
 
 -  ``ARM_ARCH_MINOR``: The minor version of ARM Architecture to target when
    compiling ARM Trusted Firmware. Its value must be a numeric, and defaults
@@ -320,6 +321,11 @@
    payload. Please refer to the "Booting an EL3 payload" section for more
    details.
 
+-  ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions.
+   This is an optional architectural feature available on v8.4 onwards. Some
+   v8.2 implementations also implement an AMU and this option can be used to
+   enable this feature on those systems as well. Default is 0.
+
 -  ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()``
    are compiled out. For debug builds, this option defaults to 1, and calls to
    ``assert()`` are left in place. For release builds, this option defaults to 0
@@ -344,9 +350,9 @@
    the ``ENABLE_PMF`` build option as well. Default is 0.
 
 -  ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
-   extensions. This is an optional architectural feature available only for
-   AArch64 8.2 onwards. This option defaults to 1 but is automatically
-   disabled when the target architecture is AArch32 or AArch64 8.0/8.1.
+   extensions. This is an optional architectural feature for AArch64.
+   The default is 1 but is automatically disabled when the target architecture
+   is AArch32.
 
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong" and "0" (default).
@@ -425,11 +431,15 @@
 
 -  ``KEY_ALG``: This build flag enables the user to select the algorithm to be
    used for generating the PKCS keys and subsequent signing of the certificate.
-   It accepts 3 values viz ``rsa``, ``rsa_1_5``, ``ecdsa``. The ``rsa_1_5`` is
+   It accepts 3 values viz. ``rsa``, ``rsa_1_5``, ``ecdsa``. The ``rsa_1_5`` is
    the legacy PKCS#1 RSA 1.5 algorithm which is not TBBR compliant and is
    retained only for compatibility. The default value of this flag is ``rsa``
    which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
 
+-  ``HASH_ALG``: This build flag enables the user to select the secure hash
+   algorithm. It accepts 3 values viz. ``sha256``, ``sha384``, ``sha512``.
+   The default value of this flag is ``sha256``.
+
 -  ``LDFLAGS``: Extra user options appended to the linkers' command line in
    addition to the one set by the build system.
 
@@ -1202,7 +1212,7 @@
 
           make ARCH=aarch64 PLAT=juno LOAD_IMAGE_V2=1 JUNO_AARCH32_EL3_RUNTIME=1 \
           BL33=<path-to-juno32-oe-uboot>/SOFTWARE/bl33-uboot.bin \
-          SCP_BL2=<path-to-juno32-oe-uboot>/SOFTWARE/scp_bl2.bin SPD=tspd \
+          SCP_BL2=<path-to-juno32-oe-uboot>/SOFTWARE/scp_bl2.bin \
           BL32=<path-to-bl32>/bl32.bin all fip
 
 The resulting BL1 and FIP images may be found in:
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index 72f15cd..8798659 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.c
@@ -176,7 +176,19 @@
 	gic_version = gicd_read_pidr2(plat_driver_data->gicd_base);
 	gic_version = (gic_version >> PIDR2_ARCH_REV_SHIFT)
 					& PIDR2_ARCH_REV_MASK;
-	assert(gic_version == ARCH_REV_GICV2);
+
+	/*
+	 * GICv1 with security extension complies with trusted firmware
+	 * GICv2 driver as far as virtualization and few tricky power
+	 * features are not used. GICv2 features that are not supported
+	 * by GICv1 with Security Extensions are:
+	 * - virtual interrupt support.
+	 * - wake up events.
+	 * - writeable GIC state register (for power sequences)
+	 * - interrupt priority drop.
+	 * - interrupt signal bypass.
+	 */
+	assert(gic_version == ARCH_REV_GICV2 || gic_version == ARCH_REV_GICV1);
 
 	driver_data = plat_driver_data;
 
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index d8810d6..bc9ed3a 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #include <crypto_mod.h>
 #include <debug.h>
 #include <mbedtls_common.h>
+#include <mbedtls_config.h>
 #include <stddef.h>
 #include <string.h>
 
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk
index d6fc7eb..8eb4873 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.mk
+++ b/drivers/auth/mbedtls/mbedtls_crypto.mk
@@ -37,9 +37,30 @@
 					pk_wrap.c 				\
 					pkparse.c 				\
 					pkwrite.c 				\
-					sha256.c				\
 					)
 
+ifeq (${HASH_ALG}, sha384)
+    MBEDTLS_CRYPTO_SOURCES  += \
+					$(addprefix ${MBEDTLS_DIR}/library/,	\
+						sha256.c            \
+						sha512.c            \
+					)
+    TF_MBEDTLS_HASH_ALG_ID	:=	TF_MBEDTLS_SHA384
+else ifeq (${HASH_ALG}, sha512)
+    MBEDTLS_CRYPTO_SOURCES  += \
+					$(addprefix ${MBEDTLS_DIR}/library/,	\
+						sha256.c            \
+						sha512.c            \
+					)
+    TF_MBEDTLS_HASH_ALG_ID	:=	TF_MBEDTLS_SHA512
+else
+    MBEDTLS_CRYPTO_SOURCES  += \
+					$(addprefix ${MBEDTLS_DIR}/library/,	\
+						sha256.c            \
+					)
+    TF_MBEDTLS_HASH_ALG_ID	:=	TF_MBEDTLS_SHA256
+endif
+
 # Key algorithm specific files
 MBEDTLS_ECDSA_CRYPTO_SOURCES	+=	$(addprefix ${MBEDTLS_DIR}/library/,	\
 					ecdsa.c					\
@@ -67,6 +88,7 @@
 
 # Needs to be set to drive mbed TLS configuration correctly
 $(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
+$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
 
 BL1_SOURCES			+=	${MBEDTLS_CRYPTO_SOURCES}
 BL2_SOURCES			+=	${MBEDTLS_CRYPTO_SOURCES}
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index 4aaab39..01d6fb5 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -19,7 +19,7 @@
  * Maximum key and hash sizes (in DER format)
  */
 #define PK_DER_LEN			294
-#define HASH_DER_LEN			51
+#define HASH_DER_LEN			83
 
 /*
  * The platform must allocate buffers to store the authentication parameters
diff --git a/include/common/aarch32/asm_macros.S b/include/common/aarch32/asm_macros.S
index f573744..7432222 100644
--- a/include/common/aarch32/asm_macros.S
+++ b/include/common/aarch32/asm_macros.S
@@ -79,6 +79,25 @@
 	ldr r0, =(\_name + \_size)
 	.endm
 
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	/*
+	 * ARMv7 cores without Virtualization extension do not support the
+	 * eret instruction.
+	 */
+	.macro eret
+	movs	pc, lr
+	.endm
+#endif
+
+#if (ARM_ARCH_MAJOR == 7)
+	/* ARMv7 does not support stl instruction */
+	.macro stl _reg, _write_lock
+	dmb
+	str	\_reg, \_write_lock
+	dsb
+	.endm
+#endif
+
 	/*
 	 * Helper macro to generate the best mov/movw/movt combinations
 	 * according to the value to be moved.
diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S
index 6fc00dd..59e99f8 100644
--- a/include/common/aarch32/el3_common_macros.S
+++ b/include/common/aarch32/el3_common_macros.S
@@ -107,6 +107,7 @@
 	vmsr	FPEXC, r0
 	isb
 
+#if (ARM_ARCH_MAJOR > 7)
 	/* ---------------------------------------------------------------------
 	 * Initialise SDCR, setting all the fields rather than relying on hw.
 	 *
@@ -116,6 +117,7 @@
 	 */
 	ldr	r0, =(SDCR_RESET_VAL | SDCR_SPD(SDCR_SPD_DISABLE))
 	stcopr	r0, SDCR
+#endif
 
 	.endm
 
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index 34fdaee..ed35df8 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -95,10 +95,6 @@
 	 * MDCR_EL3.SPD32: Set to 0b10 to disable AArch32 Secure self-hosted
 	 *  privileged debug from S-EL1.
 	 *
-	 * MDCR_EL3.NSPB (ARM v8.2): SPE enabled in non-secure state and
-	 * disabled in secure state. Accesses to SPE registers at SEL1 generate
-	 * trap exceptions to EL3.
-	 *
 	 * MDCR_EL3.TDOSA: Set to zero so that EL2 and EL2 System register
 	 *  access to the powerdown debug registers do not trap to EL3.
 	 *
@@ -112,19 +108,6 @@
 	 */
 	mov_imm	x0, ((MDCR_EL3_RESET_VAL | MDCR_SDD_BIT | MDCR_SPD32(MDCR_SPD32_DISABLE)) \
 			& ~(MDCR_TDOSA_BIT | MDCR_TDA_BIT | MDCR_TPM_BIT))
-
-#if ENABLE_SPE_FOR_LOWER_ELS
-	/* Detect if SPE is implemented */
-	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH
-	cmp	x1, #0x1
-	b.ne	1f
-
-	/* Enable SPE for use by normal world */
-	orr	x0, x0, #MDCR_NSPB(MDCR_NSPB_EL1)
-1:
-#endif
-
 	msr	mdcr_el3, x0
 
 	/* ---------------------------------------------------------------------
diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h
index efa9703..001f573 100644
--- a/include/drivers/arm/gic_common.h
+++ b/include/drivers/arm/gic_common.h
@@ -72,6 +72,8 @@
 #define ARCH_REV_GICV3		0x3
 /* GICv2 revision as reported by the PIDR2 register */
 #define ARCH_REV_GICV2		0x2
+/* GICv1 revision as reported by the PIDR2 register */
+#define ARCH_REV_GICV1		0x1
 
 #define IGROUPR_SHIFT		5
 #define ISENABLER_SHIFT		5
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index 96587ac..f8f2608 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -14,6 +14,13 @@
 #define TF_MBEDTLS_RSA_AND_ECDSA	3
 
 /*
+ * Hash algorithms currently supported on mbed TLS libraries
+ */
+#define TF_MBEDTLS_SHA256		1
+#define TF_MBEDTLS_SHA384		2
+#define TF_MBEDTLS_SHA512		3
+
+/*
  * Configuration file to build mbed TLS with the required features for
  * Trusted Boot
  */
@@ -66,6 +73,9 @@
 #endif
 
 #define MBEDTLS_SHA256_C
+#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
+#define MBEDTLS_SHA512_C
+#endif
 
 #define MBEDTLS_VERSION_C
 
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 3846bec..4d2a5fc 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -78,6 +78,11 @@
 /* CSSELR definitions */
 #define LEVEL_SHIFT		1
 
+/* ID_PFR0 definitions */
+#define ID_PFR0_AMU_SHIFT	U(20)
+#define ID_PFR0_AMU_LENGTH	U(4)
+#define ID_PFR0_AMU_MASK	U(0xf)
+
 /* ID_PFR1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT	12
 #define ID_PFR1_VIRTEXT_MASK	0xf
@@ -87,15 +92,21 @@
 #define ID_PFR1_GIC_MASK	0xf
 
 /* SCTLR definitions */
-#define SCTLR_RES1	((1 << 23) | (1 << 22) | (1 << 11) | (1 << 4) | \
-			(1 << 3))
+#define SCTLR_RES1_DEF		((1 << 23) | (1 << 22) | (1 << 4) | (1 << 3))
+#if ARM_ARCH_MAJOR == 7
+#define SCTLR_RES1		SCTLR_RES1_DEF
+#else
+#define SCTLR_RES1		(SCTLR_RES1_DEF | (1 << 11))
+#endif
 #define SCTLR_M_BIT		(1 << 0)
 #define SCTLR_A_BIT		(1 << 1)
 #define SCTLR_C_BIT		(1 << 2)
 #define SCTLR_CP15BEN_BIT	(1 << 5)
 #define SCTLR_ITD_BIT		(1 << 7)
+#define SCTLR_Z_BIT		(1 << 11)
 #define SCTLR_I_BIT		(1 << 12)
 #define SCTLR_V_BIT		(1 << 13)
+#define SCTLR_RR_BIT		(1 << 14)
 #define SCTLR_NTWI_BIT		(1 << 16)
 #define SCTLR_NTWE_BIT		(1 << 18)
 #define SCTLR_WXN_BIT		(1 << 19)
@@ -181,6 +192,7 @@
 /* HCPTR definitions */
 #define HCPTR_RES1		((1 << 13) | (1<<12) | 0x3ff)
 #define TCPAC_BIT		(1 << 31)
+#define TAM_BIT			(1 << 30)
 #define TTA_BIT			(1 << 20)
 #define TCP11_BIT		(1 << 10)
 #define TCP10_BIT		(1 << 10)
@@ -385,6 +397,7 @@
 /* System register defines The format is: coproc, opt1, CRn, CRm, opt2 */
 #define SCR		p15, 0, c1, c1, 0
 #define SCTLR		p15, 0, c1, c0, 0
+#define ACTLR		p15, 0, c1, c0, 1
 #define SDCR		p15, 0, c1, c3, 1
 #define MPIDR		p15, 0, c0, c0, 5
 #define MIDR		p15, 0, c0, c0, 0
@@ -400,6 +413,7 @@
 #define DCISW		p15, 0, c7, c6, 2
 #define CTR		p15, 0, c0, c0, 1
 #define CNTFRQ		p15, 0, c14, c0, 0
+#define ID_PFR0		p15, 0, c0, c1, 0
 #define ID_PFR1		p15, 0, c0, c1, 1
 #define MAIR0		p15, 0, c10, c2, 0
 #define MAIR1		p15, 0, c10, c2, 1
@@ -431,6 +445,11 @@
 #define PMCR		p15, 0, c9, c12, 0
 #define CNTHP_CTL	p15, 4, c14, c2, 1
 
+/* AArch32 coproc registers for 32bit MMU descriptor support */
+#define PRRR		p15, 0, c10, c2, 0
+#define NMRR		p15, 0, c10, c2, 1
+#define DACR		p15, 0, c3, c0, 0
+
 /* GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
 #define ICC_IAR1	p15, 0, c12, c12, 0
 #define ICC_IAR0	p15, 0, c12, c8, 0
@@ -513,4 +532,28 @@
 
 #define MAKE_MAIR_NORMAL_MEMORY(inner, outer)	((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT))
 
+/*******************************************************************************
+ * Definitions for system register interface to AMU for ARMv8.4 onwards
+ ******************************************************************************/
+#define AMCR		p15, 0, c13, c2, 0
+#define AMCFGR		p15, 0, c13, c2, 1
+#define AMCGCR		p15, 0, c13, c2, 2
+#define AMUSERENR	p15, 0, c13, c2, 3
+#define AMCNTENCLR0	p15, 0, c13, c2, 4
+#define AMCNTENSET0	p15, 0, c13, c2, 5
+#define AMCNTENCLR1	p15, 0, c13, c3, 0
+#define AMCNTENSET1	p15, 0, c13, c1, 1
+
+/* Activity Monitor Group 0 Event Counter Registers */
+#define AMEVCNTR00	p15, 0, c0
+#define AMEVCNTR01	p15, 1, c0
+#define AMEVCNTR02	p15, 2, c0
+#define AMEVCNTR03	p15, 3, c0
+
+/* Activity Monitor Group 0 Event Type Registers */
+#define AMEVTYPER00	p15, 0, c13, c6, 0
+#define AMEVTYPER01	p15, 0, c13, c6, 1
+#define AMEVTYPER02	p15, 0, c13, c6, 2
+#define AMEVTYPER03	p15, 0, c13, c6, 3
+
 #endif /* __ARCH_H__ */
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index 469e9b0..0230195 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -227,6 +227,7 @@
  ******************************************************************************/
 DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
 DEFINE_COPROCR_READ_FUNC(midr, MIDR)
+DEFINE_COPROCR_READ_FUNC(id_pfr0, ID_PFR0)
 DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
 DEFINE_COPROCR_READ_FUNC(isr, ISR)
 DEFINE_COPROCR_READ_FUNC(clidr, CLIDR)
@@ -235,6 +236,7 @@
 DEFINE_COPROCR_RW_FUNCS(scr, SCR)
 DEFINE_COPROCR_RW_FUNCS(ctr, CTR)
 DEFINE_COPROCR_RW_FUNCS(sctlr, SCTLR)
+DEFINE_COPROCR_RW_FUNCS(actlr, ACTLR)
 DEFINE_COPROCR_RW_FUNCS(hsctlr, HSCTLR)
 DEFINE_COPROCR_RW_FUNCS(hcr, HCR)
 DEFINE_COPROCR_RW_FUNCS(hcptr, HCPTR)
@@ -273,6 +275,18 @@
 DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
 DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
 
+DEFINE_COPROCR_RW_FUNCS(nsacr, NSACR)
+
+/* AArch32 coproc registers for 32bit MMU descriptor support */
+DEFINE_COPROCR_RW_FUNCS(prrr, PRRR)
+DEFINE_COPROCR_RW_FUNCS(nmrr, NMRR)
+DEFINE_COPROCR_RW_FUNCS(dacr, DACR)
+
+DEFINE_COPROCR_RW_FUNCS(amcntenset0, AMCNTENSET0)
+DEFINE_COPROCR_RW_FUNCS(amcntenset1, AMCNTENSET1)
+DEFINE_COPROCR_RW_FUNCS(amcntenclr0, AMCNTENCLR0)
+DEFINE_COPROCR_RW_FUNCS(amcntenclr1, AMCNTENCLR1)
+
 /*
  * TLBI operation prototypes
  */
@@ -296,6 +310,7 @@
 
 /* Previously defined accessor functions with incomplete register names  */
 #define dsb()			dsbsy()
+#define dmb()			dmbsy()
 
 #define IS_IN_SECURE() \
 	(GET_NS_BIT(read_scr()) == 0)
diff --git a/include/lib/aarch32/smcc_macros.S b/include/lib/aarch32/smcc_macros.S
index cf26175..93f211f 100644
--- a/include/lib/aarch32/smcc_macros.S
+++ b/include/lib/aarch32/smcc_macros.S
@@ -22,6 +22,44 @@
 	mov	r0, sp
 	add	r0, r0, #SMC_CTX_SP_USR
 
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	/* Must be in secure state to restore Monitor mode */
+	ldcopr	r4, SCR
+	bic	r2, r4, #SCR_NS_BIT
+	stcopr	r2, SCR
+	isb
+
+	cps	#MODE32_sys
+	stm	r0!, {sp, lr}
+
+	cps	#MODE32_irq
+	mrs	r2, spsr
+	stm	r0!, {r2, sp, lr}
+
+	cps	#MODE32_fiq
+	mrs	r2, spsr
+	stm	r0!, {r2, sp, lr}
+
+	cps	#MODE32_svc
+	mrs	r2, spsr
+	stm	r0!, {r2, sp, lr}
+
+	cps	#MODE32_abt
+	mrs	r2, spsr
+	stm	r0!, {r2, sp, lr}
+
+	cps	#MODE32_und
+	mrs	r2, spsr
+	stm	r0!, {r2, sp, lr}
+
+	/* lr_mon is already saved by caller */
+	cps	#MODE32_mon
+	mrs	r2, spsr
+	stm	r0!, {r2}
+
+	stcopr	r4, SCR
+	isb
+#else
 	/* Save the banked registers including the current SPSR and LR */
 	mrs	r4, sp_usr
 	mrs	r5, lr_usr
@@ -44,9 +82,10 @@
 	mrs	r11, lr_und
 	mrs	r12, spsr
 	stm	r0!, {r4-r12}
-
 	/* lr_mon is already saved by caller */
+
 	ldcopr	r4, SCR
+#endif
 	str	r4, [sp, #SMC_CTX_SCR]
 	ldcopr	r4, PMCR
 	str	r4, [sp, #SMC_CTX_PMCR]
@@ -82,6 +121,44 @@
 
 	/* Restore the banked registers including the current SPSR */
 	add	r1, r0, #SMC_CTX_SP_USR
+
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
+	/* Must be in secure state to restore Monitor mode */
+	ldcopr	r4, SCR
+	bic	r2, r4, #SCR_NS_BIT
+	stcopr	r2, SCR
+	isb
+
+	cps	#MODE32_sys
+	ldm	r1!, {sp, lr}
+
+	cps	#MODE32_irq
+	ldm	r1!, {r2, sp, lr}
+	msr	spsr_fsxc, r2
+
+	cps	#MODE32_fiq
+	ldm	r1!, {r2, sp, lr}
+	msr	spsr_fsxc, r2
+
+	cps	#MODE32_svc
+	ldm	r1!, {r2, sp, lr}
+	msr	spsr_fsxc, r2
+
+	cps	#MODE32_abt
+	ldm	r1!, {r2, sp, lr}
+	msr	spsr_fsxc, r2
+
+	cps	#MODE32_und
+	ldm	r1!, {r2, sp, lr}
+	msr	spsr_fsxc, r2
+
+	cps	#MODE32_mon
+	ldm	r1!, {r2}
+	msr	spsr_fsxc, r2
+
+	stcopr	r4, SCR
+	isb
+#else
 	ldm	r1!, {r4-r12}
 	msr	sp_usr, r4
 	msr	lr_usr, r5
@@ -109,6 +186,7 @@
 	 * f->[31:24] and c->[7:0] bits of SPSR.
 	 */
 	msr	spsr_fsxc, r12
+#endif
 
 	/* Restore the LR */
 	ldr	lr, [r0, #SMC_CTX_LR_MON]
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index cb7dab7..65e9fc1 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -110,6 +110,9 @@
 #define ID_AA64PFR0_EL1_SHIFT	U(4)
 #define ID_AA64PFR0_EL2_SHIFT	U(8)
 #define ID_AA64PFR0_EL3_SHIFT	U(12)
+#define ID_AA64PFR0_AMU_SHIFT	U(44)
+#define ID_AA64PFR0_AMU_LENGTH	U(4)
+#define ID_AA64PFR0_AMU_MASK	U(0xf)
 #define ID_AA64PFR0_ELX_MASK	U(0xf)
 
 /* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
@@ -135,6 +138,7 @@
 #define PARANGE_0011	U(42)
 #define PARANGE_0100	U(44)
 #define PARANGE_0101	U(48)
+#define PARANGE_0110	U(52)
 
 #define ID_AA64MMFR0_EL1_TGRAN4_SHIFT		U(28)
 #define ID_AA64MMFR0_EL1_TGRAN4_MASK		U(0xf)
@@ -294,6 +298,7 @@
 
 /* CPTR_EL3 definitions */
 #define TCPAC_BIT		(U(1) << 31)
+#define TAM_BIT			(U(1) << 30)
 #define TTA_BIT			(U(1) << 20)
 #define TFP_BIT			(U(1) << 10)
 #define CPTR_EL3_RESET_VAL	U(0x0)
@@ -301,6 +306,7 @@
 /* CPTR_EL2 definitions */
 #define CPTR_EL2_RES1		((U(1) << 13) | (U(1) << 12) | (U(0x3ff)))
 #define CPTR_EL2_TCPAC_BIT	(U(1) << 31)
+#define CPTR_EL2_TAM_BIT	(U(1) << 30)
 #define CPTR_EL2_TTA_BIT	(U(1) << 20)
 #define CPTR_EL2_TFP_BIT	(U(1) << 10)
 #define CPTR_EL2_RESET_VAL	CPTR_EL2_RES1
@@ -604,4 +610,33 @@
 #define PAR_ADDR_SHIFT	12
 #define PAR_ADDR_MASK	(BIT(40) - 1) /* 40-bits-wide page address */
 
+/*******************************************************************************
+ * Definitions for system register interface to SPE
+ ******************************************************************************/
+#define PMBLIMITR_EL1		S3_0_C9_C10_0
+
+/*******************************************************************************
+ * Definitions for system register interface to AMU for ARMv8.4 onwards
+ ******************************************************************************/
+#define AMCR_EL0		S3_3_C13_C2_0
+#define AMCFGR_EL0		S3_3_C13_C2_1
+#define AMCGCR_EL0		S3_3_C13_C2_2
+#define AMUSERENR_EL0		S3_3_C13_C2_3
+#define AMCNTENCLR0_EL0		S3_3_C13_C2_4
+#define AMCNTENSET0_EL0		S3_3_C13_C2_5
+#define AMCNTENCLR1_EL0		S3_3_C13_C3_0
+#define AMCNTENSET1_EL0		S3_3_C13_C3_1
+
+/* Activity Monitor Group 0 Event Counter Registers */
+#define AMEVCNTR00_EL0		S3_3_C13_C4_0
+#define AMEVCNTR01_EL0		S3_3_C13_C4_1
+#define AMEVCNTR02_EL0		S3_3_C13_C4_2
+#define AMEVCNTR03_EL0		S3_3_C13_C4_3
+
+/* Activity Monitor Group 0 Event Type Registers */
+#define AMEVTYPER00_EL0		S3_3_C13_C6_0
+#define AMEVTYPER01_EL0		S3_3_C13_C6_1
+#define AMEVTYPER02_EL0		S3_3_C13_C6_2
+#define AMEVTYPER03_EL0		S3_3_C13_C6_3
+
 #endif /* __ARCH_H__ */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 782343d..b6be167 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -197,6 +197,7 @@
 DEFINE_SYSOP_TYPE_FUNC(dmb, st)
 DEFINE_SYSOP_TYPE_FUNC(dmb, ld)
 DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
+DEFINE_SYSOP_TYPE_FUNC(dsb, nsh)
 DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
 DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
 DEFINE_SYSOP_TYPE_FUNC(dmb, ishst)
@@ -301,6 +302,7 @@
 DEFINE_SYSREG_READ_FUNC(ctr_el0)
 
 DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
+DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
 DEFINE_SYSREG_RW_FUNCS(hstr_el2)
 DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)
 DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
@@ -320,6 +322,12 @@
 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
 DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
 
+DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr0_el0, AMCNTENCLR0_EL0)
+DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
+DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
+DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
+
+DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
 
 #define IS_IN_EL(x) \
 	(GET_EL(read_CurrentEl()) == MODE_EL##x)
diff --git a/include/lib/cpus/aarch32/cortex_a12.h b/include/lib/cpus/aarch32/cortex_a12.h
new file mode 100644
index 0000000..3068a41
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a12.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A12_H__
+#define __CORTEX_A12_H__
+
+/*******************************************************************************
+ * Cortex-A12 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A12_MIDR			0x410FC0C0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A12_ACTLR_SMP_BIT	(1 << 6)
+
+#endif /* __CORTEX_A12_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a15.h b/include/lib/cpus/aarch32/cortex_a15.h
new file mode 100644
index 0000000..905c139
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a15.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A15_H__
+#define __CORTEX_A15_H__
+
+/*******************************************************************************
+ * Cortex-A15 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A15_MIDR			0x410FC0F0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A15_ACTLR_SMP_BIT	(1 << 6)
+
+#endif /* __CORTEX_A15_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a17.h b/include/lib/cpus/aarch32/cortex_a17.h
new file mode 100644
index 0000000..d2ca91c
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a17.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A17_H__
+#define __CORTEX_A17_H__
+
+/*******************************************************************************
+ * Cortex-A17 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A17_MIDR			0x410FC0E0
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A17_ACTLR_SMP_BIT	(1 << 6)
+
+#endif /* __CORTEX_A17_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a5.h b/include/lib/cpus/aarch32/cortex_a5.h
new file mode 100644
index 0000000..0a0b7ff
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a5.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A5_H__
+#define __CORTEX_A5_H__
+
+/*******************************************************************************
+ * Cortex-A8 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A5_MIDR			0x410FC050
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A5_ACTLR_SMP_BIT		(1 << 6)
+
+#endif /* __CORTEX_A5_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a7.h b/include/lib/cpus/aarch32/cortex_a7.h
new file mode 100644
index 0000000..61b0d00
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a7.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A7_H__
+#define __CORTEX_A7_H__
+
+/*******************************************************************************
+ * Cortex-A7 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A7_MIDR			0x410FC070
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A7_ACTLR_SMP_BIT		(1 << 6)
+
+#endif /* __CORTEX_A7_H__ */
diff --git a/include/lib/cpus/aarch32/cortex_a9.h b/include/lib/cpus/aarch32/cortex_a9.h
new file mode 100644
index 0000000..be85f9b
--- /dev/null
+++ b/include/lib/cpus/aarch32/cortex_a9.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_A9_H__
+#define __CORTEX_A9_H__
+
+/*******************************************************************************
+ * Cortex-A9 midr with version/revision set to 0
+ ******************************************************************************/
+#define CORTEX_A9_MIDR			0x410FC090
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A9_ACTLR_SMP_BIT		(1 << 6)
+#define CORTEX_A9_ACTLR_FLZW_BIT	(1 << 3)
+
+/*******************************************************************************
+ * CPU Power Control Register
+ ******************************************************************************/
+#define PCR		p15, 0, c15, c0, 0
+
+#ifndef __ASSEMBLY__
+#include <arch_helpers.h>
+DEFINE_COPROCR_RW_FUNCS(pcr, PCR)
+#endif
+
+#endif /* __CORTEX_A9_H__ */
diff --git a/include/lib/cpus/aarch64/cortex_a75.h b/include/lib/cpus/aarch64/cortex_a75.h
index 1ffe20b..d68c957 100644
--- a/include/lib/cpus/aarch64/cortex_a75.h
+++ b/include/lib/cpus/aarch64/cortex_a75.h
@@ -19,4 +19,38 @@
 /* Definitions of register field mask in CORTEX_A75_CPUPWRCTLR_EL1 */
 #define CORTEX_A75_CORE_PWRDN_EN_MASK	0x1
 
+/*******************************************************************************
+ * CPU Activity Monitor Unit register specific definitions.
+ ******************************************************************************/
+#define CPUAMCNTENCLR_EL0	S3_3_C15_C9_7
+#define CPUAMCNTENSET_EL0	S3_3_C15_C9_6
+#define CPUAMCFGR_EL0		S3_3_C15_C10_6
+#define CPUAMUSERENR_EL0	S3_3_C15_C10_7
+
+/* Activity Monitor Event Counter Registers */
+#define CPUAMEVCNTR0_EL0	S3_3_C15_C9_0
+#define CPUAMEVCNTR1_EL0	S3_3_C15_C9_1
+#define CPUAMEVCNTR2_EL0	S3_3_C15_C9_2
+#define CPUAMEVCNTR3_EL0	S3_3_C15_C9_3
+#define CPUAMEVCNTR4_EL0	S3_3_C15_C9_4
+
+/* Activity Monitor Event Type Registers */
+#define CPUAMEVTYPER0_EL0	S3_3_C15_C10_0
+#define CPUAMEVTYPER1_EL0	S3_3_C15_C10_1
+#define CPUAMEVTYPER2_EL0	S3_3_C15_C10_2
+#define CPUAMEVTYPER3_EL0	S3_3_C15_C10_3
+#define CPUAMEVTYPER4_EL0	S3_3_C15_C10_4
+
+#define CORTEX_A75_ACTLR_AMEN_BIT	(U(1) << 4)
+
+/*
+ * The Cortex-A75 core implements five counters, 0-4. Events 0, 1, 2, are
+ * fixed and are enabled (Group 0). Events 3 and 4 (Group 1) are
+ * programmable by programming the appropriate Event count bits in
+ * CPUAMEVTYPER<n> register and are disabled by default. Platforms may
+ * enable this with suitable programming.
+ */
+#define CORTEX_A75_AMU_GROUP0_MASK	0x7
+#define CORTEX_A75_AMU_GROUP1_MASK	(0 << 3)
+
 #endif /* __CORTEX_A75_H__ */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index cf06a64..5889904 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -313,7 +313,6 @@
  * Function prototypes
  ******************************************************************************/
 void el1_sysregs_context_save(el1_sys_regs_t *regs);
-void el1_sysregs_context_save_post_ops(void);
 void el1_sysregs_context_restore(el1_sys_regs_t *regs);
 #if CTX_INCLUDE_FPREGS
 void fpregs_context_save(fp_regs_t *regs);
diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h
new file mode 100644
index 0000000..bbefe8f
--- /dev/null
+++ b/include/lib/extensions/amu.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __AMU_H__
+#define __AMU_H__
+
+/* Enable all group 0 counters */
+#define AMU_GROUP0_COUNTERS_MASK	0xf
+
+void amu_enable(int el2_unused);
+
+#endif /* __AMU_H__ */
diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h
new file mode 100644
index 0000000..8a74127
--- /dev/null
+++ b/include/lib/extensions/spe.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SPE_H__
+#define __SPE_H__
+
+void spe_enable(int el2_unused);
+void spe_disable(void);
+
+#endif /* __SPE_H__ */
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h
index 97a1af4..68f4a0e 100644
--- a/include/plat/arm/board/common/board_arm_def.h
+++ b/include/plat/arm/board/common/board_arm_def.h
@@ -96,6 +96,14 @@
 #define PLAT_ARM_MAX_BL31_SIZE		0x1D000
 #endif
 
+#ifdef AARCH32
+/*
+ * PLAT_ARM_MAX_BL32_SIZE is calculated for SP_MIN as the AArch32 Secure
+ * Payload.
+ */
+# define PLAT_ARM_MAX_BL32_SIZE		0x1D000
+#endif
+
 #endif /* ARM_BOARD_OPTIMISE_MEM */
 
 #define MAX_IO_DEVICES			3
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index b8955af..7887525 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -326,14 +326,21 @@
 /*******************************************************************************
  * BL2 specific defines.
  ******************************************************************************/
-#if ARM_BL31_IN_DRAM || (defined(AARCH32) && !defined(JUNO_AARCH32_EL3_RUNTIME))
+#if ARM_BL31_IN_DRAM
 /*
- * For AArch32 BL31 is not applicable.
  * For AArch64 BL31 is loaded in the DRAM.
  * Put BL2 just below BL1.
  */
 #define BL2_BASE			(BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
 #define BL2_LIMIT			BL1_RW_BASE
+
+#elif defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME
+/*
+ * Put BL2 just below BL32.
+ */
+#define BL2_BASE			(BL32_BASE - PLAT_ARM_MAX_BL2_SIZE)
+#define BL2_LIMIT			BL32_BASE
+
 #else
 /*
  * Put BL2 just below BL31.
@@ -370,76 +377,86 @@
 #define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
 #endif
 
+#if defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME
 /*******************************************************************************
- * BL32 specific defines.
+ * BL32 specific defines for EL3 runtime in AArch32 mode
+ ******************************************************************************/
+# if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME
+/* SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM to BL32 */
+#  define BL32_BASE			ARM_BL_RAM_BASE
+#  define BL32_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+# else
+/* Put BL32 at the top of the Trusted SRAM.*/
+#  define BL32_BASE			(ARM_BL_RAM_BASE +		\
+						ARM_BL_RAM_SIZE -	\
+						PLAT_ARM_MAX_BL32_SIZE)
+#  define BL32_PROGBITS_LIMIT		BL1_RW_BASE
+#  define BL32_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+# endif /* RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME */
+
+#else
+/*******************************************************************************
+ * BL32 specific defines for EL3 runtime in AArch64 mode
  ******************************************************************************/
 /*
  * On ARM standard platforms, the TSP can execute from Trusted SRAM,
  * Trusted DRAM (if available) or the DRAM region secured by the TrustZone
  * controller.
  */
-#if ENABLE_SPM
-# define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
-# define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
-# define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
-# define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
+# if ENABLE_SPM
+#  define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
+#  define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
+#  define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
+#  define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						ARM_AP_TZC_DRAM1_SIZE)
-#elif ARM_BL31_IN_DRAM
-# define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE +	\
+# elif ARM_BL31_IN_DRAM
+#  define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE +	\
 						PLAT_ARM_MAX_BL31_SIZE)
-# define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE -	\
+#  define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE -	\
 						PLAT_ARM_MAX_BL31_SIZE)
-# define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE +	\
+#  define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE +	\
 						PLAT_ARM_MAX_BL31_SIZE)
-# define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
+#  define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						ARM_AP_TZC_DRAM1_SIZE)
-#elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_SRAM_ID
-# define TSP_SEC_MEM_BASE		ARM_BL_RAM_BASE
-# define TSP_SEC_MEM_SIZE		ARM_BL_RAM_SIZE
-# define TSP_PROGBITS_LIMIT		BL2_BASE
-# define BL32_BASE			ARM_BL_RAM_BASE
-# define BL32_LIMIT			BL31_BASE
-#elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID
-# define TSP_SEC_MEM_BASE		PLAT_ARM_TRUSTED_DRAM_BASE
-# define TSP_SEC_MEM_SIZE		PLAT_ARM_TRUSTED_DRAM_SIZE
-# define BL32_BASE			PLAT_ARM_TRUSTED_DRAM_BASE
-# define BL32_LIMIT			(PLAT_ARM_TRUSTED_DRAM_BASE	\
+# elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_SRAM_ID
+#  define TSP_SEC_MEM_BASE		ARM_BL_RAM_BASE
+#  define TSP_SEC_MEM_SIZE		ARM_BL_RAM_SIZE
+#  define TSP_PROGBITS_LIMIT		BL2_BASE
+#  define BL32_BASE			ARM_BL_RAM_BASE
+#  define BL32_LIMIT			BL31_BASE
+# elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID
+#  define TSP_SEC_MEM_BASE		PLAT_ARM_TRUSTED_DRAM_BASE
+#  define TSP_SEC_MEM_SIZE		PLAT_ARM_TRUSTED_DRAM_SIZE
+#  define BL32_BASE			PLAT_ARM_TRUSTED_DRAM_BASE
+#  define BL32_LIMIT			(PLAT_ARM_TRUSTED_DRAM_BASE	\
 						+ (1 << 21))
-#elif ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID
-# define TSP_SEC_MEM_BASE		ARM_AP_TZC_DRAM1_BASE
-# define TSP_SEC_MEM_SIZE		ARM_AP_TZC_DRAM1_SIZE
-# define BL32_BASE			ARM_AP_TZC_DRAM1_BASE
-# define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
+# elif ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID
+#  define TSP_SEC_MEM_BASE		ARM_AP_TZC_DRAM1_BASE
+#  define TSP_SEC_MEM_SIZE		ARM_AP_TZC_DRAM1_SIZE
+#  define BL32_BASE			ARM_AP_TZC_DRAM1_BASE
+#  define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						ARM_AP_TZC_DRAM1_SIZE)
-#else
-# error "Unsupported ARM_TSP_RAM_LOCATION_ID value"
-#endif
+# else
+#  error "Unsupported ARM_TSP_RAM_LOCATION_ID value"
+# endif
+#endif /* AARCH32 || JUNO_AARCH32_EL3_RUNTIME */
 
 /*
  * BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
  * SPD and no SPM, as they are the only ones that can be used as BL32.
  */
-#ifndef AARCH32
+#if !(defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME)
 # if defined(SPD_none) && !ENABLE_SPM
 #  undef BL32_BASE
-# endif
-#endif
+# endif /* defined(SPD_none) && !ENABLE_SPM */
+#endif /* !(defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME) */
 
 /*******************************************************************************
  * FWU Images: NS_BL1U, BL2U & NS_BL2U defines.
  ******************************************************************************/
 #define BL2U_BASE			BL2_BASE
-#if ARM_BL31_IN_DRAM || (defined(AARCH32) && !defined(JUNO_AARCH32_EL3_RUNTIME))
-/*
- * For AArch32 BL31 is not applicable.
- * For AArch64 BL31 is loaded in the DRAM.
- * BL2U extends up to BL1.
- */
-#define BL2U_LIMIT			BL1_RW_BASE
-#else
-/* BL2U extends up to BL31. */
-#define BL2U_LIMIT			BL31_BASE
-#endif
+#define BL2U_LIMIT			BL2_LIMIT
+
 #define NS_BL2U_BASE			ARM_NS_DRAM1_BASE
 #define NS_BL1U_BASE			(PLAT_ARM_NVM_BASE + 0x03EB8000)
 
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index a28a903..abd7395 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -227,7 +227,4 @@
 		uint32_t cookie_lo,
 		void *handle);
 
-/* Disable Statistical Profiling Extensions helper */
-void arm_disable_spe(void);
-
 #endif /* __PLAT_ARM_H__ */
diff --git a/include/services/sdei.h b/include/services/sdei.h
index b07e93b..ce9a008 100644
--- a/include/services/sdei.h
+++ b/include/services/sdei.h
@@ -154,7 +154,7 @@
 	int32_t ev_num;		/* Event number */
 	unsigned int intr;	/* Physical interrupt number for a bound map */
 	unsigned int map_flags;	/* Mapping flags, see SDEI_MAPF_* */
-	unsigned int reg_count;	/* Registration count */
+	int reg_count;		/* Registration count */
 	spinlock_t lock;	/* Per-event lock */
 } sdei_ev_map_t;
 
diff --git a/lib/aarch32/arm32_aeabi_divmod.c b/lib/aarch32/arm32_aeabi_divmod.c
new file mode 100644
index 0000000..a8f2e74
--- /dev/null
+++ b/lib/aarch32/arm32_aeabi_divmod.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Form ABI specifications:
+ *      int __aeabi_idiv(int numerator, int denominator);
+ *     unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
+ *
+ *     typedef struct { int quot; int rem; } idiv_return;
+ *     typedef struct { unsigned quot; unsigned rem; } uidiv_return;
+ *
+ *     __value_in_regs idiv_return __aeabi_idivmod(int numerator,
+ *     int *denominator);
+ *     __value_in_regs uidiv_return __aeabi_uidivmod(unsigned *numerator,
+ *     unsigned denominator);
+ */
+
+/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
+struct qr {
+	unsigned int q;		/* computed quotient */
+	unsigned int r;		/* computed remainder */
+	unsigned int q_n;	/* specficies if quotient shall be negative */
+	unsigned int r_n;	/* specficies if remainder shall be negative */
+};
+
+static void uint_div_qr(unsigned int numerator, unsigned int denominator,
+			struct qr *qr);
+
+/* returns in R0 and R1 by tail calling an asm function */
+unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator);
+
+unsigned int __aeabi_uidiv(unsigned int numerator, unsigned int denominator);
+unsigned int __aeabi_uimod(unsigned int numerator, unsigned int denominator);
+
+/* returns in R0 and R1 by tail calling an asm function */
+signed int __aeabi_idivmod(signed int numerator, signed int denominator);
+
+signed int __aeabi_idiv(signed int numerator, signed int denominator);
+signed int __aeabi_imod(signed int numerator, signed int denominator);
+
+/*
+ * __ste_idivmod_ret_t __aeabi_idivmod(signed numerator, signed denominator)
+ * Numerator and Denominator are received in R0 and R1.
+ * Where __ste_idivmod_ret_t is returned in R0 and R1.
+ *
+ * __ste_uidivmod_ret_t __aeabi_uidivmod(unsigned numerator,
+ *                                       unsigned denominator)
+ * Numerator and Denominator are received in R0 and R1.
+ * Where __ste_uidivmod_ret_t is returned in R0 and R1.
+ */
+#ifdef __GNUC__
+signed int ret_idivmod_values(signed int quotient, signed int remainder);
+unsigned int ret_uidivmod_values(unsigned int quotient, unsigned int remainder);
+#else
+#error "Compiler not supported"
+#endif
+
+static void division_qr(unsigned int n, unsigned int p, struct qr *qr)
+{
+	unsigned int i = 1, q = 0;
+
+	if (p == 0) {
+		qr->r = 0xFFFFFFFF;	/* division by 0 */
+		return;
+	}
+
+	while ((p >> 31) == 0) {
+		i = i << 1;	/* count the max division steps */
+		p = p << 1;     /* increase p until it has maximum size*/
+	}
+
+	while (i > 0) {
+		q = q << 1;	/* write bit in q at index (size-1) */
+		if (n >= p) {
+			n -= p;
+			q++;
+		}
+		p = p >> 1;	/* decrease p */
+		i = i >> 1;	/* decrease remaining size in q */
+	}
+	qr->r = n;
+	qr->q = q;
+}
+
+static void uint_div_qr(unsigned int numerator, unsigned int denominator,
+			struct qr *qr)
+{
+	division_qr(numerator, denominator, qr);
+
+	/* negate quotient and/or remainder according to requester */
+	if (qr->q_n)
+		qr->q = -qr->q;
+	if (qr->r_n)
+		qr->r = -qr->r;
+}
+
+unsigned int __aeabi_uidiv(unsigned int numerator, unsigned int denominator)
+{
+	struct qr qr = { .q_n = 0, .r_n = 0 };
+
+	uint_div_qr(numerator, denominator, &qr);
+
+	return qr.q;
+}
+
+unsigned int __aeabi_uimod(unsigned int numerator, unsigned int denominator)
+{
+	struct qr qr = { .q_n = 0, .r_n = 0 };
+
+	uint_div_qr(numerator, denominator, &qr);
+
+	return qr.r;
+}
+
+unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator)
+{
+	struct qr qr = { .q_n = 0, .r_n = 0 };
+
+	uint_div_qr(numerator, denominator, &qr);
+
+	return ret_uidivmod_values(qr.q, qr.r);
+}
+
+signed int __aeabi_idiv(signed int numerator, signed int denominator)
+{
+	struct qr qr = { .q_n = 0, .r_n = 0 };
+
+	if (((numerator < 0) && (denominator > 0)) ||
+	    ((numerator > 0) && (denominator < 0)))
+		qr.q_n = 1;	/* quotient shall be negate */
+
+	if (numerator < 0) {
+		numerator = -numerator;
+		qr.r_n = 1;	/* remainder shall be negate */
+	}
+
+	if (denominator < 0)
+		denominator = -denominator;
+
+	uint_div_qr(numerator, denominator, &qr);
+
+	return qr.q;
+}
+
+signed int __aeabi_imod(signed int numerator, signed int denominator)
+{
+	signed int s;
+	signed int i;
+	signed int j;
+	signed int h;
+	struct qr qr = { .q_n = 0, .r_n = 0 };
+
+	/* in case modulo of a power of 2 */
+	for (i = 0, j = 0, h = 0, s = denominator; (s != 0) || (h > 1); i++) {
+		if (s & 1) {
+			j = i;
+			h++;
+		}
+		s = s >> 1;
+	}
+	if (h == 1)
+		return numerator >> j;
+
+	if (((numerator < 0) && (denominator > 0)) ||
+	    ((numerator > 0) && (denominator < 0)))
+		qr.q_n = 1;	/* quotient shall be negate */
+
+	if (numerator < 0) {
+		numerator = -numerator;
+		qr.r_n = 1;	/* remainder shall be negate */
+	}
+
+	if (denominator < 0)
+		denominator = -denominator;
+
+	uint_div_qr(numerator, denominator, &qr);
+
+	return qr.r;
+}
+
+signed int __aeabi_idivmod(signed int numerator, signed int denominator)
+{
+	struct qr qr = { .q_n = 0, .r_n = 0 };
+
+	if (((numerator < 0) && (denominator > 0)) ||
+	    ((numerator > 0) && (denominator < 0)))
+		qr.q_n = 1;	/* quotient shall be negate */
+
+	if (numerator < 0) {
+		numerator = -numerator;
+		qr.r_n = 1;	/* remainder shall be negate */
+	}
+
+	if (denominator < 0)
+		denominator = -denominator;
+
+	uint_div_qr(numerator, denominator, &qr);
+
+	return ret_idivmod_values(qr.q, qr.r);
+}
diff --git a/lib/aarch32/arm32_aeabi_divmod_a32.S b/lib/aarch32/arm32_aeabi_divmod_a32.S
new file mode 100644
index 0000000..6915dcd
--- /dev/null
+++ b/lib/aarch32/arm32_aeabi_divmod_a32.S
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+/*
+ * EABI wrappers from the udivmod and idivmod functions
+ */
+
+	.globl ret_uidivmod_values
+	.globl ret_idivmod_values
+
+/*
+ * signed ret_idivmod_values(signed quot, signed rem);
+ * return quotient and remaining the EABI way (regs r0,r1)
+ */
+func ret_idivmod_values
+        bx lr
+endfunc ret_idivmod_values
+
+/*
+ * unsigned ret_uidivmod_values(unsigned quot, unsigned rem);
+ * return quotient and remaining the EABI way (regs r0,r1)
+ */
+func ret_uidivmod_values
+        bx      lr
+endfunc ret_uidivmod_values
diff --git a/lib/cpus/aarch32/cortex_a12.S b/lib/cpus/aarch32/cortex_a12.S
new file mode 100644
index 0000000..73c9750
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a12.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a12.h>
+#include <cpu_macros.S>
+
+	.macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+		ldcopr	r0, SCTLR
+		tst	r0, #SCTLR_C_BIT
+		ASM_ASSERT(eq)
+#endif
+	.endm
+
+func cortex_a12_disable_smp
+	ldcopr	r0, ACTLR
+	bic	r0, #CORTEX_A12_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	dsb	sy
+	bx	lr
+endfunc cortex_a12_disable_smp
+
+func cortex_a12_enable_smp
+	ldcopr	r0, ACTLR
+	orr	r0, #CORTEX_A12_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	bx	lr
+endfunc cortex_a12_enable_smp
+
+func cortex_a12_reset_func
+	b	cortex_a12_enable_smp
+endfunc cortex_a12_reset_func
+
+func cortex_a12_core_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 cache */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a12_disable_smp
+endfunc cortex_a12_core_pwr_dwn
+
+func cortex_a12_cluster_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	bl	plat_disable_acp
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a12_disable_smp
+endfunc cortex_a12_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a12, CORTEX_A12_MIDR, \
+	cortex_a12_reset_func, \
+	cortex_a12_core_pwr_dwn, \
+	cortex_a12_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a15.S b/lib/cpus/aarch32/cortex_a15.S
new file mode 100644
index 0000000..0d5a116
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a15.S
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a15.h>
+#include <cpu_macros.S>
+
+/*
+ * Cortex-A15 support LPAE and Virtualization Extensions.
+ * Don't care if confiugration uses or not LPAE and VE.
+ * Therefore, where we don't check ARCH_IS_ARMV7_WITH_LPAE/VE
+ */
+
+	.macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+		ldcopr	r0, SCTLR
+		tst	r0, #SCTLR_C_BIT
+		ASM_ASSERT(eq)
+#endif
+	.endm
+
+func cortex_a15_disable_smp
+	ldcopr	r0, ACTLR
+	bic	r0, #CORTEX_A15_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	dsb	sy
+	bx	lr
+endfunc cortex_a15_disable_smp
+
+func cortex_a15_enable_smp
+	ldcopr	r0, ACTLR
+	orr	r0, #CORTEX_A15_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	bx	lr
+endfunc cortex_a15_enable_smp
+
+func cortex_a15_reset_func
+	b	cortex_a15_enable_smp
+endfunc cortex_a15_reset_func
+
+func cortex_a15_core_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 cache */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a15_disable_smp
+endfunc cortex_a15_core_pwr_dwn
+
+func cortex_a15_cluster_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	bl	plat_disable_acp
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a15_disable_smp
+endfunc cortex_a15_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a15, CORTEX_A15_MIDR, \
+	cortex_a15_reset_func, \
+	cortex_a15_core_pwr_dwn, \
+	cortex_a15_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a17.S b/lib/cpus/aarch32/cortex_a17.S
new file mode 100644
index 0000000..316d4f0
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a17.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a17.h>
+#include <cpu_macros.S>
+
+	.macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+		ldcopr	r0, SCTLR
+		tst	r0, #SCTLR_C_BIT
+		ASM_ASSERT(eq)
+#endif
+	.endm
+
+func cortex_a17_disable_smp
+	ldcopr	r0, ACTLR
+	bic	r0, #CORTEX_A17_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	dsb	sy
+	bx	lr
+endfunc cortex_a17_disable_smp
+
+func cortex_a17_enable_smp
+	ldcopr	r0, ACTLR
+	orr	r0, #CORTEX_A17_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	bx	lr
+endfunc cortex_a17_enable_smp
+
+func cortex_a17_reset_func
+	b	cortex_a17_enable_smp
+endfunc cortex_a17_reset_func
+
+func cortex_a17_core_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 cache */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a17_disable_smp
+endfunc cortex_a17_core_pwr_dwn
+
+func cortex_a17_cluster_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	bl	plat_disable_acp
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a17_disable_smp
+endfunc cortex_a17_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a17, CORTEX_A17_MIDR, \
+	cortex_a17_reset_func, \
+	cortex_a17_core_pwr_dwn, \
+	cortex_a17_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a5.S b/lib/cpus/aarch32/cortex_a5.S
new file mode 100644
index 0000000..c07c13e
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a5.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a5.h>
+#include <cpu_macros.S>
+
+	.macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+		ldcopr	r0, SCTLR
+		tst	r0, #SCTLR_C_BIT
+		ASM_ASSERT(eq)
+#endif
+	.endm
+
+func cortex_a5_disable_smp
+	ldcopr	r0, ACTLR
+	bic	r0, #CORTEX_A5_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	dsb	sy
+	bx	lr
+endfunc cortex_a5_disable_smp
+
+func cortex_a5_enable_smp
+	ldcopr	r0, ACTLR
+	orr	r0, #CORTEX_A5_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	bx	lr
+endfunc cortex_a5_enable_smp
+
+func cortex_a5_reset_func
+	b	cortex_a5_enable_smp
+endfunc cortex_a5_reset_func
+
+func cortex_a5_core_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 cache */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a5_disable_smp
+endfunc cortex_a5_core_pwr_dwn
+
+func cortex_a5_cluster_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	bl	plat_disable_acp
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a5_disable_smp
+endfunc cortex_a5_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a5, CORTEX_A5_MIDR, \
+	cortex_a5_reset_func, \
+	cortex_a5_core_pwr_dwn, \
+	cortex_a5_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a7.S b/lib/cpus/aarch32/cortex_a7.S
new file mode 100644
index 0000000..0278d1f
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a7.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a7.h>
+#include <cpu_macros.S>
+
+	.macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+		ldcopr	r0, SCTLR
+		tst	r0, #SCTLR_C_BIT
+		ASM_ASSERT(eq)
+#endif
+	.endm
+
+func cortex_a7_disable_smp
+	ldcopr	r0, ACTLR
+	bic	r0, #CORTEX_A7_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	dsb	sy
+	bx	lr
+endfunc cortex_a7_disable_smp
+
+func cortex_a7_enable_smp
+	ldcopr	r0, ACTLR
+	orr	r0, #CORTEX_A7_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	bx	lr
+endfunc cortex_a7_enable_smp
+
+func cortex_a7_reset_func
+	b	cortex_a7_enable_smp
+endfunc cortex_a7_reset_func
+
+func cortex_a7_core_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 cache */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a7_disable_smp
+endfunc cortex_a7_core_pwr_dwn
+
+func cortex_a7_cluster_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	bl	plat_disable_acp
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a7_disable_smp
+endfunc cortex_a7_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a7, CORTEX_A7_MIDR, \
+	cortex_a7_reset_func, \
+	cortex_a7_core_pwr_dwn, \
+	cortex_a7_cluster_pwr_dwn
diff --git a/lib/cpus/aarch32/cortex_a9.S b/lib/cpus/aarch32/cortex_a9.S
new file mode 100644
index 0000000..4f30f84
--- /dev/null
+++ b/lib/cpus/aarch32/cortex_a9.S
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <cortex_a9.h>
+#include <cpu_macros.S>
+
+	.macro assert_cache_enabled
+#if ENABLE_ASSERTIONS
+		ldcopr	r0, SCTLR
+		tst	r0, #SCTLR_C_BIT
+		ASM_ASSERT(eq)
+#endif
+	.endm
+
+func cortex_a9_disable_smp
+	ldcopr	r0, ACTLR
+	bic	r0, #CORTEX_A9_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	dsb	sy
+	bx	lr
+endfunc cortex_a9_disable_smp
+
+func cortex_a9_enable_smp
+	ldcopr	r0, ACTLR
+	orr	r0, #CORTEX_A9_ACTLR_SMP_BIT
+	stcopr	r0, ACTLR
+	isb
+	bx	lr
+endfunc cortex_a9_enable_smp
+
+func cortex_a9_reset_func
+	b	cortex_a9_enable_smp
+endfunc cortex_a9_reset_func
+
+func cortex_a9_core_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 cache */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a9_disable_smp
+endfunc cortex_a9_core_pwr_dwn
+
+func cortex_a9_cluster_pwr_dwn
+	push	{r12, lr}
+
+	assert_cache_enabled
+
+	/* Flush L1 caches */
+	mov	r0, #DC_OP_CISW
+	bl	dcsw_op_level1
+
+	bl	plat_disable_acp
+
+	/* Exit cluster coherency */
+	pop	{r12, lr}
+	b	cortex_a9_disable_smp
+endfunc cortex_a9_cluster_pwr_dwn
+
+declare_cpu_ops cortex_a9, CORTEX_A9_MIDR, \
+	cortex_a9_reset_func, \
+	cortex_a9_core_pwr_dwn, \
+	cortex_a9_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index 1f4500c..4cab9e4 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -11,6 +11,33 @@
 #include <plat_macros.S>
 #include <cortex_a75.h>
 
+func cortex_a75_reset_func
+#if ENABLE_AMU
+	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
+	mrs	x0, actlr_el3
+	orr	x0, x0, #CORTEX_A75_ACTLR_AMEN_BIT
+	msr	actlr_el3, x0
+	isb
+
+	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
+	mrs	x0, actlr_el2
+	orr	x0, x0, #CORTEX_A75_ACTLR_AMEN_BIT
+	msr	actlr_el2, x0
+	isb
+
+	/* Enable group0 counters */
+	mov	x0, #CORTEX_A75_AMU_GROUP0_MASK
+	msr	CPUAMCNTENSET_EL0, x0
+	isb
+
+	/* Enable group1 counters */
+	mov	x0, #CORTEX_A75_AMU_GROUP1_MASK
+	msr	CPUAMCNTENSET_EL0, x0
+	isb
+#endif
+	ret
+endfunc cortex_a75_reset_func
+
 	/* ---------------------------------------------
 	 * HW will do the cache maintenance while powering down
 	 * ---------------------------------------------
@@ -47,5 +74,5 @@
 endfunc cortex_a75_cpu_reg_dump
 
 declare_cpu_ops cortex_a75, CORTEX_A75_MIDR, \
-	CPU_NO_RESET_FUNC, \
+	cortex_a75_reset_func, \
 	cortex_a75_core_pwr_dwn
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 3e7a5b7..76e440e3 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <amu.h>
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
@@ -125,6 +126,20 @@
 }
 
 /*******************************************************************************
+ * Enable architecture extensions on first entry to Non-secure world.
+ * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
+ * it is zero.
+ ******************************************************************************/
+static void enable_extensions_nonsecure(int el2_unused)
+{
+#if IMAGE_BL32
+#if ENABLE_AMU
+	amu_enable(el2_unused);
+#endif
+#endif
+}
+
+/*******************************************************************************
  * The following function initializes the cpu_context for a CPU specified by
  * its `cpu_idx` for first use, and sets the initial entrypoint state as
  * specified by the entry_point_info structure.
@@ -161,6 +176,7 @@
 {
 	uint32_t hsctlr, scr;
 	cpu_context_t *ctx = cm_get_context(security_state);
+	int el2_unused = 0;
 
 	assert(ctx);
 
@@ -185,6 +201,8 @@
 			isb();
 		} else if (read_id_pfr1() &
 			(ID_PFR1_VIRTEXT_MASK << ID_PFR1_VIRTEXT_SHIFT)) {
+			el2_unused = 1;
+
 			/*
 			 * Set the NS bit to access NS copies of certain banked
 			 * registers
@@ -283,5 +301,6 @@
 			write_scr(read_scr() & ~SCR_NS_BIT);
 			isb();
 		}
+		enable_extensions_nonsecure(el2_unused);
 	}
 }
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 143da95..620ec16 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -9,7 +9,6 @@
 #include <context.h>
 
 	.global	el1_sysregs_context_save
-	.global el1_sysregs_context_save_post_ops
 	.global	el1_sysregs_context_restore
 #if CTX_INCLUDE_FPREGS
 	.global	fpregs_context_save
@@ -112,36 +111,6 @@
 /* -----------------------------------------------------
  * The following function strictly follows the AArch64
  * PCS to use x9-x17 (temporary caller-saved registers)
- * to do post operations after saving the EL1 system
- * register context.
- * -----------------------------------------------------
- */
-func el1_sysregs_context_save_post_ops
-#if ENABLE_SPE_FOR_LOWER_ELS
-	/* Detect if SPE is implemented */
-	mrs	x9, id_aa64dfr0_el1
-	ubfx	x9, x9, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH
-	cmp	x9, #0x1
-	b.ne	1f
-
-	/*
-	 * Before switching from normal world to secure world
-	 * the profiling buffers need to be drained out to memory.  This is
-	 * required to avoid an invalid memory access when TTBR is switched
-	 * for entry to SEL1.
-	 */
-	.arch	armv8.2-a+profile
-	psb	csync
-	dsb	nsh
-	.arch	armv8-a
-1:
-#endif
-	ret
-endfunc el1_sysregs_context_save_post_ops
-
-/* -----------------------------------------------------
- * The following function strictly follows the AArch64
- * PCS to use x9-x17 (temporary caller-saved registers)
  * to restore EL1 system register context.  It assumes
  * that 'x0' is pointing to a 'el1_sys_regs' structure
  * from where the register context will be restored
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index c8232df..b892729 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <amu.h>
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
@@ -15,6 +16,7 @@
 #include <platform_def.h>
 #include <pubsub_events.h>
 #include <smcc_helpers.h>
+#include <spe.h>
 #include <string.h>
 #include <utils.h>
 
@@ -209,6 +211,24 @@
 }
 
 /*******************************************************************************
+ * Enable architecture extensions on first entry to Non-secure world.
+ * When EL2 is implemented but unused `el2_unused` is non-zero, otherwise
+ * it is zero.
+ ******************************************************************************/
+static void enable_extensions_nonsecure(int el2_unused)
+{
+#if IMAGE_BL31
+#if ENABLE_SPE_FOR_LOWER_ELS
+	spe_enable(el2_unused);
+#endif
+
+#if ENABLE_AMU
+	amu_enable(el2_unused);
+#endif
+#endif
+}
+
+/*******************************************************************************
  * The following function initializes the cpu_context for a CPU specified by
  * its `cpu_idx` for first use, and sets the initial entrypoint state as
  * specified by the entry_point_info structure.
@@ -245,6 +265,7 @@
 {
 	uint32_t sctlr_elx, scr_el3, mdcr_el2;
 	cpu_context_t *ctx = cm_get_context(security_state);
+	int el2_unused = 0;
 
 	assert(ctx);
 
@@ -258,6 +279,8 @@
 			sctlr_elx |= SCTLR_EL2_RES1;
 			write_sctlr_el2(sctlr_elx);
 		} else if (EL_IMPLEMENTED(2)) {
+			el2_unused = 1;
+
 			/*
 			 * EL2 present but unused, need to disable safely.
 			 * SCTLR_EL2 can be ignored in this case.
@@ -340,13 +363,6 @@
 			 * relying on hw. Some fields are architecturally
 			 * UNKNOWN on reset.
 			 *
-			 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
-			 * profiling controls to EL2.
-			 *
-			 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in non-secure
-			 * state. Accesses to profiling buffer controls at
-			 * non-secure EL1 are not trapped to EL2.
-			 *
 			 * MDCR_EL2.TDRA: Set to zero so that Non-secure EL0 and
 			 *  EL1 System register accesses to the Debug ROM
 			 *  registers are not trapped to EL2.
@@ -383,22 +399,6 @@
 					| MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT
 					| MDCR_EL2_TPMCR_BIT));
 
-#if ENABLE_SPE_FOR_LOWER_ELS
-			uint64_t id_aa64dfr0_el1;
-
-			/* Detect if SPE is implemented */
-			id_aa64dfr0_el1 = read_id_aa64dfr0_el1() >>
-				ID_AA64DFR0_PMS_SHIFT;
-			if ((id_aa64dfr0_el1 & ID_AA64DFR0_PMS_MASK) == 1) {
-				/*
-				 * Make sure traps to EL2 are not generated if
-				 * EL2 is implemented but not used.
-				 */
-				mdcr_el2 &= ~MDCR_EL2_TPMS;
-				mdcr_el2 |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
-			}
-#endif
-
 			write_mdcr_el2(mdcr_el2);
 
 			/*
@@ -420,6 +420,7 @@
 			write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
 						~(CNTHP_CTL_ENABLE_BIT));
 		}
+		enable_extensions_nonsecure(el2_unused);
 	}
 
 	cm_el1_sysregs_context_restore(security_state);
@@ -439,7 +440,6 @@
 	assert(ctx);
 
 	el1_sysregs_context_save(get_sysregs_ctx(ctx));
-	el1_sysregs_context_save_post_ops();
 
 #if IMAGE_BL31
 	if (security_state == SECURE)
diff --git a/lib/extensions/amu/aarch32/amu.c b/lib/extensions/amu/aarch32/amu.c
new file mode 100644
index 0000000..d450bd6
--- /dev/null
+++ b/lib/extensions/amu/aarch32/amu.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <amu.h>
+#include <arch.h>
+#include <arch_helpers.h>
+
+void amu_enable(int el2_unused)
+{
+	uint64_t features;
+
+	features = read_id_pfr0() >> ID_PFR0_AMU_SHIFT;
+	if ((features & ID_PFR0_AMU_MASK) == 1) {
+		if (el2_unused) {
+			uint64_t v;
+
+			/*
+			 * Non-secure access from EL0 or EL1 to the Activity Monitor
+			 * registers do not trap to EL2.
+			 */
+			v = read_hcptr();
+			v &= ~TAM_BIT;
+			write_hcptr(v);
+		}
+
+		/* Enable group 0 counters */
+		write_amcntenset0(AMU_GROUP0_COUNTERS_MASK);
+	}
+}
diff --git a/lib/extensions/amu/aarch64/amu.c b/lib/extensions/amu/aarch64/amu.c
new file mode 100644
index 0000000..007b349
--- /dev/null
+++ b/lib/extensions/amu/aarch64/amu.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <amu.h>
+#include <arch.h>
+#include <arch_helpers.h>
+
+void amu_enable(int el2_unused)
+{
+	uint64_t features;
+
+	features = read_id_aa64pfr0_el1() >> ID_AA64PFR0_AMU_SHIFT;
+	if ((features & ID_AA64PFR0_AMU_MASK) == 1) {
+		uint64_t v;
+
+		if (el2_unused) {
+			/*
+			 * CPTR_EL2.TAM: Set to zero so any accesses to
+			 * the Activity Monitor registers do not trap to EL2.
+			 */
+			v = read_cptr_el2();
+			v &= ~CPTR_EL2_TAM_BIT;
+			write_cptr_el2(v);
+		}
+
+		/*
+		 * CPTR_EL3.TAM: Set to zero so that any accesses to
+		 * the Activity Monitor registers do not trap to EL3.
+		 */
+		v = read_cptr_el3();
+		v &= ~TAM_BIT;
+		write_cptr_el3(v);
+
+		/* Enable group 0 counters */
+		write_amcntenset0_el0(AMU_GROUP0_COUNTERS_MASK);
+	}
+}
diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c
new file mode 100644
index 0000000..3b297f2
--- /dev/null
+++ b/lib/extensions/spe/spe.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <pubsub.h>
+
+/*
+ * The assembler does not yet understand the psb csync mnemonic
+ * so use the equivalent hint instruction.
+ */
+#define psb_csync()	asm volatile("hint #17")
+
+void spe_enable(int el2_unused)
+{
+	uint64_t features;
+
+	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
+	if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
+		uint64_t v;
+
+		if (el2_unused) {
+			/*
+			 * MDCR_EL2.TPMS (ARM v8.2): Do not trap statistical
+			 * profiling controls to EL2.
+			 *
+			 * MDCR_EL2.E2PB (ARM v8.2): SPE enabled in Non-secure
+			 * state. Accesses to profiling buffer controls at
+			 * Non-secure EL1 are not trapped to EL2.
+			 */
+			v = read_mdcr_el2();
+			v &= ~MDCR_EL2_TPMS;
+			v |= MDCR_EL2_E2PB(MDCR_EL2_E2PB_EL1);
+			write_mdcr_el2(v);
+		}
+
+		/*
+		 * MDCR_EL2.NSPB (ARM v8.2): SPE enabled in Non-secure state
+		 * and disabled in secure state. Accesses to SPE registers at
+		 * S-EL1 generate trap exceptions to EL3.
+		 */
+		v = read_mdcr_el3();
+		v |= MDCR_NSPB(MDCR_NSPB_EL1);
+		write_mdcr_el3(v);
+	}
+}
+
+void spe_disable(void)
+{
+	uint64_t features;
+
+	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
+	if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
+		uint64_t v;
+
+		/* Drain buffered data */
+		psb_csync();
+		dsbnsh();
+
+		/* Disable profiling buffer */
+		v = read_pmblimitr_el1();
+		v &= ~(1ULL << 0);
+		write_pmblimitr_el1(v);
+		isb();
+	}
+}
+
+static void *spe_drain_buffers_hook(const void *arg)
+{
+	uint64_t features;
+
+	features = read_id_aa64dfr0_el1() >> ID_AA64DFR0_PMS_SHIFT;
+	if ((features & ID_AA64DFR0_PMS_MASK) == 1) {
+		/* Drain buffered data */
+		psb_csync();
+		dsbnsh();
+	}
+
+	return 0;
+}
+
+SUBSCRIBE_TO_EVENT(cm_entering_secure_world, spe_drain_buffers_hook);
diff --git a/lib/locks/exclusive/aarch32/spinlock.S b/lib/locks/exclusive/aarch32/spinlock.S
index bc77bc9..9492cc0 100644
--- a/lib/locks/exclusive/aarch32/spinlock.S
+++ b/lib/locks/exclusive/aarch32/spinlock.S
@@ -9,6 +9,17 @@
 	.globl	spin_lock
 	.globl	spin_unlock
 
+#if ARM_ARCH_AT_LEAST(8, 0)
+/*
+ * According to the ARMv8-A Architecture Reference Manual, "when the global
+ * monitor for a PE changes from Exclusive Access state to Open Access state,
+ * an event is generated.". This applies to both AArch32 and AArch64 modes of
+ * ARMv8-A. As a result, no explicit SEV with unlock is required.
+ */
+#define COND_SEV()
+#else
+#define COND_SEV()	sev
+#endif
 
 func spin_lock
 	mov	r2, #1
@@ -27,5 +38,6 @@
 func spin_unlock
 	mov	r1, #0
 	stl	r1, [r0]
+	COND_SEV()
 	bx	lr
 endfunc spin_unlock
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 4105e63..8e41cf0 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -220,6 +220,23 @@
 	if (target_idx == -1)
 		return PSCI_E_INVALID_PARAMS;
 
+	/*
+	 * Generic management:
+	 * Perform cache maintanence ahead of reading the target CPU state to
+	 * ensure that the data is not stale.
+	 * There is a theoretical edge case where the cache may contain stale
+	 * data for the target CPU data - this can occur under the following
+	 * conditions:
+	 * - the target CPU is in another cluster from the current
+	 * - the target CPU was the last CPU to shutdown on its cluster
+	 * - the cluster was removed from coherency as part of the CPU shutdown
+	 *
+	 * In this case the cache maintenace that was performed as part of the
+	 * target CPUs shutdown was not seen by the current CPU's cluster. And
+	 * so the cache may contain stale data for the target CPU.
+	 */
+	flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+
 	return psci_get_aff_info_state_by_idx(target_idx);
 }
 
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index a841dda..c00bd94 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -266,8 +266,10 @@
  ******************************************************************************/
 void psci_arch_setup(void)
 {
+#if ARM_ARCH_MAJOR > 7 || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
 	/* Program the counter frequency */
 	write_cntfrq_el0(plat_get_syscnt_freq2());
+#endif
 
 	/* Initialize the cpu_ops pointer. */
 	init_cpu_ops();
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index c7e34f2..720d446 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -13,6 +13,10 @@
 #include <xlat_tables.h>
 #include "../xlat_tables_private.h"
 
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
+#error ARMv7 target does not support LPAE MMU descriptors
+#endif
+
 #define XLAT_TABLE_LEVEL_BASE	\
        GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE)
 
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 28ae1f7..eabc3df 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -60,7 +60,10 @@
 /* Physical Address ranges supported in the AArch64 Memory Model */
 static const unsigned int pa_range_bits_arr[] = {
 	PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
-	PARANGE_0101
+	PARANGE_0101,
+#if ARM_ARCH_AT_LEAST(8, 2)
+	PARANGE_0110,
+#endif
 };
 
 static unsigned long long get_max_supported_pa(void)
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 642f799..fc7ca46 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -14,6 +14,10 @@
 #include <xlat_tables_v2.h>
 #include "../xlat_tables_private.h"
 
+#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
+#error ARMv7 target does not support LPAE MMU descriptors
+#endif
+
 #if ENABLE_ASSERTIONS
 unsigned long long xlat_arch_get_max_supported_pa(void)
 {
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 4331107..aa5b9e5 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -48,7 +48,10 @@
 /* Physical Address ranges supported in the AArch64 Memory Model */
 static const unsigned int pa_range_bits_arr[] = {
 	PARANGE_0000, PARANGE_0001, PARANGE_0010, PARANGE_0011, PARANGE_0100,
-	PARANGE_0101
+	PARANGE_0101,
+#if ARM_ARCH_AT_LEAST(8, 2)
+	PARANGE_0110,
+#endif
 };
 
 unsigned long long xlat_arch_get_max_supported_pa(void)
diff --git a/maintainers.rst b/maintainers.rst
index 388073e..701ea17 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -91,6 +91,11 @@
 -  docs/plat/xilinx-zynqmp.md
 -  plat/xilinx/\*
 
+ARMv7 architecture sub-maintainer
+---------------------------------
+
+Etienne Carriere (etienne.carriere@linaro.org, `etienne-lms`_)
+
 .. _danh-arm: https://github.com/danh-arm
 .. _davidcunado-arm: https://github.com/davidcunado-arm
 .. _jenswi-linaro: https://github.com/jenswi-linaro
@@ -100,3 +105,4 @@
 .. _TonyXie06: https://github.com/TonyXie06
 .. _rkchrome: https://github.com/rkchrome
 .. _sorenb-xlnx: https://github.com/sorenb-xlnx
+.. _etienne-lms: https://github.com/etienne-lms
diff --git a/make_helpers/armv7-a-cpus.mk b/make_helpers/armv7-a-cpus.mk
new file mode 100644
index 0000000..20e7ec5
--- /dev/null
+++ b/make_helpers/armv7-a-cpus.mk
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifneq (${ARCH},aarch32)
+$(error ARM_ARCH_MAJOR=7 mandates ARCH=aarch32)
+endif
+
+# For ARMv7, set march32 from platform directive ARMV7_CORTEX_Ax=yes
+# and ARM_WITH_NEON=yes/no.
+#
+# GCC and Clang require -march=armv7-a for C-A9 and -march=armv7ve for C-A15.
+# armClang requires -march=armv7-a for all ARMv7 Cortex-A. To comply with
+# all, just drop -march and supply only -mcpu.
+
+# Platform can override march32-directive through MARCH32_DIRECTIVE
+ifdef MARCH32_DIRECTIVE
+march32-directive		:= $(MARCH32_DIRECTIVE)
+else
+march32-set-${ARM_CORTEX_A5}	:= -mcpu=cortex-a5
+march32-set-${ARM_CORTEX_A7}	:= -mcpu=cortex-a7
+march32-set-${ARM_CORTEX_A9}	:= -mcpu=cortex-a9
+march32-set-${ARM_CORTEX_A12}	:= -mcpu=cortex-a12
+march32-set-${ARM_CORTEX_A15}	:= -mcpu=cortex-a15
+march32-set-${ARM_CORTEX_A17}	:= -mcpu=cortex-a17
+march32-neon-$(ARM_WITH_NEON)	:= -mfpu=neon
+
+# default to -march=armv7-a as target directive
+march32-set-yes			?= -march=armv7-a
+march32-directive		:= ${march32-set-yes} ${march32-neon-yes}
+endif
+
+# Platform may override these extension support directives:
+#
+# ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING
+# Defined if core supports the Large Page Addressing extension.
+#
+# ARMV7_SUPPORTS_VIRTUALIZATION
+# Defined if ARMv7 core supports the Virtualization extension.
+#
+# ARMV7_SUPPORTS_GENERIC_TIMER
+# Defined if ARMv7 core supports the Generic Timer extension.
+
+ifeq ($(filter yes,$(ARM_CORTEX_A7) $(ARM_CORTEX_A12) $(ARM_CORTEX_A15) $(ARM_CORTEX_A17)),yes)
+$(eval $(call add_define,ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING))
+$(eval $(call add_define,ARMV7_SUPPORTS_VIRTUALIZATION))
+$(eval $(call add_define,ARMV7_SUPPORTS_GENERIC_TIMER))
+endif
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index e0d822d..4584e63 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -146,19 +146,12 @@
 # platforms).
 WARMBOOT_ENABLE_DCACHE_EARLY	:= 0
 
-# By default, enable Statistical Profiling Extensions.
-# The top level Makefile will disable this feature depending on
-# the target architecture and version number.
+# Build option to enable/disable the Statistical Profiling Extensions
 ENABLE_SPE_FOR_LOWER_ELS	:= 1
 
-# SPE is enabled by default but only supported on AArch64 8.2 onwards.
-# Disable it in all other cases.
+# SPE is only supported on AArch64 so disable it on AArch32.
 ifeq (${ARCH},aarch32)
     override ENABLE_SPE_FOR_LOWER_ELS := 0
-else
-    ifeq (${ARM_ARCH_MAJOR},8)
-        ifeq ($(ARM_ARCH_MINOR),$(filter $(ARM_ARCH_MINOR),0 1))
-            ENABLE_SPE_FOR_LOWER_ELS := 0
-        endif
-    endif
 endif
+
+ENABLE_AMU			:= 0
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index 712fa6f..6e6e273 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -54,6 +54,7 @@
 # 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 ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-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)))
@@ -76,6 +77,7 @@
 endif
 
 ifeq (${ARCH},aarch64)
+ifeq (${NEED_BL31},yes)
 # Add the BL31 CoT (key cert + img cert + image)
 $(if ${BL31},$(eval $(call CERT_ADD_CMD_OPT,${BL31},--soc-fw,true)),\
              $(eval $(call CERT_ADD_CMD_OPT,$(call IMG_BIN,31),--soc-fw,true)))
@@ -85,6 +87,7 @@
 $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_content.crt,--soc-fw-cert))
 $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_key.crt,--soc-fw-key-cert))
 endif
+endif
 
 # Add the BL32 CoT (key cert + img cert + image)
 ifeq (${NEED_BL32},yes)
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 0ab5b82..13bd8f2 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -14,6 +14,7 @@
 #include <plat_arm.h>
 #include <platform.h>
 #include <psci.h>
+#include <spe.h>
 #include <v2m_def.h>
 #include "drivers/pwrc/fvp_pwrc.h"
 #include "fvp_def.h"
@@ -57,7 +58,7 @@
 	 * On power down we need to disable statistical profiling extensions
 	 * before exiting coherency.
 	 */
-	arm_disable_spe();
+	spe_disable();
 #endif
 
 	/* Disable coherency if this cluster is to be turned off */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 1b50296..7edbd3d 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -147,6 +147,9 @@
 # Disable the PSCI platform compatibility layer
 ENABLE_PLAT_COMPAT	:= 	0
 
+# Enable Activity Monitor Unit extensions by default
+ENABLE_AMU			:=	1
+
 ifneq (${ENABLE_STACK_PROTECTOR},0)
 PLAT_BL_COMMON_SOURCES	+=	plat/arm/board/fvp/fvp_stack_protector.c
 endif
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index ccc7771..e475ece 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -128,6 +128,15 @@
  */
 #define PLAT_ARM_MAX_BL31_SIZE		0x1E000
 
+#if JUNO_AARCH32_EL3_RUNTIME
+/*
+ * PLAT_ARM_MAX_BL32_SIZE is calculated for SP_MIN as the AArch32 Secure
+ * Payload. We also need to take care of SCP_BL2 size as well, as the SCP_BL2
+ * is loaded into the space BL32 -> BL1_RW_BASE
+ */
+# define PLAT_ARM_MAX_BL32_SIZE		0x1E000
+#endif
+
 /*
  * Since free SRAM space is scant, enable the ASSERTION message size
  * optimization by fixing the PLAT_LOG_LEVEL_ASSERT to LOG_LEVEL_INFO (40).
diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c
index 2771e0f..cedef66 100644
--- a/plat/arm/board/juno/juno_bl2_setup.c
+++ b/plat/arm/board/juno/juno_bl2_setup.c
@@ -29,33 +29,4 @@
 
 	return err;
 }
-
-#if !CSS_USE_SCMI_SDS_DRIVER
-/*
- * We need to override some of the platform functions when booting SP_MIN
- * on Juno AArch32. These needs to be done only for SCPI/BOM SCP systems as
- * in case of SDS, the structures remain in memory and doesn't need to be
- * overwritten.
- */
-
-static unsigned int scp_boot_config;
-
-void bl2_early_platform_setup(meminfo_t *mem_layout)
-{
-	arm_bl2_early_platform_setup(mem_layout);
-
-	/* Save SCP Boot config before it gets overwritten by SCP_BL2 loading */
-	VERBOSE("BL2: Saving SCP Boot config = 0x%x\n", scp_boot_config);
-	scp_boot_config = mmio_read_32(SCP_BOOT_CFG_ADDR);
-}
-
-void bl2_platform_setup(void)
-{
-	arm_bl2_platform_setup();
-
-	mmio_write_32(SCP_BOOT_CFG_ADDR, scp_boot_config);
-	VERBOSE("BL2: Restored SCP Boot config = 0x%x\n", scp_boot_config);
-}
-#endif
-
 #endif /* JUNO_AARCH32_EL3_RUNTIME */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 5cd125b..bfb7847 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -31,6 +31,19 @@
 $(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME))
 $(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME))
 
+ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
+# Include BL32 in FIP
+NEED_BL32		:= yes
+# BL31 is not required
+override BL31_SOURCES =
+
+# The BL32 needs to be built separately invoking the AARCH32 compiler and
+# be specifed via `BL32` build option.
+  ifneq (${ARCH}, aarch32)
+    override BL32_SOURCES =
+  endif
+endif
+
 ifeq (${ARCH},aarch64)
 BL1_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index b53e60d..9d3a108 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -12,7 +12,6 @@
 	.globl	plat_crash_console_putc
 	.globl	plat_crash_console_flush
 	.globl	platform_mem_init
-	.globl	arm_disable_spe
 
 
 	/* -----------------------------------------------------
@@ -88,34 +87,6 @@
 	ret
 endfunc platform_mem_init
 
-	/* -----------------------------------------------------
-	 * void arm_disable_spe (void);
-	 * -----------------------------------------------------
-	 */
-#if ENABLE_SPE_FOR_LOWER_ELS
-func arm_disable_spe
-	/* Detect if SPE is implemented */
-	mrs	x0, id_aa64dfr0_el1
-	ubfx	x0, x0, #ID_AA64DFR0_PMS_SHIFT, #ID_AA64DFR0_PMS_LENGTH
-	cmp	x0, #0x1
-	b.ne	1f
-
-	/* Drain buffered data */
-	.arch	armv8.2-a+profile
-	psb	csync
-	dsb	nsh
-
-	/* Disable Profiling Buffer */
-	mrs	x0, pmblimitr_el1
-	bic	x0, x0, #1
-	msr	pmblimitr_el1, x0
-	isb
-	.arch	armv8-a
-1:
-	ret
-endfunc arm_disable_spe
-#endif
-
 /*
  * Need to use coherent stack when ARM Cryptocell is used to autheticate images
  * since Cryptocell uses DMA to transfer data and it is not coherent with the
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 9b4800e..b4aafd4 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -49,13 +49,13 @@
 }
 
 #if !CSS_USE_SCMI_SDS_DRIVER
-# ifdef EL3_PAYLOAD_BASE
+# if defined(EL3_PAYLOAD_BASE) || JUNO_AARCH32_EL3_RUNTIME
 
 /*
  * We need to override some of the platform functions when booting an EL3
- * payload. These needs to be done only for SCPI/BOM SCP systems as
- * in case of SDS, the structures remain in memory and doesn't need to be
- * overwritten.
+ * payload or SP_MIN on Juno AArch32. This needs to be done only for
+ * SCPI/BOM SCP systems as in case of SDS, the structures remain in memory and
+ * don't need to be overwritten.
  */
 
 static unsigned int scp_boot_config;
diff --git a/plat/common/aarch32/platform_helpers.S b/plat/common/aarch32/platform_helpers.S
index 61d21ab..0a0e927 100644
--- a/plat/common/aarch32/platform_helpers.S
+++ b/plat/common/aarch32/platform_helpers.S
@@ -7,12 +7,15 @@
 #include <arch.h>
 #include <asm_macros.S>
 
+	.weak	plat_report_exception
 	.weak	plat_crash_console_init
 	.weak	plat_crash_console_putc
 	.weak	plat_crash_console_flush
 	.weak	plat_reset_handler
 	.weak	plat_disable_acp
+	.weak	bl1_plat_prepare_exit
 	.weak	platform_mem_init
+	.weak	plat_error_handler
 	.weak	plat_panic_handler
 	.weak	bl2_plat_preload_setup
 	.weak	plat_try_next_boot_source
@@ -22,6 +25,15 @@
 	 * each platform.
 	 * -----------------------------------------------------
 	 */
+func plat_report_exception
+	bx	lr
+endfunc plat_report_exception
+
+	/* -----------------------------------------------------
+	 * Placeholder function which should be redefined by
+	 * each platform.
+	 * -----------------------------------------------------
+	 */
 func plat_crash_console_init
 	mov	r0, #0
 	bx	lr
@@ -74,6 +86,25 @@
 endfunc platform_mem_init
 
 	/* -----------------------------------------------------
+	 * void bl1_plat_prepare_exit(entry_point_info_t *ep_info);
+	 * Called before exiting BL1. Default: do nothing
+	 * -----------------------------------------------------
+	 */
+func bl1_plat_prepare_exit
+	bx	lr
+endfunc bl1_plat_prepare_exit
+
+	/* -----------------------------------------------------
+	 * void plat_error_handler(int err) __dead2;
+	 * Endless loop by default.
+	 * -----------------------------------------------------
+	 */
+func plat_error_handler
+	wfi
+	b	plat_error_handler
+endfunc plat_error_handler
+
+	/* -----------------------------------------------------
 	 * void plat_panic_handler(void) __dead2;
 	 * Endless loop by default.
 	 * -----------------------------------------------------
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index 4551a8b..42bf46d 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -475,8 +475,10 @@
 	sdei_cpu_state_t *state;
 
 	/* Validate preempted security state */
-	if ((preempted_sec_state != SECURE) || (preempted_sec_state != NON_SECURE))
+	if ((preempted_sec_state != SECURE) &&
+			(preempted_sec_state != NON_SECURE)) {
 		return -1;
+	}
 
 	/* Can't dispatch if events are masked on this PE */
 	state = sdei_get_this_pe_state();
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 4fe990a..2f08c8b 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -120,6 +120,7 @@
 		/* Platform events are always bound, so set the bound flag */
 		if (is_map_dynamic(map)) {
 			assert(map->intr == SDEI_DYN_IRQ);
+			assert(is_event_normal(map));
 			num_dyn_shrd_slots++;
 		} else {
 			/* Shared mappings must be bound to shared interrupt */
@@ -171,6 +172,7 @@
 		if (map->ev_num != SDEI_EVENT_0) {
 			if (is_map_dynamic(map)) {
 				assert(map->intr == SDEI_DYN_IRQ);
+				assert(is_event_normal(map));
 				num_dyn_priv_slots++;
 			} else {
 				/*
diff --git a/services/std_svc/spm/secure_partition_setup.c b/services/std_svc/spm/secure_partition_setup.c
index 6730160..6f4b057 100644
--- a/services/std_svc/spm/secure_partition_setup.c
+++ b/services/std_svc/spm/secure_partition_setup.c
@@ -92,20 +92,20 @@
 
 	/* Get max granularity supported by the platform. */
 
-	u_register_t id_aa64prf0_el1 = read_id_aa64pfr0_el1();
+	u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
 
 	int tgran64_supported =
-		((id_aa64prf0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
+		((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
 		 ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
 		 ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
 
 	int tgran16_supported =
-		((id_aa64prf0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
+		((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
 		 ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
 		 ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
 
 	int tgran4_supported =
-		((id_aa64prf0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
+		((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
 		 ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
 		 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
 
@@ -121,7 +121,7 @@
 	}
 
 	VERBOSE("Max translation granule supported: %lu KiB\n",
-		max_granule_size);
+		max_granule_size / 1024);
 
 	uintptr_t max_granule_size_mask = max_granule_size - 1;
 
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index 1b40d81..de657a2 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -431,12 +431,14 @@
 			cm_el1_sysregs_context_restore(SECURE);
 			cm_set_next_eret_context(SECURE);
 
-			if (x2 != 0) {
-				VERBOSE("SP_COMMUNICATE_AARCH32/64: X2 is not 0 as recommended.");
+			/* Cookie. Reserved for future use. It must be zero. */
+			assert(x1 == 0);
+
+			if (x3 != 0) {
+				VERBOSE("SP_COMMUNICATE_AARCH32/64: X3 is not 0 as recommended.\n");
 			}
 
-			SMC_RET4(&sp_ctx.cpu_ctx,
-				 smc_fid, x2, x3, plat_my_core_pos());
+			SMC_RET4(&sp_ctx.cpu_ctx, smc_fid, x1, x2, x3);
 
 		case SP_MEM_ATTRIBUTES_GET_AARCH64:
 		case SP_MEM_ATTRIBUTES_SET_AARCH64:
diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h
index 256e7af..9b4ef5a 100644
--- a/tools/cert_create/include/cert.h
+++ b/tools/cert_create/include/cert.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -48,7 +48,13 @@
 int cert_init(void);
 cert_t *cert_get_by_opt(const char *opt);
 int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value);
-int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk);
+int cert_new(
+	int key_alg,
+	int md_alg,
+	cert_t *cert,
+	int days,
+	int ca,
+	STACK_OF(X509_EXTENSION) * sk);
 
 /* Macro to register the certificates used in the CoT */
 #define REGISTER_COT(_certs) \
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index 304fa61..1a253cc 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -30,6 +30,13 @@
 	KEY_ALG_MAX_NUM
 };
 
+/* Supported hash algorithms */
+enum{
+	HASH_ALG_SHA256,
+	HASH_ALG_SHA384,
+	HASH_ALG_SHA512,
+};
+
 /*
  * This structure contains the relevant information to create the keys
  * required to sign the certificates.
diff --git a/tools/cert_create/include/sha.h b/tools/cert_create/include/sha.h
index 6907fa1..4d07a1e 100644
--- a/tools/cert_create/include/sha.h
+++ b/tools/cert_create/include/sha.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,6 @@
 #ifndef SHA_H_
 #define SHA_H_
 
-int sha_file(const char *filename, unsigned char *md);
+int sha_file(int md_alg, const char *filename, unsigned char *md);
 
 #endif /* SHA_H_ */
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index 3f0b4d3..8e8aee6 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -56,6 +56,19 @@
 
 	return ret;
 }
+const EVP_MD *get_digest(int alg)
+{
+	switch (alg) {
+	case HASH_ALG_SHA256:
+		return EVP_sha256();
+	case HASH_ALG_SHA384:
+		return EVP_sha384();
+	case HASH_ALG_SHA512:
+		return EVP_sha512();
+	default:
+		return NULL;
+	}
+}
 
 int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value)
 {
@@ -79,7 +92,13 @@
 	return 1;
 }
 
-int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk)
+int cert_new(
+	int key_alg,
+	int md_alg,
+	cert_t *cert,
+	int days,
+	int ca,
+	STACK_OF(X509_EXTENSION) * sk)
 {
 	EVP_PKEY *pkey = keys[cert->key].key;
 	cert_t *issuer_cert = &certs[cert->issuer];
@@ -118,7 +137,7 @@
 	}
 
 	/* Sign the certificate with the issuer key */
-	if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, EVP_sha256(), NULL, ikey)) {
+	if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, get_digest(md_alg), NULL, ikey)) {
 		ERR_print_errors_fp(stdout);
 		goto END;
 	}
@@ -138,7 +157,7 @@
 			goto END;
 		}
 
-		if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256())) {
+		if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, get_digest(md_alg))) {
 			ERR_print_errors_fp(stdout);
 			goto END;
 		}
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index 741242f..4abfe6d 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -68,6 +68,7 @@
 
 /* Global options */
 static int key_alg;
+static int hash_alg;
 static int new_keys;
 static int save_keys;
 static int print_cert;
@@ -95,6 +96,12 @@
 #endif /* OPENSSL_NO_EC */
 };
 
+static const char *hash_algs_str[] = {
+	[HASH_ALG_SHA256] = "sha256",
+	[HASH_ALG_SHA384] = "sha384",
+	[HASH_ALG_SHA512] = "sha512",
+};
+
 static void print_help(const char *cmd, const struct option *long_opt)
 {
 	int rem, i = 0;
@@ -150,6 +157,19 @@
 	return -1;
 }
 
+static int get_hash_alg(const char *hash_alg_str)
+{
+	int i;
+
+	for (i = 0 ; i < NUM_ELEM(hash_algs_str) ; i++) {
+		if (0 == strcmp(hash_alg_str, hash_algs_str[i])) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
 static void check_cmd_params(void)
 {
 	cert_t *cert;
@@ -228,6 +248,10 @@
 PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'"
 	},
 	{
+		{ "hash-alg", required_argument, NULL, 's' },
+		"Hash algorithm : 'sha256' (default), 'sha384', 'sha512'"
+	},
+	{
 		{ "save-keys", no_argument, NULL, 'k' },
 		"Save key pairs into files. Filenames must be provided"
 	},
@@ -254,7 +278,8 @@
 	const struct option *cmd_opt;
 	const char *cur_opt;
 	unsigned int err_code;
-	unsigned char md[SHA256_DIGEST_LENGTH];
+	unsigned char md[SHA512_DIGEST_LENGTH];
+	unsigned int  md_len;
 	const EVP_MD *md_info;
 
 	NOTICE("CoT Generation Tool: %s\n", build_msg);
@@ -262,6 +287,7 @@
 
 	/* Set default options */
 	key_alg = KEY_ALG_RSA;
+	hash_alg = HASH_ALG_SHA256;
 
 	/* Add common command line options */
 	for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) {
@@ -291,7 +317,7 @@
 
 	while (1) {
 		/* getopt_long stores the option index here. */
-		c = getopt_long(argc, argv, "a:hknp", cmd_opt, &opt_idx);
+		c = getopt_long(argc, argv, "a:hknps:", cmd_opt, &opt_idx);
 
 		/* Detect the end of the options. */
 		if (c == -1) {
@@ -318,6 +344,13 @@
 		case 'p':
 			print_cert = 1;
 			break;
+		case 's':
+			hash_alg = get_hash_alg(optarg);
+			if (hash_alg < 0) {
+				ERROR("Invalid hash algorithm '%s'\n", optarg);
+				exit(1);
+			}
+			break;
 		case CMD_OPT_EXT:
 			cur_opt = cmd_opt_get_name(opt_idx);
 			ext = ext_get_by_opt(cur_opt);
@@ -343,9 +376,18 @@
 	/* Check command line arguments */
 	check_cmd_params();
 
-	/* Indicate SHA256 as image hash algorithm in the certificate
+	/* Indicate SHA as image hash algorithm in the certificate
 	 * extension */
-	md_info = EVP_sha256();
+	if (hash_alg == HASH_ALG_SHA384) {
+		md_info = EVP_sha384();
+		md_len  = SHA384_DIGEST_LENGTH;
+	} else if (hash_alg == HASH_ALG_SHA512) {
+		md_info = EVP_sha512();
+		md_len  = SHA512_DIGEST_LENGTH;
+	} else {
+		md_info = EVP_sha256();
+		md_len  = SHA256_DIGEST_LENGTH;
+	}
 
 	/* Load private keys from files (or generate new ones) */
 	for (i = 0 ; i < num_keys ; i++) {
@@ -421,14 +463,14 @@
 				if (ext->arg == NULL) {
 					if (ext->optional) {
 						/* Include a hash filled with zeros */
-						memset(md, 0x0, SHA256_DIGEST_LENGTH);
+						memset(md, 0x0, SHA512_DIGEST_LENGTH);
 					} else {
 						/* Do not include this hash in the certificate */
 						break;
 					}
 				} else {
 					/* Calculate the hash of the file */
-					if (!sha_file(ext->arg, md)) {
+					if (!sha_file(hash_alg, ext->arg, md)) {
 						ERROR("Cannot calculate hash of %s\n",
 							ext->arg);
 						exit(1);
@@ -436,7 +478,7 @@
 				}
 				CHECK_NULL(cert_ext, ext_new_hash(ext_nid,
 						EXT_CRIT, md_info, md,
-						SHA256_DIGEST_LENGTH));
+						md_len));
 				break;
 			case EXT_TYPE_PKEY:
 				CHECK_NULL(cert_ext, ext_new_key(ext_nid,
@@ -453,7 +495,7 @@
 		}
 
 		/* Create certificate. Signed with corresponding key */
-		if (cert->fn && !cert_new(key_alg, cert, VAL_DAYS, 0, sk)) {
+		if (cert->fn && !cert_new(key_alg, hash_alg, cert, VAL_DAYS, 0, sk)) {
 			ERROR("Cannot create %s\n", cert->cn);
 			exit(1);
 		}
diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c
index 2971593..3d977fb 100644
--- a/tools/cert_create/src/sha.c
+++ b/tools/cert_create/src/sha.c
@@ -1,20 +1,21 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <openssl/sha.h>
 #include <stdio.h>
-
 #include "debug.h"
+#include "key.h"
 
 #define BUFFER_SIZE	256
 
-int sha_file(const char *filename, unsigned char *md)
+int sha_file(int md_alg, const char *filename, unsigned char *md)
 {
 	FILE *inFile;
 	SHA256_CTX shaContext;
+	SHA512_CTX sha512Context;
 	int bytes;
 	unsigned char data[BUFFER_SIZE];
 
@@ -29,11 +30,25 @@
 		return 0;
 	}
 
-	SHA256_Init(&shaContext);
-	while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
-		SHA256_Update(&shaContext, data, bytes);
+	if (md_alg == HASH_ALG_SHA384) {
+		SHA384_Init(&sha512Context);
+		while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+			SHA384_Update(&sha512Context, data, bytes);
+		}
+		SHA384_Final(md, &sha512Context);
+	} else if (md_alg == HASH_ALG_SHA512) {
+		SHA512_Init(&sha512Context);
+		while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+			SHA512_Update(&sha512Context, data, bytes);
+		}
+		SHA512_Final(md, &sha512Context);
+	} else {
+		SHA256_Init(&shaContext);
+		while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+			SHA256_Update(&shaContext, data, bytes);
+		}
+		SHA256_Final(md, &shaContext);
 	}
-	SHA256_Final(md, &shaContext);
 
 	fclose(inFile);
 	return 1;