Merge pull request #1471 from Anson-Huang/master

Add i.MX8QX/i.MX8QM power management feature
diff --git a/Makefile b/Makefile
index 180c558..533cb8a 100644
--- a/Makefile
+++ b/Makefile
@@ -85,7 +85,13 @@
 ifneq (${DEBUG}, 0)
         BUILD_TYPE	:=	debug
         TF_CFLAGS	+= 	-g
-        ASFLAGS		+= 	-g -Wa,--gdwarf-2
+
+        ifneq ($(findstring clang,$(notdir $(CC))),)
+             ASFLAGS		+= 	-g
+        else
+             ASFLAGS		+= 	-g -Wa,--gdwarf-2
+        endif
+
         # Use LOG_LEVEL_INFO by default for debug builds
         LOG_LEVEL	:=	40
 else
@@ -119,7 +125,7 @@
 CPP			:=	${CROSS_COMPILE}cpp
 AS			:=	${CROSS_COMPILE}gcc
 AR			:=	${CROSS_COMPILE}ar
-LD			:=	${CROSS_COMPILE}ld
+LINKER			:=	${CROSS_COMPILE}ld
 OC			:=	${CROSS_COMPILE}objcopy
 OD			:=	${CROSS_COMPILE}objdump
 NM			:=	${CROSS_COMPILE}nm
@@ -128,8 +134,8 @@
 
 # Use ${LD}.bfd instead if it exists (as absolute path or together with $PATH).
 ifneq ($(strip $(wildcard ${LD}.bfd) \
-	$(foreach dir,$(subst :, ,${PATH}),$(wildcard ${dir}/${LD}.bfd))),)
-LD			:=	${LD}.bfd
+	$(foreach dir,$(subst :, ,${PATH}),$(wildcard ${dir}/${LINKER}.bfd))),)
+LINKER			:=	${LINKER}.bfd
 endif
 
 ifeq (${ARM_ARCH_MAJOR},7)
@@ -143,12 +149,21 @@
 ifeq ($(notdir $(CC)),armclang)
 TF_CFLAGS_aarch32	=	-target arm-arm-none-eabi $(march32-directive)
 TF_CFLAGS_aarch64	=	-target aarch64-arm-none-eabi -march=armv8-a
+LD			=	$(LINKER)
+AS			=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
+CPP			=	$(CC) -E $(TF_CFLAGS_$(ARCH))
+PP			=	$(CC) -E $(TF_CFLAGS_$(ARCH))
 else ifneq ($(findstring clang,$(notdir $(CC))),)
 TF_CFLAGS_aarch32	=	$(target32-directive)
 TF_CFLAGS_aarch64	=	-target aarch64-elf
