Merge pull request #1178 from davidcunado-arm/dc/enable_sve

Enable SVE for Non-secure world
diff --git a/Makefile b/Makefile
index 324eb8a..c0fddcf 100644
--- a/Makefile
+++ b/Makefile
@@ -383,6 +383,17 @@
         NEED_SCP_BL2		:=	yes
 endif
 
+# For AArch32, BL31 is not currently supported.
+ifneq (${ARCH},aarch32)
+    ifdef BL31_SOURCES
+        # When booting an EL3 payload, there is no need to compile the BL31 image nor
+        # put it in the FIP.
+        ifndef EL3_PAYLOAD_BASE
+            NEED_BL31 := yes
+        endif
+    endif
+endif
+
 # Process TBB related flags
 ifneq (${GENERATE_COT},0)
         # Common cert_create options
@@ -434,17 +445,11 @@
 include bl2u/bl2u.mk
 endif
 
-# For AArch32, BL31 is not currently supported.
-ifneq (${ARCH},aarch32)
+ifeq (${NEED_BL31},yes)
 ifdef BL31_SOURCES
-# When booting an EL3 payload, there is no need to compile the BL31 image nor
-# put it in the FIP.
-ifndef EL3_PAYLOAD_BASE
-NEED_BL31 := yes
 include bl31/bl31.mk
 endif
 endif
-endif
 
 ################################################################################
 # Build options checks
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index 2c453bd..e4c454b 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -5,6 +5,7 @@
  */
 
 #include <platform_def.h>