+LD			=	$(LINKER)
+AS			=	$(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
+CPP			=	$(CC) -E
+PP			=	$(CC) -E
 else
 TF_CFLAGS_aarch32	=	$(march32-directive)
 TF_CFLAGS_aarch64	=	-march=armv8-a
+LD			=	$(LINKER)
 endif
 
 TF_CFLAGS_aarch32	+=	-mno-unaligned-access
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S
index 7ac028a..cf8a6a7 100644
--- a/bl1/aarch64/bl1_exceptions.S
+++ b/bl1/aarch64/bl1_exceptions.S
@@ -26,25 +26,25 @@
 	mov	x0, #SYNC_EXCEPTION_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionSP0
+end_vector_entry SynchronousExceptionSP0
 
 vector_entry IrqSP0
 	mov	x0, #IRQ_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqSP0
+end_vector_entry IrqSP0
 
 vector_entry FiqSP0
 	mov	x0, #FIQ_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqSP0
+end_vector_entry FiqSP0
 
 vector_entry SErrorSP0
 	mov	x0, #SERROR_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorSP0
+end_vector_entry SErrorSP0
 
 	/* -----------------------------------------------------
 	 * Current EL with SPx: 0x200 - 0x400
@@ -54,25 +54,25 @@
 	mov	x0, #SYNC_EXCEPTION_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionSPx
+end_vector_entry SynchronousExceptionSPx
 
 vector_entry IrqSPx
 	mov	x0, #IRQ_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqSPx
+end_vector_entry IrqSPx
 
 vector_entry FiqSPx
 	mov	x0, #FIQ_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqSPx
+end_vector_entry FiqSPx
 
 vector_entry SErrorSPx
 	mov	x0, #SERROR_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorSPx
+end_vector_entry SErrorSPx
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -91,25 +91,25 @@
 	b.ne	unexpected_sync_exception
 
 	b	smc_handler64
-	check_vector_size SynchronousExceptionA64
+end_vector_entry SynchronousExceptionA64
 
 vector_entry IrqA64
 	mov	x0, #IRQ_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqA64
+end_vector_entry IrqA64
 
 vector_entry FiqA64
 	mov	x0, #FIQ_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqA64
+end_vector_entry FiqA64
 
 vector_entry SErrorA64
 	mov	x0, #SERROR_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorA64
+end_vector_entry SErrorA64
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -119,25 +119,25 @@
 	mov	x0, #SYNC_EXCEPTION_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionA32
+end_vector_entry SynchronousExceptionA32
 
 vector_entry IrqA32
 	mov	x0, #IRQ_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqA32
+end_vector_entry IrqA32
 
 vector_entry FiqA32
 	mov	x0, #FIQ_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqA32
+end_vector_entry FiqA32
 
 vector_entry SErrorA32
 	mov	x0, #SERROR_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorA32
+end_vector_entry SErrorA32
 
 
 func smc_handler64
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index 26c0ae4..fabe3ef 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -28,10 +28,19 @@
         *bl1_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
      } >ROM
 
+     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+     .ARM.extab . : {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+     } >ROM
+
+     .ARM.exidx . : {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+     } >ROM
+
     .rodata . : {
         __RODATA_START__ = .;
         *(.rodata*)
@@ -152,7 +161,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index 64b363c..047cd6f 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -74,8 +74,8 @@
  * populates a new memory layout for BL2 that ensures that BL1's data sections
  * resident in secure RAM are not visible to BL2.
  ******************************************************************************/
-void bl1_init_bl2_mem_layout(const meminfo_t *bl1_mem_layout,
-			     meminfo_t *bl2_mem_layout)
+void bl1_init_bl2_mem_layout(const struct meminfo *bl1_mem_layout,
+			     struct meminfo *bl2_mem_layout)
 {
 	bl1_calc_bl2_mem_layout(bl1_mem_layout, bl2_mem_layout);
 }
diff --git a/bl2/aarch64/bl2_el3_exceptions.S b/bl2/aarch64/bl2_el3_exceptions.S
index 987f6e3..07d1040 100644
--- a/bl2/aarch64/bl2_el3_exceptions.S
+++ b/bl2/aarch64/bl2_el3_exceptions.S
@@ -26,25 +26,25 @@
 	mov	x0, #SYNC_EXCEPTION_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionSP0
+end_vector_entry SynchronousExceptionSP0
 
 vector_entry IrqSP0
 	mov	x0, #IRQ_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqSP0
+end_vector_entry IrqSP0
 
 vector_entry FiqSP0
 	mov	x0, #FIQ_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqSP0
+end_vector_entry FiqSP0
 
 vector_entry SErrorSP0
 	mov	x0, #SERROR_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorSP0
+end_vector_entry SErrorSP0
 
 	/* -----------------------------------------------------
 	 * Current EL with SPx: 0x200 - 0x400
@@ -54,25 +54,25 @@
 	mov	x0, #SYNC_EXCEPTION_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionSPx
+end_vector_entry SynchronousExceptionSPx
 
 vector_entry IrqSPx
 	mov	x0, #IRQ_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqSPx
+end_vector_entry IrqSPx
 
 vector_entry FiqSPx
 	mov	x0, #FIQ_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqSPx
+end_vector_entry FiqSPx
 
 vector_entry SErrorSPx
 	mov	x0, #SERROR_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorSPx
+end_vector_entry SErrorSPx
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -82,25 +82,25 @@
 	mov	x0, #SYNC_EXCEPTION_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionA64
+end_vector_entry SynchronousExceptionA64
 
 vector_entry IrqA64
 	mov	x0, #IRQ_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqA64
+end_vector_entry IrqA64
 
 vector_entry FiqA64
 	mov	x0, #FIQ_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqA64
+end_vector_entry FiqA64
 
 vector_entry SErrorA64
 	mov	x0, #SERROR_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorA64
+end_vector_entry SErrorA64
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -110,22 +110,22 @@
 	mov	x0, #SYNC_EXCEPTION_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionA32
+end_vector_entry SynchronousExceptionA32
 
 vector_entry IrqA32
 	mov	x0, #IRQ_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqA32
+end_vector_entry IrqA32
 
 vector_entry FiqA32
 	mov	x0, #FIQ_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqA32
+end_vector_entry FiqA32
 
 vector_entry SErrorA32
 	mov	x0, #SERROR_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorA32
+end_vector_entry SErrorA32
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 69c22eb..6d26cdb 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -28,10 +28,19 @@
         *bl2_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
      } >RAM
 
+     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+     .ARM.extab . : {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+     } >RAM
+
+     .ARM.exidx . : {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+     } >RAM
+
     .rodata . : {
         __RODATA_START__ = .;
         *(.rodata*)
@@ -42,7 +51,7 @@
         KEEP(*(.img_parser_lib_descs))
         __PARSER_LIB_DESCS_END__ = .;
 
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -65,7 +74,7 @@
          * read-only, executable.  No RW data from the next section must
          * creep in.  Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -131,7 +140,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 0f91edc..82ab427 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -42,7 +42,7 @@
 	__TEXT_RESIDENT_END__ = .;
         *(.text*)
         *(.vectors)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
 #if BL2_IN_XIP_MEM
      } >ROM
@@ -69,7 +69,7 @@
         KEEP(*(cpu_ops))
         __CPU_OPS_END__ = .;
 
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
 #if BL2_IN_XIP_MEM
     } >ROM
@@ -111,7 +111,7 @@
          * read-only, executable.  No RW data from the next section must
          * creep in.  Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
 
         __RO_END__ = .;
 #if BL2_IN_XIP_MEM
@@ -195,7 +195,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 7b97758..3db5f89 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -28,14 +28,23 @@
         *bl2u_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
      } >RAM
 
+     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+     .ARM.extab . : {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+     } >RAM
+
+     .ARM.exidx . : {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+     } >RAM
+
     .rodata . : {
         __RODATA_START__ = .;
         *(.rodata*)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -52,7 +61,7 @@
          * read-only, executable.  No RW data from the next section must
          * creep in.  Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -118,7 +127,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 346cd3b..12f9f10 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -233,7 +233,7 @@
 vector_entry sync_exception_sp_el0
 	/* We don't expect any synchronous exceptions from EL3 */
 	b	report_unhandled_exception
-	check_vector_size sync_exception_sp_el0
+end_vector_entry sync_exception_sp_el0
 
 vector_entry irq_sp_el0
 	/*
@@ -241,17 +241,17 @@
 	 * error. Loop infinitely.
 	 */
 	b	report_unhandled_interrupt
-	check_vector_size irq_sp_el0
+end_vector_entry irq_sp_el0
 
 
 vector_entry fiq_sp_el0
 	b	report_unhandled_interrupt
-	check_vector_size fiq_sp_el0
+end_vector_entry fiq_sp_el0
 
 
 vector_entry serror_sp_el0
 	b	report_unhandled_exception
-	check_vector_size serror_sp_el0
+end_vector_entry serror_sp_el0
 
 	/* ---------------------------------------------------------------------
 	 * Current EL with SP_ELx: 0x200 - 0x400
@@ -265,19 +265,19 @@
 	 * corrupted.
 	 */
 	b	report_unhandled_exception
-	check_vector_size sync_exception_sp_elx
+end_vector_entry sync_exception_sp_elx
 
 vector_entry irq_sp_elx
 	b	report_unhandled_interrupt
-	check_vector_size irq_sp_elx
+end_vector_entry irq_sp_elx
 
 vector_entry fiq_sp_elx
 	b	report_unhandled_interrupt
-	check_vector_size fiq_sp_elx
+end_vector_entry fiq_sp_elx
 
 vector_entry serror_sp_elx
 	b	report_unhandled_exception
-	check_vector_size serror_sp_elx
+end_vector_entry serror_sp_elx
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -292,17 +292,17 @@
 	 */
 	check_and_unmask_ea
 	handle_sync_exception
-	check_vector_size sync_exception_aarch64
+end_vector_entry sync_exception_aarch64
 
 vector_entry irq_aarch64
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch64
-	check_vector_size irq_aarch64
+end_vector_entry irq_aarch64
 
 vector_entry fiq_aarch64
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch64
-	check_vector_size fiq_aarch64
+end_vector_entry fiq_aarch64
 
 vector_entry serror_aarch64
 	msr	daifclr, #DAIF_ABT_BIT
@@ -313,7 +313,7 @@
 	 */
 	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	handle_ea #ERROR_EA_ASYNC
-	check_vector_size serror_aarch64
+end_vector_entry serror_aarch64
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -328,17 +328,17 @@
 	 */
 	check_and_unmask_ea
 	handle_sync_exception
-	check_vector_size sync_exception_aarch32
+end_vector_entry sync_exception_aarch32
 
 vector_entry irq_aarch32
 	check_and_unmask_ea
 	handle_interrupt_exception irq_aarch32
-	check_vector_size irq_aarch32
+end_vector_entry irq_aarch32
 
 vector_entry fiq_aarch32
 	check_and_unmask_ea
 	handle_interrupt_exception fiq_aarch32
-	check_vector_size fiq_aarch32
+end_vector_entry fiq_aarch32
 
 vector_entry serror_aarch32
 	msr	daifclr, #DAIF_ABT_BIT
@@ -349,7 +349,7 @@
 	 */
 	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
 	handle_ea #ERROR_EA_ASYNC
-	check_vector_size serror_aarch32
+end_vector_entry serror_aarch32
 
 
 	/* ---------------------------------------------------------------------
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 59df9b8..66cb3f3 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -32,7 +32,7 @@
         *bl31_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
     } >RAM
 
@@ -67,7 +67,7 @@
         . = ALIGN(8);
 #include <pubsub_events.h>
 
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -111,7 +111,7 @@
          * executable.  No RW data from the next section must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -131,7 +131,7 @@
     spm_shim_exceptions : ALIGN(PAGE_SIZE) {
         __SPM_SHIM_EXCEPTIONS_START__ = .;
         *(.spm_shim_exceptions)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __SPM_SHIM_EXCEPTIONS_END__ = .;
     } >RAM
 #endif
@@ -246,7 +246,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 71de883..ce6c954 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -28,10 +28,19 @@
         *entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
     } >RAM
 
+     /* .ARM.extab and .ARM.exidx are only added because Clang need them */
+     .ARM.extab . : {
+        *(.ARM.extab* .gnu.linkonce.armextab.*)
+     } >RAM
+
+     .ARM.exidx . : {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+     } >RAM
+
     .rodata . : {
         __RODATA_START__ = .;
         *(.rodata*)
@@ -55,7 +64,7 @@
         . = ALIGN(8);
 #include <pubsub_events.h>
 
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -92,7 +101,7 @@
          * read-only, executable.  No RW data from the next section must
          * creep in.  Ensure the rest of the current memory block is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -207,7 +216,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index 8e891b7..f06a48b 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -20,6 +20,7 @@
 #include <smccc_helpers.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <std_svc.h>
 #include <string.h>
 #include <types.h>
 #include <utils.h>
diff --git a/bl32/tsp/aarch64/tsp_exceptions.S b/bl32/tsp/aarch64/tsp_exceptions.S
index 4b2ad75..48e358a 100644
--- a/bl32/tsp/aarch64/tsp_exceptions.S
+++ b/bl32/tsp/aarch64/tsp_exceptions.S
@@ -82,19 +82,19 @@
 	 */
 vector_entry sync_exception_sp_el0
 	b	plat_panic_handler
-	check_vector_size sync_exception_sp_el0
+end_vector_entry sync_exception_sp_el0
 
 vector_entry irq_sp_el0
 	b	plat_panic_handler
-	check_vector_size irq_sp_el0
+end_vector_entry irq_sp_el0
 
 vector_entry fiq_sp_el0
 	b	plat_panic_handler
-	check_vector_size fiq_sp_el0
+end_vector_entry fiq_sp_el0
 
 vector_entry serror_sp_el0
 	b	plat_panic_handler
-	check_vector_size serror_sp_el0
+end_vector_entry serror_sp_el0
 
 
 	/* -----------------------------------------------------
@@ -104,19 +104,19 @@
 	 */
 vector_entry sync_exception_sp_elx
 	b	plat_panic_handler
-	check_vector_size sync_exception_sp_elx
+end_vector_entry sync_exception_sp_elx
 
 vector_entry irq_sp_elx
 	handle_tsp_interrupt irq_sp_elx
-	check_vector_size irq_sp_elx
+end_vector_entry irq_sp_elx
 
 vector_entry fiq_sp_elx
 	handle_tsp_interrupt fiq_sp_elx
-	check_vector_size fiq_sp_elx
+end_vector_entry fiq_sp_elx
 
 vector_entry serror_sp_elx
 	b	plat_panic_handler
-	check_vector_size serror_sp_elx
+end_vector_entry serror_sp_elx
 
 
 	/* -----------------------------------------------------
@@ -126,19 +126,19 @@
 	 */
 vector_entry sync_exception_aarch64
 	b	plat_panic_handler
-	check_vector_size sync_exception_aarch64
+end_vector_entry sync_exception_aarch64
 
 vector_entry irq_aarch64
 	b	plat_panic_handler
-	check_vector_size irq_aarch64
+end_vector_entry irq_aarch64
 
 vector_entry fiq_aarch64
 	b	plat_panic_handler
-	check_vector_size fiq_aarch64
+end_vector_entry fiq_aarch64
 
 vector_entry serror_aarch64
 	b	plat_panic_handler
-	check_vector_size serror_aarch64
+end_vector_entry serror_aarch64
 
 
 	/* -----------------------------------------------------
@@ -148,16 +148,16 @@
 	 */
 vector_entry sync_exception_aarch32
 	b	plat_panic_handler
-	check_vector_size sync_exception_aarch32
+end_vector_entry sync_exception_aarch32
 
 vector_entry irq_aarch32
 	b	plat_panic_handler
-	check_vector_size irq_aarch32
+end_vector_entry irq_aarch32
 
 vector_entry fiq_aarch32
 	b	plat_panic_handler
-	check_vector_size fiq_aarch32
+end_vector_entry fiq_aarch32
 
 vector_entry serror_aarch32
 	b	plat_panic_handler
-	check_vector_size serror_aarch32
+end_vector_entry serror_aarch32
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index 31c5a67..97b12ce 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -29,14 +29,14 @@
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(.rodata*)
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -52,7 +52,7 @@
          * read-only, executable.  No RW data from the next section must
          * creep in.  Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -117,7 +117,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/common/aarch64/early_exceptions.S b/common/aarch64/early_exceptions.S
index 19cc35d..ba94f6c 100644
--- a/common/aarch64/early_exceptions.S
+++ b/common/aarch64/early_exceptions.S
@@ -24,25 +24,25 @@
 	mov	x0, #SYNC_EXCEPTION_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionSP0
+end_vector_entry SynchronousExceptionSP0
 
 vector_entry IrqSP0
 	mov	x0, #IRQ_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqSP0
+end_vector_entry IrqSP0
 
 vector_entry FiqSP0
 	mov	x0, #FIQ_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqSP0
+end_vector_entry FiqSP0
 
 vector_entry SErrorSP0
 	mov	x0, #SERROR_SP_EL0
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorSP0
+end_vector_entry SErrorSP0
 
 	/* -----------------------------------------------------
 	 * Current EL with SPx: 0x200 - 0x400
@@ -52,25 +52,25 @@
 	mov	x0, #SYNC_EXCEPTION_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionSPx
+end_vector_entry SynchronousExceptionSPx
 
 vector_entry IrqSPx
 	mov	x0, #IRQ_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqSPx
+end_vector_entry IrqSPx
 
 vector_entry FiqSPx
 	mov	x0, #FIQ_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqSPx
+end_vector_entry FiqSPx
 
 vector_entry SErrorSPx
 	mov	x0, #SERROR_SP_ELX
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorSPx
+end_vector_entry SErrorSPx
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -80,25 +80,25 @@
 	mov	x0, #SYNC_EXCEPTION_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionA64
+end_vector_entry SynchronousExceptionA64
 
 vector_entry IrqA64
 	mov	x0, #IRQ_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqA64
+end_vector_entry IrqA64
 
 vector_entry FiqA64
 	mov	x0, #FIQ_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqA64
+end_vector_entry FiqA64
 
 vector_entry SErrorA64
 	mov	x0, #SERROR_AARCH64
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorA64
+end_vector_entry SErrorA64
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -108,22 +108,22 @@
 	mov	x0, #SYNC_EXCEPTION_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SynchronousExceptionA32
+end_vector_entry SynchronousExceptionA32
 
 vector_entry IrqA32
 	mov	x0, #IRQ_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size IrqA32
+end_vector_entry IrqA32
 
 vector_entry FiqA32
 	mov	x0, #FIQ_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size FiqA32
+end_vector_entry FiqA32
 
 vector_entry SErrorA32
 	mov	x0, #SERROR_AARCH32
 	bl	plat_report_exception
 	no_ret	plat_panic_handler
-	check_vector_size SErrorA32
+end_vector_entry SErrorA32
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
index c8e2405..0ba564d 100644
--- a/docs/plat/rpi3.rst
+++ b/docs/plat/rpi3.rst
@@ -123,7 +123,7 @@
                |   Secure SRAM   | BL2, BL31
     0x10100000 +-----------------+
                |   Secure DRAM   | BL32 (Secure payload)
-    0x10300000 +-----------------+
+    0x10C00000 +-----------------+
                | Non-secure DRAM | BL33
     0x11000000 +-----------------+
                |                 |
@@ -196,29 +196,19 @@
 
     CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3             \
     RPI3_BL33_IN_AARCH32=1                                      \
-    BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin     \
-    all fip
+    BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin
 
 For a AArch64 kernel, use this other command line:
 
 .. code:: shell
 
     CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3             \
-    BL33=../rpi3-arm-tf-bootstrap/aarch64/el2-bootstrap.bin     \
-    all fip
+    BL33=../rpi3-arm-tf-bootstrap/aarch64/el2-bootstrap.bin
 
-Then, join BL1 and the FIP with the following instructions (replace ``release``
-by ``debug`` if you set the build option ``DEBUG=1``):
-
-.. code:: shell
-
-    cp build/rpi3/release/bl1.bin bl1.pad.bin
-    truncate --size=131072 bl1.pad.bin
-    cat bl1.pad.bin build/rpi3/release/fip.bin > armstub8.bin
-
-The resulting file, ``armstub8.bin``, contains BL1 and the FIP in the place they
-need to be for TF-A to boot correctly. Now, follow the instructions in
-`Setup SD card`_.
+The build system concatenates BL1 and the FIP so that the addresses match the
+ones in the memory map. The resulting file is ``armstub8.bin``, located in the
+build folder (e.g. ``build/rpi3/debug/armstub8.bin``). Now, follow the
+instructions in `Setup SD card`_.
 
 The following build options are supported:
 
@@ -243,6 +233,12 @@
   BL32_EXTRA1=tee-pager_v2.bin  BL32_EXTRA2=tee-pageable_v2.bin``
   to put the binaries into the FIP.
 
+  Note: If OP-TEE is used it may be needed to add the following options to the
+  Linux command line so that the USB driver doesn't use FIQs:
+  ``dwc_otg.fiq_enable=0 dwc_otg.fiq_fsm_enable=0 dwc_otg.nak_holdoff=0``.
+  This will unfortunately reduce the performance of the USB driver. It is needed
+  when using Raspbian, for example.
+
 - ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option
   ``TRUSTED_BOARD_BOOT=1`` to enable it. In order to use TBB, you might
   want to set ``GENERATE_COT=1`` to let the contents of the FIP automatically
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 68a74ed..da26026 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -52,7 +52,7 @@
 
 ::
 
-    sudo apt-get install build-essential gcc make git libssl-dev
+    sudo apt-get install device-tree-compiler build-essential gcc make git libssl-dev
 
 TF-A has been tested with `Linaro Release 17.10`_.
 
@@ -62,8 +62,8 @@
 guidance and a script, which can be used to download Linaro deliverables
 automatically.
 
-Optionally, TF-A can be built using clang or Arm Compiler 6.
-See instructions below on how to switch the default compiler.
+Optionally, TF-A can be built using clang version 4.0 or newer or Arm
+Compiler 6. See instructions below on how to switch the default compiler.
 
 In addition, the following optional packages and tools may be needed:
 
@@ -103,10 +103,14 @@
 
        export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
 
-   It is possible to build TF-A using clang or Arm Compiler 6. To do so
-   ``CC`` needs to point to the clang or armclang binary. Only the compiler
-   is switched; the assembler and linker need to be provided by the GNU
-   toolchain, thus ``CROSS_COMPILE`` should be set as described above.
+   It is possible to build TF-A using Clang or Arm Compiler 6. To do so
+   ``CC`` needs to point to the clang or armclang binary, which will
+   also select the clang or armclang assembler. Be aware that the
+   GNU linker is used by default.  In case of being needed the linker
+   can be overriden using the ``LD`` variable. Clang linker version 6 is
+   known to work with TF-A.
+
+   In both cases ``CROSS_COMPILE`` should be set as described above.
 
    Arm Compiler 6 will be selected when the base name of the path assigned
    to ``CC`` matches the string 'armclang'.
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
new file mode 100644
index 0000000..8fe3239
--- /dev/null
+++ b/drivers/mmc/mmc.c
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* Define a simple and generic interface to access eMMC and SD-card devices. */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <mmc.h>
+#include <stdbool.h>
+#include <string.h>
+#include <utils.h>
+
+#define MMC_DEFAULT_MAX_RETRIES		5
+#define SEND_OP_COND_MAX_RETRIES	100
+
+#define MULT_BY_512K_SHIFT		19
+
+static const struct mmc_ops *ops;
+static unsigned int mmc_ocr_value;
+static struct mmc_csd_emmc mmc_csd;
+static unsigned char mmc_ext_csd[512] __aligned(4);
+static unsigned int mmc_flags;
+static struct mmc_device_info *mmc_dev_info;
+static unsigned int rca;
+
+static const unsigned char tran_speed_base[16] = {
+	0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80
+};
+
+static const unsigned char sd_tran_speed_base[16] = {
+	0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80
+};
+
+static bool is_cmd23_enabled(void)
+{
+	return ((mmc_flags & MMC_FLAG_CMD23) != 0U);
+}
+
+static int mmc_send_cmd(unsigned int idx, unsigned int arg,
+			unsigned int r_type, unsigned int *r_data)
+{
+	struct mmc_cmd cmd;
+	int ret;
+
+	zeromem(&cmd, sizeof(struct mmc_cmd));
+
+	cmd.cmd_idx = idx;
+	cmd.cmd_arg = arg;
+	cmd.resp_type = r_type;
+
+	ret = ops->send_cmd(&cmd);
+
+	if ((ret == 0) && (r_data != NULL)) {
+		int i;
+
+		for (i = 0; i < 4; i++) {
+			*r_data = cmd.resp_data[i];
+			r_data++;
+		}
+	}
+
+	if (ret != 0) {
+		VERBOSE("Send command %u error: %d\n", idx, ret);
+	}
+
+	return ret;
+}
+
+static int mmc_device_state(void)
+{
+	int retries = MMC_DEFAULT_MAX_RETRIES;
+	unsigned int resp_data[4];
+
+	do {
+		int ret;
+
+		if (retries == 0) {
+			ERROR("CMD13 failed after %d retries\n",
+			      MMC_DEFAULT_MAX_RETRIES);
+			return -EIO;
+		}
+
+		ret = mmc_send_cmd(MMC_CMD(13), rca << RCA_SHIFT_OFFSET,
+				   MMC_RESPONSE_R(1), &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		if ((resp_data[0] & STATUS_SWITCH_ERROR) != 0U) {
+			return -EIO;
+		}
+
+		retries--;
+	} while ((resp_data[0] & STATUS_READY_FOR_DATA) == 0U);
+
+	return MMC_GET_STATE(resp_data[0]);
+}
+
+static int mmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
+{
+	int ret;
+
+	ret = mmc_send_cmd(MMC_CMD(6),
+			   EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
+			   EXTCSD_VALUE(value) | EXTCSD_CMD_SET_NORMAL,
+			   0, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = mmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret == MMC_STATE_PRG);
+
+	return 0;
+}
+
+static int mmc_sd_switch(unsigned int bus_width)
+{
+	int ret;
+	int retries = MMC_DEFAULT_MAX_RETRIES;
+	unsigned int scr[2] = { 0 };
+	unsigned int bus_width_arg = 0;
+
+	ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD55: Application Specific Command */
+	ret = mmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACMD51: SEND_SCR */
+	do {
+		ret = mmc_send_cmd(MMC_ACMD(51), 0, MMC_RESPONSE_R(1), NULL);
+		if ((ret != 0) && (retries == 0)) {
+			ERROR("ACMD51 failed after %d retries (ret=%d)\n",
+			      MMC_DEFAULT_MAX_RETRIES, ret);
+			return ret;
+		}
+
+		retries--;
+	} while (ret != 0);
+
+	ret = ops->read(0, (uintptr_t)&scr, sizeof(scr));
+	if (ret != 0) {
+		return ret;
+	}
+
+	if (((scr[0] & SD_SCR_BUS_WIDTH_4) != 0U) &&
+	    (bus_width == MMC_BUS_WIDTH_4)) {
+		bus_width_arg = 2;
+	}
+
+	/* CMD55: Application Specific Command */
+	ret = mmc_send_cmd(MMC_CMD(55), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* ACMD6: SET_BUS_WIDTH */
+	ret = mmc_send_cmd(MMC_ACMD(6), bus_width_arg, MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = mmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret == MMC_STATE_PRG);
+
+	return 0;
+}
+
+static int mmc_set_ios(unsigned int clk, unsigned int bus_width)
+{
+	int ret;
+	unsigned int width = bus_width;
+
+	if (mmc_dev_info->mmc_dev_type != MMC_IS_EMMC) {
+		if (width == MMC_BUS_WIDTH_8) {
+			WARN("Wrong bus config for SD-card, force to 4\n");
+			width = MMC_BUS_WIDTH_4;
+		}
+		ret = mmc_sd_switch(width);
+		if (ret != 0) {
+			return ret;
+		}
+	} else if (mmc_csd.spec_vers == 4U) {
+		ret = mmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH,
+				      (unsigned int)width);
+		if (ret != 0) {
+			return ret;
+		}
+	} else {
+		VERBOSE("Wrong MMC type or spec version\n");
+	}
+
+	return ops->set_ios(clk, width);
+}
+
+static int mmc_fill_device_info(void)
+{
+	unsigned long long c_size;
+	unsigned int speed_idx;
+	unsigned int nb_blocks;
+	unsigned int freq_unit;
+	int ret;
+	struct mmc_csd_sd_v2 *csd_sd_v2;
+
+	switch (mmc_dev_info->mmc_dev_type) {
+	case MMC_IS_EMMC:
+		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
+
+		ret = ops->prepare(0, (uintptr_t)&mmc_ext_csd,
+				   sizeof(mmc_ext_csd));
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* MMC CMD8: SEND_EXT_CSD */
+		ret = mmc_send_cmd(MMC_CMD(8), 0, MMC_RESPONSE_R(1), NULL);
+		if (ret != 0) {
+			return ret;
+		}
+
+		ret = ops->read(0, (uintptr_t)&mmc_ext_csd,
+				sizeof(mmc_ext_csd));
+		if (ret != 0) {
+			return ret;
+		}
+
+		nb_blocks = (mmc_ext_csd[CMD_EXTCSD_SEC_CNT] << 0) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 1] << 8) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 2] << 16) |
+			    (mmc_ext_csd[CMD_EXTCSD_SEC_CNT + 3] << 24);
+
+		mmc_dev_info->device_size = (unsigned long long)nb_blocks *
+			mmc_dev_info->block_size;
+
+		break;
+
+	case MMC_IS_SD:
+		/*
+		 * Use the same mmc_csd struct, as required fields here
+		 * (READ_BL_LEN, C_SIZE, CSIZE_MULT) are common with eMMC.
+		 */
+		mmc_dev_info->block_size = BIT_32(mmc_csd.read_bl_len);
+
+		c_size = ((unsigned long long)mmc_csd.c_size_high << 2U) |
+			 (unsigned long long)mmc_csd.c_size_low;
+		assert(c_size != 0xFFFU);
+
+		mmc_dev_info->device_size = (c_size + 1U) *
+					    BIT_64(mmc_csd.c_size_mult + 2U) *
+					    mmc_dev_info->block_size;
+
+		break;
+
+	case MMC_IS_SD_HC:
+		assert(mmc_csd.csd_structure == 1U);
+
+		mmc_dev_info->block_size = MMC_BLOCK_SIZE;
+
+		/* Need to use mmc_csd_sd_v2 struct */
+		csd_sd_v2 = (struct mmc_csd_sd_v2 *)&mmc_csd;
+		c_size = ((unsigned long long)csd_sd_v2->c_size_high << 16) |
+			 (unsigned long long)csd_sd_v2->c_size_low;
+
+		mmc_dev_info->device_size = (c_size + 1U) << MULT_BY_512K_SHIFT;
+
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (ret != 0) {
+		return ret;
+	}
+
+	speed_idx = (mmc_csd.tran_speed & CSD_TRAN_SPEED_MULT_MASK) >>
+			 CSD_TRAN_SPEED_MULT_SHIFT;
+
+	assert(speed_idx > 0U);
+
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		mmc_dev_info->max_bus_freq = tran_speed_base[speed_idx];
+	} else {
+		mmc_dev_info->max_bus_freq = sd_tran_speed_base[speed_idx];
+	}
+
+	freq_unit = mmc_csd.tran_speed & CSD_TRAN_SPEED_UNIT_MASK;
+	while (freq_unit != 0U) {
+		mmc_dev_info->max_bus_freq *= 10U;
+		--freq_unit;
+	}
+
+	mmc_dev_info->max_bus_freq *= 10000U;
+
+	return 0;
+}
+
+static int sd_send_op_cond(void)
+{
+	int retries = SEND_OP_COND_MAX_RETRIES;
+	unsigned int resp_data[4];
+
+	do {
+		int ret;
+
+		if (retries == 0) {
+			ERROR("ACMD41 failed after %d retries\n",
+			      SEND_OP_COND_MAX_RETRIES);
+			return -EIO;
+		}
+
+		/* CMD55: Application Specific Command */
+		ret = mmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R(1), NULL);
+		if (ret != 0) {
+			return ret;
+		}
+
+		/* ACMD41: SD_SEND_OP_COND */
+		ret = mmc_send_cmd(MMC_ACMD(41), OCR_HCS, MMC_RESPONSE_R(3),
+				   &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		retries--;
+	} while ((resp_data[0] & OCR_POWERUP) == 0U);
+
+	mmc_ocr_value = resp_data[0];
+
+	if ((mmc_ocr_value & OCR_HCS) != 0U) {
+		mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
+	} else {
+		mmc_dev_info->mmc_dev_type = MMC_IS_SD;
+	}
+
+	return 0;
+}
+
+static int mmc_send_op_cond(void)
+{
+	int ret;
+	int retries = SEND_OP_COND_MAX_RETRIES;
+	unsigned int resp_data[4];
+
+	/* CMD0: reset to IDLE */
+	ret = mmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		if (retries == 0) {
+			ERROR("CMD1 failed after %d retries\n",
+			      SEND_OP_COND_MAX_RETRIES);
+			return -EIO;
+		}
+
+		/* CMD1: get OCR register (SEND_OP_COND) */
+		ret = mmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
+				   OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
+				   MMC_RESPONSE_R(3), &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		retries--;
+	} while ((resp_data[0] & OCR_POWERUP) == 0U);
+
+	mmc_ocr_value = resp_data[0];
+
+	return 0;
+}
+
+static int mmc_enumerate(unsigned int clk, unsigned int bus_width)
+{
+	int ret;
+	unsigned int resp_data[4];
+
+	ops->init();
+
+	/* CMD0: reset to IDLE */
+	ret = mmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD8: Send Interface Condition Command */
+	ret = mmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
+			   MMC_RESPONSE_R(7), &resp_data[0]);
+
+	if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
+		ret = sd_send_op_cond();
+	} else {
+		ret = mmc_send_op_cond();
+	}
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD2: Card Identification */
+	ret = mmc_send_cmd(MMC_CMD(2), 0, MMC_RESPONSE_R(2), NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	/* CMD3: Set Relative Address */
+	if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
+		rca = MMC_FIX_RCA;
+		ret = mmc_send_cmd(MMC_CMD(3), rca << RCA_SHIFT_OFFSET,
+				   MMC_RESPONSE_R(1), NULL);
+		if (ret != 0) {
+			return ret;
+		}
+	} else {
+		ret = mmc_send_cmd(MMC_CMD(3), 0,
+				   MMC_RESPONSE_R(6), &resp_data[0]);
+		if (ret != 0) {
+			return ret;
+		}
+
+		rca = (resp_data[0] & 0xFFFF0000U) >> 16;
+	}
+
+	/* CMD9: CSD Register */
+	ret = mmc_send_cmd(MMC_CMD(9), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R(2), &resp_data[0]);
+	if (ret != 0) {
+		return ret;
+	}
+
+	memcpy(&mmc_csd, &resp_data, sizeof(resp_data));
+
+	/* CMD7: Select Card */
+	ret = mmc_send_cmd(MMC_CMD(7), rca << RCA_SHIFT_OFFSET,
+			   MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return ret;
+	}
+
+	do {
+		ret = mmc_device_state();
+		if (ret < 0) {
+			return ret;
+		}
+	} while (ret != MMC_STATE_TRAN);
+
+	ret = mmc_fill_device_info();
+	if (ret != 0) {
+		return ret;
+	}
+
+	return mmc_set_ios(clk, bus_width);
+}
+
+size_t mmc_read_blocks(unsigned int lba, uintptr_t buf, size_t size)
+{
+	int ret;
+	unsigned int cmd_idx, cmd_arg;
+
+	assert((ops != NULL) &&
+	       (ops->read != NULL) &&
+	       (size != 0U) &&
+	       ((size & MMC_BLOCK_MASK) == 0U));
+
+	ret = ops->prepare(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	if (is_cmd23_enabled()) {
+		/* Set block count */
+		ret = mmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
+				   MMC_RESPONSE_R(1), NULL);
+		if (ret != 0) {
+			return 0;
+		}
+
+		cmd_idx = MMC_CMD(18);
+	} else {
+		if (size > MMC_BLOCK_SIZE) {
+			cmd_idx = MMC_CMD(18);
+		} else {
+			cmd_idx = MMC_CMD(17);
+		}
+	}
+
+	if (((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) &&
+	    (mmc_dev_info->mmc_dev_type != MMC_IS_SD_HC)) {
+		cmd_arg = lba * MMC_BLOCK_SIZE;
+	} else {
+		cmd_arg = lba;
+	}
+
+	ret = mmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = ops->read(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	/* Wait buffer empty */
+	do {
+		ret = mmc_device_state();
+		if (ret < 0) {
+			return 0;
+		}
+	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_DATA));
+
+	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
+		ret = mmc_send_cmd(MMC_CMD(12), 0, 0, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+size_t mmc_write_blocks(unsigned int lba, const uintptr_t buf, size_t size)
+{
+	int ret;
+	unsigned int cmd_idx, cmd_arg;
+
+	assert((ops != NULL) &&
+	       (ops->write != NULL) &&
+	       (size != 0U) &&
+	       ((buf & MMC_BLOCK_MASK) == 0U) &&
+	       ((size & MMC_BLOCK_MASK) == 0U));
+
+	ret = ops->prepare(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	if (is_cmd23_enabled()) {
+		/* Set block count */
+		ret = mmc_send_cmd(MMC_CMD(23), size / MMC_BLOCK_SIZE,
+				   MMC_RESPONSE_R(1), NULL);
+		if (ret != 0) {
+			return 0;
+		}
+
+		cmd_idx = MMC_CMD(25);
+	} else {
+		if (size > MMC_BLOCK_SIZE) {
+			cmd_idx = MMC_CMD(25);
+		} else {
+			cmd_idx = MMC_CMD(24);
+		}
+	}
+
+	if ((mmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE) {
+		cmd_arg = lba * MMC_BLOCK_SIZE;
+	} else {
+		cmd_arg = lba;
+	}
+
+	ret = mmc_send_cmd(cmd_idx, cmd_arg, MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = ops->write(lba, buf, size);
+	if (ret != 0) {
+		return 0;
+	}
+
+	/* Wait buffer empty */
+	do {
+		ret = mmc_device_state();
+		if (ret < 0) {
+			return 0;
+		}
+	} while ((ret != MMC_STATE_TRAN) && (ret != MMC_STATE_RCV));
+
+	if (!is_cmd23_enabled() && (size > MMC_BLOCK_SIZE)) {
+		ret = mmc_send_cmd(MMC_CMD(12), 0, 0, NULL);
+		if (ret != 0) {
+			return 0;
+		}
+	}
+
+	return size;
+}
+
+size_t mmc_erase_blocks(unsigned int lba, size_t size)
+{
+	int ret;
+
+	assert(ops != NULL);
+	assert((size != 0U) && ((size & MMC_BLOCK_MASK) == 0U));
+
+	ret = mmc_send_cmd(MMC_CMD(35), lba, MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = mmc_send_cmd(MMC_CMD(36), lba + (size / MMC_BLOCK_SIZE) - 1U,
+			   MMC_RESPONSE_R(1), NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	ret = mmc_send_cmd(MMC_CMD(38), lba, MMC_RESPONSE_R(0x1B), NULL);
+	if (ret != 0) {
+		return 0;
+	}
+
+	do {
+		ret = mmc_device_state();
+		if (ret < 0) {
+			return 0;
+		}
+	} while (ret != MMC_STATE_TRAN);
+
+	return size;
+}
+
+static inline void mmc_rpmb_enable(void)
+{
+	mmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
+			PART_CFG_BOOT_PARTITION1_ENABLE |
+			PART_CFG_PARTITION1_ACCESS);
+}
+
+static inline void mmc_rpmb_disable(void)
+{
+	mmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
+			PART_CFG_BOOT_PARTITION1_ENABLE);
+}
+
+size_t mmc_rpmb_read_blocks(unsigned int lba, uintptr_t buf, size_t size)
+{
+	size_t size_read;
+
+	mmc_rpmb_enable();
+	size_read = mmc_read_blocks(lba, buf, size);
+	mmc_rpmb_disable();
+
+	return size_read;
+}
+
+size_t mmc_rpmb_write_blocks(unsigned int lba, const uintptr_t buf, size_t size)
+{
+	size_t size_written;
+
+	mmc_rpmb_enable();
+	size_written = mmc_write_blocks(lba, buf, size);
+	mmc_rpmb_disable();
+
+	return size_written;
+}
+
+size_t mmc_rpmb_erase_blocks(unsigned int lba, size_t size)
+{
+	size_t size_erased;
+
+	mmc_rpmb_enable();
+	size_erased = mmc_erase_blocks(lba, size);
+	mmc_rpmb_disable();
+
+	return size_erased;
+}
+
+int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
+	     unsigned int width, unsigned int flags,
+	     struct mmc_device_info *device_info)
+{
+	assert((ops_ptr != NULL) &&
+	       (ops_ptr->init != NULL) &&
+	       (ops_ptr->send_cmd != NULL) &&
+	       (ops_ptr->set_ios != NULL) &&
+	       (ops_ptr->prepare != NULL) &&
+	       (ops_ptr->read != NULL) &&
+	       (ops_ptr->write != NULL) &&
+	       (device_info != NULL) &&
+	       (clk != 0) &&
+	       ((width == MMC_BUS_WIDTH_1) ||
+		(width == MMC_BUS_WIDTH_4) ||
+		(width == MMC_BUS_WIDTH_8) ||
+		(width == MMC_BUS_WIDTH_DDR_4) ||
+		(width == MMC_BUS_WIDTH_DDR_8)));
+
+	ops = ops_ptr;
+	mmc_flags = flags;
+	mmc_dev_info = device_info;
+
+	return mmc_enumerate(clk, width);
+}
diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S
index 5b05045..6e66ea9 100644
--- a/include/common/aarch64/asm_macros.S
+++ b/include/common/aarch64/asm_macros.S
@@ -83,23 +83,31 @@
 	.section \section_name, "ax"
 	.align 7, 0
 	.type \label, %function
-	.func \label
 	.cfi_startproc
 	\label:
 	.endm
 
 	/*
+	 * Add the bytes until fill the full exception vector, whose size is always
+	 * 32 instructions. If there are more than 32 instructions in the
+	 * exception vector then an error is emitted.
+	 */
+	.macro end_vector_entry label
+	.cfi_endproc
+	.fill	\label + (32 * 4) - .
+	.endm
+
+	/*
 	 * This macro verifies that the given vector doesn't exceed the
 	 * architectural limit of 32 instructions. This is meant to be placed
 	 * immediately after the last instruction in the vector. It takes the
 	 * vector entry as the parameter
 	 */
 	.macro check_vector_size since
-	  .endfunc
-	  .cfi_endproc
-	  .if (. - \since) > (32 * 4)
-	    .error "Vector exceeds 32 instructions"
-	  .endif
+#if ERROR_DEPRECATED
+      .error "check_vector_size must not be used. Use end_vector_entry instead"
+#endif
+	end_vector_entry \since
 	.endm
 
 #if ENABLE_PLAT_COMPAT
diff --git a/include/common/asm_macros_common.S b/include/common/asm_macros_common.S
index ca8c1ad..081addc 100644
--- a/include/common/asm_macros_common.S
+++ b/include/common/asm_macros_common.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,7 +31,6 @@
 	.cfi_sections .debug_frame
 	.section .text.asm.\_name, "ax"
 	.type \_name, %function
-	.func \_name
 	/*
 	 * .cfi_startproc and .cfi_endproc are needed to output entries in
 	 * .debug_frame
@@ -45,7 +44,6 @@
 	 * This macro is used to mark the end of a function.
 	 */
 	.macro endfunc _name
-	.endfunc
 	.cfi_endproc
 	.size \_name, . - \_name
 	.endm
diff --git a/include/common/debug.h b/include/common/debug.h
index 3f0f84a..99f402c 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,10 +7,12 @@
 #ifndef __DEBUG_H__
 #define __DEBUG_H__
 
-/* The log output macros print output to the console. These macros produce
+/*
+ * The log output macros print output to the console. These macros produce
  * compiled log output only if the LOG_LEVEL defined in the makefile (or the
  * make command line) is greater or equal than the level required for that
  * type of log output.
+ *
  * The format expected is the same as for printf(). For example:
  * INFO("Info %s.\n", "message")    -> INFO:    Info message.
  * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
@@ -38,34 +40,46 @@
 #define LOG_MARKER_INFO			"\x28"	/* 40 */
 #define LOG_MARKER_VERBOSE		"\x32"	/* 50 */
 
+/*
+ * If the log output is too low then this macro is used in place of tf_log()
+ * below. The intent is to get the compiler to evaluate the function call for
+ * type checking and format specifier correctness but let it optimize it out.
+ */
+#define no_tf_log(fmt, ...)				\
+	do {						\
+		if (0) {				\
+			tf_log(fmt, ##__VA_ARGS__);	\
+		}					\
+	} while (0)
+
 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
 # define NOTICE(...)	tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
 #else
-# define NOTICE(...)
+# define NOTICE(...)	no_tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
 #endif
 
 #if LOG_LEVEL >= LOG_LEVEL_ERROR
 # define ERROR(...)	tf_log(LOG_MARKER_ERROR __VA_ARGS__)
 #else
-# define ERROR(...)
+# define ERROR(...)	no_tf_log(LOG_MARKER_ERROR __VA_ARGS__)
 #endif
 
 #if LOG_LEVEL >= LOG_LEVEL_WARNING
 # define WARN(...)	tf_log(LOG_MARKER_WARNING __VA_ARGS__)
 #else
-# define WARN(...)
+# define WARN(...)	no_tf_log(LOG_MARKER_WARNING __VA_ARGS__)
 #endif
 
 #if LOG_LEVEL >= LOG_LEVEL_INFO
 # define INFO(...)	tf_log(LOG_MARKER_INFO __VA_ARGS__)
 #else
-# define INFO(...)
+# define INFO(...)	no_tf_log(LOG_MARKER_INFO __VA_ARGS__)
 #endif
 
 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
 # define VERBOSE(...)	tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
 #else
-# define VERBOSE(...)
+# define VERBOSE(...)	no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
 #endif
 
 void __dead2 do_panic(void);
diff --git a/include/drivers/mmc.h b/include/drivers/mmc.h
new file mode 100644
index 0000000..65f4bbd
--- /dev/null
+++ b/include/drivers/mmc.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __MMC_H__
+#define __MMC_H__
+
+#include <stdint.h>
+#include <utils_def.h>
+
+#define MMC_BLOCK_SIZE			U(512)
+#define MMC_BLOCK_MASK			(MMC_BLOCK_SIZE - U(1))
+#define MMC_BOOT_CLK_RATE		(400 * 1000)
+
+#define MMC_CMD(_x)			U(_x)
+
+#define MMC_ACMD(_x)			U(_x)
+
+#define OCR_POWERUP			BIT(31)
+#define OCR_HCS				BIT(30)
+#define OCR_BYTE_MODE			(U(0) << 29)
+#define OCR_SECTOR_MODE			(U(2) << 29)
+#define OCR_ACCESS_MODE_MASK		(U(3) << 29)
+#define OCR_3_5_3_6			BIT(23)
+#define OCR_3_4_3_5			BIT(22)
+#define OCR_3_3_3_4			BIT(21)
+#define OCR_3_2_3_3			BIT(20)
+#define OCR_3_1_3_2			BIT(19)
+#define OCR_3_0_3_1			BIT(18)
+#define OCR_2_9_3_0			BIT(17)
+#define OCR_2_8_2_9			BIT(16)
+#define OCR_2_7_2_8			BIT(15)
+#define OCR_VDD_MIN_2V7			GENMASK(23, 15)
+#define OCR_VDD_MIN_2V0			GENMASK(14, 8)
+#define OCR_VDD_MIN_1V7			BIT(7)
+
+#define MMC_RESPONSE_R(_x)		U(_x)
+
+/* Value randomly chosen for eMMC RCA, it should be > 1 */
+#define MMC_FIX_RCA			6
+#define RCA_SHIFT_OFFSET		16
+
+#define CMD_EXTCSD_PARTITION_CONFIG	179
+#define CMD_EXTCSD_BUS_WIDTH		183
+#define CMD_EXTCSD_HS_TIMING		185
+#define CMD_EXTCSD_SEC_CNT		212
+
+#define PART_CFG_BOOT_PARTITION1_ENABLE	(U(1) << 3)
+#define PART_CFG_PARTITION1_ACCESS	(U(1) << 0)
+
+/* Values in EXT CSD register */
+#define MMC_BUS_WIDTH_1			U(0)
+#define MMC_BUS_WIDTH_4			U(1)
+#define MMC_BUS_WIDTH_8			U(2)
+#define MMC_BUS_WIDTH_DDR_4		U(5)
+#define MMC_BUS_WIDTH_DDR_8		U(6)
+#define MMC_BOOT_MODE_BACKWARD		(U(0) << 3)
+#define MMC_BOOT_MODE_HS_TIMING		(U(1) << 3)
+#define MMC_BOOT_MODE_DDR		(U(2) << 3)
+
+#define EXTCSD_SET_CMD			(U(0) << 24)
+#define EXTCSD_SET_BITS			(U(1) << 24)
+#define EXTCSD_CLR_BITS			(U(2) << 24)
+#define EXTCSD_WRITE_BYTES		(U(3) << 24)
+#define EXTCSD_CMD(x)			(((x) & 0xff) << 16)
+#define EXTCSD_VALUE(x)			(((x) & 0xff) << 8)
+#define EXTCSD_CMD_SET_NORMAL		U(1)
+
+#define CSD_TRAN_SPEED_UNIT_MASK	GENMASK(2, 0)
+#define CSD_TRAN_SPEED_MULT_MASK	GENMASK(6, 3)
+#define CSD_TRAN_SPEED_MULT_SHIFT	3
+
+#define STATUS_CURRENT_STATE(x)		(((x) & 0xf) << 9)
+#define STATUS_READY_FOR_DATA		BIT(8)
+#define STATUS_SWITCH_ERROR		BIT(7)
+#define MMC_GET_STATE(x)		(((x) >> 9) & 0xf)
+#define MMC_STATE_IDLE			0
+#define MMC_STATE_READY			1
+#define MMC_STATE_IDENT			2
+#define MMC_STATE_STBY			3
+#define MMC_STATE_TRAN			4
+#define MMC_STATE_DATA			5
+#define MMC_STATE_RCV			6
+#define MMC_STATE_PRG			7
+#define MMC_STATE_DIS			8
+#define MMC_STATE_BTST			9
+#define MMC_STATE_SLP			10
+
+#define MMC_FLAG_CMD23			(U(1) << 0)
+
+#define CMD8_CHECK_PATTERN		U(0xAA)
+#define VHS_2_7_3_6_V			BIT(8)
+
+#define SD_SCR_BUS_WIDTH_1		BIT(8)
+#define SD_SCR_BUS_WIDTH_4		BIT(10)
+
+struct mmc_cmd {
+	unsigned int	cmd_idx;
+	unsigned int	cmd_arg;
+	unsigned int	resp_type;
+	unsigned int	resp_data[4];
+};
+
+struct mmc_ops {
+	void (*init)(void);
+	int (*send_cmd)(struct mmc_cmd *cmd);
+	int (*set_ios)(unsigned int clk, unsigned int width);
+	int (*prepare)(int lba, uintptr_t buf, size_t size);
+	int (*read)(int lba, uintptr_t buf, size_t size);
+	int (*write)(int lba, const uintptr_t buf, size_t size);
+};
+
+struct mmc_csd_emmc {
+	unsigned int		not_used:		1;
+	unsigned int		crc:			7;
+	unsigned int		ecc:			2;
+	unsigned int		file_format:		2;
+	unsigned int		tmp_write_protect:	1;
+	unsigned int		perm_write_protect:	1;
+	unsigned int		copy:			1;
+	unsigned int		file_format_grp:	1;
+
+	unsigned int		reserved_1:		5;
+	unsigned int		write_bl_partial:	1;
+	unsigned int		write_bl_len:		4;
+	unsigned int		r2w_factor:		3;
+	unsigned int		default_ecc:		2;
+	unsigned int		wp_grp_enable:		1;
+
+	unsigned int		wp_grp_size:		5;
+	unsigned int		erase_grp_mult:		5;
+	unsigned int		erase_grp_size:		5;
+	unsigned int		c_size_mult:		3;
+	unsigned int		vdd_w_curr_max:		3;
+	unsigned int		vdd_w_curr_min:		3;
+	unsigned int		vdd_r_curr_max:		3;
+	unsigned int		vdd_r_curr_min:		3;
+	unsigned int		c_size_low:		2;
+
+	unsigned int		c_size_high:		10;
+	unsigned int		reserved_2:		2;
+	unsigned int		dsr_imp:		1;
+	unsigned int		read_blk_misalign:	1;
+	unsigned int		write_blk_misalign:	1;
+	unsigned int		read_bl_partial:	1;
+	unsigned int		read_bl_len:		4;
+	unsigned int		ccc:			12;
+
+	unsigned int		tran_speed:		8;
+	unsigned int		nsac:			8;
+	unsigned int		taac:			8;
+	unsigned int		reserved_3:		2;
+	unsigned int		spec_vers:		4;
+	unsigned int		csd_structure:		2;
+};
+
+struct mmc_csd_sd_v2 {
+	unsigned int		not_used:		1;
+	unsigned int		crc:			7;
+	unsigned int		reserved_1:		2;
+	unsigned int		file_format:		2;
+	unsigned int		tmp_write_protect:	1;
+	unsigned int		perm_write_protect:	1;
+	unsigned int		copy:			1;
+	unsigned int		file_format_grp:	1;
+
+	unsigned int		reserved_2:		5;
+	unsigned int		write_bl_partial:	1;
+	unsigned int		write_bl_len:		4;
+	unsigned int		r2w_factor:		3;
+	unsigned int		reserved_3:		2;
+	unsigned int		wp_grp_enable:		1;
+
+	unsigned int		wp_grp_size:		7;
+	unsigned int		sector_size:		7;
+	unsigned int		erase_block_en:		1;
+	unsigned int		reserved_4:		1;
+	unsigned int		c_size_low:		16;
+
+	unsigned int		c_size_high:		6;
+	unsigned int		reserved_5:		6;
+	unsigned int		dsr_imp:		1;
+	unsigned int		read_blk_misalign:	1;
+	unsigned int		write_blk_misalign:	1;
+	unsigned int		read_bl_partial:	1;
+	unsigned int		read_bl_len:		4;
+	unsigned int		ccc:			12;
+
+	unsigned int		tran_speed:		8;
+	unsigned int		nsac:			8;
+	unsigned int		taac:			8;
+	unsigned int		reserved_6:		6;
+	unsigned int		csd_structure:		2;
+};
+
+enum mmc_device_type {
+	MMC_IS_EMMC,
+	MMC_IS_SD,
+	MMC_IS_SD_HC,
+};
+
+struct mmc_device_info {
+	unsigned long long	device_size;	/* Size of device in bytes */
+	unsigned int		block_size;	/* Block size in bytes */
+	unsigned int		max_bus_freq;	/* Max bus freq in Hz */
+	enum mmc_device_type	mmc_dev_type;	/* Type of MMC */
+};
+
+size_t mmc_read_blocks(unsigned int lba, uintptr_t buf, size_t size);
+size_t mmc_write_blocks(unsigned int lba, const uintptr_t buf, size_t size);
+size_t mmc_erase_blocks(unsigned int lba, size_t size);
+size_t mmc_rpmb_read_blocks(unsigned int lba, uintptr_t buf, size_t size);
+size_t mmc_rpmb_write_blocks(unsigned int lba, const uintptr_t buf,
+			     size_t size);
+size_t mmc_rpmb_erase_blocks(unsigned int lba, size_t size);
+int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
+	     unsigned int width, unsigned int flags,
+	     struct mmc_device_info *device_info);
+
+#endif	/* __MMC_H__ */
diff --git a/include/lib/cpus/aarch32/cpu_macros.S b/include/lib/cpus/aarch32/cpu_macros.S
index 0f3a572..7703be3 100644
--- a/include/lib/cpus/aarch32/cpu_macros.S
+++ b/include/lib/cpus/aarch32/cpu_macros.S
@@ -35,38 +35,47 @@
 # define REPORT_ERRATA	0
 #endif
 
-	/*
-	 * Define the offsets to the fields in cpu_ops structure.
-	 */
-	.struct 0
-CPU_MIDR: /* cpu_ops midr */
-	.space  4
-/* Reset fn is needed during reset */
-#if defined(IMAGE_AT_EL3)
-CPU_RESET_FUNC: /* cpu_ops reset_func */
-	.space  4
+
+	.equ	CPU_MIDR_SIZE, CPU_WORD_SIZE
+	.equ	CPU_RESET_FUNC_SIZE, CPU_WORD_SIZE
+	.equ	CPU_PWR_DWN_OPS_SIZE, CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS
+	.equ	CPU_ERRATA_FUNC_SIZE, CPU_WORD_SIZE
+	.equ	CPU_ERRATA_LOCK_SIZE, CPU_WORD_SIZE
+	.equ	CPU_ERRATA_PRINTED_SIZE, CPU_WORD_SIZE
+
+#ifndef IMAGE_AT_EL3
+	.equ	CPU_RESET_FUNC_SIZE, 0
 #endif
-#ifdef IMAGE_BL32 /* The power down core and cluster is needed only in BL32 */
-CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
-	.space  (4 * CPU_MAX_PWR_DWN_OPS)
+
+/* The power down core and cluster is needed only in BL32 */
+#ifndef IMAGE_BL32
+	.equ	CPU_PWR_DWN_OPS_SIZE, 0
 #endif
 
-/*
- * Fields required to print errata status. Only in BL32 that the printing
- * require mutual exclusion and printed flag.
- */
-#if REPORT_ERRATA
-CPU_ERRATA_FUNC: /* CPU errata status printing function */
-	.space  4
-#if defined(IMAGE_BL32)
-CPU_ERRATA_LOCK:
-	.space	4
-CPU_ERRATA_PRINTED:
-	.space	4
+/* Fields required to print errata status  */
+#if !REPORT_ERRATA
+	.equ	CPU_ERRATA_FUNC_SIZE, 0
 #endif
+
+/* Only BL32 requires mutual exclusion and printed flag. */
+#if !(REPORT_ERRATA && defined(IMAGE_BL32))
+	.equ	CPU_ERRATA_LOCK_SIZE, 0
+	.equ	CPU_ERRATA_PRINTED_SIZE, 0
 #endif
 
+
-CPU_OPS_SIZE = .
+/*
+ * Define the offsets to the fields in cpu_ops structure.
+ * Every offset is defined based on the offset and size of the previous
+ * field.
+ */
+	.equ	CPU_MIDR, 0
+	.equ	CPU_RESET_FUNC, CPU_MIDR + CPU_MIDR_SIZE
+	.equ	CPU_PWR_DWN_OPS, CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
+	.equ	CPU_ERRATA_FUNC, CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
+	.equ	CPU_ERRATA_LOCK, CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
+	.equ	CPU_ERRATA_PRINTED, CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
+	.equ	CPU_OPS_SIZE, CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
 
 	/*
 	 * Write given expressions as words
@@ -128,21 +137,8 @@
 	.word \_resetfunc
 #endif
 #ifdef IMAGE_BL32
-1:
 	/* Insert list of functions */
 	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
-2:
-	/*
-	 * Error if no or more than CPU_MAX_PWR_DWN_OPS were specified in the
-	 * list
-	 */
-	.ifeq 2b - 1b
-	  .error "At least one power down function must be specified"
-	.else
-	  .iflt 2b - 1b - (CPU_MAX_PWR_DWN_OPS * CPU_WORD_SIZE)
-	    .error "More than CPU_MAX_PWR_DWN_OPS functions specified"
-	  .endif
-	.endif
 #endif
 
 #if REPORT_ERRATA
diff --git a/include/lib/cpus/aarch64/cortex_deimos.h b/include/lib/cpus/aarch64/cortex_deimos.h
new file mode 100644
index 0000000..3c36567
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_deimos.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_DEIMOS_H__
+#define __CORTEX_DEIMOS_H__
+
+#define CORTEX_DEIMOS_MIDR					U(0x410FD0D0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_DEIMOS_CPUECTLR_EL1				S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_DEIMOS_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_DEIMOS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		(U(1) << 0)
+
+#endif /* __CORTEX_DEIMOS_H__ */
diff --git a/include/lib/cpus/aarch64/cortex_helios.h b/include/lib/cpus/aarch64/cortex_helios.h
new file mode 100644
index 0000000..1098a12
--- /dev/null
+++ b/include/lib/cpus/aarch64/cortex_helios.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CORTEX_HELIOS_H__
+#define __CORTEX_HELIOS_H__
+
+#define CORTEX_HELIOS_MIDR		U(0x410FD060)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_HELIOS_ECTLR_EL1		S3_0_C15_C1_4
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_HELIOS_CPUACTLR_EL1	S3_0_C15_C1_0
+
+/*******************************************************************************
+ * CPU Power Control register specific definitions.
+ ******************************************************************************/
+
+#define CORTEX_HELIOS_CPUPWRCTLR_EL1				S3_0_C15_C2_7
+#define CORTEX_HELIOS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT		(U(1) << 0)
+
+#endif /* __CORTEX_HELIOS_H__ */
diff --git a/include/lib/cpus/aarch64/cpu_macros.S b/include/lib/cpus/aarch64/cpu_macros.S
index cd8f3e8..026a48e 100644
--- a/include/lib/cpus/aarch64/cpu_macros.S
+++ b/include/lib/cpus/aarch64/cpu_macros.S
@@ -38,46 +38,56 @@
 # define REPORT_ERRATA	0
 #endif
 
-	/*
-	 * Define the offsets to the fields in cpu_ops structure.
-	 */
-	.struct 0
-CPU_MIDR: /* cpu_ops midr */
-	.space  8
-/* Reset fn is needed in BL at reset vector */
-#if defined(IMAGE_AT_EL3)
-CPU_RESET_FUNC: /* cpu_ops reset_func */
-	.space  8
+
+	.equ	CPU_MIDR_SIZE, CPU_WORD_SIZE
+	.equ	CPU_EXTRA1_FUNC_SIZE, CPU_WORD_SIZE
+	.equ	CPU_EXTRA2_FUNC_SIZE, CPU_WORD_SIZE
+	.equ	CPU_RESET_FUNC_SIZE, CPU_WORD_SIZE
+	.equ	CPU_PWR_DWN_OPS_SIZE, CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS
+	.equ	CPU_ERRATA_FUNC_SIZE, CPU_WORD_SIZE
+	.equ	CPU_ERRATA_LOCK_SIZE, CPU_WORD_SIZE
+	.equ	CPU_ERRATA_PRINTED_SIZE, CPU_WORD_SIZE
+	.equ	CPU_REG_DUMP_SIZE, CPU_WORD_SIZE
+
+#ifndef IMAGE_AT_EL3
+	.equ	CPU_RESET_FUNC_SIZE, 0
 #endif
-CPU_EXTRA1_FUNC:
-	.space	8
-CPU_EXTRA2_FUNC:
-	.space	8
-#ifdef IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */
-CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
-	.space  (8 * CPU_MAX_PWR_DWN_OPS)
+
+/* The power down core and cluster is needed only in BL31 */
+#ifndef IMAGE_BL31
+	.equ	CPU_PWR_DWN_OPS_SIZE, 0
 #endif
 
-/*
- * Fields required to print errata status. Only in BL31 that the printing
- * require mutual exclusion and printed flag.
- */
-#if REPORT_ERRATA
-CPU_ERRATA_FUNC:
-	.space	8
-#if defined(IMAGE_BL31)
-CPU_ERRATA_LOCK:
-	.space	8
-CPU_ERRATA_PRINTED:
-	.space	8
+/* Fields required to print errata status. */
+#if !REPORT_ERRATA
+	.equ	CPU_ERRATA_FUNC_SIZE, 0
 #endif
+
+/* Only BL31 requieres mutual exclusion and printed flag.  */
+#if !(REPORT_ERRATA && defined(IMAGE_BL31))
+	.equ	CPU_ERRATA_LOCK_SIZE, 0
+	.equ	CPU_ERRATA_PRINTED_SIZE, 0
 #endif
 
-#if defined(IMAGE_BL31) && CRASH_REPORTING
-CPU_REG_DUMP: /* cpu specific register dump for crash reporting */
-	.space  8
+#if !defined(IMAGE_BL31) || !CRASH_REPORTING
+	.equ	CPU_REG_DUMP_SIZE, 0
 #endif
-CPU_OPS_SIZE = .
+
+/*
+ * Define the offsets to the fields in cpu_ops structure.
+ * Every offset is defined based in the offset and size of the previous
+ * field.
+ */
+	.equ	CPU_MIDR, 0
+	.equ	CPU_RESET_FUNC, CPU_MIDR + CPU_MIDR_SIZE
+	.equ	CPU_EXTRA1_FUNC, CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
+	.equ	CPU_EXTRA2_FUNC, CPU_EXTRA1_FUNC + CPU_EXTRA1_FUNC_SIZE
+	.equ	CPU_PWR_DWN_OPS, CPU_EXTRA2_FUNC + CPU_EXTRA2_FUNC_SIZE
+	.equ	CPU_ERRATA_FUNC, CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
+	.equ	CPU_ERRATA_LOCK, CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
+	.equ	CPU_ERRATA_PRINTED, CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
+	.equ	CPU_REG_DUMP, CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
+	.equ	CPU_OPS_SIZE, CPU_REG_DUMP + CPU_REG_DUMP_SIZE
 
 	/*
 	 * Write given expressions as quad words
@@ -149,21 +159,8 @@
 	.quad \_extra1
 	.quad \_extra2
 #ifdef IMAGE_BL31
-1:
 	/* Insert list of functions */
 	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
-2:
-	/*
-	 * Error if no or more than CPU_MAX_PWR_DWN_OPS were specified in the
-	 * list
-	 */
-	.ifeq 2b - 1b
-	  .error "At least one power down function must be specified"
-	.else
-	  .iflt 2b - 1b - (CPU_MAX_PWR_DWN_OPS * CPU_WORD_SIZE)
-	    .error "More than CPU_MAX_PWR_DWN_OPS functions specified"
-	  .endif
-	.endif
 #endif
 
 #if REPORT_ERRATA
diff --git a/include/lib/utils.h b/include/lib/utils.h
index f367a1f..5f13e99 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -37,10 +37,10 @@
  * in a way that they minimize the number of entries used in the
  * translation tables.
  */
-void clear_map_dyn_mem_regions(mem_region_t *region,
+void clear_map_dyn_mem_regions(struct mem_region *regions,
 			       size_t nregions,
 			       uintptr_t va,
-			       size_t chunk_size);
+			       size_t chunk);
 
 /*
  * checks that a region (addr + nbytes-1) of memory is totally covered by
diff --git a/include/plat/arm/common/aarch64/arm_macros.S b/include/plat/arm/common/aarch64/arm_macros.S
index 12bf734..7953d7e 100644
--- a/include/plat/arm/common/aarch64/arm_macros.S
+++ b/include/plat/arm/common/aarch64/arm_macros.S
@@ -22,8 +22,7 @@
 
 /* Registers common to both GICv2 and GICv3 */
 gicd_pend_reg:
-	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n"	\
-		" Offset:\t\t\tvalue\n"
+	.asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n"
 newline:
 	.asciz "\n"
 spacer:
diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_common.ld.S
index 6edfa09..3f6e29b 100644
--- a/include/plat/arm/common/arm_common.ld.S
+++ b/include/plat/arm/common/arm_common.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,7 +22,7 @@
 	*(arm_el3_tzc_dram)
 	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
 
-	. = NEXT(PAGE_SIZE);
+	. = ALIGN(PAGE_SIZE);
 	__EL3_SEC_DRAM_END__ = .;
 	} >EL3_SEC_DRAM
 }
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 33f2c7d..42bbf38 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -86,7 +86,7 @@
  * Use this macro to instantiate lock before it is used in below
  * arm_lock_xxx() macros
  */
-#define ARM_INSTANTIATE_LOCK	DEFINE_BAKERY_LOCK(arm_lock)
+#define ARM_INSTANTIATE_LOCK	static DEFINE_BAKERY_LOCK(arm_lock)
 #define ARM_LOCK_GET_INSTANCE	(&arm_lock)
 /*
  * These are wrapper macros to the Coherent Memory Bakery Lock API.
@@ -171,7 +171,6 @@
 int arm_validate_ns_entrypoint(uintptr_t entrypoint);
 void arm_system_pwr_domain_save(void);
 void arm_system_pwr_domain_resume(void);
-void arm_program_trusted_mailbox(uintptr_t address);
 int arm_psci_read_mem_protect(int *enabled);
 int arm_nor_psci_write_mem_protect(int val);
 void arm_nor_psci_do_static_mem_protect(void);
@@ -250,6 +249,7 @@
 void plat_arm_interconnect_init(void);
 void plat_arm_interconnect_enter_coherency(void);
 void plat_arm_interconnect_exit_coherency(void);
+void plat_arm_program_trusted_mailbox(uintptr_t address);
 
 #if ARM_PLAT_MT
 unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 14705d7..51d0b15 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -107,19 +107,19 @@
 	 */
 vector_entry cortex_a76_sync_exception_sp_el0
 	b	sync_exception_sp_el0
-	check_vector_size cortex_a76_sync_exception_sp_el0
+end_vector_entry cortex_a76_sync_exception_sp_el0
 
 vector_entry cortex_a76_irq_sp_el0
 	b	irq_sp_el0
-	check_vector_size cortex_a76_irq_sp_el0
+end_vector_entry cortex_a76_irq_sp_el0
 
 vector_entry cortex_a76_fiq_sp_el0
 	b	fiq_sp_el0
-	check_vector_size cortex_a76_fiq_sp_el0
+end_vector_entry cortex_a76_fiq_sp_el0
 
 vector_entry cortex_a76_serror_sp_el0
 	b	serror_sp_el0
-	check_vector_size cortex_a76_serror_sp_el0
+end_vector_entry cortex_a76_serror_sp_el0
 
 	/* ---------------------------------------------------------------------
 	 * Current EL with SP_ELx: 0x200 - 0x400
@@ -127,19 +127,19 @@
 	 */
 vector_entry cortex_a76_sync_exception_sp_elx
 	b	sync_exception_sp_elx
-	check_vector_size cortex_a76_sync_exception_sp_elx
+end_vector_entry cortex_a76_sync_exception_sp_elx
 
 vector_entry cortex_a76_irq_sp_elx
 	b	irq_sp_elx
-	check_vector_size cortex_a76_irq_sp_elx
+end_vector_entry cortex_a76_irq_sp_elx
 
 vector_entry cortex_a76_fiq_sp_elx
 	b	fiq_sp_elx
-	check_vector_size cortex_a76_fiq_sp_elx
+end_vector_entry cortex_a76_fiq_sp_elx
 
 vector_entry cortex_a76_serror_sp_elx
 	b	serror_sp_elx
-	check_vector_size cortex_a76_serror_sp_elx
+end_vector_entry cortex_a76_serror_sp_elx
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -148,22 +148,22 @@
 vector_entry cortex_a76_sync_exception_aarch64
 	apply_cve_2018_3639_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	sync_exception_aarch64
-	check_vector_size cortex_a76_sync_exception_aarch64
+end_vector_entry cortex_a76_sync_exception_aarch64
 
 vector_entry cortex_a76_irq_aarch64
 	apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	irq_aarch64
-	check_vector_size cortex_a76_irq_aarch64
+end_vector_entry cortex_a76_irq_aarch64
 
 vector_entry cortex_a76_fiq_aarch64
 	apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	fiq_aarch64
-	check_vector_size cortex_a76_fiq_aarch64
+end_vector_entry cortex_a76_fiq_aarch64
 
 vector_entry cortex_a76_serror_aarch64
 	apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	serror_aarch64
-	check_vector_size cortex_a76_serror_aarch64
+end_vector_entry cortex_a76_serror_aarch64
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -172,22 +172,22 @@
 vector_entry cortex_a76_sync_exception_aarch32
 	apply_cve_2018_3639_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	sync_exception_aarch32
-	check_vector_size cortex_a76_sync_exception_aarch32
+end_vector_entry cortex_a76_sync_exception_aarch32
 
 vector_entry cortex_a76_irq_aarch32
 	apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	irq_aarch32
-	check_vector_size cortex_a76_irq_aarch32
+end_vector_entry cortex_a76_irq_aarch32
 
 vector_entry cortex_a76_fiq_aarch32
 	apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	fiq_aarch32
-	check_vector_size cortex_a76_fiq_aarch32
+end_vector_entry cortex_a76_fiq_aarch32
 
 vector_entry cortex_a76_serror_aarch32
 	apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	serror_aarch32
-	check_vector_size cortex_a76_serror_aarch32
+end_vector_entry cortex_a76_serror_aarch32
 
 func check_errata_cve_2018_3639
 #if WORKAROUND_CVE_2018_3639
diff --git a/lib/cpus/aarch64/cortex_deimos.S b/lib/cpus/aarch64/cortex_deimos.S
new file mode 100644
index 0000000..aec62a2
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_deimos.S
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <cortex_deimos.h>
+#include <cpu_macros.S>
+#include <plat_macros.S>
+
+	/* ---------------------------------------------
+	 * HW will do the cache maintenance while powering down
+	 * ---------------------------------------------
+	 */
+func cortex_deimos_core_pwr_dwn
+	/* ---------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * ---------------------------------------------
+	 */
+	mrs	x0, CORTEX_DEIMOS_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_DEIMOS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_DEIMOS_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_deimos_core_pwr_dwn
+
+	/* ---------------------------------------------
+	 * This function provides Cortex-Deimos specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ascii and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.cortex_deimos_regs, "aS"
+cortex_deimos_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_deimos_cpu_reg_dump
+	adr	x6, cortex_deimos_regs
+	mrs	x8, CORTEX_DEIMOS_CPUECTLR_EL1
+	ret
+endfunc cortex_deimos_cpu_reg_dump
+
+declare_cpu_ops cortex_deimos, CORTEX_DEIMOS_MIDR, \
+	CPU_NO_RESET_FUNC, \
+	cortex_deimos_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_helios.S b/lib/cpus/aarch64/cortex_helios.S
new file mode 100644
index 0000000..bcda741
--- /dev/null
+++ b/lib/cpus/aarch64/cortex_helios.S
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <cortex_helios.h>
+#include <cpu_macros.S>
+#include <debug.h>
+#include <plat_macros.S>
+
+func cortex_helios_cpu_pwr_dwn
+	mrs	x0, CORTEX_HELIOS_CPUPWRCTLR_EL1
+	orr	x0, x0, #CORTEX_HELIOS_CPUPWRCTLR_EL1_CORE_PWRDN_BIT
+	msr	CORTEX_HELIOS_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc cortex_helios_cpu_pwr_dwn
+
+.section .rodata.cortex_helios_regs, "aS"
+cortex_helios_regs:  /* The ascii list of register names to be reported */
+	.asciz	"cpuectlr_el1", ""
+
+func cortex_helios_cpu_reg_dump
+	adr	x6, cortex_helios_regs
+	mrs	x8, CORTEX_HELIOS_ECTLR_EL1
+	ret
+endfunc cortex_helios_cpu_reg_dump
+
+declare_cpu_ops cortex_helios, CORTEX_HELIOS_MIDR, \
+	CPU_NO_RESET_FUNC, \
+	cortex_helios_cpu_pwr_dwn
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index aee4fee..f04dbd6 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -55,19 +55,19 @@
 	 */
 vector_entry workaround_bpflush_sync_exception_sp_el0
 	b	sync_exception_sp_el0
-	check_vector_size workaround_bpflush_sync_exception_sp_el0
+end_vector_entry workaround_bpflush_sync_exception_sp_el0
 
 vector_entry workaround_bpflush_irq_sp_el0
 	b	irq_sp_el0
-	check_vector_size workaround_bpflush_irq_sp_el0
+end_vector_entry workaround_bpflush_irq_sp_el0
 
 vector_entry workaround_bpflush_fiq_sp_el0
 	b	fiq_sp_el0
-	check_vector_size workaround_bpflush_fiq_sp_el0
+end_vector_entry workaround_bpflush_fiq_sp_el0
 
 vector_entry workaround_bpflush_serror_sp_el0
 	b	serror_sp_el0
-	check_vector_size workaround_bpflush_serror_sp_el0
+end_vector_entry workaround_bpflush_serror_sp_el0
 
 	/* ---------------------------------------------------------------------
 	 * Current EL with SP_ELx: 0x200 - 0x400
@@ -75,19 +75,19 @@
 	 */
 vector_entry workaround_bpflush_sync_exception_sp_elx
 	b	sync_exception_sp_elx
-	check_vector_size workaround_bpflush_sync_exception_sp_elx
+end_vector_entry workaround_bpflush_sync_exception_sp_elx
 
 vector_entry workaround_bpflush_irq_sp_elx
 	b	irq_sp_elx
-	check_vector_size workaround_bpflush_irq_sp_elx
+end_vector_entry workaround_bpflush_irq_sp_elx
 
 vector_entry workaround_bpflush_fiq_sp_elx
 	b	fiq_sp_elx
-	check_vector_size workaround_bpflush_fiq_sp_elx
+end_vector_entry workaround_bpflush_fiq_sp_elx
 
 vector_entry workaround_bpflush_serror_sp_elx
 	b	serror_sp_elx
-	check_vector_size workaround_bpflush_serror_sp_elx
+end_vector_entry workaround_bpflush_serror_sp_elx
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -96,22 +96,22 @@
 vector_entry workaround_bpflush_sync_exception_aarch64
 	apply_workaround
 	b	sync_exception_aarch64
-	check_vector_size workaround_bpflush_sync_exception_aarch64
+end_vector_entry workaround_bpflush_sync_exception_aarch64
 
 vector_entry workaround_bpflush_irq_aarch64
 	apply_workaround
 	b	irq_aarch64
-	check_vector_size workaround_bpflush_irq_aarch64
+end_vector_entry workaround_bpflush_irq_aarch64
 
 vector_entry workaround_bpflush_fiq_aarch64
 	apply_workaround
 	b	fiq_aarch64
-	check_vector_size workaround_bpflush_fiq_aarch64
+end_vector_entry workaround_bpflush_fiq_aarch64
 
 vector_entry workaround_bpflush_serror_aarch64
 	apply_workaround
 	b	serror_aarch64
-	check_vector_size workaround_bpflush_serror_aarch64
+end_vector_entry workaround_bpflush_serror_aarch64
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -120,22 +120,22 @@
 vector_entry workaround_bpflush_sync_exception_aarch32
 	apply_workaround
 	b	sync_exception_aarch32
-	check_vector_size workaround_bpflush_sync_exception_aarch32
+end_vector_entry workaround_bpflush_sync_exception_aarch32
 
 vector_entry workaround_bpflush_irq_aarch32
 	apply_workaround
 	b	irq_aarch32
-	check_vector_size workaround_bpflush_irq_aarch32
+end_vector_entry workaround_bpflush_irq_aarch32
 
 vector_entry workaround_bpflush_fiq_aarch32
 	apply_workaround
 	b	fiq_aarch32
-	check_vector_size workaround_bpflush_fiq_aarch32
+end_vector_entry workaround_bpflush_fiq_aarch32
 
 vector_entry workaround_bpflush_serror_aarch32
 	apply_workaround
 	b	serror_aarch32
-	check_vector_size workaround_bpflush_serror_aarch32
+end_vector_entry workaround_bpflush_serror_aarch32
 
 	.global	denver_disable_dco
 
diff --git a/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S b/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
index 8437155..c613ebd 100644
--- a/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
+++ b/lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S
@@ -114,19 +114,19 @@
 	.word	EMIT_BPIALL
 	.word	EMIT_SMC
 
-	check_vector_size bpiall_sync_exception_sp_el0
+end_vector_entry bpiall_sync_exception_sp_el0
 
 vector_entry bpiall_irq_sp_el0
 	b	irq_sp_el0
-	check_vector_size bpiall_irq_sp_el0
+end_vector_entry bpiall_irq_sp_el0
 
 vector_entry bpiall_fiq_sp_el0
 	b	fiq_sp_el0
-	check_vector_size bpiall_fiq_sp_el0
+end_vector_entry bpiall_fiq_sp_el0
 
 vector_entry bpiall_serror_sp_el0
 	b	serror_sp_el0
-	check_vector_size bpiall_serror_sp_el0
+end_vector_entry bpiall_serror_sp_el0
 
 	/* ---------------------------------------------------------------------
 	 * Current EL with SP_ELx: 0x200 - 0x400
@@ -134,19 +134,19 @@
 	 */
 vector_entry bpiall_sync_exception_sp_elx
 	b	sync_exception_sp_elx
-	check_vector_size bpiall_sync_exception_sp_elx
+end_vector_entry bpiall_sync_exception_sp_elx
 
 vector_entry bpiall_irq_sp_elx
 	b	irq_sp_elx
-	check_vector_size bpiall_irq_sp_elx
+end_vector_entry bpiall_irq_sp_elx
 
 vector_entry bpiall_fiq_sp_elx
 	b	fiq_sp_elx
-	check_vector_size bpiall_fiq_sp_elx
+end_vector_entry bpiall_fiq_sp_elx
 
 vector_entry bpiall_serror_sp_elx
 	b	serror_sp_elx
-	check_vector_size bpiall_serror_sp_elx
+end_vector_entry bpiall_serror_sp_elx
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -154,19 +154,19 @@
 	 */
 vector_entry bpiall_sync_exception_aarch64
 	apply_cve_2017_5715_wa 1
-	check_vector_size bpiall_sync_exception_aarch64
+end_vector_entry bpiall_sync_exception_aarch64
 
 vector_entry bpiall_irq_aarch64
 	apply_cve_2017_5715_wa 2
-	check_vector_size bpiall_irq_aarch64
+end_vector_entry bpiall_irq_aarch64
 
 vector_entry bpiall_fiq_aarch64
 	apply_cve_2017_5715_wa 4
-	check_vector_size bpiall_fiq_aarch64
+end_vector_entry bpiall_fiq_aarch64
 
 vector_entry bpiall_serror_aarch64
 	apply_cve_2017_5715_wa 8
-	check_vector_size bpiall_serror_aarch64
+end_vector_entry bpiall_serror_aarch64
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -174,19 +174,19 @@
 	 */
 vector_entry bpiall_sync_exception_aarch32
 	apply_cve_2017_5715_wa 1
-	check_vector_size bpiall_sync_exception_aarch32
+end_vector_entry bpiall_sync_exception_aarch32
 
 vector_entry bpiall_irq_aarch32
 	apply_cve_2017_5715_wa 2
-	check_vector_size bpiall_irq_aarch32
+end_vector_entry bpiall_irq_aarch32
 
 vector_entry bpiall_fiq_aarch32
 	apply_cve_2017_5715_wa 4
-	check_vector_size bpiall_fiq_aarch32
+end_vector_entry bpiall_fiq_aarch32
 
 vector_entry bpiall_serror_aarch32
 	apply_cve_2017_5715_wa 8
-	check_vector_size bpiall_serror_aarch32
+end_vector_entry bpiall_serror_aarch32
 
 	/* ---------------------------------------------------------------------
 	 * This vector table is used while the workaround is executing.  It
@@ -203,19 +203,19 @@
 	 */
 vector_entry bpiall_ret_sync_exception_sp_el0
 	b	report_unhandled_exception
-	check_vector_size bpiall_ret_sync_exception_sp_el0
+end_vector_entry bpiall_ret_sync_exception_sp_el0
 
 vector_entry bpiall_ret_irq_sp_el0
 	b	report_unhandled_interrupt
-	check_vector_size bpiall_ret_irq_sp_el0
+end_vector_entry bpiall_ret_irq_sp_el0
 
 vector_entry bpiall_ret_fiq_sp_el0
 	b	report_unhandled_interrupt
-	check_vector_size bpiall_ret_fiq_sp_el0
+end_vector_entry bpiall_ret_fiq_sp_el0
 
 vector_entry bpiall_ret_serror_sp_el0
 	b	report_unhandled_exception
-	check_vector_size bpiall_ret_serror_sp_el0
+end_vector_entry bpiall_ret_serror_sp_el0
 
 	/* ---------------------------------------------------------------------
 	 * Current EL with SP_ELx: 0x200 - 0x400 (UNUSED)
@@ -223,19 +223,19 @@
 	 */
 vector_entry bpiall_ret_sync_exception_sp_elx
 	b	report_unhandled_exception
-	check_vector_size bpiall_ret_sync_exception_sp_elx
+end_vector_entry bpiall_ret_sync_exception_sp_elx
 
 vector_entry bpiall_ret_irq_sp_elx
 	b	report_unhandled_interrupt
-	check_vector_size bpiall_ret_irq_sp_elx
+end_vector_entry bpiall_ret_irq_sp_elx
 
 vector_entry bpiall_ret_fiq_sp_elx
 	b	report_unhandled_interrupt
-	check_vector_size bpiall_ret_fiq_sp_elx
+end_vector_entry bpiall_ret_fiq_sp_elx
 
 vector_entry bpiall_ret_serror_sp_elx
 	b	report_unhandled_exception
-	check_vector_size bpiall_ret_serror_sp_elx
+end_vector_entry bpiall_ret_serror_sp_elx
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600 (UNUSED)
@@ -243,19 +243,19 @@
 	 */
 vector_entry bpiall_ret_sync_exception_aarch64
 	b	report_unhandled_exception
-	check_vector_size bpiall_ret_sync_exception_aarch64
+end_vector_entry bpiall_ret_sync_exception_aarch64
 
 vector_entry bpiall_ret_irq_aarch64
 	b	report_unhandled_interrupt
-	check_vector_size bpiall_ret_irq_aarch64
+end_vector_entry bpiall_ret_irq_aarch64
 
 vector_entry bpiall_ret_fiq_aarch64
 	b	report_unhandled_interrupt
-	check_vector_size bpiall_ret_fiq_aarch64
+end_vector_entry bpiall_ret_fiq_aarch64
 
 vector_entry bpiall_ret_serror_aarch64
 	b	report_unhandled_exception
-	check_vector_size bpiall_ret_serror_aarch64
+end_vector_entry bpiall_ret_serror_aarch64
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -324,7 +324,7 @@
 1:
 	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
 	b	sync_exception_aarch64
-	check_vector_size bpiall_ret_sync_exception_aarch32
+end_vector_entry bpiall_ret_sync_exception_aarch32
 
 vector_entry bpiall_ret_irq_aarch32
 	b	report_unhandled_interrupt
@@ -346,12 +346,12 @@
 bpiall_ret_serror:
 	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
 	b	serror_aarch64
-	check_vector_size bpiall_ret_irq_aarch32
+end_vector_entry bpiall_ret_irq_aarch32
 
 vector_entry bpiall_ret_fiq_aarch32
 	b	report_unhandled_interrupt
-	check_vector_size bpiall_ret_fiq_aarch32
+end_vector_entry bpiall_ret_fiq_aarch32
 
 vector_entry bpiall_ret_serror_aarch32
 	b	report_unhandled_exception
-	check_vector_size bpiall_ret_serror_aarch32
+end_vector_entry bpiall_ret_serror_aarch32
diff --git a/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S b/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
index a556d1f..d7b6e26 100644
--- a/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
+++ b/lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
@@ -66,19 +66,19 @@
 	 */
 vector_entry mmu_sync_exception_sp_el0
 	b	sync_exception_sp_el0
-	check_vector_size mmu_sync_exception_sp_el0
+end_vector_entry mmu_sync_exception_sp_el0
 
 vector_entry mmu_irq_sp_el0
 	b	irq_sp_el0
-	check_vector_size mmu_irq_sp_el0
+end_vector_entry mmu_irq_sp_el0
 
 vector_entry mmu_fiq_sp_el0
 	b	fiq_sp_el0
-	check_vector_size mmu_fiq_sp_el0
+end_vector_entry mmu_fiq_sp_el0
 
 vector_entry mmu_serror_sp_el0
 	b	serror_sp_el0
-	check_vector_size mmu_serror_sp_el0
+end_vector_entry mmu_serror_sp_el0
 
 	/* ---------------------------------------------------------------------
 	 * Current EL with SP_ELx: 0x200 - 0x400
@@ -86,19 +86,19 @@
 	 */
 vector_entry mmu_sync_exception_sp_elx
 	b	sync_exception_sp_elx
-	check_vector_size mmu_sync_exception_sp_elx
+end_vector_entry mmu_sync_exception_sp_elx
 
 vector_entry mmu_irq_sp_elx
 	b	irq_sp_elx
-	check_vector_size mmu_irq_sp_elx
+end_vector_entry mmu_irq_sp_elx
 
 vector_entry mmu_fiq_sp_elx
 	b	fiq_sp_elx
-	check_vector_size mmu_fiq_sp_elx
+end_vector_entry mmu_fiq_sp_elx
 
 vector_entry mmu_serror_sp_elx
 	b	serror_sp_elx
-	check_vector_size mmu_serror_sp_elx
+end_vector_entry mmu_serror_sp_elx
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600
@@ -107,22 +107,22 @@
 vector_entry mmu_sync_exception_aarch64
 	apply_cve_2017_5715_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	sync_exception_aarch64
-	check_vector_size mmu_sync_exception_aarch64
+end_vector_entry mmu_sync_exception_aarch64
 
 vector_entry mmu_irq_aarch64
 	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	irq_aarch64
-	check_vector_size mmu_irq_aarch64
+end_vector_entry mmu_irq_aarch64
 
 vector_entry mmu_fiq_aarch64
 	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	fiq_aarch64
-	check_vector_size mmu_fiq_aarch64
+end_vector_entry mmu_fiq_aarch64
 
 vector_entry mmu_serror_aarch64
 	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
 	b	serror_aarch64
-	check_vector_size mmu_serror_aarch64
+end_vector_entry mmu_serror_aarch64
 
 	/* ---------------------------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -131,19 +131,19 @@
 vector_entry mmu_sync_exception_aarch32
 	apply_cve_2017_5715_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	sync_exception_aarch32
-	check_vector_size mmu_sync_exception_aarch32
+end_vector_entry mmu_sync_exception_aarch32
 
 vector_entry mmu_irq_aarch32
 	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	irq_aarch32
-	check_vector_size mmu_irq_aarch32
+end_vector_entry mmu_irq_aarch32
 
 vector_entry mmu_fiq_aarch32
 	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	fiq_aarch32
-	check_vector_size mmu_fiq_aarch32
+end_vector_entry mmu_fiq_aarch32
 
 vector_entry mmu_serror_aarch32
 	apply_cve_2017_5715_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
 	b	serror_aarch32
-	check_vector_size mmu_serror_aarch32
+end_vector_entry mmu_serror_aarch32
diff --git a/lib/utils/mem_region.c b/lib/utils/mem_region.c
index e9541ba..a5c3c61 100644
--- a/lib/utils/mem_region.c
+++ b/lib/utils/mem_region.c
@@ -50,7 +50,7 @@
  * be cleared, and chunk is the amount of memory mapped and
  * cleared in every iteration.
  */
-void clear_map_dyn_mem_regions(mem_region_t *regions,
+void clear_map_dyn_mem_regions(struct mem_region *regions,
 			       size_t nregions,
 			       uintptr_t va,
 			       size_t chunk)
diff --git a/plat/arm/board/fvp/fvp_bl2u_setup.c b/plat/arm/board/fvp/fvp_bl2u_setup.c
index 361e84d..b9ab3f3 100644
--- a/plat/arm/board/fvp/fvp_bl2u_setup.c
+++ b/plat/arm/board/fvp/fvp_bl2u_setup.c
@@ -9,7 +9,7 @@
 #include "fvp_def.h"
 #include "fvp_private.h"
 
-void bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
+void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info)
 {
 	arm_bl2u_early_platform_setup(mem_layout, plat_info);
 
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index ed41d4c..2b1e0ac 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -116,7 +116,8 @@
 				lib/cpus/aarch64/cortex_a73.S			\
 				lib/cpus/aarch64/cortex_a75.S			\
 				lib/cpus/aarch64/cortex_a76.S			\
-				lib/cpus/aarch64/cortex_ares.S
+				lib/cpus/aarch64/cortex_ares.S			\
+				lib/cpus/aarch64/cortex_deimos.S
 else
 FVP_CPU_LIBS		+=	lib/cpus/aarch32/cortex_a32.S
 endif
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index d141f64..c9b1a68 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -27,7 +27,7 @@
 /* Data structure which holds the extents of the trusted SRAM for BL1*/
 static meminfo_t bl1_tzram_layout;
 
-meminfo_t *bl1_plat_sec_mem_layout(void)
+struct meminfo *bl1_plat_sec_mem_layout(void)
 {
 	return &bl1_tzram_layout;
 }
@@ -144,7 +144,7 @@
 	 * in order to release secondary CPUs from their holding pen and make
 	 * them jump there.
 	 */
-	arm_program_trusted_mailbox(ep_info->pc);
+	plat_arm_program_trusted_mailbox(ep_info->pc);
 	dsbsy();
 	sev();
 #endif
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 3aa99f8..33c2fe8 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -172,7 +172,8 @@
  * in x0. This memory layout is sitting at the base of the free trusted SRAM.
  * Copy it to a safe location before its reclaimed by later BL2 functionality.
  ******************************************************************************/
-void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, meminfo_t *mem_layout)
+void arm_bl2_early_platform_setup(uintptr_t tb_fw_config,
+				  struct meminfo *mem_layout)
 {
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index cd691e5..dce00e5 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -32,7 +32,7 @@
 	arm_bl2u_platform_setup();
 }
 
-void arm_bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
+void arm_bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info)
 {
 	/* Initialize the console to provide early debug support */
 	arm_console_boot_init();
@@ -46,7 +46,7 @@
  * In case of ARM FVP platforms x1 is not used.
  * In both cases, x0 contains the extents of the memory available to BL2U
  ******************************************************************************/
-void bl2u_early_platform_setup(meminfo_t *mem_layout, void *plat_info)
+void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info)
 {
 	arm_bl2u_early_platform_setup(mem_layout, plat_info);
 }
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index 6346f0f..b1f95c9 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -44,7 +44,7 @@
  * while BL32 corresponds to the secure image type. A NULL pointer is returned
  * if the image does not exist.
  ******************************************************************************/
-entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
 {
 	entry_point_info_t *next_image_info;
 
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 32fd9ee..270abb2 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -14,8 +14,6 @@
 #include <platform.h>
 #include <secure_partition.h>
 
-extern const mmap_region_t plat_arm_mmap[];
-
 /* Weak definitions may be overridden in specific ARM standard platform */
 #pragma weak plat_get_ns_image_entrypoint
 #pragma weak plat_arm_get_mmap
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 5330847..67b574d 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -166,7 +166,7 @@
 				plat/arm/common/arm_err.c			\
 				plat/arm/common/arm_io_storage.c
 ifdef EL3_PAYLOAD_BASE
-# Need the arm_program_trusted_mailbox() function to release secondary CPUs from
+# Need the plat_arm_program_trusted_mailbox() function to release secondary CPUs from
 # their holding pen
 BL1_SOURCES		+=	plat/arm/common/arm_pm.c
 endif
diff --git a/plat/arm/common/arm_image_load.c b/plat/arm/common/arm_image_load.c
index 916fa8d..4f86efd 100644
--- a/plat/arm/common/arm_image_load.c
+++ b/plat/arm/common/arm_image_load.c
@@ -28,7 +28,7 @@
 /*******************************************************************************
  * This function returns the list of loadable images.
  ******************************************************************************/
-bl_load_info_t *plat_get_bl_image_load_info(void)
+struct bl_load_info *plat_get_bl_image_load_info(void)
 {
 	return get_bl_load_info_from_mem_params_desc();
 }
@@ -36,7 +36,7 @@
 /*******************************************************************************
  * This function returns the list of executable images.
  ******************************************************************************/
-bl_params_t *plat_get_next_bl_params(void)
+struct bl_params *plat_get_next_bl_params(void)
 {
 	bl_params_t *next_bl_params = get_next_bl_params_from_mem_params_desc();
 
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index 4632099..d0350d6 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -14,11 +14,9 @@
 #include <platform_def.h>
 #include <psci.h>
 
-/* Allow ARM Standard platforms to override this function */
+/* Allow ARM Standard platforms to override these functions */
 #pragma weak plat_arm_psci_override_pm_ops
-
-/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */
-extern plat_psci_ops_t plat_arm_psci_pm_ops;
+#pragma weak plat_arm_program_trusted_mailbox
 
 #if ARM_RECOM_STATE_ID_ENC
 extern unsigned int arm_pm_idle_states[];
@@ -192,11 +190,11 @@
 }
 
 /*******************************************************************************
- * Private function to program the mailbox for a cpu before it is released
+ * ARM platform function to program the mailbox for a cpu before it is released
  * from reset. This function assumes that the Trusted mail box base is within
  * the ARM_SHARED_RAM region
  ******************************************************************************/
-void arm_program_trusted_mailbox(uintptr_t address)
+void plat_arm_program_trusted_mailbox(uintptr_t address)
 {
 	uintptr_t *mailbox = (void *) PLAT_ARM_TRUSTED_MAILBOX_BASE;
 
@@ -221,6 +219,6 @@
 	*psci_ops = plat_arm_psci_override_pm_ops(&plat_arm_psci_pm_ops);
 
 	/* Setup mailbox with entry point. */
-	arm_program_trusted_mailbox(sec_entrypoint);
+	plat_arm_program_trusted_mailbox(sec_entrypoint);
 	return 0;
 }
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index 72d5527..29dd01d 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -32,6 +32,7 @@
 				plat/arm/css/drivers/scpi/css_scpi.c
 else
 BL31_SOURCES		+=	plat/arm/css/drivers/scp/css_pm_scmi.c		\
+				plat/arm/css/drivers/scmi/scmi_ap_core_proto.c	\
 				plat/arm/css/drivers/scmi/scmi_common.c		\
 				plat/arm/css/drivers/scmi/scmi_pwr_dmn_proto.c	\
 				plat/arm/css/drivers/scmi/scmi_sys_pwr_proto.c	\
diff --git a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
index b9faf67..54f3e05 100644
--- a/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
+++ b/plat/arm/css/drivers/mhu/css_mhu_doorbell.c
@@ -9,7 +9,7 @@
 #include "css_mhu_doorbell.h"
 #include "../scmi/scmi.h"
 
-void mhu_ring_doorbell(scmi_channel_plat_info_t *plat_info)
+void mhu_ring_doorbell(struct scmi_channel_plat_info *plat_info)
 {
 	MHU_RING_DOORBELL(plat_info->db_reg_addr,
 			plat_info->db_modify_mask,
@@ -17,7 +17,7 @@
 	return;
 }
 
-void mhuv2_ring_doorbell(scmi_channel_plat_info_t *plat_info)
+void mhuv2_ring_doorbell(struct scmi_channel_plat_info *plat_info)
 {
 	/* wake receiver */
 	MHU_V2_ACCESS_REQUEST(MHUV2_BASE_ADDR);
diff --git a/plat/arm/css/drivers/scmi/scmi.h b/plat/arm/css/drivers/scmi/scmi.h
index cf9ef5e..723fd06 100644
--- a/plat/arm/css/drivers/scmi/scmi.h
+++ b/plat/arm/css/drivers/scmi/scmi.h
@@ -12,6 +12,7 @@
 #include <stdint.h>
 
 /* Supported SCMI Protocol Versions */
+#define SCMI_AP_CORE_PROTO_VER			MAKE_SCMI_VERSION(1, 0)
 #define SCMI_PWR_DMN_PROTO_VER			MAKE_SCMI_VERSION(1, 0)
 #define SCMI_SYS_PWR_PROTO_VER			MAKE_SCMI_VERSION(1, 0)
 
@@ -29,6 +30,8 @@
 /* SCMI Protocol identifiers */
 #define SCMI_PWR_DMN_PROTO_ID			0x11
 #define SCMI_SYS_PWR_PROTO_ID			0x12
+/* The AP core protocol is a CSS platform-specific extension */
+#define SCMI_AP_CORE_PROTO_ID			0x90
 
 /* Mandatory messages IDs for all SCMI protocols */
 #define SCMI_PROTO_VERSION_MSG			0x0
@@ -43,6 +46,10 @@
 #define SCMI_SYS_PWR_STATE_SET_MSG		0x3
 #define SCMI_SYS_PWR_STATE_GET_MSG		0x4
 
+/* SCMI AP core protocol message IDs */
+#define SCMI_AP_CORE_RESET_ADDR_SET_MSG		0x3
+#define SCMI_AP_CORE_RESET_ADDR_GET_MSG		0x4
+
 /* Helper macros for system power management protocol commands */
 
 /*
@@ -73,6 +80,13 @@
 #define SCMI_SYS_PWR_POWER_UP			0x3
 #define SCMI_SYS_PWR_SUSPEND			0x4
 
+/*
+ * Macros to describe the bit-fields of the `attribute` of AP core protocol
+ * AP_CORE_RESET_ADDR set/get messages.
+ */
+#define SCMI_AP_CORE_LOCK_ATTR_SHIFT		0x0
+#define SCMI_AP_CORE_LOCK_ATTR			(1U << SCMI_AP_CORE_LOCK_ATTR_SHIFT)
+
 /* SCMI Error code definitions */
 #define SCMI_E_QUEUED			1
 #define SCMI_E_SUCCESS			0
@@ -133,4 +147,8 @@
 int scmi_sys_pwr_state_set(void *p, uint32_t flags, uint32_t system_state);
 int scmi_sys_pwr_state_get(void *p, uint32_t *system_state);
 
+/* SCMI AP core configuration protocol commands. */
+int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr);
+int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr);
+
 #endif	/* __CSS_SCMI_H__ */
diff --git a/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c b/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c
new file mode 100644
index 0000000..1438cba
--- /dev/null
+++ b/plat/arm/css/drivers/scmi/scmi_ap_core_proto.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include "scmi.h"
+#include "scmi_private.h"
+
+/*
+ * API to set the SCMI AP core reset address and attributes
+ */
+int scmi_ap_core_set_reset_addr(void *p, uint64_t reset_addr, uint32_t attr)
+{
+	mailbox_mem_t *mbx_mem;
+	int token = 0, ret;
+	scmi_channel_t *ch = (scmi_channel_t *)p;
+
+	validate_scmi_channel(ch);
+
+	scmi_get_channel(ch);
+
+	mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+	mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
+			SCMI_AP_CORE_RESET_ADDR_SET_MSG, token);
+	mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN;
+	mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+	SCMI_PAYLOAD_ARG3(mbx_mem->payload, reset_addr & 0xffffffff,
+		reset_addr >> 32, attr);
+
+	scmi_send_sync_command(ch);
+
+	/* Get the return values */
+	SCMI_PAYLOAD_RET_VAL1(mbx_mem->payload, ret);
+	assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN);
+	assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+	scmi_put_channel(ch);
+
+	return ret;
+}
+
+/*
+ * API to get the SCMI AP core reset address and attributes
+ */
+int scmi_ap_core_get_reset_addr(void *p, uint64_t *reset_addr, uint32_t *attr)
+{
+	mailbox_mem_t *mbx_mem;
+	int token = 0, ret;
+	scmi_channel_t *ch = (scmi_channel_t *)p;
+	uint32_t lo_addr, hi_addr;
+
+	validate_scmi_channel(ch);
+
+	scmi_get_channel(ch);
+
+	mbx_mem = (mailbox_mem_t *)(ch->info->scmi_mbx_mem);
+	mbx_mem->msg_header = SCMI_MSG_CREATE(SCMI_AP_CORE_PROTO_ID,
+			SCMI_AP_CORE_RESET_ADDR_GET_MSG, token);
+	mbx_mem->len = SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN;
+	mbx_mem->flags = SCMI_FLAG_RESP_POLL;
+
+	scmi_send_sync_command(ch);
+
+	/* Get the return values */
+	SCMI_PAYLOAD_RET_VAL4(mbx_mem->payload, ret, lo_addr, hi_addr, *attr);
+	*reset_addr = lo_addr | (uint64_t)hi_addr << 32;
+	assert(mbx_mem->len == SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN);
+	assert(token == SCMI_MSG_GET_TOKEN(mbx_mem->msg_header));
+
+	scmi_put_channel(ch);
+
+	return ret;
+}
diff --git a/plat/arm/css/drivers/scmi/scmi_private.h b/plat/arm/css/drivers/scmi/scmi_private.h
index 67fe748..39bc8cc 100644
--- a/plat/arm/css/drivers/scmi/scmi_private.h
+++ b/plat/arm/css/drivers/scmi/scmi_private.h
@@ -18,6 +18,12 @@
 #define SCMI_PROTO_MSG_ATTR_MSG_LEN		8
 #define SCMI_PROTO_MSG_ATTR_RESP_LEN		12
 
+#define SCMI_AP_CORE_RESET_ADDR_SET_MSG_LEN	16
+#define SCMI_AP_CORE_RESET_ADDR_SET_RESP_LEN	8
+
+#define SCMI_AP_CORE_RESET_ADDR_GET_MSG_LEN	4
+#define SCMI_AP_CORE_RESET_ADDR_GET_RESP_LEN	20
+
 #define SCMI_PWR_STATE_SET_MSG_LEN		16
 #define SCMI_PWR_STATE_SET_RESP_LEN		8
 
@@ -113,6 +119,11 @@
 		(val3) = mmio_read_32((uintptr_t)&payld_arr[2]);	\
 	} while (0)
 
+#define SCMI_PAYLOAD_RET_VAL4(payld_arr, val1, val2, val3, val4)	do {	\
+		SCMI_PAYLOAD_RET_VAL3(payld_arr, val1, val2, val3);		\
+		(val4) = mmio_read_32((uintptr_t)&payld_arr[3]);		\
+	} while (0)
+
 /*
  * Private data structure for representing the mailbox memory layout. Refer
  * the SCMI specification for more details.
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index 91ea63a..7032267 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -142,7 +142,7 @@
  * Helper function to turn off a CPU power domain and its parent power domains
  * if applicable.
  */
-void css_scp_off(const psci_power_state_t *target_state)
+void css_scp_off(const struct psci_power_state *target_state)
 {
 	int lvl = 0, ret;
 	uint32_t scmi_pwr_state = 0;
@@ -298,7 +298,7 @@
 	css_scp_system_off(SCMI_SYS_PWR_COLD_RESET);
 }
 
-scmi_channel_plat_info_t plat_css_scmi_plat_info = {
+static scmi_channel_plat_info_t plat_css_scmi_plat_info = {
 		.scmi_mbx_mem = CSS_SCMI_PAYLOAD_BASE,
 		.db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF,
 		.db_preserve_mask = 0xfffffffe,
@@ -306,6 +306,28 @@
 		.ring_doorbell = &mhu_ring_doorbell,
 };
 
+static int scmi_ap_core_init(scmi_channel_t *ch)
+{
+#if PROGRAMMABLE_RESET_ADDRESS
+	uint32_t version;
+	int ret;
+
+	ret = scmi_proto_version(ch, SCMI_AP_CORE_PROTO_ID, &version);
+	if (ret != SCMI_E_SUCCESS) {
+		WARN("SCMI AP core protocol version message failed\n");
+		return -1;
+	}
+
+	if (!is_scmi_version_compatible(SCMI_AP_CORE_PROTO_VER, version)) {
+		WARN("SCMI AP core protocol version 0x%x incompatible with driver version 0x%x\n",
+			version, SCMI_AP_CORE_PROTO_VER);
+		return -1;
+	}
+	INFO("SCMI AP core protocol version 0x%x detected\n", version);
+#endif
+	return 0;
+}
+
 void plat_arm_pwrc_setup(void)
 {
 	channel.info = &plat_css_scmi_plat_info;
@@ -315,6 +337,10 @@
 		ERROR("SCMI Initialization failed\n");
 		panic();
 	}
+	if (scmi_ap_core_init(&channel) < 0) {
+		ERROR("SCMI AP core protocol initialization failed\n");
+		panic();
+	}
 }
 
 /******************************************************************************
@@ -386,3 +412,18 @@
 	 */
 	return 0;
 }