+#include <xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
@@ -18,7 +19,7 @@
 SECTIONS
 {
     . = BL1_RO_BASE;
-    ASSERT(. == ALIGN(4096),
+    ASSERT(. == ALIGN(PAGE_SIZE),
            "BL1_RO_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
@@ -27,7 +28,7 @@
         *bl1_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
      } >ROM
 
@@ -88,7 +89,7 @@
            "cpu_ops not defined for this platform.")
 
     . = BL1_RW_BASE;
-    ASSERT(BL1_RW_BASE == ALIGN(4096),
+    ASSERT(BL1_RW_BASE == ALIGN(PAGE_SIZE),
            "BL1_RW_BASE address is not aligned on a page boundary.")
 
     /*
@@ -141,7 +142,7 @@
      * are not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(4096) {
+    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
@@ -150,7 +151,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index f3ab706..4fe78f9 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -5,6 +5,7 @@
  */
 
 #include <platform_def.h>
+#include <xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
@@ -18,7 +19,7 @@
 SECTIONS
 {
     . = BL2_BASE;
-    ASSERT(. == ALIGN(4096),
+    ASSERT(. == ALIGN(PAGE_SIZE),
            "BL2_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
@@ -27,7 +28,7 @@
         *bl2_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
      } >RAM
 
@@ -41,7 +42,7 @@
         KEEP(*(.img_parser_lib_descs))
         __PARSER_LIB_DESCS_END__ = .;
 
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -64,7 +65,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(4096);
+        . = NEXT(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -120,7 +121,7 @@
      * are not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(4096) {
+    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
@@ -129,7 +130,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index efae293..da58717 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -5,6 +5,7 @@
  */
 
 #include <platform_def.h>
+#include <xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
@@ -18,7 +19,7 @@
 SECTIONS
 {
     . = BL2U_BASE;
-    ASSERT(. == ALIGN(4096),
+    ASSERT(. == ALIGN(PAGE_SIZE),
            "BL2U_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
@@ -27,14 +28,14 @@
         *bl2u_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
      } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(.rodata*)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -51,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(4096);
+        . = NEXT(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -107,7 +108,7 @@
      * are not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(4096) {
+    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
@@ -116,7 +117,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index 7f442d0..dd046c4 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -5,6 +5,7 @@
  */
 
 #include <platform_def.h>
+#include <xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
@@ -22,7 +23,7 @@
 SECTIONS
 {
     . = BL31_BASE;
-    ASSERT(. == ALIGN(4096),
+    ASSERT(. == ALIGN(PAGE_SIZE),
            "BL31_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
@@ -31,7 +32,7 @@
         *bl31_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
     } >RAM
 
@@ -66,7 +67,7 @@
         . = ALIGN(8);
 #include <pubsub_events.h>
 
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -110,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(4096);
+        . = NEXT(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -127,10 +128,10 @@
      * There's no need to include this into the RO section of BL31 because it
      * doesn't need to be accessed by BL31.
      */
-    spm_shim_exceptions : ALIGN(4096) {
+    spm_shim_exceptions : ALIGN(PAGE_SIZE) {
         __SPM_SHIM_EXCEPTIONS_START__ = .;
         *(.spm_shim_exceptions)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __SPM_SHIM_EXCEPTIONS_END__ = .;
     } >RAM
 #endif
@@ -223,7 +224,7 @@
         __SP_IMAGE_XLAT_TABLES_START__ = .;
         *secure_partition*.o(xlat_table)
         /* Make sure that the rest of the page is empty. */
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __SP_IMAGE_XLAT_TABLES_END__ = .;
 #endif
         *(xlat_table)
@@ -236,7 +237,7 @@
      * are not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(4096) {
+    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         /*
          * Bakery locks are stored in coherent memory
@@ -251,7 +252,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(4096);
+        . = NEXT(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 fc44d52..e798a0d 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -5,6 +5,7 @@
  */
 
 #include <platform_def.h>
+#include <xlat_tables_defs.h>
 
 OUTPUT_FORMAT(elf32-littlearm)
 OUTPUT_ARCH(arm)
@@ -18,7 +19,7 @@
 SECTIONS
 {
     . = BL32_BASE;
-   ASSERT(. == ALIGN(4096),
+   ASSERT(. == ALIGN(PAGE_SIZE),
           "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
@@ -27,7 +28,7 @@
         *entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
     } >RAM
 
@@ -54,7 +55,7 @@
         . = ALIGN(8);
 #include <pubsub_events.h>
 
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -91,7 +92,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(4096);
+        . = NEXT(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -110,6 +111,10 @@
         __DATA_END__ = .;
     } >RAM
 
+#ifdef BL32_PROGBITS_LIMIT
+    ASSERT(. <= BL32_PROGBITS_LIMIT, "BL32 progbits has exceeded its limit.")
+#endif
+
     stacks (NOLOAD) : {
         __STACKS_START__ = .;
         *(tzfw_normal_stacks)
@@ -186,7 +191,7 @@
      * are not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(4096) {
+    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         /*
          * Bakery locks are stored in coherent memory
@@ -201,7 +206,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 
diff --git a/bl32/tsp/tsp.ld.S b/bl32/tsp/tsp.ld.S
index 2b672ef..d256b46 100644
--- a/bl32/tsp/tsp.ld.S
+++ b/bl32/tsp/tsp.ld.S
@@ -5,6 +5,7 @@
  */
 
 #include <platform_def.h>
+#include <xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
@@ -19,7 +20,7 @@
 SECTIONS
 {
     . = BL32_BASE;
-    ASSERT(. == ALIGN(4096),
+    ASSERT(. == ALIGN(PAGE_SIZE),
            "BL32_BASE address is not aligned on a page boundary.")
 
 #if SEPARATE_CODE_AND_RODATA
@@ -28,14 +29,14 @@
         *tsp_entrypoint.o(.text*)
         *(.text*)
         *(.vectors)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
     } >RAM
 
     .rodata . : {
         __RODATA_START__ = .;
         *(.rodata*)
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
     } >RAM
 #else
@@ -51,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(4096);
+        . = NEXT(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 #endif
@@ -106,7 +107,7 @@
      * are not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(4096) {
+    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         *(tzfw_coherent_mem)
         __COHERENT_RAM_END_UNALIGNED__ = .;
@@ -115,7 +116,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM
 #endif
diff --git a/common/bl_common.c b/common/bl_common.c
index e4473ed..b0d1bfa 100644
--- a/common/bl_common.c
+++ b/common/bl_common.c
@@ -200,14 +200,14 @@
 #if LOAD_IMAGE_V2
 
 /*******************************************************************************
- * Generic function to load an image at a specific address given
+ * Internal function to load an image at a specific address given
  * an image ID and extents of free memory.
  *
  * If the load is successful then the image information is updated.
  *
  * Returns 0 on success, a negative error code otherwise.
  ******************************************************************************/
-int load_image(unsigned int image_id, image_info_t *image_data)
+static int load_image(unsigned int image_id, image_info_t *image_data)
 {
 	uintptr_t dev_handle;
 	uintptr_t image_handle;
@@ -266,17 +266,6 @@
 		goto exit;
 	}
 
-#if !TRUSTED_BOARD_BOOT
-	/*
-	 * File has been successfully loaded.
-	 * Flush the image to main memory so that it can be executed later by
-	 * any CPU, regardless of cache and MMU state.
-	 * When TBB is enabled the image is flushed later, after image
-	 * authentication.
-	 */
-	flush_dcache_range(image_base, image_size);
-#endif /* TRUSTED_BOARD_BOOT */
-
 	INFO("Image id=%u loaded: %p - %p\n", image_id, (void *) image_base,
 	     (void *) (image_base + image_size));
 
@@ -329,18 +318,19 @@
 				   image_data->image_size);
 		return -EAUTH;
 	}
+#endif /* TRUSTED_BOARD_BOOT */
 
 	/*
-	 * File has been successfully loaded and authenticated.
 	 * Flush the image to main memory so that it can be executed later by
-	 * any CPU, regardless of cache and MMU state.
-	 * Do it only for child images, not for the parents (certificates).
+	 * any CPU, regardless of cache and MMU state. If TBB is enabled, then
+	 * the file has been successfully loaded and authenticated and flush
+	 * only for child images, not for the parents (certificates).
 	 */
 	if (!is_parent_image) {
 		flush_dcache_range(image_data->image_base,
 				   image_data->image_size);
 	}
-#endif /* TRUSTED_BOARD_BOOT */
+
 
 	return 0;
 }
diff --git a/docs/plat/poplar.rst b/docs/plat/poplar.rst
index d7f1fe0..0129478 100644
--- a/docs/plat/poplar.rst
+++ b/docs/plat/poplar.rst
@@ -11,6 +11,8 @@
 It supports a premium user experience with up to H.265 HEVC decoding of 4K
 video at 60 frames per second.
 
+::
+
     SOC Hisilicon Hi3798CV200
     CPU Quad-core ARM Cortex-A53 64 bit
     DRAM DDR3/3L/4 SDRAM interface, maximum 32-bit data width 2 GB
@@ -28,6 +30,8 @@
 binary whose main role is to change the processor state to 64bit mode. This
 must  happen prior invoking the arm trusted  firmware:
 
+::
+
     l-loader --> arm_trusted_firmware --> u-boot
 
 How to build
@@ -54,10 +58,16 @@
 -  Prepare the AARCH64 toolchain.
 
 -  Build u-boot using poplar_defconfig
+
+.. code:: bash
+
        make CROSS_COMPILE=aarch64-linux-gnu- poplar_defconfig
        make CROSS_COMPILE=aarch64-linux-gnu-
 
 -  Build atf providing the previously generated u-boot.bin as the BL33 image
+
+.. code:: bash
+
        make CROSS_COMPILE=aarch64-linux-gnu-  all fip SPD=none PLAT=poplar
        BL33=u-boot.bin
 
@@ -81,85 +91,86 @@
 Boot trace
 ==========
 
-Bootrom start
-Boot Media: eMMC
-Decrypt auxiliary code ...OK
+::
 
-lsadc voltage min: 000000FE, max: 000000FF, aver: 000000FE, index: 00000000
+    Bootrom start
+    Boot Media: eMMC
+    Decrypt auxiliary code ...OK
 
-Entry boot auxiliary code
+    lsadc voltage min: 000000FE, max: 000000FF, aver: 000000FE, index: 00000000
 
-Auxiliary code - v1.00
-DDR code - V1.1.2 20160205
-Build: Mar 24 2016 - 17:09:44
-Reg Version:  v134
-Reg Time:     2016/03/18 09:44:55
-Reg Name:     hi3798cv2dmb_hi3798cv200_ddr3_2gbyte_8bitx4_4layers.reg
+    Entry boot auxiliary code
 
-Boot auxiliary code success
-Bootrom success
+    Auxiliary code - v1.00
+    DDR code - V1.1.2 20160205
+    Build: Mar 24 2016 - 17:09:44
+    Reg Version:  v134
+    Reg Time:     2016/03/18 09:44:55
+    Reg Name:     hi3798cv2dmb_hi3798cv200_ddr3_2gbyte_8bitx4_4layers.reg
 
-LOADER:  Switched to aarch64 mode
-LOADER:  Entering ARM TRUSTED FIRMWARE
-LOADER:  CPU0 executes at 0x000ce000
+    Boot auxiliary code success
+    Bootrom success
 
-INFO:    BL1: 0xe1000 - 0xe7000 [size = 24576]
-NOTICE:  Booting Trusted Firmware
-NOTICE:  BL1: v1.3(debug):v1.3-372-g1ba9c60
-NOTICE:  BL1: Built : 17:51:33, Apr 30 2017
-INFO:    BL1: RAM 0xe1000 - 0xe7000
-INFO:    BL1: Loading BL2
-INFO:    Loading image id=1 at address 0xe9000
-INFO:    Image id=1 loaded at address 0xe9000, size = 0x5008
-NOTICE:  BL1: Booting BL2
-INFO:    Entry point address = 0xe9000
-INFO:    SPSR = 0x3c5
-NOTICE:  BL2: v1.3(debug):v1.3-372-g1ba9c60
-NOTICE:  BL2: Built : 17:51:33, Apr 30 2017
-INFO:    BL2: Loading BL31
-INFO:    Loading image id=3 at address 0x129000
-INFO:    Image id=3 loaded at address 0x129000, size = 0x8038
-INFO:    BL2: Loading BL33
-INFO:    Loading image id=5 at address 0x37000000
-INFO:    Image id=5 loaded at address 0x37000000, size = 0x58f17
-NOTICE:  BL1: Booting BL31
-INFO:    Entry point address = 0x129000
-INFO:    SPSR = 0x3cd
-INFO:    Boot bl33 from 0x37000000 for 364311 Bytes
-NOTICE:  BL31: v1.3(debug):v1.3-372-g1ba9c60
-NOTICE:  BL31: Built : 17:51:33, Apr 30 2017
-INFO:    BL31: Initializing runtime services
-INFO:    BL31: Preparing for EL3 exit to normal world
-INFO:    Entry point address = 0x37000000
-INFO:    SPSR = 0x3c9
+    LOADER:  Switched to aarch64 mode
+    LOADER:  Entering ARM TRUSTED FIRMWARE
+    LOADER:  CPU0 executes at 0x000ce000
 
+    INFO:    BL1: 0xe1000 - 0xe7000 [size = 24576]
+    NOTICE:  Booting Trusted Firmware
+    NOTICE:  BL1: v1.3(debug):v1.3-372-g1ba9c60
+    NOTICE:  BL1: Built : 17:51:33, Apr 30 2017
+    INFO:    BL1: RAM 0xe1000 - 0xe7000
+    INFO:    BL1: Loading BL2
+    INFO:    Loading image id=1 at address 0xe9000
+    INFO:    Image id=1 loaded at address 0xe9000, size = 0x5008
+    NOTICE:  BL1: Booting BL2
+    INFO:    Entry point address = 0xe9000
+    INFO:    SPSR = 0x3c5
+    NOTICE:  BL2: v1.3(debug):v1.3-372-g1ba9c60
+    NOTICE:  BL2: Built : 17:51:33, Apr 30 2017
+    INFO:    BL2: Loading BL31
+    INFO:    Loading image id=3 at address 0x129000
+    INFO:    Image id=3 loaded at address 0x129000, size = 0x8038
+    INFO:    BL2: Loading BL33
+    INFO:    Loading image id=5 at address 0x37000000
+    INFO:    Image id=5 loaded at address 0x37000000, size = 0x58f17
+    NOTICE:  BL1: Booting BL31
+    INFO:    Entry point address = 0x129000
+    INFO:    SPSR = 0x3cd
+    INFO:    Boot bl33 from 0x37000000 for 364311 Bytes
+    NOTICE:  BL31: v1.3(debug):v1.3-372-g1ba9c60
+    NOTICE:  BL31: Built : 17:51:33, Apr 30 2017
+    INFO:    BL31: Initializing runtime services
+    INFO:    BL31: Preparing for EL3 exit to normal world
+    INFO:    Entry point address = 0x37000000
+    INFO:    SPSR = 0x3c9
 
-U-Boot 2017.05-rc2-00130-gd2255b0 (Apr 30 2017 - 17:51:28 +0200)poplar
 
-Model: HiSilicon Poplar Development Board
-BOARD: Hisilicon HI3798cv200 Poplar
-DRAM:  1 GiB
-MMC:   Hisilicon DWMMC: 0
-In:    serial@f8b00000
-Out:   serial@f8b00000
-Err:   serial@f8b00000
-Net:   Net Initialization Skipped
-No ethernet found.
+    U-Boot 2017.05-rc2-00130-gd2255b0 (Apr 30 2017 - 17:51:28 +0200)poplar
 
-Hit any key to stop autoboot:  0
-starting USB...
-USB0:   USB EHCI 1.00
-scanning bus 0 for devices... 1 USB Device(s) found
-USB1:   USB EHCI 1.00
-scanning bus 1 for devices... 4 USB Device(s) found
-       scanning usb for storage devices... 1 Storage Device(s) found
-       scanning usb for ethernet devices... 1 Ethernet Device(s) found
+    Model: HiSilicon Poplar Development Board
+    BOARD: Hisilicon HI3798cv200 Poplar
+    DRAM:  1 GiB
+    MMC:   Hisilicon DWMMC: 0
+    In:    serial@f8b00000
+    Out:   serial@f8b00000
+    Err:   serial@f8b00000
+    Net:   Net Initialization Skipped
+    No ethernet found.
 
-USB device 0:
-    Device 0: Vendor: SanDisk Rev: 1.00 Prod: Cruzer Blade
-            Type: Removable Hard Disk
-            Capacity: 7632.0 MB = 7.4 GB (15630336 x 512)
-... is now current device
-Scanning usb 0:1...
-=>
+    Hit any key to stop autoboot:  0
+    starting USB...
+    USB0:   USB EHCI 1.00
+    scanning bus 0 for devices... 1 USB Device(s) found
+    USB1:   USB EHCI 1.00
+    scanning bus 1 for devices... 4 USB Device(s) found
+           scanning usb for storage devices... 1 Storage Device(s) found
+           scanning usb for ethernet devices... 1 Ethernet Device(s) found
 
+    USB device 0:
+        Device 0: Vendor: SanDisk Rev: 1.00 Prod: Cruzer Blade
+                Type: Removable Hard Disk
+                Capacity: 7632.0 MB = 7.4 GB (15630336 x 512)
+    ... is now current device
+    Scanning usb 0:1...
+    =>
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
new file mode 100644
index 0000000..219faaf
--- /dev/null
+++ b/docs/plat/rpi3.rst
@@ -0,0 +1,364 @@
+Arm Trusted Firmware for Raspberry Pi 3
+=======================================
+
+.. section-numbering::
+    :suffix: .
+
+.. contents::
+
+The `Raspberry Pi 3`_ is an inexpensive single-board computer that contains four
+Cortex-A53 cores, which makes it possible to have a port of the Arm Trusted
+Firmware.
+
+The following instructions explain how to use this port of the Trusted Firmware
+with the default distribution of `Raspbian`_ because that's the distribution
+officially supported by the Raspberry Pi Foundation. At the moment of writing
+this, the officially supported kernel is a AArch32 kernel. This doesn't mean
+that this port of the Trusted Firmware can't boot a AArch64 kernel. The `Linux
+tree fork`_ maintained by the Foundation can be compiled for AArch64 by
+following the steps in `AArch64 kernel build instructions`_.
+
+**IMPORTANT NOTE**: This port isn't secure. All of the memory used is DRAM,
+which is available from both the Non-secure and Secure worlds. This port
+shouldn't be considered more than a prototype to play with and implement
+elements like PSCI to support the Linux kernel.
+
+Design
+------
+
+The SoC used by the Raspberry Pi 3 is the Broadcom BCM2837. It is a SoC with a
+VideoCore IV that acts as primary processor (and loads everything from the SD
+card) and is located between all Arm cores and the DRAM. Check the `Raspberry Pi
+3 documentation`_ for more information.
+
+This explains why it is possible to change the execution state (AArch64/AArch32)
+depending on a few files on the SD card. We only care about the cases in which
+the cores boot in AArch64 mode.
+
+The rules are simple:
+
+- If a file called ``kernel8.img`` is located on the ``boot`` partition of the
+  SD card, it will load it and execute in EL2 in AArch64. Basically, it executes
+  a `default AArch64 stub`_ at address **0x0** that jumps to the kernel.
+
+- If there is also a file called ``armstub8.bin``, it will load it at address
+  **0x0** (instead of the default stub) and execute it in EL3 in AArch64. All
+  the cores are powered on at the same time and start at address **0x0**.
+
+This means that we can use the default AArch32 kernel provided in the official
+`Raspbian`_ distribution by renaming it to ``kernel8.img``, while the Trusted
+Firmware and anything else we need is in ``armstub8.bin``. This way we can
+forget about the default bootstrap code. When using a AArch64 kernel, it is only
+needed to make sure that the name on the SD card is ``kernel8.img``.
+
+Ideally, we want to load the kernel and have all cores available, which means
+that we need to make the secondary cores work in the way the kernel expects, as
+explained in `Secondary cores`_. In practice, a small bootstrap is needed
+between the Trusted Firmware and the kernel.
+
+To get the most out of a AArch32 kernel, we want to boot it in Hypervisor mode
+in AArch32. This means that BL33 can't be in EL2 in AArch64 mode. The
+architecture specifies that AArch32 Hypervisor mode isn't present when AArch64
+is used for EL2. When using a AArch64 kernel, it should simply start in EL2.
+
+Placement of images
+~~~~~~~~~~~~~~~~~~~
+
+The file ``armstub8.bin`` contains BL1 and the FIP. It is needed to add padding
+between them so that the addresses they are loaded to match the ones specified
+when compiling the Trusted Firmware.
+
+The device tree block is loaded by the VideoCore loader from an appropriate
+file, but we can specify the address it is loaded to in ``config.txt``.
+
+The file ``kernel8.img`` contains a kernel image that is loaded to the address
+specified in ``config.txt``. The `Linux kernel tree`_ has information about how
+a AArch32 Linux kernel image is loaded in ``Documentation/arm/Booting``:
+
+::
+
+    The zImage may also be placed in system RAM and called there.  The
+    kernel should be placed in the first 128MiB of RAM.  It is recommended
+    that it is loaded above 32MiB in order to avoid the need to relocate
+    prior to decompression, which will make the boot process slightly
+    faster.
+
+There are no similar restrictions for AArch64 kernels, as specified in the file
+``Documentation/arm64/booting.txt``.
+
+This means that we need to avoid the first 128 MiB of RAM when placing the
+Trusted Firmware images (and specially the first 32 MiB, as they are directly
+used to place the uncompressed AArch32 kernel image. This way, both AArch32 and
+AArch64 kernels can be placed at the same address.
+
+In the end, the images look like the following diagram when placed in memory.
+All addresses are Physical Addresses from the point of view of the Arm cores.
+Again, note that this is all just part of the same DRAM that goes from
+**0x00000000** to **0x3F000000**, it just has different names to simulate a real
+secure platform!
+
+::
+
+    0x00000000 +-----------------+
+               |       ROM       | BL1
+    0x00010000 +-----------------+
+               |       FIP       |
+    0x00200000 +-----------------+
+               |                 |
+               |       ...       |
+               |                 |
+    0x01000000 +-----------------+
+               |     Kernel      |
+               +-----------------+
+               |                 |
+               |       ...       |
+               |                 |
+    0x02000000 +-----------------+
+               |       DTB       |
+               +-----------------+
+               |                 |
+               |       ...       |
+               |                 |
+    0x10000000 +-----------------+
+               |   Secure SRAM   | BL2, BL31
+    0x10100000 +-----------------+
+               |   Secure DRAM   |
+    0x10300000 +-----------------+
+               | Non-secure DRAM | BL33
+    0x11000000 +-----------------+
+               |                 |
+               |       ...       |
+               |                 |
+    0x3F000000 +-----------------+
+               |       I/O       |
+    0x40000000 +-----------------+
+
+The area between **0x10000000** and **0x11000000** has to be protected so that
+the kernel doesn't use it. That is done by adding ``memmap=256M$16M`` to the
+command line passed to the kernel. See the `Setup SD card`_ instructions to see
+how to do it.
+
+The last 16 MiB of DRAM can only be accessed by the VideoCore, that has
+different mappings than the Arm cores in which the I/O addresses don't overlap
+the DRAM. The memory reserved to be used by the VideoCore is always placed at
+the end of the DRAM, so this space isn't wasted.
+
+Considering the 128 MiB allocated to the GPU and the 16 MiB allocated for the
+Trusted Firmware, there are 880 MiB available for Linux.
+
+Boot sequence
+~~~~~~~~~~~~~
+
+The boot sequence of the Trusted Firmware is the usual one except when booting
+a AArch32 kernel. In that case, BL33 is booted in AArch32 Hypervisor mode so
+that it can jump to the kernel in the same mode and let it take over that
+privilege level. If BL33 was running in EL2 in AArch64 (as in the default
+bootflow of the Trusted Firmware) it could only jump to the kernel in AArch32 in
+Supervisor mode.
+
+The `Linux kernel tree`_ has instructions on how to jump to the Linux kernel
+in ``Documentation/arm/Booting`` and ``Documentation/arm64/booting.txt``. The
+bootstrap should take care of this.
+
+Secondary cores
+~~~~~~~~~~~~~~~
+
+The kernel used by `Raspbian`_ doesn't have support for PSCI, so it is needed to
+use mailboxes to trap the secondary cores until they are ready to jump to the
+kernel. This mailbox is located at a different address in the AArch32 default
+kernel than in the AArch64 kernel.
+
+Also, this port of the Trusted Firmware has another Trusted Mailbox in Shared BL
+RAM. During cold boot, all secondary cores wait in a loop until they are given
+given an address to jump to in this Mailbox (``bl31_warm_entrypoint``).
+
+Once BL31 has finished and the primary core has jumped to the BL33 payload, it
+has to call ``PSCI_CPU_ON`` to release the secondary CPUs from the wait loop.
+The payload then makes them wait in another waitloop listening from messages
+from the kernel. When the primary CPU jumps into the kernel, it will send an
+address to the mailbox so that the secondary CPUs jump to it and are recognised
+by the kernel.
+
+Build Instructions
+------------------
+
+To boot a AArch64 kernel, only the AArch64 toolchain is required.
+
+To boot a AArch32 kernel, both AArch64 and AArch32 toolchains are required. The
+AArch32 toolchain is needed for the AArch32 bootstrap needed to load a 32-bit
+kernel.
+
+First, clone and compile `Raspberry Pi 3 Arm Trusted Firmware bootstrap`_.
+Choose the one needed for the architecture of your kernel.
+
+Then compile the Arm Trusted Firmware. For a AArch32 kernel, use the following
+command line:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3             \
+    RPI3_BL33_IN_AARCH32=1                                      \
+    BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin     \
+    all fip
+
+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
+
+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=65536 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 the Trusted Firmware to boot correctly. Now, follow the
+instructions in `Setup SD card`_.
+
+The following build options are supported:
+
+- ``PRELOADED_BL33_BASE``: Specially useful because the file ``kernel8.img`` can
+  be loaded anywhere by modifying the file ``config.txt``. It doesn't have to
+  contain a kernel, it could have any arbitrary payload.
+
+- ``RESET_TO_BL31``: Set to 1 by default. If using a 32-bit kernel like
+  `Raspbian`_, the space used by BL1 can overwritten by the kernel when it is
+  being loaded. Even when using a AArch64 kernel the region used by
+  BL1 isn't protected and the kernel could overwrite it. The space used by BL31
+  is reserved by the command line passed to the kernel.
+
+- ``RPI3_BL33_IN_AARCH32``: This port can load a AArch64 or AArch32 BL33 image.
+  By default this option is 0, which means that the Trusted Firmware will jump
+  to BL33 in EL2 in AArch64 mode. If set to 1, it will jump to BL33 in
+  Hypervisor in AArch32 mode.
+
+The following is not currently supported:
+
+- AArch32 for the Trusted Firmware itself.
+
+- ``EL3_PAYLOAD_BASE``: The reason is that you can already load anything to any
+  address by changing the file ``armstub8.bin``, so there's no point in using
+  the Trusted Firmware in this case.
+
+- ``LOAD_IMAGE_V2=0``: Only version 2 is supported.
+
+AArch64 kernel build instructions
+---------------------------------
+
+The following instructions show how to install and run a AArch64 kernel by
+using a SD card with the default `Raspbian`_ install as base. Skip them if you
+want to use the default 32-bit kernel.
+
+Note that this system won't be fully 64-bit because all the tools in the
+filesystem are 32-bit binaries, but it's a quick way to get it working, and it
+allows the user to run 64-bit binaries in addition to 32-bit binaries.
+
+1. Clone the `Linux tree fork`_ maintained by the Raspberry Pi Foundation. To
+   speed things up, do a shallow clone of the desired branch.
+
+.. code:: shell
+
+    git clone --depth=1 -b rpi-4.14.y https://github.com/raspberrypi/linux
+    cd linux
+
+2. Configure and compile the kernel. Adapt the number after ``-j`` so that it is
+   1.5 times the number of CPUs in your computer. This may take some time to
+   finish.
+
+.. code:: shell
+
+    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig
+    make -j 6 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
+
+3. Copy the kernel image and the device tree to the SD card. Replace the path
+   by the corresponding path in your computers to the ``boot`` partition of the
+   SD card.
+
+.. code:: shell
+
+    cp arch/arm64/boot/Image /path/to/boot/kernel8.img
+    cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /path/to/boot/
+
+4. Install the kernel modules. Replace the path by the corresponding path to the
+   filesystem partition of the SD card on your computer.
+
+.. code:: shell
+
+    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
+    INSTALL_MOD_PATH=/path/to/filesystem modules_install
+
+5. Follow the instructions in `Setup SD card`_ except for the step of renaming
+   the existing ``kernel7.img`` (we have already copied a AArch64 kernel).
+
+Setup SD card
+-------------
+
+The instructions assume that you have an SD card with a fresh install of
+`Raspbian`_ (or that, at least, the ``boot`` partition is untouched, or nearly
+untouched). They have been tested with the image available in 2017-09-07.
+
+1. Insert the SD card and open the ``boot`` partition.
+
+2. Rename ``kernel7.img`` to ``kernel8.img``. This tricks the VideoCore
+   bootloader into booting the Arm cores in AArch64 mode, like the Trusted
+   Firmware needs, even though the kernel is not compiled for AArch64.
+
+3. Copy ``armstub8.bin`` here. When ``kernel8.img`` is available, The VideoCore
+   bootloader will look for a file called ``armstub8.bin`` and load it at
+   address **0x0** instead of a predefined one.
+
+4. Open ``cmdline.txt`` and add ``memmap=256M$16M`` to prevent the kernel from
+   using the memory needed by the Trusted Firmware. If you want to enable the
+   serial port "Mini UART", make sure that this file also contains
+   ``console=serial0,115200 console=tty1``.
+
+   Note that the 16 MiB reserved this way won't be available for Linux, the same
+   way as the memory reserved in DRAM for the GPU isn't available.
+
+5. Open ``config.txt`` and add the following lines at the end (``enable_uart=1``
+   is only needed to enable debugging through the Mini UART):
+
+::
+
+    enable_uart=1
+    kernel_address=0x01000000
+    device_tree_address=0x02000000
+
+If you connect a serial cable to the Mini UART and your computer, and connect
+to it (for example, with ``screen /dev/ttyUSB0 115200``) you should see some
+text. In the case of an AArch32 kernel, you should see something like this:
+
+::
+
+    NOTICE:  Booting Trusted Firmware
+    NOTICE:  BL1: v1.4(release):v1.4-329-g61e94684-dirty
+    NOTICE:  BL1: Built : 00:09:25, Nov  6 2017
+    NOTICE:  BL1: Booting BL2
+    NOTICE:  BL2: v1.4(release):v1.4-329-g61e94684-dirty
+    NOTICE:  BL2: Built : 00:09:25, Nov  6 2017
+    NOTICE:  BL1: Booting BL31
+    NOTICE:  BL31: v1.4(release):v1.4-329-g61e94684-dirty
+    NOTICE:  BL31: Built : 00:09:25, Nov  6 2017
+    [    0.266484] bcm2835-aux-uart 3f215040.serial: could not get clk: -517
+
+    Raspbian GNU/Linux 9 raspberrypi ttyS0
+    raspberrypi login:
+
+Just enter your credentials, everything should work as expected. Note that the
+HDMI output won't show any text during boot.
+
+.. _default Arm stub: https://github.com/raspberrypi/tools/blob/master/armstubs/armstub7.S
+.. _default AArch64 stub: https://github.com/raspberrypi/tools/blob/master/armstubs/armstub8.S
+.. _Linux kernel tree: https://github.com/torvalds/linux
+.. _Linux tree fork: https://github.com/raspberrypi/linux
+.. _Raspberry Pi 3: https://www.raspberrypi.org/products/raspberry-pi-3-model-b/
+.. _Raspberry Pi 3 Arm Trusted Firmware bootstrap: https://github.com/AntonioND/rpi3-arm-tf-bootstrap
+.. _Raspberry Pi 3 documentation: https://www.raspberrypi.org/documentation/
+.. _Raspbian: https://www.raspberrypi.org/downloads/raspbian/
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 04acbe7..13f0964 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -1223,7 +1223,7 @@
 
           make ARCH=aarch64 PLAT=juno LOAD_IMAGE_V2=1 JUNO_AARCH32_EL3_RUNTIME=1 \
           BL33=<path-to-juno32-oe-uboot>/SOFTWARE/bl33-uboot.bin \
-          SCP_BL2=<path-to-juno32-oe-uboot>/SOFTWARE/scp_bl2.bin SPD=tspd \
+          SCP_BL2=<path-to-juno32-oe-uboot>/SOFTWARE/scp_bl2.bin \
           BL32=<path-to-bl32>/bl32.bin all fip
 
 The resulting BL1 and FIP images may be found in:
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 15ffc57..8915ba0 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -205,7 +205,6 @@
 
 #if LOAD_IMAGE_V2
 
-int load_image(unsigned int image_id, image_info_t *image_data);
 int load_auth_image(unsigned int image_id, image_info_t *image_data);
 
 #else
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 73a9c53..ba3e360 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -168,21 +168,28 @@
 					 _xlat_tables_count,		\
 					 _virt_addr_space_size,		\
 					 _phy_addr_space_size,		\
-					 IMAGE_XLAT_DEFAULT_REGIME)
+					 IMAGE_XLAT_DEFAULT_REGIME,	\
+					"xlat_table")
 
 /*
- * Same as REGISTER_XLAT_CONTEXT plus the additional parameter _xlat_regime to
- * specify the translation regime managed by this xlat_ctx_t instance. The
- * values are the one from xlat_regime_t enumeration.
+ * Same as REGISTER_XLAT_CONTEXT plus the additional parameters:
+ *
+ * _xlat_regime:
+ *   Specify the translation regime managed by this xlat_ctx_t instance. The
+ *   values are the one from xlat_regime_t enumeration.
+ *
+ * _section_name:
+ *   Specify the name of the section where the translation tables have to be
+ *   placed by the linker.
  */
 #define REGISTER_XLAT_CONTEXT2(_ctx_name, _mmap_count, _xlat_tables_count,	\
 			_virt_addr_space_size, _phy_addr_space_size,		\
-			_xlat_regime)					\
+			_xlat_regime, _section_name)				\
 	_REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count,	\
 					 _xlat_tables_count,		\
 					 _virt_addr_space_size,		\
 					 _phy_addr_space_size,		\
-					 _xlat_regime)
+					 _xlat_regime, _section_name)
 
 /******************************************************************************
  * Generic translation table APIs.
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index 96dee1a..1be99b7 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -123,7 +123,7 @@
 
 #define _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, _xlat_tables_count,	\
 			_virt_addr_space_size, _phy_addr_space_size,		\
-			_xlat_regime)					\
+			_xlat_regime, _section_name)				\
 	CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size),		\
 		assert_invalid_virtual_addr_space_size_for_##_ctx_name);	\
 										\
@@ -134,7 +134,7 @@
 										\
 	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]		\
 		[XLAT_TABLE_ENTRIES]						\
-		__aligned(XLAT_TABLE_SIZE) __section("xlat_table");		\
+		__aligned(XLAT_TABLE_SIZE) __section(_section_name);		\
 										\
 	static uint64_t _ctx_name##_base_xlat_table				\
 		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]		\
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h
index 97a1af4..69eb727 100644
--- a/include/plat/arm/board/common/board_arm_def.h
+++ b/include/plat/arm/board/common/board_arm_def.h
@@ -90,10 +90,14 @@
  * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a
  * little space for growth.
  */
-#if ENABLE_SPM
-#define PLAT_ARM_MAX_BL31_SIZE		0x28000
-#else
 #define PLAT_ARM_MAX_BL31_SIZE		0x1D000
+
+#ifdef AARCH32
+/*
+ * PLAT_ARM_MAX_BL32_SIZE is calculated for SP_MIN as the AArch32 Secure
+ * Payload.
+ */
+# define PLAT_ARM_MAX_BL32_SIZE		0x1D000
 #endif
 
 #endif /* ARM_BOARD_OPTIMISE_MEM */
diff --git a/include/plat/arm/common/arm_common.ld.S b/include/plat/arm/common/arm_common.ld.S
index 478b08c..6edfa09 100644
--- a/include/plat/arm/common/arm_common.ld.S
+++ b/include/plat/arm/common/arm_common.ld.S
@@ -6,6 +6,8 @@
 #ifndef __ARM_COMMON_LD_S__
 #define __ARM_COMMON_LD_S__
 
+#include <xlat_tables_defs.h>
+
 MEMORY {
     EL3_SEC_DRAM (rw): ORIGIN = ARM_EL3_TZC_DRAM1_BASE, LENGTH = ARM_EL3_TZC_DRAM1_SIZE
 }
@@ -13,14 +15,14 @@
 SECTIONS
 {
 	. = ARM_EL3_TZC_DRAM1_BASE;
-	ASSERT(. == ALIGN(4096),
+	ASSERT(. == ALIGN(PAGE_SIZE),
 	"ARM_EL3_TZC_DRAM_BASE address is not aligned on a page boundary.")
-	el3_tzc_dram (NOLOAD) : ALIGN(4096) {
+	el3_tzc_dram (NOLOAD) : ALIGN(PAGE_SIZE) {
 	__EL3_SEC_DRAM_START__ = .;
 	*(arm_el3_tzc_dram)
 	__EL3_SEC_DRAM_UNALIGNED_END__ = .;
 
-	. = NEXT(4096);
+	. = NEXT(PAGE_SIZE);
 	__EL3_SEC_DRAM_END__ = .;
 	} >EL3_SEC_DRAM
 }
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index b8955af..7887525 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -326,14 +326,21 @@
 /*******************************************************************************
  * BL2 specific defines.
  ******************************************************************************/
-#if ARM_BL31_IN_DRAM || (defined(AARCH32) && !defined(JUNO_AARCH32_EL3_RUNTIME))
+#if ARM_BL31_IN_DRAM
 /*
- * For AArch32 BL31 is not applicable.
  * For AArch64 BL31 is loaded in the DRAM.
  * Put BL2 just below BL1.
  */
 #define BL2_BASE			(BL1_RW_BASE - PLAT_ARM_MAX_BL2_SIZE)
 #define BL2_LIMIT			BL1_RW_BASE
+
+#elif defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME
+/*
+ * Put BL2 just below BL32.
+ */
+#define BL2_BASE			(BL32_BASE - PLAT_ARM_MAX_BL2_SIZE)
+#define BL2_LIMIT			BL32_BASE
+
 #else
 /*
  * Put BL2 just below BL31.
@@ -370,76 +377,86 @@
 #define BL31_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
 #endif
 
+#if defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME
 /*******************************************************************************
- * BL32 specific defines.
+ * BL32 specific defines for EL3 runtime in AArch32 mode
+ ******************************************************************************/
+# if RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME
+/* SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM to BL32 */
+#  define BL32_BASE			ARM_BL_RAM_BASE
+#  define BL32_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+# else
+/* Put BL32 at the top of the Trusted SRAM.*/
+#  define BL32_BASE			(ARM_BL_RAM_BASE +		\
+						ARM_BL_RAM_SIZE -	\
+						PLAT_ARM_MAX_BL32_SIZE)
+#  define BL32_PROGBITS_LIMIT		BL1_RW_BASE
+#  define BL32_LIMIT			(ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+# endif /* RESET_TO_SP_MIN && !JUNO_AARCH32_EL3_RUNTIME */
+
+#else
+/*******************************************************************************
+ * BL32 specific defines for EL3 runtime in AArch64 mode
  ******************************************************************************/
 /*
  * On ARM standard platforms, the TSP can execute from Trusted SRAM,
  * Trusted DRAM (if available) or the DRAM region secured by the TrustZone
  * controller.
  */
-#if ENABLE_SPM
-# define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
-# define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
-# define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
-# define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
+# if ENABLE_SPM
+#  define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
+#  define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
+#  define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
+#  define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						ARM_AP_TZC_DRAM1_SIZE)
-#elif ARM_BL31_IN_DRAM
-# define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE +	\
+# elif ARM_BL31_IN_DRAM
+#  define TSP_SEC_MEM_BASE		(ARM_AP_TZC_DRAM1_BASE +	\
 						PLAT_ARM_MAX_BL31_SIZE)
-# define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE -	\
+#  define TSP_SEC_MEM_SIZE		(ARM_AP_TZC_DRAM1_SIZE -	\
 						PLAT_ARM_MAX_BL31_SIZE)
-# define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE +	\
+#  define BL32_BASE			(ARM_AP_TZC_DRAM1_BASE +	\
 						PLAT_ARM_MAX_BL31_SIZE)
-# define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
+#  define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						ARM_AP_TZC_DRAM1_SIZE)
-#elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_SRAM_ID
-# define TSP_SEC_MEM_BASE		ARM_BL_RAM_BASE
-# define TSP_SEC_MEM_SIZE		ARM_BL_RAM_SIZE
-# define TSP_PROGBITS_LIMIT		BL2_BASE
-# define BL32_BASE			ARM_BL_RAM_BASE
-# define BL32_LIMIT			BL31_BASE
-#elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID
-# define TSP_SEC_MEM_BASE		PLAT_ARM_TRUSTED_DRAM_BASE
-# define TSP_SEC_MEM_SIZE		PLAT_ARM_TRUSTED_DRAM_SIZE
-# define BL32_BASE			PLAT_ARM_TRUSTED_DRAM_BASE
-# define BL32_LIMIT			(PLAT_ARM_TRUSTED_DRAM_BASE	\
+# elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_SRAM_ID
+#  define TSP_SEC_MEM_BASE		ARM_BL_RAM_BASE
+#  define TSP_SEC_MEM_SIZE		ARM_BL_RAM_SIZE
+#  define TSP_PROGBITS_LIMIT		BL2_BASE
+#  define BL32_BASE			ARM_BL_RAM_BASE
+#  define BL32_LIMIT			BL31_BASE
+# elif ARM_TSP_RAM_LOCATION_ID == ARM_TRUSTED_DRAM_ID
+#  define TSP_SEC_MEM_BASE		PLAT_ARM_TRUSTED_DRAM_BASE
+#  define TSP_SEC_MEM_SIZE		PLAT_ARM_TRUSTED_DRAM_SIZE
+#  define BL32_BASE			PLAT_ARM_TRUSTED_DRAM_BASE
+#  define BL32_LIMIT			(PLAT_ARM_TRUSTED_DRAM_BASE	\
 						+ (1 << 21))
-#elif ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID
-# define TSP_SEC_MEM_BASE		ARM_AP_TZC_DRAM1_BASE
-# define TSP_SEC_MEM_SIZE		ARM_AP_TZC_DRAM1_SIZE
-# define BL32_BASE			ARM_AP_TZC_DRAM1_BASE
-# define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
+# elif ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID
+#  define TSP_SEC_MEM_BASE		ARM_AP_TZC_DRAM1_BASE
+#  define TSP_SEC_MEM_SIZE		ARM_AP_TZC_DRAM1_SIZE
+#  define BL32_BASE			ARM_AP_TZC_DRAM1_BASE
+#  define BL32_LIMIT			(ARM_AP_TZC_DRAM1_BASE +	\
 						ARM_AP_TZC_DRAM1_SIZE)
-#else
-# error "Unsupported ARM_TSP_RAM_LOCATION_ID value"
-#endif
+# else
+#  error "Unsupported ARM_TSP_RAM_LOCATION_ID value"
+# endif
+#endif /* AARCH32 || JUNO_AARCH32_EL3_RUNTIME */
 
 /*
  * BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
  * SPD and no SPM, as they are the only ones that can be used as BL32.
  */
-#ifndef AARCH32
+#if !(defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME)
 # if defined(SPD_none) && !ENABLE_SPM
 #  undef BL32_BASE
-# endif
-#endif
+# endif /* defined(SPD_none) && !ENABLE_SPM */
+#endif /* !(defined(AARCH32) || JUNO_AARCH32_EL3_RUNTIME) */
 
 /*******************************************************************************
  * FWU Images: NS_BL1U, BL2U & NS_BL2U defines.
  ******************************************************************************/
 #define BL2U_BASE			BL2_BASE
-#if ARM_BL31_IN_DRAM || (defined(AARCH32) && !defined(JUNO_AARCH32_EL3_RUNTIME))
-/*
- * For AArch32 BL31 is not applicable.
- * For AArch64 BL31 is loaded in the DRAM.
- * BL2U extends up to BL1.
- */
-#define BL2U_LIMIT			BL1_RW_BASE
-#else
-/* BL2U extends up to BL31. */
-#define BL2U_LIMIT			BL31_BASE
-#endif
+#define BL2U_LIMIT			BL2_LIMIT
+
 #define NS_BL2U_BASE			ARM_NS_DRAM1_BASE
 #define NS_BL1U_BASE			(PLAT_ARM_NVM_BASE + 0x03EB8000)
 
diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h
index 83277a6..3f5c958 100644
--- a/include/plat/arm/common/arm_spm_def.h
+++ b/include/plat/arm/common/arm_spm_def.h
@@ -98,6 +98,12 @@
 /* Total number of memory regions with distinct properties */
 #define ARM_SP_IMAGE_NUM_MEM_REGIONS	6
 
+/*
+ * Name of the section to put the translation tables used by the S-EL1/S-EL0
+ * context of a Secure Partition.
+ */
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	"arm_el3_tzc_dram"
+
 /* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */
 #define PLAT_SPM_COOKIE_0		ULL(0)
 #define PLAT_SPM_COOKIE_1		ULL(0)
diff --git a/include/services/spm_svc.h b/include/services/spm_svc.h
index 2c8c7cd..738979e 100644
--- a/include/services/spm_svc.h
+++ b/include/services/spm_svc.h
@@ -32,24 +32,24 @@
  * Manager from the Secure Partition(s). These services enable a partition to
  * handle delegated events and request privileged operations from the manager.
  */
-#define SPM_VERSION_AARCH32		U(0x84000060)
-#define SP_EVENT_COMPLETE_AARCH64	U(0xC4000061)
-#define SP_MEM_ATTRIBUTES_GET_AARCH64	U(0xC4000064)
-#define SP_MEM_ATTRIBUTES_SET_AARCH64	U(0xC4000065)
+#define SPM_VERSION_AARCH32			U(0x84000060)
+#define SP_EVENT_COMPLETE_AARCH64		U(0xC4000061)
+#define SP_MEMORY_ATTRIBUTES_GET_AARCH64	U(0xC4000064)
+#define SP_MEMORY_ATTRIBUTES_SET_AARCH64	U(0xC4000065)
 
 /*
- * Macros used by SP_MEM_ATTRIBUTES_SET_AARCH64.
+ * Macros used by SP_MEMORY_ATTRIBUTES_SET_AARCH64.
  */
 
-#define SP_MEM_ATTR_ACCESS_NOACCESS	U(0)
-#define SP_MEM_ATTR_ACCESS_RW		U(1)
+#define SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS	U(0)
+#define SP_MEMORY_ATTRIBUTES_ACCESS_RW		U(1)
 /* Value U(2) is reserved. */
-#define SP_MEM_ATTR_ACCESS_RO		U(3)
-#define SP_MEM_ATTR_ACCESS_MASK		U(3)
-#define SP_MEM_ATTR_ACCESS_SHIFT	0
+#define SP_MEMORY_ATTRIBUTES_ACCESS_RO		U(3)
+#define SP_MEMORY_ATTRIBUTES_ACCESS_MASK	U(3)
+#define SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT	0
 
-#define SP_MEM_ATTR_EXEC		(U(0) << 2)
-#define SP_MEM_ATTR_NON_EXEC		(U(1) << 2)
+#define SP_MEMORY_ATTRIBUTES_EXEC		(U(0) << 2)
+#define SP_MEMORY_ATTRIBUTES_NON_EXEC		(U(1) << 2)
 
 /*
  * SMC IDs defined in [1] for accessing secure partition services from the
@@ -59,8 +59,8 @@
 #define SP_VERSION_AARCH64		U(0xC4000040)
 #define SP_VERSION_AARCH32		U(0x84000040)
 
-#define SP_COMMUNICATE_AARCH64		U(0xC4000041)
-#define SP_COMMUNICATE_AARCH32		U(0x84000041)
+#define MM_COMMUNICATE_AARCH64		U(0xC4000041)
+#define MM_COMMUNICATE_AARCH32		U(0x84000041)
 
 /* SPM error codes. */
 #define SPM_SUCCESS		0
diff --git a/lib/cpus/aarch32/cortex_a53.S b/lib/cpus/aarch32/cortex_a53.S
index 74cedc3..1647e16 100644
--- a/lib/cpus/aarch32/cortex_a53.S
+++ b/lib/cpus/aarch32/cortex_a53.S
@@ -174,7 +174,7 @@
 	push	{r12, lr}
 
 	/* Assert if cache is enabled */
-#if ASM_ASSERTION
+#if ENABLE_ASSERTIONS
 	ldcopr	r0, SCTLR
 	tst	r0, #SCTLR_C_BIT
 	ASM_ASSERT(eq)
@@ -204,7 +204,7 @@
 	push	{r12, lr}
 
 	/* Assert if cache is enabled */
-#if ASM_ASSERTION
+#if ENABLE_ASSERTIONS
 	ldcopr	r0, SCTLR
 	tst	r0, #SCTLR_C_BIT
 	ASM_ASSERT(eq)
diff --git a/lib/cpus/aarch32/cortex_a57.S b/lib/cpus/aarch32/cortex_a57.S
index b5189e7..64a6d67 100644
--- a/lib/cpus/aarch32/cortex_a57.S
+++ b/lib/cpus/aarch32/cortex_a57.S
@@ -406,7 +406,7 @@
 	push	{r12, lr}
 
 	/* Assert if cache is enabled */
-#if ASM_ASSERTION
+#if ENABLE_ASSERTIONS
 	ldcopr	r0, SCTLR
 	tst	r0, #SCTLR_C_BIT
 	ASM_ASSERT(eq)
@@ -448,7 +448,7 @@
 	push	{r12, lr}
 
 	/* Assert if cache is enabled */
-#if ASM_ASSERTION
+#if ENABLE_ASSERTIONS
 	ldcopr	r0, SCTLR
 	tst	r0, #SCTLR_C_BIT
 	ASM_ASSERT(eq)
diff --git a/lib/cpus/aarch32/cortex_a72.S b/lib/cpus/aarch32/cortex_a72.S
index 69cc2ea..7550520 100644
--- a/lib/cpus/aarch32/cortex_a72.S
+++ b/lib/cpus/aarch32/cortex_a72.S
@@ -120,7 +120,7 @@
 	push	{r12, lr}
 
 	/* Assert if cache is enabled */
-#if ASM_ASSERTION
+#if ENABLE_ASSERTIONS
 	ldcopr	r0, SCTLR
 	tst	r0, #SCTLR_C_BIT
 	ASM_ASSERT(eq)
@@ -167,7 +167,7 @@
 	push	{r12, lr}
 
 	/* Assert if cache is enabled */
-#if ASM_ASSERTION
+#if ENABLE_ASSERTIONS
 	ldcopr	r0, SCTLR
 	tst	r0, #SCTLR_C_BIT
 	ASM_ASSERT(eq)
diff --git a/maintainers.rst b/maintainers.rst
index 701ea17..04ab695 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -21,8 +21,8 @@
 
 Files:
 
--  docs/spd/optee-dispatcher.md
--  docs/plat/qemu.md
+-  docs/plat/qemu.rst
+-  docs/spd/optee-dispatcher.rst
 -  services/spd/opteed/\*
 -  plat/qemu/\*
 
@@ -33,8 +33,9 @@
 
 Files:
 
--  docs/spd/tlk-dispatcher.md
--  docs/spd/trusty-dispatcher.md
+-  docs/plat/nvidia-tegra.rst
+-  docs/spd/tlk-dispatcher.rst
+-  docs/spd/trusty-dispatcher.rst
 -  include/bl32/payloads/tlk.h
 -  include/lib/cpus/aarch64/denver.h
 -  lib/cpus/aarch64/denver.S
@@ -49,8 +50,9 @@
 
 Files:
 
--  docs/plat/hikey.md
--  docs/plat/hikey960.md
+-  docs/plat/hikey.rst
+-  docs/plat/hikey960.rst
+-  docs/plat/poplar.rst
 -  drivers/emmc/\*
 -  drivers/partition/\*
 -  drivers/synopsys/emmc/\*
@@ -71,24 +73,44 @@
 
 -  plat/mediatek/\*
 
+Raspberry Pi 3 platform sub-maintainer
+--------------------------------------
+
+Antonio Niño Díaz (antonio.ninodiaz@arm.com, `antonio-nino-diaz-arm`_)
+
+Files:
+
+-  docs/plat/rpi3.rst
+-  plat/rpi3/\*
+
 RockChip platform sub-maintainer
 --------------------------------
 
 Tony Xie (tony.xie@rock-chips.com, `TonyXie06`_
-or `rkchrome`_)
+or `rockchip-linux`_)
 
 Files:
 
 -  plat/rockchip/\*
 
+UniPhier platform sub-maintainer
+--------------------------------
+
+Masahiro Yamada (yamada.masahiro@socionext.com, `masahir0y`_)
+
+Files:
+
+- docs/plat/socionext-uniphier.rst
+- plat/socionext/\*
+
 Xilinx platform sub-maintainer
 ------------------------------
 
-Sören Brinkmann (soren.brinkmann@xilinx.com, `sorenb-xlnx`_)
+Siva Durga Prasad Paladugu (siva.durga.paladugu@xilinx.com, `sivadur`_)
 
 Files:
 
--  docs/plat/xilinx-zynqmp.md
+-  docs/plat/xilinx-zynqmp.rst
 -  plat/xilinx/\*
 
 ARMv7 architecture sub-maintainer
@@ -96,13 +118,15 @@
 
 Etienne Carriere (etienne.carriere@linaro.org, `etienne-lms`_)
 
+.. _antonio-nino-diaz-arm: https://github.com/antonio-nino-diaz-arm
 .. _danh-arm: https://github.com/danh-arm
 .. _davidcunado-arm: https://github.com/davidcunado-arm
 .. _jenswi-linaro: https://github.com/jenswi-linaro
 .. _vwadekar: https://github.com/vwadekar
 .. _hzhuang1: https://github.com/hzhuang1
+.. _masahir0y: https://github.com/masahir0y
 .. _mtk09422: https://github.com/mtk09422
 .. _TonyXie06: https://github.com/TonyXie06
-.. _rkchrome: https://github.com/rkchrome
-.. _sorenb-xlnx: https://github.com/sorenb-xlnx
+.. _sivadur: https://github.com/sivadur
+.. _rockchip-linux: https://github.com/rockchip-linux
 .. _etienne-lms: https://github.com/etienne-lms
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index 1d20080..fa0d17d 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -24,9 +24,6 @@
 # in EL3. The platform port can change this value if needed.
 ARM_GIC_ARCH			:= 2
 
-# Flag used to indicate if ASM_ASSERTION should be enabled for the build.
-ASM_ASSERTION			:= 0
-
 # Base commit to perform code check on
 BASE_COMMIT			:= origin/master
 
diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk
index b13afe4..6e6e273 100644
--- a/make_helpers/tbbr/tbbr_tools.mk
+++ b/make_helpers/tbbr/tbbr_tools.mk
@@ -77,6 +77,7 @@
 endif
 
 ifeq (${ARCH},aarch64)
+ifeq (${NEED_BL31},yes)
 # Add the BL31 CoT (key cert + img cert + image)
 $(if ${BL31},$(eval $(call CERT_ADD_CMD_OPT,${BL31},--soc-fw,true)),\
              $(eval $(call CERT_ADD_CMD_OPT,$(call IMG_BIN,31),--soc-fw,true)))
@@ -86,6 +87,7 @@
 $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_content.crt,--soc-fw-cert))
 $(eval $(call FIP_ADD_PAYLOAD,${BUILD_PLAT}/soc_fw_key.crt,--soc-fw-key-cert))
 endif
+endif
 
 # Add the BL32 CoT (key cert + img cert + image)
 ifeq (${NEED_BL32},yes)
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 13bd8f2..7284584 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -402,12 +402,20 @@
 	.validate_ns_entrypoint = arm_validate_psci_entrypoint,
 	.translate_power_state_by_mpidr = fvp_translate_power_state_by_mpidr,
 	.get_node_hw_state = fvp_node_hw_state,
+#if !ARM_BL31_IN_DRAM
+	/*
+	 * The TrustZone Controller is set up during the warmboot sequence after
+	 * resuming the CPU from a SYSTEM_SUSPEND. If BL31 is located in SRAM
+	 * this is  not a problem but, if it is in TZC-secured DRAM, it tries to
+	 * reconfigure the same memory it is running on, causing an exception.
+	 */
 	.get_sys_suspend_power_state = fvp_get_sys_suspend_power_state,
-/*
- * mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
- * as that would require mapping in all of NS DRAM into BL31 or BL32.
- */
+#endif
 #if !RESET_TO_BL31 && !RESET_TO_SP_MIN
+	/*
+	 * mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
+	 * as that would require mapping in all of NS DRAM into BL31 or BL32.
+	 */
 	.mem_protect_chk	= arm_psci_mem_protect_chk,
 	.read_mem_protect	= arm_psci_read_mem_protect,
 	.write_mem_protect	= arm_nor_psci_write_mem_protect,
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 310db7b..7080fc3 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -8,6 +8,7 @@
 #define __PLATFORM_DEF_H__
 
 #include <arm_def.h>
+#include <arm_spm_def.h>
 #include <board_arm_def.h>
 #include <common_def.h>
 #include <tzc400.h>
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index ccc7771..e475ece 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -128,6 +128,15 @@
  */
 #define PLAT_ARM_MAX_BL31_SIZE		0x1E000
 
+#if JUNO_AARCH32_EL3_RUNTIME
+/*
+ * PLAT_ARM_MAX_BL32_SIZE is calculated for SP_MIN as the AArch32 Secure
+ * Payload. We also need to take care of SCP_BL2 size as well, as the SCP_BL2
+ * is loaded into the space BL32 -> BL1_RW_BASE
+ */
+# define PLAT_ARM_MAX_BL32_SIZE		0x1E000
+#endif
+
 /*
  * Since free SRAM space is scant, enable the ASSERTION message size
  * optimization by fixing the PLAT_LOG_LEVEL_ASSERT to LOG_LEVEL_INFO (40).
diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c
index 2771e0f..cedef66 100644
--- a/plat/arm/board/juno/juno_bl2_setup.c
+++ b/plat/arm/board/juno/juno_bl2_setup.c
@@ -29,33 +29,4 @@
 
 	return err;
 }
-
-#if !CSS_USE_SCMI_SDS_DRIVER
-/*
- * We need to override some of the platform functions when booting SP_MIN
- * on Juno AArch32. These needs to be done only for SCPI/BOM SCP systems as
- * in case of SDS, the structures remain in memory and doesn't need to be
- * overwritten.
- */
-
-static unsigned int scp_boot_config;
-
-void bl2_early_platform_setup(meminfo_t *mem_layout)
-{
-	arm_bl2_early_platform_setup(mem_layout);
-
-	/* Save SCP Boot config before it gets overwritten by SCP_BL2 loading */
-	VERBOSE("BL2: Saving SCP Boot config = 0x%x\n", scp_boot_config);
-	scp_boot_config = mmio_read_32(SCP_BOOT_CFG_ADDR);
-}
-
-void bl2_platform_setup(void)
-{
-	arm_bl2_platform_setup();
-
-	mmio_write_32(SCP_BOOT_CFG_ADDR, scp_boot_config);
-	VERBOSE("BL2: Restored SCP Boot config = 0x%x\n", scp_boot_config);
-}
-#endif
-
 #endif /* JUNO_AARCH32_EL3_RUNTIME */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 8018b92..fee4391 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -31,6 +31,19 @@
 $(eval $(call assert_boolean,JUNO_AARCH32_EL3_RUNTIME))
 $(eval $(call add_define,JUNO_AARCH32_EL3_RUNTIME))
 
+ifeq (${JUNO_AARCH32_EL3_RUNTIME}, 1)
+# Include BL32 in FIP
+NEED_BL32		:= yes
+# BL31 is not required
+override BL31_SOURCES =
+
+# The BL32 needs to be built separately invoking the AARCH32 compiler and
+# be specifed via `BL32` build option.
+  ifneq (${ARCH}, aarch32)
+    override BL32_SOURCES =
+  endif
+endif
+
 ifeq (${ARCH},aarch64)
 BL1_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
 				lib/cpus/aarch64/cortex_a57.S		\
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index 23c0317..cf13326 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -74,8 +74,8 @@
 
 #else /* if defined(EL3_PAYLOAD_BASE) */
 
-	/* Allow secure access only to DRAM for EL3 payloads. */
-	tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
+	/* Allow Secure and Non-secure access to DRAM for EL3 payloads */
+	tzc400_configure_region0(TZC_REGION_S_RDWR, PLAT_ARM_TZC_NS_DEV_ACCESS);
 
 #endif /* EL3_PAYLOAD_BASE */
 
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 9b4800e..b4aafd4 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -49,13 +49,13 @@
 }
 
 #if !CSS_USE_SCMI_SDS_DRIVER
-# ifdef EL3_PAYLOAD_BASE
+# if defined(EL3_PAYLOAD_BASE) || JUNO_AARCH32_EL3_RUNTIME
 
 /*
  * We need to override some of the platform functions when booting an EL3
- * payload. These needs to be done only for SCPI/BOM SCP systems as
- * in case of SDS, the structures remain in memory and doesn't need to be
- * overwritten.
+ * payload or SP_MIN on Juno AArch32. This needs to be done only for
+ * SCPI/BOM SCP systems as in case of SDS, the structures remain in memory and
+ * don't need to be overwritten.
  */
 
 static unsigned int scp_boot_config;
diff --git a/plat/hisilicon/hikey960/hikey960_pm.c b/plat/hisilicon/hikey960/hikey960_pm.c
index 348cdba..078f0d8 100644
--- a/plat/hisilicon/hikey960/hikey960_pm.c
+++ b/plat/hisilicon/hikey960/hikey960_pm.c
@@ -26,6 +26,38 @@
 #define SYSTEM_PWR_STATE(state) \
 	((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
 
+#define PSTATE_WIDTH		4
+#define PSTATE_MASK		((1 << PSTATE_WIDTH) - 1)
+
+#define MAKE_PWRSTATE(lvl2_state, lvl1_state, lvl0_state, pwr_lvl, type) \
+		(((lvl2_state) << (PSTATE_ID_SHIFT + PSTATE_WIDTH * 2)) | \
+		 ((lvl1_state) << (PSTATE_ID_SHIFT + PSTATE_WIDTH)) | \
+		 ((lvl0_state) << (PSTATE_ID_SHIFT)) | \
+		 ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \
+		 ((type) << PSTATE_TYPE_SHIFT))
+
+/*
+ * The table storing the valid idle power states. Ensure that the
+ * array entries are populated in ascending order of state-id to
+ * enable us to use binary search during power state validation.
+ * The table must be terminated by a NULL entry.
+ */
+const unsigned int hikey960_pwr_idle_states[] = {
+	/* State-id - 0x001 */
+	MAKE_PWRSTATE(PLAT_MAX_RUN_STATE, PLAT_MAX_RUN_STATE,
+		      PLAT_MAX_STB_STATE, MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY),
+	/* State-id - 0x002 */
+	MAKE_PWRSTATE(PLAT_MAX_RUN_STATE, PLAT_MAX_RUN_STATE,
+		      PLAT_MAX_RET_STATE, MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY),
+	/* State-id - 0x003 */
+	MAKE_PWRSTATE(PLAT_MAX_RUN_STATE, PLAT_MAX_RUN_STATE,
+		      PLAT_MAX_OFF_STATE, MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN),
+	/* State-id - 0x033 */
+	MAKE_PWRSTATE(PLAT_MAX_RUN_STATE, PLAT_MAX_OFF_STATE,
+		      PLAT_MAX_OFF_STATE, MPIDR_AFFLVL1, PSTATE_TYPE_POWERDOWN),
+	0,
+};
+
 #define DMAC_GLB_REG_SEC	0x694
 #define AXI_CONF_BASE		0x820
 
@@ -36,16 +68,21 @@
 	unsigned long scr;
 	unsigned int val = 0;
 
-	assert(cpu_state == PLAT_MAX_RET_STATE);
+	assert(cpu_state == PLAT_MAX_STB_STATE ||
+	       cpu_state == PLAT_MAX_RET_STATE);
 
 	scr = read_scr_el3();
 
 	/* Enable Physical IRQ and FIQ to wake the CPU*/
 	write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT);
 
-	set_retention_ticks(val);
+	if (cpu_state == PLAT_MAX_RET_STATE)
+		set_retention_ticks(val);
+
 	wfi();
-	clr_retention_ticks(val);
+
+	if (cpu_state == PLAT_MAX_RET_STATE)
+		clr_retention_ticks(val);
 
 	/*
 	 * Restore SCR to the original value, synchronisazion of
@@ -124,38 +161,34 @@
 int hikey960_validate_power_state(unsigned int power_state,
 			       psci_power_state_t *req_state)
 {
-	int pstate = psci_get_pstate_type(power_state);
-	int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+	unsigned int state_id;
 	int i;
 
 	assert(req_state);
 
-	if (pwr_lvl > PLAT_MAX_PWR_LVL)
+	/*
+	 *  Currently we are using a linear search for finding the matching
+	 *  entry in the idle power state array. This can be made a binary
+	 *  search if the number of entries justify the additional complexity.
+	 */
+	for (i = 0; !!hikey960_pwr_idle_states[i]; i++) {
+		if (power_state == hikey960_pwr_idle_states[i])
+			break;
+	}
+
+	/* Return error if entry not found in the idle state array */
+	if (!hikey960_pwr_idle_states[i])
 		return PSCI_E_INVALID_PARAMS;
 
-	/* Sanity check the requested state */
-	if (pstate == PSTATE_TYPE_STANDBY) {
-		/*
-		 * It's possible to enter standby only on power level 0
-		 * Ignore any other power level.
-		 */
-		if (pwr_lvl != MPIDR_AFFLVL0)
-			return PSCI_E_INVALID_PARAMS;
+	i = 0;
+	state_id = psci_get_pstate_id(power_state);
 
-		req_state->pwr_domain_state[MPIDR_AFFLVL0] =
-					PLAT_MAX_RET_STATE;
-	} else {
-		for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
-			req_state->pwr_domain_state[i] =
-					PLAT_MAX_OFF_STATE;
+	/* Parse the State ID and populate the state info parameter */
+	while (state_id) {
+		req_state->pwr_domain_state[i++] = state_id & PSTATE_MASK;
+		state_id >>= PSTATE_WIDTH;
 	}
 
-	/*
-	 * We expect the 'state id' to be zero.
-	 */
-	if (psci_get_pstate_id(power_state))
-		return PSCI_E_INVALID_PARAMS;
-
 	return PSCI_E_SUCCESS;
 }
 
diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h
index cb76090..2ac7f2a 100644
--- a/plat/hisilicon/hikey960/include/platform_def.h
+++ b/plat/hisilicon/hikey960/include/platform_def.h
@@ -31,8 +31,10 @@
 #define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CORE_COUNT + \
 					 PLATFORM_CLUSTER_COUNT + 1)
 
-#define PLAT_MAX_RET_STATE		1
-#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_RUN_STATE		0
+#define PLAT_MAX_STB_STATE		1
+#define PLAT_MAX_RET_STATE		2
+#define PLAT_MAX_OFF_STATE		3
 
 #define MAX_IO_DEVICES			3
 #define MAX_IO_HANDLES			4
diff --git a/plat/mediatek/mt6795/bl31.ld.S b/plat/mediatek/mt6795/bl31.ld.S
index 0f60a0c..eacb1b2 100644
--- a/plat/mediatek/mt6795/bl31.ld.S
+++ b/plat/mediatek/mt6795/bl31.ld.S
@@ -5,6 +5,7 @@
  */
 
 #include <platform_def.h>
+#include <xlat_tables_defs.h>
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
@@ -29,7 +30,7 @@
         *(.vectors)
     } >RAM
 
-    ASSERT(. == ALIGN(4096),
+    ASSERT(. == ALIGN(PAGE_SIZE),
            "BL31_BASE address is not aligned on a page boundary.")
 
     ro . : {
@@ -58,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(4096);
+        . = NEXT(PAGE_SIZE);
         __RO_END__ = .;
     } >RAM
 
@@ -144,7 +145,7 @@
      * are not mixed with normal data.  This is required to set up the correct
      * memory attributes for the coherent data page tables.
      */
-    coherent_ram (NOLOAD) : ALIGN(4096) {
+    coherent_ram (NOLOAD) : ALIGN(PAGE_SIZE) {
         __COHERENT_RAM_START__ = .;
         /*
          * Bakery locks are stored in coherent memory
@@ -159,7 +160,7 @@
          * as device memory.  No other unexpected data must creep in.
          * Ensure the rest of the current memory page is unused.
          */
-        . = NEXT(4096);
+        . = NEXT(PAGE_SIZE);
         __COHERENT_RAM_END__ = .;
     } >RAM2
 #endif
diff --git a/plat/rockchip/rk3399/include/plat.ld.S b/plat/rockchip/rk3399/include/plat.ld.S
index c42d9a9..85f4dc3 100644
--- a/plat/rockchip/rk3399/include/plat.ld.S
+++ b/plat/rockchip/rk3399/include/plat.ld.S
@@ -6,6 +6,8 @@
 #ifndef __ROCKCHIP_PLAT_LD_S__
 #define __ROCKCHIP_PLAT_LD_S__
 
+#include <xlat_tables_defs.h>
+
 MEMORY {
     SRAM (rwx): ORIGIN = SRAM_BASE, LENGTH = SRAM_SIZE
     PMUSRAM (rwx): ORIGIN = PMUSRAM_BASE, LENGTH = PMUSRAM_RSIZE
@@ -14,7 +16,7 @@
 SECTIONS
 {
 	. = SRAM_BASE;
-	ASSERT(. == ALIGN(4096),
+	ASSERT(. == ALIGN(PAGE_SIZE),
 		"SRAM_BASE address is not aligned on a page boundary.")
 
 	/*
@@ -27,40 +29,40 @@
 	 * | sram data
 	 * ----------------
 	 */
-	.incbin_sram : ALIGN(4096) {
+	.incbin_sram : ALIGN(PAGE_SIZE) {
 		__sram_incbin_start = .;
 		*(.sram.incbin)
 		 __sram_incbin_real_end = .;
-		. = ALIGN(4096);
+		. = ALIGN(PAGE_SIZE);
 		__sram_incbin_end = .;
 	} >SRAM
 	ASSERT((__sram_incbin_real_end - __sram_incbin_start) <=
 		SRAM_BIN_LIMIT, ".incbin_sram has exceeded its limit")
 
-	.text_sram : ALIGN(4096) {
+	.text_sram : ALIGN(PAGE_SIZE) {
 		__bl31_sram_text_start = .;
 		*(.sram.text)
 		*(.sram.rodata)
 		__bl31_sram_text_real_end = .;
-		. = ALIGN(4096);
+		. = ALIGN(PAGE_SIZE);
 		__bl31_sram_text_end = .;
 	} >SRAM
 	ASSERT((__bl31_sram_text_real_end - __bl31_sram_text_start) <=
 		SRAM_TEXT_LIMIT, ".text_sram has exceeded its limit")
 
-	.data_sram : ALIGN(4096) {
+	.data_sram : ALIGN(PAGE_SIZE) {
 		__bl31_sram_data_start = .;
 		*(.sram.data)
 		__bl31_sram_data_real_end = .;
-		. = ALIGN(4096);
+		. = ALIGN(PAGE_SIZE);
 		__bl31_sram_data_end = .;
 	} >SRAM
 	ASSERT((__bl31_sram_data_real_end - __bl31_sram_data_start) <=
 		SRAM_DATA_LIMIT, ".data_sram has exceeded its limit")
 
-	.stack_sram : ALIGN(4096) {
+	.stack_sram : ALIGN(PAGE_SIZE) {
 		__bl31_sram_stack_start = .;
-		. += 4096;
+		. += PAGE_SIZE;
 		__bl31_sram_stack_end = .;
 	} >SRAM
 
diff --git a/plat/rockchip/rk3399/plat_sip_calls.c b/plat/rockchip/rk3399/plat_sip_calls.c
index 074dc19..2fbda67 100644
--- a/plat/rockchip/rk3399/plat_sip_calls.c
+++ b/plat/rockchip/rk3399/plat_sip_calls.c
@@ -11,6 +11,7 @@
 #include <plat_sip_calls.h>
 #include <rockchip_sip_svc.h>
 #include <runtime_svc.h>
+#include <stdint.h>
 
 #define RK_SIP_DDR_CFG		0x82000008
 #define DRAM_INIT		0x00
diff --git a/plat/rpi3/aarch64/plat_helpers.S b/plat/rpi3/aarch64/plat_helpers.S
new file mode 100644
index 0000000..76a542f
--- /dev/null
+++ b/plat/rpi3/aarch64/plat_helpers.S
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <platform_def.h>
+
+#include "../rpi3_hw.h"
+
+	.globl	plat_crash_console_flush
+	.globl	plat_crash_console_init
+	.globl	plat_crash_console_putc
+	.globl	platform_mem_init
+	.globl	plat_get_my_entrypoint
+	.globl	plat_is_my_cpu_primary
+	.globl	plat_my_core_pos
+	.globl	plat_reset_handler
+	.globl	plat_rpi3_calc_core_pos
+	.globl	plat_secondary_cold_boot_setup
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_my_core_pos(void)
+	 *
+	 *  This function uses the plat_rpi3_calc_core_pos()
+	 *  definition to get the index of the calling CPU.
+	 * -----------------------------------------------------
+	 */
+func plat_my_core_pos
+	mrs	x0, mpidr_el1
+	b	plat_rpi3_calc_core_pos
+endfunc plat_my_core_pos
+
+	/* -----------------------------------------------------
+	 *  unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr);
+	 *
+	 *  CorePos = (ClusterId * 4) + CoreId
+	 * -----------------------------------------------------
+	 */
+func plat_rpi3_calc_core_pos
+	and	x1, x0, #MPIDR_CPU_MASK
+	and	x0, x0, #MPIDR_CLUSTER_MASK
+	add	x0, x1, x0, LSR #6
+	ret
+endfunc plat_rpi3_calc_core_pos
+
+	/* -----------------------------------------------------
+	 * unsigned int plat_is_my_cpu_primary (void);
+	 *
+	 * Find out whether the current cpu is the primary
+	 * cpu.
+	 * -----------------------------------------------------
+	 */
+func plat_is_my_cpu_primary
+	mrs	x0, mpidr_el1
+	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+	cmp	x0, #RPI3_PRIMARY_CPU
+	cset	w0, eq
+	ret
+endfunc plat_is_my_cpu_primary
+
+	/* -----------------------------------------------------
+	 * void plat_secondary_cold_boot_setup (void);
+	 *
+	 * This function performs any platform specific actions
+	 * needed for a secondary cpu after a cold reset e.g
+	 * mark the cpu's presence, mechanism to place it in a
+	 * holding pen etc.
+	 * -----------------------------------------------------
+	 */
+func plat_secondary_cold_boot_setup
+	/* Calculate address of our hold entry */
+	bl	plat_my_core_pos
+	lsl	x0, x0, #3
+	mov_imm	x2, PLAT_RPI3_TM_HOLD_BASE
+	add	x0, x0, x2
+
+	/*
+	 * This code runs way before requesting the warmboot of this core,
+	 * so it is possible to clear the mailbox before getting a request
+	 * to boot.
+	 */
+	mov	x1, PLAT_RPI3_TM_HOLD_STATE_WAIT
+	str	x1,[x0]
+
+	/* Wait until we have a go */
+poll_mailbox:
+	wfe
+	ldr	x1, [x0]
+	cmp	x1, PLAT_RPI3_TM_HOLD_STATE_GO
+	bne	poll_mailbox
+
+	/* Jump to the provided entrypoint */
+	mov_imm	x0, PLAT_RPI3_TM_ENTRYPOINT
+	ldr	x1, [x0]
+	br	x1
+endfunc plat_secondary_cold_boot_setup
+
+	/* ---------------------------------------------------------------------
+	 * uintptr_t plat_get_my_entrypoint (void);
+	 *
+	 * Main job of this routine is to distinguish between a cold and a warm
+	 * boot.
+	 *
+	 * This functions returns:
+	 *  - 0 for a cold boot.
+	 *  - Any other value for a warm boot.
+	 * ---------------------------------------------------------------------
+	 */
+func plat_get_my_entrypoint
+	/* TODO: support warm boot */
+	mov	x0, #0
+	ret
+endfunc plat_get_my_entrypoint
+
+	/* ---------------------------------------------
+	 * void platform_mem_init (void);
+	 *
+	 * No need to carry out any memory initialization.
+	 * ---------------------------------------------
+	 */
+func platform_mem_init
+	ret
+endfunc platform_mem_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_init(void)
+	 * Function to initialize the crash console
+	 * without a C Runtime to print crash report.
+	 * Clobber list : x0 - x3
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_init
+	mov_imm	x0, PLAT_RPI3_UART_BASE
+	mov_imm	x1, PLAT_RPI3_UART_CLK_IN_HZ
+	mov_imm	x2, PLAT_RPI3_UART_BAUDRATE
+	b	console_core_init
+endfunc plat_crash_console_init
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_putc(int c)
+	 * Function to print a character on the crash
+	 * console without a C Runtime.
+	 * Clobber list : x1, x2
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_putc
+	mov_imm	x1, PLAT_RPI3_UART_BASE
+	b	console_core_putc
+endfunc plat_crash_console_putc
+
+	/* ---------------------------------------------
+	 * int plat_crash_console_flush()
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func plat_crash_console_flush
+	mov_imm	x1, PLAT_RPI3_UART_BASE
+	b	console_core_flush
+endfunc plat_crash_console_flush
+
+	/* ---------------------------------------------
+	 * void plat_reset_handler(void);
+	 * ---------------------------------------------
+	 */
+func plat_reset_handler
+	/* use the 19.2 MHz clock for the architected timer */
+	mov	x0, #RPI3_INTC_BASE_ADDRESS
+	mov	w1, #0x80000000
+	str	wzr, [x0, #RPI3_INTC_CONTROL_OFFSET]
+	str	w1, [x0, #RPI3_INTC_PRESCALER_OFFSET]
+
+	/* wire mailbox 3 to the FIQ line */
+	mov	w1, RPI3_INTC_MBOX_CONTROL_SLOT3_FIQ
+	str	w1, [x0, #RPI3_INTC_MBOX_CONTROL_OFFSET]
+	ret
+endfunc plat_reset_handler
diff --git a/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c b/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c
new file mode 100644
index 0000000..e3acfe9
--- /dev/null
+++ b/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+
+	/* Fill BL31 related information */
+	{
+		.image_id = BL31_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE | EP_FIRST_EXE),
+		.ep_info.pc = BL31_BASE,
+		.ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+					DISABLE_ALL_EXCEPTIONS),
+#if DEBUG
+		.ep_info.args.arg1 = RPI3_BL31_PLAT_PARAM_VAL,
+#endif
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_PLAT_SETUP),
+		.image_info.image_base = BL31_BASE,
+		.image_info.image_max_size = BL31_LIMIT - BL31_BASE,
+
+# ifdef BL32_BASE
+		.next_handoff_image_id = BL32_IMAGE_ID,
+# else
+		.next_handoff_image_id = BL33_IMAGE_ID,
+# endif
+	},
+
+# ifdef BL32_BASE
+	/* Fill BL32 related information */
+	{
+		.image_id = BL32_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | EXECUTABLE),
+		.ep_info.pc = BL32_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t, 0),
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+		.next_handoff_image_id = BL33_IMAGE_ID,
+	},
+
+	/*
+	 * Fill BL32 external 1 related information.
+	 * A typical use for extra1 image is with OP-TEE where it is the pager
+	 * image.
+	 */
+	{
+		.image_id = BL32_EXTRA1_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+		.image_info.image_base = BL32_BASE,
+		.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+
+	/*
+	 * Fill BL32 external 2 related information.
+	 * A typical use for extra2 image is with OP-TEE where it is the paged
+	 * image.
+	 */
+	{
+		.image_id = BL32_EXTRA2_IMAGE_ID,
+
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      SECURE | NON_EXECUTABLE),
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	},
+# endif /* BL32_BASE */
+
+	/* Fill BL33 related information */
+	{
+		.image_id = BL33_IMAGE_ID,
+		SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+				      VERSION_2, entry_point_info_t,
+				      NON_SECURE | EXECUTABLE),
+# ifdef PRELOADED_BL33_BASE
+		.ep_info.pc = PRELOADED_BL33_BASE,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t,
+				      IMAGE_ATTRIB_SKIP_LOADING),
+# else
+		.ep_info.pc = PLAT_RPI3_NS_IMAGE_OFFSET,
+
+		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+				      VERSION_2, image_info_t, 0),
+		.image_info.image_base = PLAT_RPI3_NS_IMAGE_OFFSET,
+		.image_info.image_max_size = PLAT_RPI3_NS_IMAGE_MAX_SIZE,
+# endif /* PRELOADED_BL33_BASE */
+
+		.next_handoff_image_id = INVALID_IMAGE_ID,
+	}
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/rpi3/include/plat_macros.S b/plat/rpi3/include/plat_macros.S
new file mode 100644
index 0000000..f5e057e
--- /dev/null
+++ b/plat/rpi3/include/plat_macros.S
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <arm_macros.S>
+#include <platform_def.h>
+
+	/* ---------------------------------------------
+	 * The below required platform porting macro
+	 * prints out relevant platform registers
+	 * whenever an unhandled exception is taken in
+	 * BL31.
+	 * Clobbers: x0 - x10, x16, x17, sp
+	 * ---------------------------------------------
+	 */
+	.macro plat_crash_print_regs
+	.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi3/include/platform_def.h
new file mode 100644
index 0000000..5e2f1da
--- /dev/null
+++ b/plat/rpi3/include/platform_def.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <tbbr_img_def.h>
+#include <utils_def.h>
+
+#include "../rpi3_hw.h"
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define RPI3_BL31_PLAT_PARAM_VAL	ULL(0x0F1E2D3C4B5A6978)
+
+#define PLATFORM_STACK_SIZE		ULL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT		PLATFORM_CLUSTER0_CORE_COUNT
+
+#define RPI3_PRIMARY_CPU		U(0)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL1
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET		U(1)
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains.
+ */
+#define PLAT_LOCAL_STATE_OFF		U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH		U(4)
+#define PLAT_LOCAL_PSTATE_MASK		((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Partition memory into secure ROM, non-secure DRAM, secure "SRAM", and
+ * secure DRAM. Note that this is all actually DRAM with different names,
+ * there is no Secure RAM in the Raspberry Pi 3.
+ */
+#define SEC_ROM_BASE			ULL(0x00000000)
+#define SEC_ROM_SIZE			ULL(0x00010000)
+
+/* FIP placed after ROM to append it to BL1 with very little padding. */
+#define PLAT_RPI3_FIP_BASE		ULL(0x00010000)
+#define PLAT_RPI3_FIP_MAX_SIZE		ULL(0x001F0000)
+
+/* We have 16M of memory reserved at at 256M */
+#define SEC_SRAM_BASE			ULL(0x10000000)
+#define SEC_SRAM_SIZE			ULL(0x00100000)
+
+#define SEC_DRAM0_BASE			ULL(0x10100000)
+#define SEC_DRAM0_SIZE			ULL(0x00200000)
+
+#define NS_DRAM0_BASE			ULL(0x10300000)
+#define NS_DRAM0_SIZE			ULL(0x00D00000)
+/* End of reserved memory */
+
+/*
+ * BL33 entrypoint.
+ */
+#define PLAT_RPI3_NS_IMAGE_OFFSET	NS_DRAM0_BASE
+#define PLAT_RPI3_NS_IMAGE_MAX_SIZE	NS_DRAM0_SIZE
+
+/*
+ * I/O registers.
+ */
+#define DEVICE0_BASE			RPI3_IO_BASE
+#define DEVICE0_SIZE			RPI3_IO_SIZE
+
+/*
+ * Arm TF lives in SRAM, partition it here
+ */
+#define SHARED_RAM_BASE			SEC_SRAM_BASE
+#define SHARED_RAM_SIZE			ULL(0x00001000)
+
+#define BL_RAM_BASE			(SHARED_RAM_BASE + SHARED_RAM_SIZE)
+#define BL_RAM_SIZE			(SEC_SRAM_SIZE - SHARED_RAM_SIZE)
+
+/*
+ * Mailbox to control the secondary cores.All secondary cores are held in a wait
+ * loop in cold boot. To release them perform the following steps (plus any
+ * additional barriers that may be needed):
+ *
+ *     uint64_t *entrypoint = (uint64_t *)PLAT_RPI3_TM_ENTRYPOINT;
+ *     *entrypoint = ADDRESS_TO_JUMP_TO;
+ *
+ *     uint64_t *mbox_entry = (uint64_t *)PLAT_RPI3_TM_HOLD_BASE;
+ *     mbox_entry[cpu_id] = PLAT_RPI3_TM_HOLD_STATE_GO;
+ *
+ *     sev();
+ */
+#define PLAT_RPI3_TRUSTED_MAILBOX_BASE	SHARED_RAM_BASE
+
+#define PLAT_RPI3_TM_ENTRYPOINT		PLAT_RPI3_TRUSTED_MAILBOX_BASE
+#define PLAT_RPI3_TM_ENTRYPOINT_SIZE	ULL(8)
+
+#define PLAT_RPI3_TM_HOLD_BASE		(PLAT_RPI3_TM_ENTRYPOINT + \
+					 PLAT_RPI3_TM_ENTRYPOINT_SIZE)
+#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE	ULL(8)
+#define PLAT_RPI3_TM_HOLD_SIZE		(PLAT_RPI3_TM_HOLD_ENTRY_SIZE * \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_RPI3_TRUSTED_MAILBOX_SIZE	(PLAT_RPI3_TM_ENTRYPOINT_SIZE + \
+					 PLAT_RPI3_TM_HOLD_SIZE)
+
+#define PLAT_RPI3_TM_HOLD_STATE_WAIT	ULL(0)
+#define PLAT_RPI3_TM_HOLD_STATE_GO	ULL(1)
+
+/*
+ * BL1 specific defines.
+ *
+ * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
+ * addresses.
+ *
+ * Put BL1 RW at the top of the Secure SRAM. BL1_RW_BASE is calculated using
+ * the current BL1 RW debug size plus a little space for growth.
+ */
+#define PLAT_MAX_BL1_RW_SIZE		ULL(0x12000)
+
+#define BL1_RO_BASE			SEC_ROM_BASE
+#define BL1_RO_LIMIT			(SEC_ROM_BASE + SEC_ROM_SIZE)
+#define BL1_RW_BASE			(BL1_RW_LIMIT - PLAT_MAX_BL1_RW_SIZE)
+#define BL1_RW_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE)
+
+/*
+ * BL2 specific defines.
+ *
+ * Put BL2 just below BL31. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
+#define PLAT_MAX_BL2_SIZE		ULL(0x2C000)
+
+#define BL2_BASE			(BL2_LIMIT - PLAT_MAX_BL2_SIZE)
+#define BL2_LIMIT			BL31_BASE
+
+/*
+ * BL31 specific defines.
+ *
+ * Put BL31 at the top of the Trusted SRAM. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define PLAT_MAX_BL31_SIZE		ULL(0x20000)
+
+#define BL31_BASE			(BL31_LIMIT - PLAT_MAX_BL31_SIZE)
+#define BL31_LIMIT			(BL_RAM_BASE + BL_RAM_SIZE)
+#define BL31_PROGBITS_LIMIT		BL1_RW_BASE
+
+/*
+ * BL32 specific defines.
+ *
+ * BL32 can execute from Secure SRAM or Secure DRAM.
+ */
+#define BL32_SRAM_BASE			BL_RAM_BASE
+#define BL32_SRAM_LIMIT			BL31_BASE
+#define BL32_DRAM_BASE			SEC_DRAM0_BASE
+#define BL32_DRAM_LIMIT			(SEC_DRAM0_BASE + SEC_DRAM0_SIZE)
+
+#define SEC_SRAM_ID			0
+#define SEC_DRAM_ID			1
+
+#if RPI3_BL32_RAM_LOCATION_ID == SEC_SRAM_ID
+# define BL32_MEM_BASE			BL_RAM_BASE
+# define BL32_MEM_SIZE			BL_RAM_SIZE
+# define BL32_BASE			BL32_SRAM_BASE
+# define BL32_LIMIT			BL32_SRAM_LIMIT
+#elif RPI3_BL32_RAM_LOCATION_ID == SEC_DRAM_ID
+# define BL32_MEM_BASE			SEC_DRAM0_BASE
+# define BL32_MEM_SIZE			SEC_DRAM0_SIZE
+# define BL32_BASE			BL32_DRAM_BASE
+# define BL32_LIMIT			BL32_DRAM_LIMIT
+#else
+# error "Unsupported RPI3_BL32_RAM_LOCATION_ID value"
+#endif
+#define BL32_SIZE			(BL32_LIMIT - BL32_BASE)
+
+#ifdef SPD_none
+#undef BL32_BASE
+#endif /* SPD_none */
+
+/*
+ * Other memory-related defines.
+ */
+#define ADDR_SPACE_SIZE			(ULL(1) << 32)
+
+#define MAX_MMAP_REGIONS		U(8)
+#define MAX_XLAT_TABLES			U(4)
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+/*
+ * Serial-related constants.
+ */
+#define PLAT_RPI3_UART_BASE		RPI3_MINI_UART_BASE
+#define PLAT_RPI3_UART_CLK_IN_HZ	RPI3_MINI_UART_CLK_IN_HZ
+#define PLAT_RPI3_UART_BAUDRATE		ULL(115200)
+
+/*
+ * System counter
+ */
+#define SYS_COUNTER_FREQ_IN_TICKS	ULL(19200000)
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
new file mode 100644
index 0000000..821f801
--- /dev/null
+++ b/plat/rpi3/platform.mk
@@ -0,0 +1,113 @@
+#
+# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+PLAT_INCLUDES		:=	-Iinclude/common/tbbr			\
+				-Iinclude/plat/arm/common/		\
+				-Iinclude/plat/arm/common/aarch64/	\
+				-Iplat/rpi3/include
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/console/aarch64/console.S	\
+				drivers/ti/uart/aarch64/16550_console.S	\
+				plat/rpi3/rpi3_common.c
+
+BL1_SOURCES		+=	drivers/io/io_fip.c			\
+				drivers/io/io_memmap.c			\
+				drivers/io/io_storage.c			\
+				lib/cpus/aarch64/cortex_a53.S		\
+				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
+
+BL2_SOURCES		+=	common/desc_image_load.c		\
+				drivers/io/io_fip.c			\
+				drivers/io/io_memmap.c			\
+				drivers/io/io_storage.c			\
+				plat/common/aarch64/platform_mp_stack.S	\
+				plat/rpi3/aarch64/plat_helpers.S	\
+				plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \
+				plat/rpi3/rpi3_bl2_setup.c		\
+				plat/rpi3/rpi3_image_load.c		\
+				plat/rpi3/rpi3_io_storage.c
+
+BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a53.S		\
+				plat/common/aarch64/plat_psci_common.c	\
+				plat/rpi3/aarch64/plat_helpers.S	\
+				plat/rpi3/rpi3_bl31_setup.c		\
+				plat/rpi3/rpi3_pm.c			\
+				plat/rpi3/rpi3_topology.c
+
+# Translation tables library
+include lib/xlat_tables_v2/xlat_tables.mk
+
+PLAT_BL_COMMON_SOURCES	+=	${XLAT_TABLES_LIB_SRCS}
+
+# Tune compiler for Cortex-A53
+ifeq ($(notdir $(CC)),armclang)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a53
+else
+    TF_CFLAGS_aarch64	+=	-mtune=cortex-a53
+endif
+
+# Build config flags
+# ------------------
+
+# Enable all errata workarounds for Cortex-A53
+ERRATA_A53_826319		:= 1
+ERRATA_A53_835769		:= 1
+ERRATA_A53_836870		:= 1
+ERRATA_A53_843419		:= 1
+ERRATA_A53_855873		:= 1
+
+# Disable the PSCI platform compatibility layer by default
+ENABLE_PLAT_COMPAT		:= 0
+
+# Enable reset to BL31 by default
+RESET_TO_BL31			:= 1
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA	:= 1
+
+# Use Coherent memory
+USE_COHERENT_MEM		:= 1
+
+# Enable new version of image loading
+LOAD_IMAGE_V2			:= 1
+
+# Platform build flags
+# --------------------
+
+# BL33 images are in AArch64 by default
+RPI3_BL33_IN_AARCH32		:= 0
+
+# BL32 location
+RPI3_BL32_RAM_LOCATION	:= tdram
+ifeq (${RPI3_BL32_RAM_LOCATION}, tsram)
+  RPI3_BL32_RAM_LOCATION_ID = SEC_SRAM_ID
+else ifeq (${RPI3_BL32_RAM_LOCATION}, tdram)
+  RPI3_BL32_RAM_LOCATION_ID = SEC_DRAM_ID
+else
+  $(error "Unsupported RPI3_BL32_RAM_LOCATION value")
+endif
+
+# Process platform flags
+# ----------------------
+
+$(eval $(call add_define,RPI3_BL32_RAM_LOCATION_ID))
+$(eval $(call add_define,RPI3_BL33_IN_AARCH32))
+
+# Verify build config
+# -------------------
+
+ifneq (${LOAD_IMAGE_V2}, 1)
+  $(error Error: rpi3 needs LOAD_IMAGE_V2=1)
+endif
+
+ifeq (${ARCH},aarch32)
+  $(error Error: AArch32 not supported on rpi3)
+endif
diff --git a/plat/rpi3/rpi3_bl1_setup.c b/plat/rpi3/rpi3_bl1_setup.c
new file mode 100644
index 0000000..11c0f4a
--- /dev/null
+++ b/plat/rpi3/rpi3_bl1_setup.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <bl_common.h>
+#include <console.h>
+#include <platform_def.h>
+#include <xlat_mmu_helpers.h>
+#include <xlat_tables_defs.h>
+
+#include "../../bl1/bl1_private.h"
+#include "rpi3_private.h"
+
+/* 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)
+{
+	return &bl1_tzram_layout;
+}
+
+/*******************************************************************************
+ * Perform any BL1 specific platform actions.
+ ******************************************************************************/
+void bl1_early_platform_setup(void)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PLAT_RPI3_UART_BASE, PLAT_RPI3_UART_CLK_IN_HZ,
+		     PLAT_RPI3_UART_BAUDRATE);
+
+	/* Allow BL1 to see the whole Trusted RAM */
+	bl1_tzram_layout.total_base = BL_RAM_BASE;
+	bl1_tzram_layout.total_size = BL_RAM_SIZE;
+}
+
+/******************************************************************************
+ * Perform the very early platform specific architecture setup.  This only
+ * does basic initialization. Later architectural setup (bl1_arch_setup())
+ * does not do anything platform specific.
+ *****************************************************************************/
+void bl1_plat_arch_setup(void)
+{
+	rpi3_setup_page_tables(bl1_tzram_layout.total_base,
+			       bl1_tzram_layout.total_size,
+			       BL_CODE_BASE, BL1_CODE_END,
+			       BL1_RO_DATA_BASE, BL1_RO_DATA_END
+#if USE_COHERENT_MEM
+			       , BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END
+#endif
+			      );
+
+	enable_mmu_el3(0);
+}
+
+void bl1_platform_setup(void)
+{
+	/* Initialise the IO layer and register platform IO devices */
+	plat_rpi3_io_setup();
+}
diff --git a/plat/rpi3/rpi3_bl2_setup.c b/plat/rpi3/rpi3_bl2_setup.c
new file mode 100644
index 0000000..1fd822e
--- /dev/null
+++ b/plat/rpi3/rpi3_bl2_setup.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <desc_image_load.h>
+#include <platform_def.h>
+#include <xlat_mmu_helpers.h>
+#include <xlat_tables_defs.h>
+
+#include "rpi3_private.h"
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+
+/*******************************************************************************
+ * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
+ * 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 bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PLAT_RPI3_UART_BASE, PLAT_RPI3_UART_CLK_IN_HZ,
+		     PLAT_RPI3_UART_BAUDRATE);
+
+	/* Setup the BL2 memory layout */
+	bl2_tzram_layout = *mem_layout;
+
+	plat_rpi3_io_setup();
+}
+
+void bl2_platform_setup(void)
+{
+	/*
+	 * This is where a TrustZone address space controller and other
+	 * security related peripherals, would be configured.
+	 */
+}
+
+/*******************************************************************************
+ * Perform the very early platform specific architectural setup here.
+ ******************************************************************************/
+void bl2_plat_arch_setup(void)
+{
+	rpi3_setup_page_tables(bl2_tzram_layout.total_base,
+			       bl2_tzram_layout.total_size,
+			       BL_CODE_BASE, BL_CODE_END,
+			       BL_RO_DATA_BASE, BL_RO_DATA_END
+#if USE_COHERENT_MEM
+			       , BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END
+#endif
+			      );
+
+	enable_mmu_el1(0);
+}
+
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+	int err = 0;
+	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+
+	assert(bl_mem_params != NULL);
+
+	switch (image_id) {
+	case BL32_IMAGE_ID:
+		bl_mem_params->ep_info.spsr = rpi3_get_spsr_for_bl32_entry();
+		break;
+
+	case BL33_IMAGE_ID:
+		/* BL33 expects to receive the primary CPU MPID (through r0) */
+		bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
+		bl_mem_params->ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
+		break;
+
+	}
+
+	return err;
+}
diff --git a/plat/rpi3/rpi3_bl31_setup.c b/plat/rpi3/rpi3_bl31_setup.c
new file mode 100644
index 0000000..3913356
--- /dev/null
+++ b/plat/rpi3/rpi3_bl31_setup.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <xlat_mmu_helpers.h>
+#include <xlat_tables_defs.h>
+
+#include "rpi3_private.h"
+
+#define BL31_END	(uintptr_t)(&__BL31_END__)
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * 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)
+{
+	entry_point_info_t *next_image_info;
+
+	assert(sec_state_is_valid(type) != 0);
+
+	next_image_info = (type == NON_SECURE)
+			? &bl33_image_ep_info : &bl32_image_ep_info;
+
+	/* None of the images can have 0x0 as the entrypoint. */
+	if (next_image_info->pc) {
+		return next_image_info;
+	} else {
+		return NULL;
+	}
+}
+
+/*******************************************************************************
+ * Perform any BL31 early platform setup. Here is an opportunity to copy
+ * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before
+ * they are lost (potentially). This needs to be done before the MMU is
+ * initialized so that the memory layout can be used while creating page
+ * tables. BL2 has flushed this information to memory, so we are guaranteed
+ * to pick up good data.
+ ******************************************************************************/
+void bl31_early_platform_setup(void *from_bl2,
+			       void *plat_params_from_bl2)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PLAT_RPI3_UART_BASE, PLAT_RPI3_UART_CLK_IN_HZ,
+		     PLAT_RPI3_UART_BAUDRATE);
+
+#if RESET_TO_BL31
+
+	/* There are no parameters from BL2 if BL31 is a reset vector */
+	assert(from_bl2 == NULL);
+	assert(plat_params_from_bl2 == NULL);
+
+#ifdef BL32_BASE
+	/* Populate entry point information for BL32 */
+	SET_PARAM_HEAD(&bl32_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = rpi3_get_spsr_for_bl32_entry();
+#endif /* BL32_BASE */
+
+	/* Populate entry point information for BL33 */
+	SET_PARAM_HEAD(&bl33_image_ep_info,
+				PARAM_EP,
+				VERSION_1,
+				0);
+	/*
+	 * Tell BL31 where the non-trusted software image
+	 * is located and the entry state information
+	 */
+	bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+
+	bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
+	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#else /* RESET_TO_BL31 */
+
+	/*
+	 * In debug builds, we pass a special value in 'plat_params_from_bl2'
+	 * to verify platform parameters from BL2 to BL31.
+	 * In release builds, it's not used.
+	 */
+	assert(((uintptr_t)plat_params_from_bl2) == RPI3_BL31_PLAT_PARAM_VAL);
+
+	/*
+	 * Check params passed from BL2 should not be NULL,
+	 */
+	bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+
+	assert(params_from_bl2 != NULL);
+	assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+	assert(params_from_bl2->h.version >= VERSION_2);
+
+	bl_params_node_t *bl_params = params_from_bl2->head;
+
+	/*
+	 * Copy BL33 and BL32 (if present), entry point information.
+	 * They are stored in Secure RAM, in BL2's address space.
+	 */
+	while (bl_params) {
+		if (bl_params->image_id == BL32_IMAGE_ID) {
+			bl32_image_ep_info = *bl_params->ep_info;
+		}
+
+		if (bl_params->image_id == BL33_IMAGE_ID) {
+			bl33_image_ep_info = *bl_params->ep_info;
+		}
+
+		bl_params = bl_params->next_params_info;
+	}
+
+	if (bl33_image_ep_info.pc == 0) {
+		panic();
+	}
+
+#endif /* RESET_TO_BL31 */
+}
+
+void bl31_plat_arch_setup(void)
+{
+	rpi3_setup_page_tables(BL31_BASE, BL31_END - BL31_BASE,
+			       BL_CODE_BASE, BL_CODE_END,
+			       BL_RO_DATA_BASE, BL_RO_DATA_END
+#if USE_COHERENT_MEM
+			       , BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END
+#endif
+			      );
+
+	enable_mmu_el3(0);
+}
+
+void bl31_platform_setup(void)
+{
+#if RESET_TO_BL31
+	/*
+	 * Do initial security configuration to allow DRAM/device access
+	 * (if earlier BL has not already done so).
+	 */
+#endif /* RESET_TO_BL31 */
+
+	return;
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	/* Initialize the runtime console */
+	console_init(PLAT_RPI3_UART_BASE, PLAT_RPI3_UART_CLK_IN_HZ,
+		     PLAT_RPI3_UART_BAUDRATE);
+}
diff --git a/plat/rpi3/rpi3_common.c b/plat/rpi3/rpi3_common.c
new file mode 100644
index 0000000..97dce09
--- /dev/null
+++ b/plat/rpi3/rpi3_common.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <interrupt_mgmt.h>
+#include <platform_def.h>
+#include <xlat_tables_v2.h>
+
+#include "rpi3_hw.h"
+#include "rpi3_private.h"
+
+#define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
+					DEVICE0_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+#define MAP_SHARED_RAM	MAP_REGION_FLAT(SHARED_RAM_BASE,		\
+					SHARED_RAM_SIZE,		\
+					MT_DEVICE  | MT_RW | MT_SECURE)
+
+#define MAP_NS_DRAM0	MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE,	\
+					MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_FIP		MAP_REGION_FLAT(PLAT_RPI3_FIP_BASE,		\
+					PLAT_RPI3_FIP_MAX_SIZE,		\
+					MT_MEMORY | MT_RO | MT_NS)
+
+#define MAP_BL32_MEM	MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE,	\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
+ * Table of regions for various BL stages to map using the MMU.
+ */
+#ifdef IMAGE_BL1
+static const mmap_region_t plat_rpi3_mmap[] = {
+	MAP_SHARED_RAM,
+	MAP_DEVICE0,
+	MAP_FIP,
+	{0}
+};
+#endif
+
+#ifdef IMAGE_BL2
+static const mmap_region_t plat_rpi3_mmap[] = {
+	MAP_SHARED_RAM,
+	MAP_DEVICE0,
+	MAP_FIP,
+	MAP_NS_DRAM0,
+#ifdef BL32_BASE
+	MAP_BL32_MEM,
+#endif
+	{0}
+};
+#endif
+
+#ifdef IMAGE_BL31
+static const mmap_region_t plat_rpi3_mmap[] = {
+	MAP_SHARED_RAM,
+	MAP_DEVICE0,
+#ifdef BL32_BASE
+	MAP_BL32_MEM,
+#endif
+	{0}
+};
+#endif
+
+/*******************************************************************************
+ * Function that sets up the translation tables.
+ ******************************************************************************/
+void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
+			    uintptr_t code_start, uintptr_t code_limit,
+			    uintptr_t rodata_start, uintptr_t rodata_limit
+#if USE_COHERENT_MEM
+			    , uintptr_t coh_start, uintptr_t coh_limit
+#endif
+			    )
+{
+	/*
+	 * Map the Trusted SRAM with appropriate memory attributes.
+	 * Subsequent mappings will adjust the attributes for specific regions.
+	 */
+	VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
+		(void *) total_base, (void *) (total_base + total_size));
+	mmap_add_region(total_base, total_base,
+			total_size,
+			MT_MEMORY | MT_RW | MT_SECURE);
+
+	/* Re-map the code section */
+	VERBOSE("Code region: %p - %p\n",
+		(void *) code_start, (void *) code_limit);
+	mmap_add_region(code_start, code_start,
+			code_limit - code_start,
+			MT_CODE | MT_SECURE);
+
+	/* Re-map the read-only data section */
+	VERBOSE("Read-only data region: %p - %p\n",
+		(void *) rodata_start, (void *) rodata_limit);
+	mmap_add_region(rodata_start, rodata_start,
+			rodata_limit - rodata_start,
+			MT_RO_DATA | MT_SECURE);
+
+#if USE_COHERENT_MEM
+	/* Re-map the coherent memory region */
+	VERBOSE("Coherent region: %p - %p\n",
+		(void *) coh_start, (void *) coh_limit);
+	mmap_add_region(coh_start, coh_start,
+			coh_limit - coh_start,
+			MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+	mmap_add(plat_rpi3_mmap);
+
+	init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Return entrypoint of BL33.
+ ******************************************************************************/
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+#ifdef PRELOADED_BL33_BASE
+	return PRELOADED_BL33_BASE;
+#else
+	return PLAT_RPI3_NS_IMAGE_OFFSET;
+#endif
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL32 entry
+ ******************************************************************************/
+uint32_t rpi3_get_spsr_for_bl32_entry(void)
+{
+	/*
+	 * The Secure Payload Dispatcher service is responsible for
+	 * setting the SPSR prior to entry into the BL32 image.
+	 */
+	return 0;
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+uint32_t rpi3_get_spsr_for_bl33_entry(void)
+{
+#if RPI3_BL33_IN_AARCH32
+	INFO("BL33 will boot in Non-secure AArch32 Hypervisor mode\n");
+	return SPSR_MODE32(MODE32_hyp, SPSR_T_ARM, SPSR_E_LITTLE,
+			   DISABLE_ALL_EXCEPTIONS);
+#else
+	return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+#endif
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return SYS_COUNTER_FREQ_IN_TICKS;
+}
+
+uint32_t plat_ic_get_pending_interrupt_type(void)
+{
+	return INTR_TYPE_INVAL;
+}
diff --git a/plat/rpi3/rpi3_hw.h b/plat/rpi3/rpi3_hw.h
new file mode 100644
index 0000000..70272e0
--- /dev/null
+++ b/plat/rpi3/rpi3_hw.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __RPI3_HW__
+#define __RPI3_HW__
+
+#include <utils_def.h>
+
+/*
+ * Peripherals
+ */
+
+#define RPI3_IO_BASE			ULL(0x3F000000)
+#define RPI3_IO_SIZE			ULL(0x01000000)
+
+/*
+ * 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)
+
+/*
+ * Power management, reset controller, watchdog.
+ */
+#define RPI3_IO_PM_OFFSET		ULL(0x00100000)
+#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_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)
+
+/*
+ * Local interrupt controller
+ */
+#define RPI3_INTC_BASE_ADDRESS			ULL(0x40000000)
+/* Registers on top of RPI3_INTC_BASE_ADDRESS */
+#define RPI3_INTC_CONTROL_OFFSET		ULL(0x00000000)
+#define RPI3_INTC_PRESCALER_OFFSET		ULL(0x00000008)
+#define RPI3_INTC_MBOX_CONTROL_OFFSET		ULL(0x00000050)
+#define RPI3_INTC_MBOX_CONTROL_SLOT3_FIQ	ULL(0x00000080)
+#define RPI3_INTC_PENDING_FIQ_OFFSET		ULL(0x00000070)
+#define RPI3_INTC_PENDING_FIQ_MBOX3		ULL(0x00000080)
+
+#endif /* __RPI3_HW__ */
diff --git a/plat/rpi3/rpi3_image_load.c b/plat/rpi3/rpi3_image_load.c
new file mode 100644
index 0000000..fad9e4f
--- /dev/null
+++ b/plat/rpi3/rpi3_image_load.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * This function flushes the data structures so that they are visible
+ * in memory for the next BL image.
+ ******************************************************************************/
+void plat_flush_next_bl_params(void)
+{
+	flush_bl_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of loadable images.
+ ******************************************************************************/
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+	return get_bl_load_info_from_mem_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images.
+ ******************************************************************************/
+bl_params_t *plat_get_next_bl_params(void)
+{
+	return get_next_bl_params_from_mem_params_desc();
+}
diff --git a/plat/rpi3/rpi3_io_storage.c b/plat/rpi3/rpi3_io_storage.c
new file mode 100644
index 0000000..7ac45ef
--- /dev/null
+++ b/plat/rpi3/rpi3_io_storage.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <firmware_image_package.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <platform_def.h>
+#include <string.h>
+
+/* Semihosting filenames */
+#define BL2_IMAGE_NAME			"bl2.bin"
+#define BL31_IMAGE_NAME			"bl31.bin"
+#define BL32_IMAGE_NAME			"bl32.bin"
+#define BL33_IMAGE_NAME			"bl33.bin"
+
+#if TRUSTED_BOARD_BOOT
+#define BL2_CERT_NAME			"bl2.crt"
+#define TRUSTED_KEY_CERT_NAME		"trusted_key.crt"
+#define BL31_KEY_CERT_NAME		"bl31_key.crt"
+#define BL32_KEY_CERT_NAME		"bl32_key.crt"
+#define BL33_KEY_CERT_NAME		"bl33_key.crt"
+#define BL31_CERT_NAME			"bl31.crt"
+#define BL32_CERT_NAME			"bl32.crt"
+#define BL33_CERT_NAME			"bl33.crt"
+#endif /* TRUSTED_BOARD_BOOT */
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+	.offset = PLAT_RPI3_FIP_BASE,
+	.length = PLAT_RPI3_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t bl2_uuid_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t bl31_uuid_spec = {
+	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+
+static const io_uuid_spec_t bl32_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+
+static const io_uuid_spec_t bl33_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t bl2_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT,
+};
+
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+	.uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t bl31_key_cert_uuid_spec = {
+	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT,
+};
+
+static const io_uuid_spec_t bl32_key_cert_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_KEY_CERT,
+};
+
+static const io_uuid_spec_t bl33_key_cert_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT,
+};
+
+static const io_uuid_spec_t bl31_cert_uuid_spec = {
+	.uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT,
+};
+
+static const io_uuid_spec_t bl32_cert_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_CERT,
+};
+
+static const io_uuid_spec_t bl33_cert_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
+static int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+	uintptr_t *dev_handle;
+	uintptr_t image_spec;
+	int (*check)(const uintptr_t spec);
+};
+
+/* By default, load images from the FIP */
+static const struct plat_io_policy policies[] = {
+	[FIP_IMAGE_ID] = {
+		&memmap_dev_handle,
+		(uintptr_t)&fip_block_spec,
+		open_memmap
+	},
+	[BL2_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl2_uuid_spec,
+		open_fip
+	},
+	[BL31_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl31_uuid_spec,
+		open_fip
+	},
+	[BL32_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_uuid_spec,
+		open_fip
+	},
+	[BL33_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl33_uuid_spec,
+		open_fip
+	},
+#if TRUSTED_BOARD_BOOT
+	[BL2_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl2_cert_uuid_spec,
+		open_fip
+	},
+	[TRUSTED_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&trusted_key_cert_uuid_spec,
+		open_fip
+	},
+	[BL31_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl31_key_cert_uuid_spec,
+		open_fip
+	},
+	[BL32_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_key_cert_uuid_spec,
+		open_fip
+	},
+	[BL33_KEY_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl33_key_cert_uuid_spec,
+		open_fip
+	},
+	[BL31_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl31_cert_uuid_spec,
+		open_fip
+	},
+	[BL32_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_cert_uuid_spec,
+		open_fip
+	},
+	[BL33_CERT_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl33_cert_uuid_spec,
+		open_fip
+	},
+#endif /* TRUSTED_BOARD_BOOT */
+};
+
+static int open_fip(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	/* See if a Firmware Image Package is available */
+	result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+	if (result == 0) {
+		result = io_open(fip_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			VERBOSE("Using FIP\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+static int open_memmap(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+	if (result == 0) {
+		result = io_open(memmap_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			VERBOSE("Using Memmap\n");
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+void plat_rpi3_io_setup(void)
+{
+	int io_result;
+
+	io_result = register_io_dev_fip(&fip_dev_con);
+	assert(io_result == 0);
+
+	io_result = register_io_dev_memmap(&memmap_dev_con);
+	assert(io_result == 0);
+
+	/* Open connections to devices and cache the handles */
+	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+				&fip_dev_handle);
+	assert(io_result == 0);
+
+	io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+				&memmap_dev_handle);
+	assert(io_result == 0);
+
+	/* Ignore improbable errors in release builds */
+	(void)io_result;
+}
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	int result;
+	const struct plat_io_policy *policy;
+
+	assert(image_id < ARRAY_SIZE(policies));
+
+	policy = &policies[image_id];
+	result = policy->check(policy->image_spec);
+	if (result == 0) {
+		*image_spec = policy->image_spec;
+		*dev_handle = *(policy->dev_handle);
+	}
+
+	return result;
+}
diff --git a/plat/rpi3/rpi3_pm.c b/plat/rpi3/rpi3_pm.c
new file mode 100644
index 0000000..1d067fb
--- /dev/null
+++ b/plat/rpi3/rpi3_pm.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <platform.h>
+#include <psci.h>
+
+#include "rpi3_hw.h"
+
+/*
+ * The secure entry point to be used on warm reset.
+ */
+static uintptr_t secure_entrypoint;
+
+/* Make composite power state parameter till power level 0 */
+#if PSCI_EXTENDED_STATE_ID
+
+#define rpi3_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
+		(((lvl0_state) << PSTATE_ID_SHIFT) | \
+		 ((type) << PSTATE_TYPE_SHIFT))
+
+#else
+
+#define rpi3_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \
+		(((lvl0_state) << PSTATE_ID_SHIFT) | \
+		 ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \
+		 ((type) << PSTATE_TYPE_SHIFT))
+
+#endif /* PSCI_EXTENDED_STATE_ID */
+
+#define rpi3_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \
+		(((lvl1_state) << PLAT_LOCAL_PSTATE_WIDTH) | \
+		 rpi3_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type))
+
+/*
+ *  The table storing the valid idle power states. Ensure that the
+ *  array entries are populated in ascending order of state-id to
+ *  enable us to use binary search during power state validation.
+ *  The table must be terminated by a NULL entry.
+ */
+static const unsigned int rpi3_pm_idle_states[] = {
+	/* State-id - 0x01 */
+	rpi3_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_RET,
+				MPIDR_AFFLVL0, PSTATE_TYPE_STANDBY),
+	/* State-id - 0x02 */
+	rpi3_make_pwrstate_lvl1(PLAT_LOCAL_STATE_RUN, PLAT_LOCAL_STATE_OFF,
+				MPIDR_AFFLVL0, PSTATE_TYPE_POWERDOWN),
+	/* State-id - 0x22 */
+	rpi3_make_pwrstate_lvl1(PLAT_LOCAL_STATE_OFF, PLAT_LOCAL_STATE_OFF,
+				MPIDR_AFFLVL1, PSTATE_TYPE_POWERDOWN),
+	0,
+};
+
+/*******************************************************************************
+ * Platform handler called to check the validity of the power state
+ * parameter. The power state parameter has to be a composite power state.
+ ******************************************************************************/
+static int rpi3_validate_power_state(unsigned int power_state,
+				     psci_power_state_t *req_state)
+{
+	unsigned int state_id;
+	int i;
+
+	assert(req_state != 0);
+
+	/*
+	 *  Currently we are using a linear search for finding the matching
+	 *  entry in the idle power state array. This can be made a binary
+	 *  search if the number of entries justify the additional complexity.
+	 */
+	for (i = 0; rpi3_pm_idle_states[i] != 0; i++) {
+		if (power_state == rpi3_pm_idle_states[i]) {
+			break;
+		}
+	}
+
+	/* Return error if entry not found in the idle state array */
+	if (!rpi3_pm_idle_states[i]) {
+		return PSCI_E_INVALID_PARAMS;
+	}
+
+	i = 0;
+	state_id = psci_get_pstate_id(power_state);
+
+	/* Parse the State ID and populate the state info parameter */
+	while (state_id) {
+		req_state->pwr_domain_state[i++] = state_id &
+						PLAT_LOCAL_PSTATE_MASK;
+		state_id >>= PLAT_LOCAL_PSTATE_WIDTH;
+	}
+
+	return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * Platform handler called when a CPU is about to enter standby.
+ ******************************************************************************/
+static void rpi3_cpu_standby(plat_local_state_t cpu_state)
+{
+	assert(cpu_state == PLAT_LOCAL_STATE_RET);
+
+	/*
+	 * Enter standby state.
+	 * dsb is good practice before using wfi to enter low power states
+	 */
+	dsb();
+	wfi();
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
+ ******************************************************************************/
+static int rpi3_pwr_domain_on(u_register_t mpidr)
+{
+	int rc = PSCI_E_SUCCESS;
+	unsigned int pos = plat_core_pos_by_mpidr(mpidr);
+	uint64_t *hold_base = (uint64_t *)PLAT_RPI3_TM_HOLD_BASE;
+
+	assert(pos < PLATFORM_CORE_COUNT);
+
+	hold_base[pos] = PLAT_RPI3_TM_HOLD_STATE_GO;
+
+	/* Make sure that the write has completed */
+	dsb();
+	isb();
+
+	sev();
+
+	return rc;
+}
+
+/*******************************************************************************
+ * Platform handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
+ ******************************************************************************/
+void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+					PLAT_LOCAL_STATE_OFF);
+}
+
+/*******************************************************************************
+ * Platform handler to reboot the system
+ ******************************************************************************/
+#define RESET_TIMEOUT	10
+
+static void __dead2 rpi3_system_reset(void)
+{
+	/* Setup watchdog for reset */
+
+	static const uintptr_t base = RPI3_PM_BASE;
+	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();
+
+	/*
+	 * Watchdog timer = Timer clock / 16
+	 * Password (31:16) | Value (11:0)
+	 */
+	mmio_write_32(base + RPI3_PM_WDOG_OFFSET,
+		      RPI3_PM_PASSWORD | RESET_TIMEOUT);
+	mmio_write_32(base + RPI3_PM_RSTC_OFFSET,
+		      RPI3_PM_PASSWORD | rstc);
+
+	for (;;) {
+		wfi();
+	}
+}
+
+/*******************************************************************************
+ * Platform handlers and setup function.
+ ******************************************************************************/
+static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
+	.cpu_standby = rpi3_cpu_standby,
+	.pwr_domain_on = rpi3_pwr_domain_on,
+	.pwr_domain_on_finish = rpi3_pwr_domain_on_finish,
+	.system_reset = rpi3_system_reset,
+	.validate_power_state = rpi3_validate_power_state,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	uintptr_t *mailbox = (void *)PLAT_RPI3_TRUSTED_MAILBOX_BASE;
+
+	*mailbox = sec_entrypoint;
+	secure_entrypoint = (uintptr_t)sec_entrypoint;
+	*psci_ops = &plat_rpi3_psci_pm_ops;
+
+	return 0;
+}
diff --git a/plat/rpi3/rpi3_private.h b/plat/rpi3/rpi3_private.h
new file mode 100644
index 0000000..01c4055
--- /dev/null
+++ b/plat/rpi3/rpi3_private.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __RPI3_PRIVATE_H__
+#define __RPI3_PRIVATE_H__
+
+#include <sys/types.h>
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+
+/* Utility functions */
+void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
+			    uintptr_t code_start, uintptr_t code_limit,
+			    uintptr_t rodata_start, uintptr_t rodata_limit
+#if USE_COHERENT_MEM
+			    , uintptr_t coh_start, uintptr_t coh_limit
+#endif
+			    );
+
+/* Optional functions required in the Raspberry Pi 3 port */
+unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr);
+
+/* BL2 utility functions */
+uint32_t rpi3_get_spsr_for_bl32_entry(void);
+uint32_t rpi3_get_spsr_for_bl33_entry(void);
+
+/* IO storage utility functions */
+void plat_rpi3_io_setup(void);
+
+#endif /*__RPI3_PRIVATE_H__ */
diff --git a/plat/rpi3/rpi3_topology.c b/plat/rpi3/rpi3_topology.c
new file mode 100644
index 0000000..0e03ec3
--- /dev/null
+++ b/plat/rpi3/rpi3_topology.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <platform_def.h>
+#include <sys/types.h>
+
+#include "rpi3_private.h"
+
+/* The power domain tree descriptor */
+static unsigned char power_domain_tree_desc[] = {
+	/* Number of root nodes */
+	PLATFORM_CLUSTER_COUNT,
+	/* Number of children for the first node */
+	PLATFORM_CLUSTER0_CORE_COUNT,
+};
+
+/*******************************************************************************
+ * This function returns the ARM default topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	unsigned int cluster_id, cpu_id;
+
+	mpidr &= MPIDR_AFFINITY_MASK;
+	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
+		return -1;
+	}
+
+	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
+		return -1;
+	}
+
+	if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) {
+		return -1;
+	}
+
+	return plat_rpi3_calc_core_pos(mpidr);
+}
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index 2f08c8b..1969307 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -795,7 +795,7 @@
 		 */
 		ret = sdei_event_unregister(map->ev_num);
 		if ((ret == SDEI_EPEND) && (final_ret == 0))
-			final_ret = ret;
+			final_ret = SDEI_EDENY;
 	}
 
 	return final_ret;
@@ -817,7 +817,7 @@
 		 */
 		ret = sdei_event_unregister(map->ev_num);
 		if ((ret == SDEI_EPEND) && (final_ret == 0))
-			final_ret = ret;
+			final_ret = SDEI_EDENY;
 	}
 
 	if (final_ret != 0)
diff --git a/services/std_svc/spm/secure_partition_setup.c b/services/std_svc/spm/secure_partition_setup.c
index 6f4b057..c1f0edf 100644
--- a/services/std_svc/spm/secure_partition_setup.c
+++ b/services/std_svc/spm/secure_partition_setup.c
@@ -6,7 +6,6 @@
 
 #include <arch.h>
 #include <arch_helpers.h>
-#include <arm_spm_def.h>
 #include <assert.h>
 #include <common_def.h>
 #include <context.h>
@@ -22,12 +21,17 @@
 #include "spm_private.h"
 #include "spm_shim_private.h"
 
+/* Place translation tables by default along with the ones used by BL31. */
+#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
+#define PLAT_SP_IMAGE_XLAT_SECTION_NAME	"xlat_table"
+#endif
+
 /* Allocate and initialise the translation context for the secure partition. */
 REGISTER_XLAT_CONTEXT2(secure_partition,
 			PLAT_SP_IMAGE_MMAP_REGIONS,
 			PLAT_SP_IMAGE_MAX_XLAT_TABLES,
 			PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
-			EL1_EL0_REGIME);
+			EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME);
 
 /* Export a handle on the secure partition translation context */
 xlat_ctx_t *secure_partition_xlat_ctx_handle = &secure_partition_xlat_ctx;
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
index de657a2..00f3a30 100644
--- a/services/std_svc/spm/spm_main.c
+++ b/services/std_svc/spm/spm_main.c
@@ -132,7 +132,7 @@
 	rc = spm_synchronous_sp_entry(&sp_ctx);
 	assert(rc == 0);
 	sp_init_in_progress = 0;
-	VERBOSE("SP_MEM_ATTRIBUTES_SET_AARCH64 availability has been revoked\n");
+	VERBOSE("SP_MEMORY_ATTRIBUTES_SET_AARCH64 availability has been revoked\n");
 
 	return rc;
 }
@@ -228,21 +228,21 @@
 {
 	mmap_attr_t tf_attr = 0;
 
-	unsigned int access = (attributes & SP_MEM_ATTR_ACCESS_MASK)
-			      >> SP_MEM_ATTR_ACCESS_SHIFT;
+	unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+			      >> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
 
-	if (access == SP_MEM_ATTR_ACCESS_RW) {
+	if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
 		tf_attr |= MT_RW | MT_USER;
-	} else if (access ==  SP_MEM_ATTR_ACCESS_RO) {
+	} else if (access ==  SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
 		tf_attr |= MT_RO | MT_USER;
 	} else {
 		/* Other values are reserved. */
-		assert(access ==  SP_MEM_ATTR_ACCESS_NOACCESS);
+		assert(access ==  SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
 		/* The only requirement is that there's no access from EL0 */
 		tf_attr |= MT_RO | MT_PRIVILEGED;
 	}
 
-	if ((attributes & SP_MEM_ATTR_NON_EXEC) == 0) {
+	if ((attributes & SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
 		tf_attr |= MT_EXECUTE;
 	} else {
 		tf_attr |= MT_EXECUTE_NEVER;
@@ -263,20 +263,21 @@
 
 	if ((attr & MT_USER) == 0) {
 		/* No access from EL0. */
-		data_access = SP_MEM_ATTR_ACCESS_NOACCESS;
+		data_access = SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
 	} else {
 		if ((attr & MT_RW) != 0) {
 			assert(MT_TYPE(attr) != MT_DEVICE);
-			data_access = SP_MEM_ATTR_ACCESS_RW;
+			data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RW;
 		} else {
-			data_access = SP_MEM_ATTR_ACCESS_RO;
+			data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RO;
 		}
 	}
 
-	smc_attr |= (data_access & SP_MEM_ATTR_ACCESS_MASK) << SP_MEM_ATTR_ACCESS_SHIFT;
+	smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+		    << SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
 
 	if (attr & MT_EXECUTE_NEVER) {
-		smc_attr |= SP_MEM_ATTR_NON_EXEC;
+		smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
 	}
 
 	return smc_attr;
@@ -387,20 +388,20 @@
 			/* Return to normal world */
 			SMC_RET1(ns_cpu_context, x1);
 
-		case SP_MEM_ATTRIBUTES_GET_AARCH64:
-			INFO("Received SP_MEM_ATTRIBUTES_GET_AARCH64 SMC\n");
+		case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+			INFO("Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
 
 			if (!sp_init_in_progress) {
-				WARN("SP_MEM_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
+				WARN("SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
 				SMC_RET1(handle, SPM_NOT_SUPPORTED);
 			}
 			SMC_RET1(handle, spm_memory_attributes_get_smc_handler(x1));
 
-		case SP_MEM_ATTRIBUTES_SET_AARCH64:
-			INFO("Received SP_MEM_ATTRIBUTES_SET_AARCH64 SMC\n");
+		case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
+			INFO("Received SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
 
 			if (!sp_init_in_progress) {
-				WARN("SP_MEM_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
+				WARN("SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
 				SMC_RET1(handle, SPM_NOT_SUPPORTED);
 			}
 			SMC_RET1(handle, spm_memory_attributes_set_smc_handler(x1, x2, x3));
@@ -417,8 +418,8 @@
 		case  SP_VERSION_AARCH32:
 			SMC_RET1(handle, SP_VERSION_COMPILED);
 
-		case SP_COMMUNICATE_AARCH32:
-		case SP_COMMUNICATE_AARCH64:
+		case MM_COMMUNICATE_AARCH32:
+		case MM_COMMUNICATE_AARCH64:
 
 			/* Save the Normal world context */
 			cm_el1_sysregs_context_save(NON_SECURE);
@@ -435,13 +436,13 @@
 			assert(x1 == 0);
 
 			if (x3 != 0) {
-				VERBOSE("SP_COMMUNICATE_AARCH32/64: X3 is not 0 as recommended.\n");
+				VERBOSE("MM_COMMUNICATE_AARCH32/64: X3 is not 0 as recommended.\n");
 			}
 
 			SMC_RET4(&sp_ctx.cpu_ctx, smc_fid, x1, x2, x3);
 
-		case SP_MEM_ATTRIBUTES_GET_AARCH64:
-		case SP_MEM_ATTRIBUTES_SET_AARCH64:
+		case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+		case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
 			/* SMC interfaces reserved for secure callers. */
 			SMC_RET1(handle, SPM_NOT_SUPPORTED);