+
+#if PROGRAMMABLE_RESET_ADDRESS
+void plat_arm_program_trusted_mailbox(uintptr_t address)
+{
+	int ret;
+
+	assert(scmi_handle);
+	ret = scmi_ap_core_set_reset_addr(scmi_handle, address,
+		SCMI_AP_CORE_LOCK_ATTR);
+	if (ret != SCMI_E_SUCCESS) {
+		ERROR("CSS: Failed to program reset address: %d\n", ret);
+		panic();
+	}
+}
+#endif
diff --git a/plat/arm/css/drivers/scp/css_pm_scpi.c b/plat/arm/css/drivers/scp/css_pm_scpi.c
index 18e71f6..123d54f 100644
--- a/plat/arm/css/drivers/scp/css_pm_scpi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scpi.c
@@ -47,7 +47,7 @@
  * if applicable. Since SCPI doesn't differentiate between OFF and suspend, we
  * call the suspend helper here.
  */
-void css_scp_off(const psci_power_state_t *target_state)
+void css_scp_off(const struct psci_power_state *target_state)
 {
 	css_scp_suspend(target_state);
 }
diff --git a/plat/arm/css/drivers/scp/css_sds.c b/plat/arm/css/drivers/scp/css_sds.c
index a7a51ba..561e97b 100644
--- a/plat/arm/css/drivers/scp/css_sds.c
+++ b/plat/arm/css/drivers/scp/css_sds.c
@@ -11,6 +11,7 @@
 #include <delay_timer.h>
 #include <platform.h>
 #include <stdint.h>
+#include "css_scp.h"
 #include "../sds/sds.h"
 
 int css_scp_boot_image_xfer(void *image, unsigned int image_size)
diff --git a/plat/arm/css/drivers/sds/sds.h b/plat/arm/css/drivers/sds/sds.h
index ff3787d..4aef0df 100644
--- a/plat/arm/css/drivers/sds/sds.h
+++ b/plat/arm/css/drivers/sds/sds.h
@@ -80,7 +80,7 @@
 } sds_access_mode_t;
 
 int sds_init(void);
-int sds_struct_exists(uint32_t structure_id);
+int sds_struct_exists(unsigned int structure_id);
 int sds_struct_read(uint32_t structure_id, unsigned int fld_off, void *data,
 		size_t size, sds_access_mode_t mode);
 int sds_struct_write(uint32_t structure_id, unsigned int fld_off, void *data,
diff --git a/plat/common/plat_bl1_common.c b/plat/common/plat_bl1_common.c
index c5bbe74..6777979 100644
--- a/plat/common/plat_bl1_common.c
+++ b/plat/common/plat_bl1_common.c
@@ -34,7 +34,7 @@
 }
 
 void bl1_plat_set_ep_info(unsigned int image_id,
-		entry_point_info_t *ep_info)
+		struct entry_point_info *ep_info)
 {
 
 }
@@ -48,7 +48,7 @@
  * Following is the default definition that always
  * returns BL2 image details.
  */
-image_desc_t *bl1_plat_get_image_desc(unsigned int image_id)
+struct image_desc *bl1_plat_get_image_desc(unsigned int image_id)
 {
 	static image_desc_t bl2_img_desc = BL2_IMAGE_DESC;
 	return &bl2_img_desc;
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
index 0fbd3f7..8f391df 100644
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ b/plat/mediatek/mt6795/bl31.ld.S
@@ -59,7 +59,7 @@
          * executable.  No RW data from the next section must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 
@@ -161,7 +161,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(PAGE_SIZE);
+        . = ALIGN(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM2
 #endif
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 2fe4e7d..f0a7036 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -116,9 +116,6 @@
 {
 	plat_params_from_bl2_t *plat_params =
 		(plat_params_from_bl2_t *)plat_params_from_bl2;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
-	int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
-#endif
 	image_info_t bl32_img_info = { {0} };
 	uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
 
@@ -227,8 +224,9 @@
 	/* Early platform setup for Tegra SoCs */
 	plat_early_platform_setup();
 
-	INFO("BL3-1: Boot CPU: %s Processor [%lx]\n", (impl == DENVER_IMPL) ?
-		"Denver" : "ARM", read_mpidr());
+	INFO("BL3-1: Boot CPU: %s Processor [%lx]\n",
+	     (((read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK)
+	      == DENVER_IMPL) ? "Denver" : "ARM", read_mpidr());
 }
 
 #ifdef SPD_trusty
diff --git a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
index 5a1854b..991fe6c 100644
--- a/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
+++ b/plat/rockchip/common/pmusram/pmu_sram_cpus_on.S
@@ -12,7 +12,6 @@
 	.macro pmusram_entry_func _name
 	.section .pmusram.entry, "ax"
 	.type \_name, %function
-	.func \_name
 	.cfi_startproc
 	\_name:
 	.endm
diff --git a/plat/rockchip/rk3399/drivers/pmu/plat_pmu_macros.S b/plat/rockchip/rk3399/drivers/pmu/plat_pmu_macros.S
index 70fd9bf..546c09a 100644
--- a/plat/rockchip/rk3399/drivers/pmu/plat_pmu_macros.S
+++ b/plat/rockchip/rk3399/drivers/pmu/plat_pmu_macros.S
@@ -15,7 +15,6 @@
 	.cfi_sections .debug_frame
 	.section .sram.text, "ax"
 	.type \_name, %function
-	.func \_name
 	.cfi_startproc
 	\_name:
 	.endm
diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi3/include/platform_def.h
index 2cd0dff..5b84aa6 100644
--- a/plat/rpi3/include/platform_def.h
+++ b/plat/rpi3/include/platform_def.h
@@ -75,10 +75,10 @@
 #define SEC_SRAM_SIZE			ULL(0x00100000)
 
 #define SEC_DRAM0_BASE			ULL(0x10100000)
-#define SEC_DRAM0_SIZE			ULL(0x00200000)
+#define SEC_DRAM0_SIZE			ULL(0x00B00000)
 
-#define NS_DRAM0_BASE			ULL(0x10300000)
-#define NS_DRAM0_SIZE			ULL(0x00D00000)
+#define NS_DRAM0_BASE			ULL(0x10C00000)
+#define NS_DRAM0_SIZE			ULL(0x00400000)
 /* End of reserved memory */
 
 /*
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index df19705..5990f27 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -20,7 +20,8 @@
 				plat/common/aarch64/platform_mp_stack.S	\
 				plat/rpi3/aarch64/plat_helpers.S	\
 				plat/rpi3/rpi3_bl1_setup.c		\
-				plat/rpi3/rpi3_io_storage.c
+				plat/rpi3/rpi3_io_storage.c		\
+				plat/rpi3/rpi3_mbox.c
 
 BL2_SOURCES		+=	common/desc_image_load.c		\
 				drivers/io/io_fip.c			\
@@ -54,6 +55,26 @@
     TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
 endif
 
+# Platform Makefile target
+# ------------------------
+
+RPI3_BL1_PAD_BIN	:=	${BUILD_PLAT}/bl1_pad.bin
+RPI3_ARMSTUB8_BIN	:=	${BUILD_PLAT}/armstub8.bin
+
+# Add new default target when compiling this platform
+all: armstub
+
+# This target concatenates BL1 and the FIP so that the base addresses match the
+# ones defined in the memory map
+armstub: bl1 fip
+	@echo "  CAT     $@"
+	${Q}cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
+	${Q}truncate --size=131072 ${RPI3_BL1_PAD_BIN}
+	${Q}cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
+	@${ECHO_BLANK_LINE}
+	@echo "Built $@ successfully"
+	@${ECHO_BLANK_LINE}
+
 # Build config flags
 # ------------------
 
diff --git a/plat/rpi3/rpi3_bl1_setup.c b/plat/rpi3/rpi3_bl1_setup.c
index c98715b..39bb332 100644
--- a/plat/rpi3/rpi3_bl1_setup.c
+++ b/plat/rpi3/rpi3_bl1_setup.c
@@ -7,6 +7,7 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <bl_common.h>
+#include <debug.h>
 #include <platform_def.h>
 #include <xlat_mmu_helpers.h>
 #include <xlat_tables_defs.h>
@@ -56,6 +57,39 @@
 
 void bl1_platform_setup(void)
 {
+	uint32_t __unused rev;
+	int __unused rc;
+
+	rc = rpi3_vc_hardware_get_board_revision(&rev);
+
+	if (rc == 0) {
+		const char __unused *model, __unused *info;
+
+		switch (rev) {
+		case 0xA02082:
+			model = "Raspberry Pi 3 Model B";
+			info = "(1GB, Sony, UK)";
+			break;
+		case 0xA22082:
+			model = "Raspberry Pi 3 Model B";
+			info = "(1GB, Embest, China)";
+			break;
+		case 0xA020D3:
+			model = "Raspberry Pi 3 Model B+";
+			info = "(1GB, Sony, UK)";
+			break;
+		default:
+			model = "Unknown";
+			info = "(Unknown)";
+			ERROR("rpi3: Unknown board revision 0x%08x\n", rev);
+			break;
+		}
+
+		NOTICE("rpi3: Detected: %s %s [0x%08x]\n", model, info, rev);
+	} else {
+		ERROR("rpi3: Unable to detect board revision\n");
+	}
+
 	/* Initialise the IO layer and register platform IO devices */
 	plat_rpi3_io_setup();
 }
diff --git a/plat/rpi3/rpi3_common.c b/plat/rpi3/rpi3_common.c
index 65f5e7a..98cf534 100644
--- a/plat/rpi3/rpi3_common.c
+++ b/plat/rpi3/rpi3_common.c
@@ -5,6 +5,7 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
@@ -198,15 +199,21 @@
 
 uint32_t plat_ic_get_pending_interrupt_type(void)
 {
+	ERROR("rpi3: Interrupt routed to EL3.\n");
 	return INTR_TYPE_INVAL;
 }
 
-uint32_t plat_interrupt_type_to_line(uint32_t type,
-				     uint32_t security_state)
+uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
 {
-	/* It is not expected to receive an interrupt route to EL3.
-	 * Hence panic() to flag error.
-	 */
-	ERROR("Interrupt not expected to be routed to EL3");
-	panic();
+	assert((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_EL3) ||
+	       (type == INTR_TYPE_NS));
+
+	assert(sec_state_is_valid(security_state));
+
+	/* Non-secure interrupts are signalled on the IRQ line always. */
+	if (type == INTR_TYPE_NS)
+		return __builtin_ctz(SCR_IRQ_BIT);
+
+	/* Secure interrupts are signalled on the FIQ line always. */
+	return  __builtin_ctz(SCR_FIQ_BIT);
 }
diff --git a/plat/rpi3/rpi3_hw.h b/plat/rpi3/rpi3_hw.h
index 70272e0..a83a0ad 100644
--- a/plat/rpi3/rpi3_hw.h
+++ b/plat/rpi3/rpi3_hw.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,11 +17,25 @@
 #define RPI3_IO_SIZE			ULL(0x01000000)
 
 /*
- * Serial port (called 'Mini UART' in the BCM docucmentation).
+ * ARM <-> VideoCore mailboxes
  */
-#define RPI3_IO_MINI_UART_OFFSET	ULL(0x00215040)
-#define RPI3_MINI_UART_BASE		(RPI3_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
-#define RPI3_MINI_UART_CLK_IN_HZ	ULL(500000000)
+#define RPI3_MBOX_OFFSET		ULL(0x0000B880)
+#define RPI3_MBOX_BASE			(RPI3_IO_BASE + RPI3_MBOX_OFFSET)
+/* VideoCore -> ARM */
+#define RPI3_MBOX0_READ_OFFSET		ULL(0x00000000)
+#define RPI3_MBOX0_PEEK_OFFSET		ULL(0x00000010)
+#define RPI3_MBOX0_SENDER_OFFSET	ULL(0x00000014)
+#define RPI3_MBOX0_STATUS_OFFSET	ULL(0x00000018)
+#define RPI3_MBOX0_CONFIG_OFFSET	ULL(0x0000001C)
+/* ARM -> VideoCore */
+#define RPI3_MBOX1_WRITE_OFFSET		ULL(0x00000020)
+#define RPI3_MBOX1_PEEK_OFFSET		ULL(0x00000030)
+#define RPI3_MBOX1_SENDER_OFFSET	ULL(0x00000034)
+#define RPI3_MBOX1_STATUS_OFFSET	ULL(0x00000038)
+#define RPI3_MBOX1_CONFIG_OFFSET	ULL(0x0000003C)
+/* Mailbox status constants */
+#define RPI3_MBOX_STATUS_FULL_MASK	U(0x80000000) /* Set if full */
+#define RPI3_MBOX_STATUS_EMPTY_MASK	U(0x40000000) /* Set if empty */
 
 /*
  * Power management, reset controller, watchdog.
@@ -30,11 +44,26 @@
 #define RPI3_PM_BASE			(RPI3_IO_BASE + RPI3_IO_PM_OFFSET)
 /* Registers on top of RPI3_PM_BASE. */
 #define RPI3_PM_RSTC_OFFSET		ULL(0x0000001C)
+#define RPI3_PM_RSTS_OFFSET		ULL(0x00000020)
 #define RPI3_PM_WDOG_OFFSET		ULL(0x00000024)
 /* Watchdog constants */
-#define RPI3_PM_PASSWORD		ULL(0x5A000000)
-#define RPI3_PM_RSTC_WRCFG_MASK		ULL(0x00000030)
-#define RPI3_PM_RSTC_WRCFG_FULL_RESET	ULL(0x00000020)
+#define RPI3_PM_PASSWORD		U(0x5A000000)
+#define RPI3_PM_RSTC_WRCFG_MASK		U(0x00000030)
+#define RPI3_PM_RSTC_WRCFG_FULL_RESET	U(0x00000020)
+/*
+ * The RSTS register is used by the VideoCore firmware when booting the
+ * Raspberry Pi to know which partition to boot from. The partition value is
+ * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
+ * to indicate halt.
+ */
+#define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
+
+/*
+ * Serial port (called 'Mini UART' in the BCM docucmentation).
+ */
+#define RPI3_IO_MINI_UART_OFFSET	ULL(0x00215040)
+#define RPI3_MINI_UART_BASE		(RPI3_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
+#define RPI3_MINI_UART_CLK_IN_HZ	ULL(500000000)
 
 /*
  * Local interrupt controller
diff --git a/plat/rpi3/rpi3_mbox.c b/plat/rpi3/rpi3_mbox.c
new file mode 100644
index 0000000..77e17af
--- /dev/null
+++ b/plat/rpi3/rpi3_mbox.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+#include "rpi3_hw.h"
+
+/* This struct must be aligned to 16 bytes */
+typedef struct __packed __aligned(16) rpi3_mbox_request {
+	uint32_t	size; /* Buffer size in bytes */
+	uint32_t	code; /* Request/response code */
+	uint32_t	tags[0];
+} rpi3_mbox_request_t;
+
+#define RPI3_MBOX_BUFFER_SIZE		U(256)
+static uint8_t __aligned(16) rpi3_mbox_buffer[RPI3_MBOX_BUFFER_SIZE];
+
+/* Constants to perform a request/check the status of a request. */
+#define RPI3_MBOX_PROCESS_REQUEST	U(0x00000000)
+#define RPI3_MBOX_REQUEST_SUCCESSFUL	U(0x80000000)
+#define RPI3_MBOX_REQUEST_ERROR		U(0x80000001)
+
+/* Command constants */
+#define RPI3_TAG_HARDWARE_GET_BOARD_REVISION	U(0x00010002)
+#define RPI3_TAG_END				U(0x00000000)
+
+#define RPI3_TAG_REQUEST		U(0x00000000)
+#define RPI3_TAG_IS_RESPONSE		U(0x80000000) /* Set if response */
+#define RPI3_TAG_RESPONSE_LENGTH_MASK	U(0x7FFFFFFF)
+
+#define RPI3_CHANNEL_ARM_TO_VC		U(0x8)
+#define RPI3_CHANNEL_MASK		U(0xF)
+
+#define RPI3_MAILBOX_MAX_RETRIES	U(1000000)
+
+/*******************************************************************************
+ * Helpers to send requests to the VideoCore using the mailboxes.
+ ******************************************************************************/
+static void rpi3_vc_mailbox_request_send(void)
+{
+	uint32_t st, data;
+	uintptr_t resp_addr, addr;
+	unsigned int retries;
+
+	/* This is the location of the request buffer */
+	addr = (uintptr_t) &rpi3_mbox_buffer;
+
+	/* Make sure that the changes are seen by the VideoCore */
+	flush_dcache_range(addr, RPI3_MBOX_BUFFER_SIZE);
+
+	/* Wait until the outbound mailbox is empty */
+	retries = 0U;
+
+	do {
+		st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX1_STATUS_OFFSET);
+
+		retries++;
+		if (retries == RPI3_MAILBOX_MAX_RETRIES) {
+			ERROR("rpi3: mbox: Send request timeout\n");
+			return;
+		}
+
+	} while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) == 0U);
+
+	/* Send base address of this message to start request */
+	mmio_write_32(RPI3_MBOX_BASE + RPI3_MBOX1_WRITE_OFFSET,
+		      RPI3_CHANNEL_ARM_TO_VC | (uint32_t) addr);
+
+	/* Wait until the inbound mailbox isn't empty */
+	retries = 0U;
+
+	do {
+		st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_STATUS_OFFSET);
+
+		retries++;
+		if (retries == RPI3_MAILBOX_MAX_RETRIES) {
+			ERROR("rpi3: mbox: Receive response timeout\n");
+			return;
+		}
+
+	} while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) != 0U);
+
+	/* Get location and channel */
+	data = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_READ_OFFSET);
+
+	if ((data & RPI3_CHANNEL_MASK) != RPI3_CHANNEL_ARM_TO_VC) {
+		ERROR("rpi3: mbox: Wrong channel: 0x%08x\n", data);
+		panic();
+	}
+
+	resp_addr = (uintptr_t)(data & ~RPI3_CHANNEL_MASK);
+	if (addr != resp_addr) {
+		ERROR("rpi3: mbox: Unexpected address: 0x%08x\n", data);
+		panic();
+	}
+
+	/* Make sure that the data seen by the CPU is up to date */
+	inv_dcache_range(addr, RPI3_MBOX_BUFFER_SIZE);
+}
+
+/*******************************************************************************
+ * Request board revision. Returns the revision and 0 on success, -1 on error.
+ ******************************************************************************/
+int rpi3_vc_hardware_get_board_revision(uint32_t *revision)
+{
+	uint32_t tag_request_size = sizeof(uint32_t);
+	rpi3_mbox_request_t *req = (rpi3_mbox_request_t *) rpi3_mbox_buffer;
+
+	assert(revision != NULL);
+
+	VERBOSE("rpi3: mbox: Sending request at %p\n", (void *)req);
+
+	req->size = sizeof(rpi3_mbox_buffer);
+	req->code = RPI3_MBOX_PROCESS_REQUEST;
+
+	req->tags[0] = RPI3_TAG_HARDWARE_GET_BOARD_REVISION;
+	req->tags[1] = tag_request_size; /* Space available for the response */
+	req->tags[2] = RPI3_TAG_REQUEST;
+	req->tags[3] = 0; /* Placeholder for the response */
+
+	req->tags[4] = RPI3_TAG_END;
+
+	rpi3_vc_mailbox_request_send();
+
+	if (req->code != RPI3_MBOX_REQUEST_SUCCESSFUL) {
+		ERROR("rpi3: mbox: Code = 0x%08x\n", req->code);
+		return -1;
+	}
+
+	if (req->tags[2] != (RPI3_TAG_IS_RESPONSE | tag_request_size)) {
+		ERROR("rpi3: mbox: get board revision failed (0x%08x)\n",
+		      req->tags[2]);
+		return -1;
+	}
+
+	*revision = req->tags[3];
+
+	return 0;
+}
diff --git a/plat/rpi3/rpi3_pm.c b/plat/rpi3/rpi3_pm.c
index 1d067fb..9694858 100644
--- a/plat/rpi3/rpi3_pm.c
+++ b/plat/rpi3/rpi3_pm.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -150,41 +150,61 @@
 }
 
 /*******************************************************************************
- * Platform handler to reboot the system
+ * Platform handlers for system reset and system off.
  ******************************************************************************/
-#define RESET_TIMEOUT	10
 
-static void __dead2 rpi3_system_reset(void)
-{
-	/* Setup watchdog for reset */
+/* 10 ticks (Watchdog timer = Timer clock / 16) */
+#define RESET_TIMEOUT	U(10)
 
-	static const uintptr_t base = RPI3_PM_BASE;
+static void __dead2 rpi3_watchdog_reset(void)
+{
 	uint32_t rstc;
 
-	INFO("rpi3: PSCI System Reset: invoking watchdog reset\n");
-
 	console_flush();
 
-	rstc = mmio_read_32(base + RPI3_PM_RSTC_OFFSET);
-	rstc &= ~RPI3_PM_RSTC_WRCFG_MASK;
-	rstc |= RPI3_PM_RSTC_WRCFG_FULL_RESET;
-
-	dmbst();
+	dsbsy();
+	isb();
 
-	/*
-	 * Watchdog timer = Timer clock / 16
-	 * Password (31:16) | Value (11:0)
-	 */
-	mmio_write_32(base + RPI3_PM_WDOG_OFFSET,
+	mmio_write_32(RPI3_PM_BASE + RPI3_PM_WDOG_OFFSET,
 		      RPI3_PM_PASSWORD | RESET_TIMEOUT);
-	mmio_write_32(base + RPI3_PM_RSTC_OFFSET,
-		      RPI3_PM_PASSWORD | rstc);
+
+	rstc = mmio_read_32(RPI3_PM_BASE + RPI3_PM_RSTC_OFFSET);
+	rstc &= ~RPI3_PM_RSTC_WRCFG_MASK;
+	rstc |= RPI3_PM_PASSWORD | RPI3_PM_RSTC_WRCFG_FULL_RESET;
+	mmio_write_32(RPI3_PM_BASE + RPI3_PM_RSTC_OFFSET, rstc);
 
 	for (;;) {
 		wfi();
 	}
 }
 
+static void __dead2 rpi3_system_reset(void)
+{
+	INFO("rpi3: PSCI_SYSTEM_RESET: Invoking watchdog reset\n");
+
+	rpi3_watchdog_reset();
+}
+
+static void __dead2 rpi3_system_off(void)
+{
+	uint32_t rsts;
+
+	INFO("rpi3: PSCI_SYSTEM_OFF: Invoking watchdog reset\n");
+
+	/*
+	 * This function doesn't actually make the Raspberry Pi turn itself off,
+	 * the hardware doesn't allow it. It simply reboots it and the RSTS
+	 * value tells the bootcode.bin firmware not to continue the regular
+	 * bootflow and to stay in a low power mode.
+	 */
+
+	rsts = mmio_read_32(RPI3_PM_BASE + RPI3_PM_RSTS_OFFSET);
+	rsts |= RPI3_PM_PASSWORD | RPI3_PM_RSTS_WRCFG_HALT;
+	mmio_write_32(RPI3_PM_BASE + RPI3_PM_RSTS_OFFSET, rsts);
+
+	rpi3_watchdog_reset();
+}
+
 /*******************************************************************************
  * Platform handlers and setup function.
  ******************************************************************************/
@@ -192,6 +212,7 @@
 	.cpu_standby = rpi3_cpu_standby,
 	.pwr_domain_on = rpi3_pwr_domain_on,
 	.pwr_domain_on_finish = rpi3_pwr_domain_on_finish,
+	.system_off = rpi3_system_off,
 	.system_reset = rpi3_system_reset,
 	.validate_power_state = rpi3_validate_power_state,
 };
diff --git a/plat/rpi3/rpi3_private.h b/plat/rpi3/rpi3_private.h
index a9fbfe4..9d1744e 100644
--- a/plat/rpi3/rpi3_private.h
+++ b/plat/rpi3/rpi3_private.h
@@ -33,4 +33,7 @@
 /* IO storage utility functions */
 void plat_rpi3_io_setup(void);
 
+/* VideoCore firmware commands */
+int rpi3_vc_hardware_get_board_revision(uint32_t *revision);
+
 #endif /*__RPI3_PRIVATE_H__ */
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 01ec2a2..59d6ed2 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -34,7 +34,7 @@
  * Address of the entrypoint vector table in OPTEE. It is
  * initialised once on the primary core after a cold boot.
  ******************************************************************************/
-optee_vectors_t *optee_vector_table;
+struct optee_vectors *optee_vector_table;
 
 /*******************************************************************************
  * Array to keep track of per-cpu OPTEE state
diff --git a/services/spd/opteed/opteed_private.h b/services/spd/opteed/opteed_private.h
index b77b6d3..a5f0a41 100644
--- a/services/spd/opteed/opteed_private.h
+++ b/services/spd/opteed/opteed_private.h
@@ -144,7 +144,7 @@
 void __dead2 opteed_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
 uint64_t opteed_synchronous_sp_entry(optee_context_t *optee_ctx);
 void __dead2 opteed_synchronous_sp_exit(optee_context_t *optee_ctx, uint64_t ret);
-void opteed_init_optee_ep_state(struct entry_point_info *optee_ep,
+void opteed_init_optee_ep_state(struct entry_point_info *optee_entry_point,
 				uint32_t rw,
 				uint64_t pc,
 				uint64_t pageable_part,
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index d6d092d..28afc1d 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -932,43 +932,43 @@
 	case SDEI_VERSION:
 		SDEI_LOG("> VER\n");
 		ret = sdei_version();
-		SDEI_LOG("< VER:%lx\n", ret);
+		SDEI_LOG("< VER:%llx\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_REGISTER:
 		x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
-		SDEI_LOG("> REG(n:%d e:%lx a:%lx f:%x m:%lx)\n", (int) x1,
+		SDEI_LOG("> REG(n:%d e:%llx a:%llx f:%x m:%llx)\n", (int) x1,
 				x2, x3, (int) x4, x5);
 		ret = sdei_event_register(x1, x2, x3, x4, x5);
-		SDEI_LOG("< REG:%ld\n", ret);
+		SDEI_LOG("< REG:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_ENABLE:
 		SDEI_LOG("> ENABLE(n:%d)\n", (int) x1);
 		ret = sdei_event_enable(x1);
-		SDEI_LOG("< ENABLE:%ld\n", ret);
+		SDEI_LOG("< ENABLE:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_DISABLE:
 		SDEI_LOG("> DISABLE(n:%d)\n", (int) x1);
 		ret = sdei_event_disable(x1);
-		SDEI_LOG("< DISABLE:%ld\n", ret);
+		SDEI_LOG("< DISABLE:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_CONTEXT:
 		SDEI_LOG("> CTX(p:%d):%lx\n", (int) x1, read_mpidr_el1());
 		ret = sdei_event_context(handle, x1);
-		SDEI_LOG("< CTX:%ld\n", ret);
+		SDEI_LOG("< CTX:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_COMPLETE_AND_RESUME:
 		resume = 1;
 
 	case SDEI_EVENT_COMPLETE:
-		SDEI_LOG("> COMPLETE(r:%d sta/ep:%lx):%lx\n", resume, x1,
+		SDEI_LOG("> COMPLETE(r:%d sta/ep:%llx):%lx\n", resume, x1,
 				read_mpidr_el1());
 		ret = sdei_event_complete(resume, x1);
-		SDEI_LOG("< COMPLETE:%lx\n", ret);
+		SDEI_LOG("< COMPLETE:%llx\n", ret);
 
 		/*
 		 * Set error code only if the call failed. If the call
@@ -985,19 +985,19 @@
 	case SDEI_EVENT_STATUS:
 		SDEI_LOG("> STAT(n:%d)\n", (int) x1);
 		ret = sdei_event_status(x1);
-		SDEI_LOG("< STAT:%ld\n", ret);
+		SDEI_LOG("< STAT:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_GET_INFO:
 		SDEI_LOG("> INFO(n:%d, %d)\n", (int) x1, (int) x2);
 		ret = sdei_event_get_info(x1, x2);
-		SDEI_LOG("< INFO:%ld\n", ret);
+		SDEI_LOG("< INFO:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_UNREGISTER:
 		SDEI_LOG("> UNREG(n:%d)\n", (int) x1);
 		ret = sdei_event_unregister(x1);
-		SDEI_LOG("< UNREG:%ld\n", ret);
+		SDEI_LOG("< UNREG:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_PE_UNMASK:
@@ -1009,49 +1009,49 @@
 	case SDEI_PE_MASK:
 		SDEI_LOG("> MASK:%lx\n", read_mpidr_el1());
 		ret = sdei_pe_mask();
-		SDEI_LOG("< MASK:%ld\n", ret);
+		SDEI_LOG("< MASK:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_INTERRUPT_BIND:
 		SDEI_LOG("> BIND(%d)\n", (int) x1);
 		ret = sdei_interrupt_bind(x1);
-		SDEI_LOG("< BIND:%ld\n", ret);
+		SDEI_LOG("< BIND:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_INTERRUPT_RELEASE:
 		SDEI_LOG("> REL(%d)\n", (int) x1);
 		ret = sdei_interrupt_release(x1);
-		SDEI_LOG("< REL:%ld\n", ret);
+		SDEI_LOG("< REL:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_SHARED_RESET:
 		SDEI_LOG("> S_RESET():%lx\n", read_mpidr_el1());
 		ret = sdei_shared_reset();
-		SDEI_LOG("< S_RESET:%ld\n", ret);
+		SDEI_LOG("< S_RESET:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_PRIVATE_RESET:
 		SDEI_LOG("> P_RESET():%lx\n", read_mpidr_el1());
 		ret = sdei_private_reset();
-		SDEI_LOG("< P_RESET:%ld\n", ret);
+		SDEI_LOG("< P_RESET:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_ROUTING_SET:
-		SDEI_LOG("> ROUTE_SET(n:%d f:%lx aff:%lx)\n", (int) x1, x2, x3);
+		SDEI_LOG("> ROUTE_SET(n:%d f:%llx aff:%llx)\n", (int) x1, x2, x3);
 		ret = sdei_event_routing_set(x1, x2, x3);
-		SDEI_LOG("< ROUTE_SET:%ld\n", ret);
+		SDEI_LOG("< ROUTE_SET:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_FEATURES:
-		SDEI_LOG("> FTRS(f:%lx)\n", x1);
+		SDEI_LOG("> FTRS(f:%llx)\n", x1);
 		ret = sdei_features(x1);
-		SDEI_LOG("< FTRS:%lx\n", ret);
+		SDEI_LOG("< FTRS:%llx\n", ret);
 		SMC_RET1(handle, ret);
 
 	case SDEI_EVENT_SIGNAL:
-		SDEI_LOG("> SIGNAL(e:%lx t:%lx)\n", x1, x2);
+		SDEI_LOG("> SIGNAL(e:%llx t:%llx)\n", x1, x2);
 		ret = sdei_signal(x1, x2);
-		SDEI_LOG("< SIGNAL:%ld\n", ret);
+		SDEI_LOG("< SIGNAL:%lld\n", ret);
 		SMC_RET1(handle, ret);
 
 	default:
diff --git a/services/std_svc/spm/aarch64/spm_shim_exceptions.S b/services/std_svc/spm/aarch64/spm_shim_exceptions.S
index 218245d..9c218df 100644
--- a/services/std_svc/spm/aarch64/spm_shim_exceptions.S
+++ b/services/std_svc/spm/aarch64/spm_shim_exceptions.S
@@ -23,19 +23,19 @@
 	 */
 vector_entry SynchronousExceptionSP0, .spm_shim_exceptions
 	b	.
-	check_vector_size SynchronousExceptionSP0
+end_vector_entry SynchronousExceptionSP0
 
 vector_entry IrqSP0, .spm_shim_exceptions
 	b	.
-	check_vector_size IrqSP0
+end_vector_entry IrqSP0
 
 vector_entry FiqSP0, .spm_shim_exceptions
 	b	.
-	check_vector_size FiqSP0
+end_vector_entry FiqSP0
 
 vector_entry SErrorSP0, .spm_shim_exceptions
 	b	.
-	check_vector_size SErrorSP0
+end_vector_entry SErrorSP0
 
 	/* -----------------------------------------------------
 	 * Current EL with SPx: 0x200 - 0x400
@@ -43,19 +43,19 @@
 	 */
 vector_entry SynchronousExceptionSPx, .spm_shim_exceptions
 	b	.
-	check_vector_size SynchronousExceptionSPx
+end_vector_entry SynchronousExceptionSPx
 
 vector_entry IrqSPx, .spm_shim_exceptions
 	b	.
-	check_vector_size IrqSPx
+end_vector_entry IrqSPx
 
 vector_entry FiqSPx, .spm_shim_exceptions
 	b	.
-	check_vector_size FiqSPx
+end_vector_entry FiqSPx
 
 vector_entry SErrorSPx, .spm_shim_exceptions
 	b	.
-	check_vector_size SErrorSPx
+end_vector_entry SErrorSPx
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch64 : 0x400 - 0x600. No exceptions
@@ -93,19 +93,19 @@
 handle_sys_trap:
 panic:
 	b	panic
-	check_vector_size SynchronousExceptionA64
+end_vector_entry SynchronousExceptionA64
 
 vector_entry IrqA64, .spm_shim_exceptions
 	b	.
-	check_vector_size IrqA64
+end_vector_entry IrqA64
 
 vector_entry FiqA64, .spm_shim_exceptions
 	b	.
-	check_vector_size FiqA64
+end_vector_entry FiqA64
 
 vector_entry SErrorA64, .spm_shim_exceptions
 	b	.
-	check_vector_size SErrorA64
+end_vector_entry SErrorA64
 
 	/* -----------------------------------------------------
 	 * Lower EL using AArch32 : 0x600 - 0x800
@@ -113,16 +113,16 @@
 	 */
 vector_entry SynchronousExceptionA32, .spm_shim_exceptions
 	b	.
-	check_vector_size SynchronousExceptionA32
+end_vector_entry SynchronousExceptionA32
 
 vector_entry IrqA32, .spm_shim_exceptions
 	b	.
-	check_vector_size IrqA32
+end_vector_entry IrqA32
 
 vector_entry FiqA32, .spm_shim_exceptions
 	b	.
-	check_vector_size FiqA32
+end_vector_entry FiqA32
 
 vector_entry SErrorA32, .spm_shim_exceptions
 	b	.
-	check_vector_size SErrorA32
+end_vector_entry SErrorA32