Merge pull request #1037 from douglas-raillard-arm/dr/doc_fix_errata_a53

Add doc for some Cortex A53 errata workarounds
diff --git a/Makefile b/Makefile
index 6aa4e9a..23ebcaa 100644
--- a/Makefile
+++ b/Makefile
@@ -438,6 +438,7 @@
 $(eval $(call assert_boolean,ENABLE_PMF))
 $(eval $(call assert_boolean,ENABLE_PSCI_STAT))
 $(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION))
+$(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS))
 $(eval $(call assert_boolean,ERROR_DEPRECATED))
 $(eval $(call assert_boolean,GENERATE_COT))
 $(eval $(call assert_boolean,HW_ASSISTED_COHERENCY))
@@ -454,7 +455,6 @@
 $(eval $(call assert_boolean,USE_COHERENT_MEM))
 $(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
-$(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
 $(eval $(call assert_numeric,ARM_ARCH_MINOR))
@@ -477,6 +477,7 @@
 $(eval $(call add_define,ENABLE_PMF))
 $(eval $(call add_define,ENABLE_PSCI_STAT))
 $(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
+$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
 $(eval $(call add_define,ERROR_DEPRECATED))
 $(eval $(call add_define,HW_ASSISTED_COHERENCY))
 $(eval $(call add_define,LOAD_IMAGE_V2))
@@ -494,7 +495,6 @@
 $(eval $(call add_define,USE_COHERENT_MEM))
 $(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
-$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
 
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
 ifdef EL3_PAYLOAD_BASE
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S
index b0902fd..eb98ffa 100644
--- a/bl1/aarch64/bl1_exceptions.S
+++ b/bl1/aarch64/bl1_exceptions.S
@@ -6,8 +6,8 @@
 
 #include <arch.h>
 #include <asm_macros.S>
-#include <bl_common.h>
 #include <bl1.h>
+#include <bl_common.h>
 #include <context.h>
 
 /* -----------------------------------------------------------------------------
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index 8dfc55f..07a7fc8 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <assert.h>
 #include <arch_helpers.h>
+#include <assert.h>
 #include <auth_mod.h>
 #include <bl1.h>
 #include <bl_common.h>
diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c
index fa4f3a4..821b6a3 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -17,8 +17,8 @@
 #include <platform_def.h>
 #include <smcc_helpers.h>
 #include <utils.h>
-#include "bl1_private.h"
 #include <uuid.h>
+#include "bl1_private.h"
 
 /* BL1 Service UUID */
 DEFINE_SVC_UUID(bl1_svc_uid,
diff --git a/bl2u/bl2u_main.c b/bl2u/bl2u_main.c
index 820da10..09ad468 100644
--- a/bl2u/bl2u_main.c
+++ b/bl2u/bl2u_main.c
@@ -8,8 +8,8 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <auth_mod.h>
-#include <bl_common.h>
 #include <bl1.h>
+#include <bl_common.h>
 #include <console.h>
 #include <debug.h>
 #include <platform.h>
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index c53f8a2..4a88bd7 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -7,8 +7,8 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
-#include <bl_common.h>
 #include <bl31.h>
+#include <bl_common.h>
 #include <console.h>
 #include <context_mgmt.h>
 #include <debug.h>
diff --git a/docs/plat/hikey.rst b/docs/plat/hikey.rst
index 027e14c..125941f 100644
--- a/docs/plat/hikey.rst
+++ b/docs/plat/hikey.rst
@@ -14,6 +14,9 @@
 -  ARM Trusted Firmware:
    `link <https://github.com/ARM-software/arm-trusted-firmware>`__
 
+-  OP-TEE
+   `link <https://github.com/OP-TEE/optee_os>`__
+
 -  edk2:
    `link <https://github.com/96boards-hikey/edk2/tree/testing/hikey960_v2.5>`__
 
@@ -24,7 +27,7 @@
    `link <https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2>`__
 
 -  uefi-tools:
-   `link <https://github.com/96boards-hikey/uefi-tools/tree/testing/hikey960_v1>`__
+   `link <https://git.linaro.org/uefi/uefi-tools.git>`__
 
 -  atf-fastboot:
    `link <https://github.com/96boards-hikey/atf-fastboot/tree/master>`__
@@ -70,13 +73,11 @@
        FASTBOOT_BUILD_OPTION=$(echo ${BUILD_OPTION} | tr '[A-Z]' '[a-z]')
        cd ${EDK2_DIR}
        # Build UEFI & ARM Trust Firmware
-       ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware hikey
+       ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware -s ../optee_os hikey
        # Generate l-loader.bin
        cd ${BUILD_PATH}/l-loader
        ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin
-       ln -sf ${EDK2_OUTPUT_DIR}/FV/fip.bin
        ln -sf ${BUILD_PATH}/atf-fastboot/build/hikey/${FASTBOOT_BUILD_OPTION}/bl1.bin fastboot.bin
-       python gen_loader.py -o l-loader.bin --img_bl1=bl1.bin --img_ns_bl1u=BL33_AP_UEFI.fd
        arm-linux-gnueabihf-gcc -c -o start.o start.S
        arm-linux-gnueabihf-ld -Bstatic -Tl-loader.lds -Ttext 0xf9800800 start.o -o loader
        arm-linux-gnueabihf-objcopy -O binary loader temp
@@ -86,7 +87,7 @@
 
    .. code:: shell
 
-       $PTABLE=aosp-4g SECTOR_SIZE=512 bash -x generate_ptable.sh
+       PTABLE=aosp-4g SECTOR_SIZE=512 bash -x generate_ptable.sh
 
 Setup Console
 -------------
@@ -110,6 +111,13 @@
 
        2004:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT banner
 
+-  Start ser2net
+
+   .. code:: shell
+
+       $sudo killall ser2net
+       $sudo ser2net -u
+
 -  Open the console.
 
    .. code:: shell
diff --git a/docs/plat/hikey960.rst b/docs/plat/hikey960.rst
index c28ef3a..cd1880e 100644
--- a/docs/plat/hikey960.rst
+++ b/docs/plat/hikey960.rst
@@ -14,6 +14,9 @@
 -  ARM Trusted Firmware:
    `link <https://github.com/ARM-software/arm-trusted-firmware>`__
 
+-  OP-TEE:
+   `link <https://github.com/OP-TEE/optee_os>`__
+
 -  edk2:
    `link <https://github.com/96boards-hikey/edk2/tree/testing/hikey960_v2.5>`__
 
@@ -24,7 +27,7 @@
    `link <https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2>`__
 
 -  uefi-tools:
-   `link <https://github.com/96boards-hikey/uefi-tools/tree/hikey960_v1>`__
+   `link <https://git.linaro.org/uefi/uefi-tools.git>`__
 
 Build Procedure
 ---------------
@@ -56,26 +59,26 @@
    .. code:: shell
 
        BUILD_OPTION=DEBUG
-       export AARCH64_TOOLCHAIN=GCC48
+       export AARCH64_TOOLCHAIN=GCC5
        export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools
        export EDK2_DIR=${BUILD_PATH}/edk2
        EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey960/${BUILD_OPTION}_${AARCH64_TOOLCHAIN}
        cd ${EDK2_DIR}
        # Build UEFI & ARM Trust Firmware
-       ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware hikey960
+       ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware -s ../optee_os hikey960
        # Generate l-loader.bin
        cd ${BUILD_PATH}/l-loader
        ln -sf ${EDK2_OUTPUT_DIR}/FV/bl1.bin
        ln -sf ${EDK2_OUTPUT_DIR}/FV/fip.bin
        ln -sf ${EDK2_OUTPUT_DIR}/FV/BL33_AP_UEFI.fd
-       python gen_loader.py -o l-loader.bin --img_bl1=bl1.bin --img_ns_bl1u=BL33_AP_UEFI.fd
+       python gen_loader_hikey960.py -o l-loader.bin --img_bl1=bl1.bin --img_ns_bl1u=BL33_AP_UEFI.fd
 
 -  Generate partition table.
    *Make sure that you're using the sgdisk in the l-loader directory.*
 
    .. code:: shell
 
-       $PTABLE=aosp-32g SECTOR_SIZE=4096 SGDISK=./sgdisk bash -x generate_ptable.sh
+       PTABLE=aosp-32g SECTOR_SIZE=4096 SGDISK=./sgdisk bash -x generate_ptable.sh
 
 Setup Console
 -------------
@@ -99,6 +102,13 @@
 
        2004:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT banner
 
+-  Start ser2net
+
+   .. code:: shell
+
+       $sudo killall ser2net
+       $sudo ser2net -u
+
 -  Open the console.
 
    .. code:: shell
@@ -126,7 +136,7 @@
 
        $vi config
        # The content of config file
-       ./sec_user_xloader.img 0x00020000
+       ./sec_usb_xloader.img 0x00020000
        ./sec_uce_boot.img 0x6A908000
        ./l-loader.bin 0x1AC00000
 
diff --git a/docs/plat/poplar.rst b/docs/plat/poplar.rst
new file mode 100644
index 0000000..d7f1fe0
--- /dev/null
+++ b/docs/plat/poplar.rst
@@ -0,0 +1,165 @@
+Description
+===========
+
+Poplar is the first development board compliant with the 96Boards Enterprise
+Edition TV Platform specification.
+
+The board features the Hi3798C V200 with an integrated quad-core 64-bit
+ARM Cortex A53 processor and high performance Mali T720 GPU, making it capable
+of running any commercial set-top solution based on Linux or Android.
+
+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
+    USB Two USB 2.0 ports One USB 3.0 ports
+    CONSOLE USB-micro port for console support
+    ETHERNET 1 GBe Ethernet
+    PCIE One PCIe 2.0 interfaces
+    JTAG 8-Pin JTAG
+    EXPANSION INTERFACE Linaro 96Boards Low Speed Expansion slot
+    DIMENSION Standard 160×120 mm 96Boards Enterprice Edition form factor
+    WIFI 802.11AC 2*2 with Bluetooth
+    CONNECTORS One connector for Smart Card One connector for TSI
+
+At the start of the boot sequence, the bootROM executes the so called l-loader
+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
+============
+
+Code Locations
+--------------
+
+-  ARM Trusted Firmware:
+   `link <https://github.com/ARM-software/arm-trusted-firmware>`__
+
+-  l-loader:
+   `link <https://github.com/Linaro/poplar-l-loader.git>`__
+
+-  u-boot:
+   `link <http://git.denx.de/u-boot.git>`__
+
+Build Procedure
+---------------
+
+-  Fetch all the above 3 repositories into local host.
+   Make all the repositories in the same ${BUILD\_PATH}.
+
+-  Prepare the AARCH64 toolchain.
+
+-  Build u-boot using poplar_defconfig
+       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
+       make CROSS_COMPILE=aarch64-linux-gnu-  all fip SPD=none PLAT=poplar
+       BL33=u-boot.bin
+
+-  Build l-loader (generated the final fastboot.bin)
+       1. copy the atf generated files fip.bin and bl1.bin to l-loader/atf/
+       2. export ARM_TRUSTED_FIRMWARE=${ATF_SOURCE_PATH)
+       3. make
+
+Install Procedure
+-----------------
+
+- Copy l-loader/fastboot.bin to a FAT partition on a USB pen drive.
+
+- Plug the USB pen drive to any of the USB2 ports
+
+- Power the board while keeping S3 pressed (usb_boot)
+
+The system will boot into a u-boot shell which you can then use to write the
+working firmware to eMMC.
+
+Boot trace
+==========
+
+Bootrom start
+Boot Media: eMMC
+Decrypt auxiliary code ...OK
+
+lsadc voltage min: 000000FE, max: 000000FF, aver: 000000FE, index: 00000000
+
+Entry boot auxiliary code
+
+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
+
+Boot auxiliary code success
+Bootrom success
+
+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.
+
+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/porting-guide.rst b/docs/porting-guide.rst
index 66fe0f1..4d4cdcd 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -60,11 +60,16 @@
 instruction and data caches for each BL stage. Setting up the translation
 tables is the responsibility of the platform port because memory maps differ
 across platforms. A memory translation library (see ``lib/xlat_tables/``) is
-provided to help in this setup. Note that although this library supports
-non-identity mappings, this is intended only for re-mapping peripheral physical
-addresses and allows platforms with high I/O addresses to reduce their virtual
-address space. All other addresses corresponding to code and data must currently
-use an identity mapping.
+provided to help in this setup.
+
+Note that although this library supports non-identity mappings, this is intended
+only for re-mapping peripheral physical addresses and allows platforms with high
+I/O addresses to reduce their virtual address space. All other addresses
+corresponding to code and data must currently use an identity mapping.
+
+Also, the only translation granule size supported in Trusted Firmware is 4KB, as
+various parts of the code assume that is the case. It is not possible to switch
+to 16 KB or 64 KB granule sizes at the moment.
 
 In ARM standard platforms, each BL stage configures the MMU in the
 platform-specific architecture setup function, ``blX_plat_arch_setup()``, and uses
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 6b82e3d..ec8c233 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -337,6 +337,11 @@
    Currently, only PSCI is instrumented. Enabling this option enables
    the ``ENABLE_PMF`` build option as well. Default is 0.
 
+-  ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
+   extensions. This is an optional architectural feature available only for
+   AArch64 8.2 onwards. This option defaults to 1 but is automatically
+   disabled when the target architecture is AArch32 or AArch64 8.0/8.1.
+
 -  ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
    checks in GCC. Allowed values are "all", "strong" and "0" (default).
    "strong" is the recommended stack protection level if this feature is
@@ -563,11 +568,6 @@
    cluster platforms). If this option is enabled, then warm boot path
    enables D-caches immediately after enabling MMU. This option defaults to 0.
 
--  ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
-   extensions. This is an optional architectural feature available only for
-   AArch64 8.2 onwards. This option defaults to 1 but is automatically
-   disabled when the target architecture is AArch32 or AArch64 8.0/8.1.
-
 ARM development platform specific build options
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/drivers/auth/cryptocell/cryptocell_crypto.c b/drivers/auth/cryptocell/cryptocell_crypto.c
index 05462be..80c1093 100644
--- a/drivers/auth/cryptocell/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/cryptocell_crypto.c
@@ -5,8 +5,8 @@
  */
 
 #include <arch_helpers.h>
-#include <crypto_mod.h>
 #include <crypto_driver.h>
+#include <crypto_mod.h>
 #include <debug.h>
 #include <mbedtls_common.h>
 #include <platform_def.h>
@@ -16,8 +16,8 @@
 #include <secureboot_gen_defs.h>
 #include <stddef.h>
 #include <string.h>
-#include <utils.h>
 #include <util.h>
+#include <utils.h>
 
 #include <mbedtls/oid.h>
 
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.c b/drivers/auth/mbedtls/mbedtls_crypto.c
index b157a32..d8810d6 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.c
+++ b/drivers/auth/mbedtls/mbedtls_crypto.c
@@ -4,7 +4,6 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-
 #include <crypto_mod.h>
 #include <debug.h>
 #include <mbedtls_common.h>
diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c
index e88c7c2..a9a4b37 100644
--- a/drivers/auth/tbbr/tbbr_cot.c
+++ b/drivers/auth/tbbr/tbbr_cot.c
@@ -6,12 +6,14 @@
 
 #include <auth_mod.h>
 #include <platform_def.h>
+#include <stddef.h>
+
 #if USE_TBBR_DEFS
 #include <tbbr_oid.h>
 #else
 #include <platform_oid.h>
 #endif
-#include <stddef.h>
+
 
 /*
  * Maximum key and hash sizes (in DER format)
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index 190ac38..e2b4683 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -6,8 +6,8 @@
 
 #include <assert.h>
 #include <debug.h>
-#include <io_storage.h>
 #include <gpt.h>
+#include <io_storage.h>
 #include <mbr.h>
 #include <partition.h>
 #include <platform.h>
diff --git a/include/drivers/arm/cryptocell/cc_pal_types_plat.h b/include/drivers/arm/cryptocell/cc_pal_types_plat.h
index d8ed3e1..8410024 100644
--- a/include/drivers/arm/cryptocell/cc_pal_types_plat.h
+++ b/include/drivers/arm/cryptocell/cc_pal_types_plat.h
@@ -11,8 +11,8 @@
 #define _CC_PAL_TYPES_PLAT_H
 /* Host specific types for standard (ISO-C99) compilant platforms */
 
-#include <stdint.h>
 #include <stddef.h>
+#include <stdint.h>
 
 typedef uint32_t CCStatus;
 
diff --git a/include/drivers/arm/cryptocell/nvm.h b/include/drivers/arm/cryptocell/nvm.h
index f806d3d..a70289f 100644
--- a/include/drivers/arm/cryptocell/nvm.h
+++ b/include/drivers/arm/cryptocell/nvm.h
@@ -13,8 +13,8 @@
 #endif
 
 #include "cc_crypto_boot_defs.h"
-#include "cc_sec_defs.h"
 #include "cc_pal_types.h"
+#include "cc_sec_defs.h"
 
 /*------------------------------------
     DEFINES
diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h
index 0a05886..fdeb52b 100644
--- a/include/drivers/auth/mbedtls/mbedtls_config.h
+++ b/include/drivers/auth/mbedtls/mbedtls_config.h
@@ -69,12 +69,12 @@
 #define MBEDTLS_MPI_WINDOW_SIZE              2
 #define MBEDTLS_MPI_MAX_SIZE               256
 
+/* System headers required to build mbed TLS with the current configuration */
+#include <stdlib.h>
+
 /* Memory buffer allocator options */
 #define MBEDTLS_MEMORY_ALIGN_MULTIPLE        8
 
 #include "mbedtls/check_config.h"
 
-/* System headers required to build mbed TLS with the current configuration */
-#include <stdlib.h>
-
 #endif /* __MBEDTLS_CONFIG_H__ */
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index 286262a..9984d69 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -12,8 +12,8 @@
 #include <bl_common.h>
 #include <platform.h>
 #include <pmf.h>
-#include <stdint.h>
 #include <stddef.h>
+#include <stdint.h>
 
 /*
  * Prototype for PMF service functions.
diff --git a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
new file mode 100644
index 0000000..a418d2d
--- /dev/null
+++ b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __XLAT_TABLES_AARCH32_H__
+#define __XLAT_TABLES_AARCH32_H__
+
+#include <arch.h>
+#include <utils_def.h>
+#include <xlat_tables_defs.h>
+
+#if !defined(PAGE_SIZE)
+#error "PAGE_SIZE is not defined."
+#endif
+
+/*
+ * In AArch32 state, the MMU only supports 4KB page granularity, which means
+ * that the first translation table level is either 1 or 2. Both of them are
+ * allowed to have block and table descriptors. See section G4.5.6 of the
+ * ARMv8-A Architecture Reference Manual (DDI 0487A.k) for more information.
+ *
+ * The define below specifies the first table level that allows block
+ * descriptors.
+ */
+#if PAGE_SIZE != (4 * 1024)
+#error "Invalid granule size. AArch32 supports 4KB pages only."
+#endif
+
+#define MIN_LVL_BLOCK_DESC	U(1)
+
+#define XLAT_TABLE_LEVEL_MIN	U(1)
+
+/*
+ * Define the architectural limits of the virtual address space in AArch32
+ * state.
+ *
+ * TTBCR.TxSZ is calculated as 32 minus the width of said address space. The
+ * value of TTBCR.TxSZ must be in the range 0 to 7 [1], which means that the
+ * virtual address space width must be in the range 32 to 25 bits.
+ *
+ * [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
+ * information, Section G4.6.5
+ */
+#define MIN_VIRT_ADDR_SPACE_SIZE	(ULL(1) << (32 - TTBCR_TxSZ_MAX))
+#define MAX_VIRT_ADDR_SPACE_SIZE	(ULL(1) << (32 - TTBCR_TxSZ_MIN))
+
+/*
+ * Here we calculate the initial lookup level from the value of the given
+ * virtual address space size. For a 4 KB page size,
+ * - level 1 supports virtual address spaces of widths 32 to 31 bits;
+ * - level 2 from 30 to 25.
+ *
+ * Wider or narrower address spaces are not supported. As a result, level 3
+ * cannot be used as the initial lookup level with 4 KB granularity.
+ * See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
+ * information, Section G4.6.5
+ *
+ * For example, for a 31-bit address space (i.e. virt_addr_space_size ==
+ * 1 << 31), TTBCR.TxSZ will be programmed to (32 - 31) = 1. According to Table
+ * G4-5 in the ARM ARM, the initial lookup level for an address space like that
+ * is 1.
+ *
+ * Note that this macro assumes that the given virtual address space size is
+ * valid. Therefore, the caller is expected to check it is the case using the
+ * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ */
+#define GET_XLAT_TABLE_LEVEL_BASE(virt_addr_space_size)			\
+	(((virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? 1 : 2)
+
+#endif /* __XLAT_TABLES_AARCH32_H__ */
diff --git a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
new file mode 100644
index 0000000..7381bc8
--- /dev/null
+++ b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __XLAT_TABLES_AARCH64_H__
+#define __XLAT_TABLES_AARCH64_H__
+
+#include <arch.h>
+#include <utils_def.h>
+#include <xlat_tables_defs.h>
+
+#if !defined(PAGE_SIZE)
+#error "PAGE_SIZE is not defined."
+#endif
+
+/*
+ * In AArch64 state, the MMU may support 4 KB, 16 KB and 64 KB page
+ * granularity. For 4KB granularity, a level 0 table descriptor doesn't support
+ * block translation. For 16KB, the same thing happens to levels 0 and 1. For
+ * 64KB, same for level 1. See section D4.3.1 of the ARMv8-A Architecture
+ * Reference Manual (DDI 0487A.k) for more information.
+ *
+ * The define below specifies the first table level that allows block
+ * descriptors.
+ */
+#if PAGE_SIZE == (4 * 1024)
+# define MIN_LVL_BLOCK_DESC	U(1)
+#elif PAGE_SIZE == (16 * 1024) || PAGE_SIZE == (64 * 1024)
+# define MIN_LVL_BLOCK_DESC	U(2)
+#endif
+
+#define XLAT_TABLE_LEVEL_MIN	U(0)
+
+/*
+ * Define the architectural limits of the virtual address space in AArch64
+ * state.
+ *
+ * TCR.TxSZ is calculated as 64 minus the width of said address space.
+ * The value of TCR.TxSZ must be in the range 16 to 39 [1], which means that
+ * the virtual address space width must be in the range 48 to 25 bits.
+ *
+ * [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
+ * information:
+ * Page 1730: 'Input address size', 'For all translation stages'.
+ */
+#define MIN_VIRT_ADDR_SPACE_SIZE	(ULL(1) << (64 - TCR_TxSZ_MAX))
+#define MAX_VIRT_ADDR_SPACE_SIZE	(ULL(1) << (64 - TCR_TxSZ_MIN))
+
+/*
+ * Here we calculate the initial lookup level from the value of the given
+ * virtual address space size. For a 4 KB page size,
+ * - level 0 supports virtual address spaces of widths 48 to 40 bits;
+ * - level 1 from 39 to 31;
+ * - level 2 from 30 to 25.
+ *
+ * Wider or narrower address spaces are not supported. As a result, level 3
+ * cannot be used as initial lookup level with 4 KB granularity. See section
+ * D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
+ * information.
+ *
+ * For example, for a 35-bit address space (i.e. virt_addr_space_size ==
+ * 1 << 35), TCR.TxSZ will be programmed to (64 - 35) = 29. According to Table
+ * D4-11 in the ARM ARM, the initial lookup level for an address space like that
+ * is 1.
+ *
+ * Note that this macro assumes that the given virtual address space size is
+ * valid. Therefore, the caller is expected to check it is the case using the
+ * CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
+ */
+#define GET_XLAT_TABLE_LEVEL_BASE(virt_addr_space_size)				\
+	(((virt_addr_space_size) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT))		\
+	? 0									\
+	 : (((virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT))	\
+	 ? 1 : 2))
+
+#endif /* __XLAT_TABLES_AARCH64_H__ */
diff --git a/include/lib/xlat_tables/xlat_tables_arch.h b/include/lib/xlat_tables/xlat_tables_arch.h
new file mode 100644
index 0000000..165b161d
--- /dev/null
+++ b/include/lib/xlat_tables/xlat_tables_arch.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __XLAT_TABLES_ARCH_H__
+#define __XLAT_TABLES_ARCH_H__
+
+#ifdef AARCH32
+#include "aarch32/xlat_tables_aarch32.h"
+#else
+#include "aarch64/xlat_tables_aarch64.h"
+#endif
+
+/*
+ * Evaluates to 1 if the given virtual address space size is valid, or 0 if it's
+ * not.
+ *
+ * A valid size is one that is a power of 2 and is within the architectural
+ * limits. Not that these limits are different for AArch32 and AArch64.
+ */
+#define CHECK_VIRT_ADDR_SPACE_SIZE(size)			\
+	(((size) >= MIN_VIRT_ADDR_SPACE_SIZE) &&		\
+	((size) <= MAX_VIRT_ADDR_SPACE_SIZE) &&			\
+	IS_POWER_OF_TWO(size))
+
+/*
+ * Evaluates to 1 if the given physical address space size is a power of 2,
+ * or 0 if it's not.
+ */
+#define CHECK_PHY_ADDR_SPACE_SIZE(size)				\
+	(IS_POWER_OF_TWO(size))
+
+/*
+ * Compute the number of entries required at the initial lookup level to address
+ * the whole virtual address space.
+ */
+#define GET_NUM_BASE_LEVEL_ENTRIES(addr_space_size)			\
+	((addr_space_size) >>						\
+		XLAT_ADDR_SHIFT(GET_XLAT_TABLE_LEVEL_BASE(addr_space_size)))
+
+#endif /* __XLAT_TABLES_ARCH_H__ */
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 4b993a0..008ae9b 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -48,7 +48,11 @@
 
 #define TABLE_ADDR_MASK		ULL(0x0000FFFFFFFFF000)
 
-#define PAGE_SIZE_SHIFT		FOUR_KB_SHIFT /* 4, 16 or 64 KB */
+/*
+ * The ARMv8-A architecture allows translation granule sizes of 4KB, 16KB or
+ * 64KB. However, TF only supports the 4KB case at the moment.
+ */
+#define PAGE_SIZE_SHIFT		FOUR_KB_SHIFT
 #define PAGE_SIZE		(U(1) << PAGE_SIZE_SHIFT)
 #define PAGE_SIZE_MASK		(PAGE_SIZE - 1)
 #define IS_PAGE_ALIGNED(addr)	(((addr) & PAGE_SIZE_MASK) == 0)
@@ -59,12 +63,6 @@
 #define XLAT_TABLE_SIZE_SHIFT	PAGE_SIZE_SHIFT /* Size of one complete table */
 #define XLAT_TABLE_SIZE		(U(1) << XLAT_TABLE_SIZE_SHIFT)
 
-#ifdef AARCH32
-#define XLAT_TABLE_LEVEL_MIN	U(1)
-#else
-#define XLAT_TABLE_LEVEL_MIN	U(0)
-#endif /* AARCH32 */
-
 #define XLAT_TABLE_LEVEL_MAX	U(3)
 
 /* Values for number of entries in each MMU translation table */
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 9db6719..288a8e0 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -13,6 +13,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <xlat_mmu_helpers.h>
+#include <xlat_tables_v2_helpers.h>
 
 /* Helper macro to define entries for mmap_region_t. It creates
  * identity mappings for each region.
@@ -82,7 +83,51 @@
 	mmap_attr_t		attr;
 } mmap_region_t;
 
-/* Generic translation table APIs */
+/*
+ * Declare the translation context type.
+ * Its definition is private.
+ */
+typedef struct xlat_ctx xlat_ctx_t;
+
+/*
+ * Statically allocate a translation context and associated structures. Also
+ * initialize them.
+ *
+ * _ctx_name:
+ *   Prefix for the translation context variable.
+ *   E.g. If _ctx_name is 'foo', the variable will be called 'foo_xlat_ctx'.
+ *   Useful to distinguish multiple contexts from one another.
+ *
+ * _mmap_count:
+ *   Number of mmap_region_t to allocate.
+ *   Would typically be MAX_MMAP_REGIONS for the translation context describing
+ *   the BL image currently executing.
+ *
+ * _xlat_tables_count:
+ *   Number of sub-translation tables to allocate.
+ *   Would typically be MAX_XLAT_TABLES for the translation context describing
+ *   the BL image currently executing.
+ *   Note that this is only for sub-tables ; at the initial lookup level, there
+ *   is always a single table.
+ *
+ * _virt_addr_space_size, _phy_addr_space_size:
+ *   Size (in bytes) of the virtual (resp. physical) address space.
+ *   Would typically be PLAT_VIRT_ADDR_SPACE_SIZE
+ *   (resp. PLAT_PHY_ADDR_SPACE_SIZE) for the translation context describing the
+ *   BL image currently executing.
+ */
+#define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count,	\
+			_virt_addr_space_size, _phy_addr_space_size)		\
+	_REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count,	\
+		_virt_addr_space_size, _phy_addr_space_size)
+
+/******************************************************************************
+ * Generic translation table APIs.
+ * Each API comes in 2 variants:
+ * - one that acts on the current translation context for this BL image
+ * - another that acts on the given translation context instead. This variant
+ *   is named after the 1st version, with an additional '_ctx' suffix.
+ *****************************************************************************/
 
 /*
  * Initialize translation tables from the current list of mmap regions. Calling
@@ -90,6 +135,7 @@
  * longer be added.
  */
 void init_xlat_tables(void);
+void init_xlat_tables_ctx(xlat_ctx_t *ctx);
 
 /*
  * Add a static region with defined base PA and base VA. This function can only
@@ -98,8 +144,19 @@
  */
 void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
 				size_t size, mmap_attr_t attr);
+void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);
 
 /*
+ * Add an array of static regions with defined base PA and base VA. This
+ * function can only be used before initializing the translation tables. The
+ * regions cannot be removed afterwards.
+ */
+void mmap_add(const mmap_region_t *mm);
+void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);
+
+
+#if PLAT_XLAT_TABLES_DYNAMIC
+/*
  * Add a dynamic region with defined base PA and base VA. This type of region
  * can be added and removed even after the translation tables are initialized.
  *
@@ -112,13 +169,7 @@
  */
 int mmap_add_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
 				size_t size, mmap_attr_t attr);
-
-/*
- * Add an array of static regions with defined base PA and base VA. This
- * function can only be used before initializing the translation tables. The
- * regions cannot be removed afterwards.
- */
-void mmap_add(const mmap_region_t *mm);
+int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
 
 /*
  * Remove a region with the specified base VA and size. Only dynamic regions can
@@ -131,6 +182,11 @@
  *    EPERM: Trying to remove a static region.
  */
 int mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
+int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx,
+				uintptr_t base_va,
+				size_t size);
+
+#endif /* PLAT_XLAT_TABLES_DYNAMIC */
 
 #endif /*__ASSEMBLY__*/
 #endif /* __XLAT_TABLES_V2_H__ */
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
new file mode 100644
index 0000000..f5e3100
--- /dev/null
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * This header file contains internal definitions that are not supposed to be
+ * used outside of this library code.
+ */
+
+#ifndef __XLAT_TABLES_V2_HELPERS_H__
+#define __XLAT_TABLES_V2_HELPERS_H__
+
+#ifndef __XLAT_TABLES_V2_H__
+#error "Do not include this header file directly. Include xlat_tables_v2.h instead."
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <cassert.h>
+#include <platform_def.h>
+#include <stddef.h>
+#include <xlat_tables_arch.h>
+#include <xlat_tables_defs.h>
+
+/* Forward declaration */
+struct mmap_region;
+
+/* Struct that holds all information about the translation tables. */
+struct xlat_ctx {
+	/*
+	 * Max allowed Virtual and Physical Addresses.
+	 */
+	unsigned long long pa_max_address;
+	uintptr_t va_max_address;
+
+	/*
+	 * Array of all memory regions stored in order of ascending end address
+	 * and ascending size to simplify the code that allows overlapping
+	 * regions. The list is terminated by the first entry with size == 0.
+	 * The max size of the list is stored in `mmap_num`. `mmap` points to an
+	 * array of mmap_num + 1 elements, so that there is space for the final
+	 * null entry.
+	 */
+	struct mmap_region *mmap;
+	unsigned int mmap_num;
+
+	/*
+	 * Array of finer-grain translation tables.
+	 * For example, if the initial lookup level is 1 then this array would
+	 * contain both level-2 and level-3 entries.
+	 */
+	uint64_t (*tables)[XLAT_TABLE_ENTRIES];
+	unsigned int tables_num;
+	/*
+	 * Keep track of how many regions are mapped in each table. The base
+	 * table can't be unmapped so it isn't needed to keep track of it.
+	 */
+#if PLAT_XLAT_TABLES_DYNAMIC
+	int *tables_mapped_regions;
+#endif /* PLAT_XLAT_TABLES_DYNAMIC */
+
+	unsigned int next_table;
+
+	/*
+	 * Base translation table. It doesn't need to have the same amount of
+	 * entries as the ones used for other levels.
+	 */
+	uint64_t *base_table;
+	unsigned int base_table_entries;
+
+	/*
+	* Max Physical and Virtual addresses currently in use by the
+	* translation tables. These might get updated as we map/unmap memory
+	* regions but they will never go beyond pa/va_max_address.
+	*/
+	unsigned long long max_pa;
+	uintptr_t max_va;
+
+	/* Level of the base translation table. */
+	unsigned int base_level;
+
+	/* Set to 1 when the translation tables are initialized. */
+	unsigned int initialized;
+
+	/*
+	 * Bit mask that has to be ORed to the rest of a translation table
+	 * descriptor in order to prohibit execution of code at the exception
+	 * level of this translation context.
+	 */
+	uint64_t execute_never_mask;
+};
+
+#if PLAT_XLAT_TABLES_DYNAMIC
+#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
+	static int _ctx_name##_mapped_regions[_xlat_tables_count];
+
+#define _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
+	.tables_mapped_regions = _ctx_name##_mapped_regions,
+#else
+#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
+	/* do nothing */
+
+#define _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
+	/* do nothing */
+#endif /* PLAT_XLAT_TABLES_DYNAMIC */
+
+
+#define _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count,	\
+			_virt_addr_space_size, _phy_addr_space_size)		\
+	CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size),		\
+		assert_invalid_virtual_addr_space_size_for_##_ctx_name);	\
+										\
+	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),		\
+		assert_invalid_physical_addr_space_sizefor_##_ctx_name);	\
+										\
+	static mmap_region_t _ctx_name##_mmap[_mmap_count + 1];			\
+										\
+	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]		\
+		[XLAT_TABLE_ENTRIES]						\
+		__aligned(XLAT_TABLE_SIZE) __section("xlat_table");		\
+										\
+	static uint64_t _ctx_name##_base_xlat_table				\
+		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]		\
+		__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)	\
+			* sizeof(uint64_t));					\
+										\
+	_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)			\
+										\
+	static xlat_ctx_t _ctx_name##_xlat_ctx = {				\
+		.va_max_address = (_virt_addr_space_size) - 1,			\
+		.pa_max_address = (_phy_addr_space_size) - 1,			\
+		.mmap = _ctx_name##_mmap,					\
+		.mmap_num = _mmap_count,					\
+		.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),	\
+		.base_table = _ctx_name##_base_xlat_table,			\
+		.base_table_entries =						\
+			GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),	\
+		.tables = _ctx_name##_xlat_tables,				\
+		.tables_num = _xlat_tables_count,				\
+		 _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
+		.max_pa = 0,							\
+		.max_va = 0,							\
+		.next_table = 0,						\
+		.initialized = 0,						\
+	}
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* __XLAT_TABLES_V2_HELPERS_H__ */
diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h
index 0b74ced..9d025f6 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -128,16 +128,22 @@
  * an SCP_BL2/SCP_BL2U image.
  */
 #if CSS_LOAD_SCP_IMAGES
+
+#if ARM_BL31_IN_DRAM
+#error "SCP_BL2 is not expected to be loaded by BL2 for ARM_BL31_IN_DRAM config"
+#endif
+
 /*
  * Load address of SCP_BL2 in CSS platform ports
- * SCP_BL2 is loaded to the same place as BL31.  Once SCP_BL2 is transferred to the
- * SCP, it is discarded and BL31 is loaded over the top.
+ * SCP_BL2 is loaded to the same place as BL31 but it shouldn't overwrite BL1
+ * rw data.  Once SCP_BL2 is transferred to the SCP, it is discarded and BL31
+ * is loaded over the top.
  */
-#define SCP_BL2_BASE			BL31_BASE
-#define SCP_BL2_LIMIT			(SCP_BL2_BASE + PLAT_CSS_MAX_SCP_BL2_SIZE)
+#define SCP_BL2_BASE			(BL1_RW_BASE - PLAT_CSS_MAX_SCP_BL2_SIZE)
+#define SCP_BL2_LIMIT			BL1_RW_BASE
 
-#define SCP_BL2U_BASE			BL31_BASE
-#define SCP_BL2U_LIMIT			(SCP_BL2U_BASE + PLAT_CSS_MAX_SCP_BL2U_SIZE)
+#define SCP_BL2U_BASE			(BL1_RW_BASE - PLAT_CSS_MAX_SCP_BL2U_SIZE)
+#define SCP_BL2U_LIMIT			BL1_RW_BASE
 #endif /* CSS_LOAD_SCP_IMAGES */
 
 /* Load address of Non-Secure Image for CSS platform ports */
diff --git a/include/plat/arm/soc/common/soc_css_def.h b/include/plat/arm/soc/common/soc_css_def.h
index dc3d7dc..3206f4e 100644
--- a/include/plat/arm/soc/common/soc_css_def.h
+++ b/include/plat/arm/soc/common/soc_css_def.h
@@ -24,8 +24,8 @@
 #define SOC_CSS_UART0_BASE		0x7ff80000
 #define SOC_CSS_UART1_BASE		0x7ff70000
 
-#define SOC_CSS_UART0_CLK_IN_HZ		7273800
-#define SOC_CSS_UART1_CLK_IN_HZ		7273800
+#define SOC_CSS_UART0_CLK_IN_HZ		7372800
+#define SOC_CSS_UART1_CLK_IN_HZ		7372800
 
 /* SoC NIC-400 Global Programmers View (GPV) */
 #define SOC_CSS_NIC400_BASE		0x7fd00000
diff --git a/lib/compiler-rt/builtins/ctzdi2.c b/lib/compiler-rt/builtins/ctzdi2.c
new file mode 100644
index 0000000..db3c6fd
--- /dev/null
+++ b/lib/compiler-rt/builtins/ctzdi2.c
@@ -0,0 +1,29 @@
+/* ===-- ctzdi2.c - Implement __ctzdi2 -------------------------------------===
+ *
+ *                     The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __ctzdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: the number of trailing 0-bits  */
+
+/* Precondition: a != 0 */
+
+COMPILER_RT_ABI si_int
+__ctzdi2(di_int a)
+{
+    dwords x;
+    x.all = a;
+    const si_int f = -(x.s.low == 0);
+    return __builtin_ctz((x.s.high & f) | (x.s.low & ~f)) +
+              (f & ((si_int)(sizeof(si_int) * CHAR_BIT)));
+}
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index 3bdd319..cb5ab31 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -30,5 +30,6 @@
 
 ifeq (${ARCH},aarch32)
 COMPILER_RT_SRCS	:=	lib/compiler-rt/builtins/arm/aeabi_uldivmod.S	\
-				lib/compiler-rt/builtins/udivmoddi4.c
+				lib/compiler-rt/builtins/udivmoddi4.c		\
+				lib/compiler-rt/builtins/ctzdi2.c
 endif
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index f103159..741c773 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -4,10 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <cortex_a55.h>
 #include <arch.h>
 #include <asm_macros.S>
 #include <bl_common.h>
+#include <cortex_a55.h>
 #include <cpu_macros.S>
 #include <plat_macros.S>
 
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index d5c9843..d3d0e2f 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -8,8 +8,8 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bl_common.h>
-#include <debug.h>
 #include <context_mgmt.h>
+#include <debug.h>
 #include <platform.h>
 #include <stddef.h>
 #include "psci_private.h"
@@ -64,7 +64,20 @@
 	/*
 	 * Generic management: Ensure that the cpu is off to be
 	 * turned on.
+	 * Perform cache maintanence ahead of reading the target CPU state to
+	 * ensure that the data is not stale.
+	 * There is a theoretical edge case where the cache may contain stale
+	 * data for the target CPU data - this can occur under the following
+	 * conditions:
+	 * - the target CPU is in another cluster from the current
+	 * - the target CPU was the last CPU to shutdown on its cluster
+	 * - the cluster was removed from coherency as part of the CPU shutdown
+	 *
+	 * In this case the cache maintenace that was performed as part of the
+	 * target CPUs shutdown was not seen by the current CPU's cluster. And
+	 * so the cache may contain stale data for the target CPU.
 	 */
+	flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
 	rc = cpu_on_validate_state(psci_get_aff_info_state_by_idx(target_idx));
 	if (rc != PSCI_E_SUCCESS)
 		goto exit;
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 4798892..0d1589e 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -4,10 +4,10 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <assert.h>
-#include <bl_common.h>
 #include <arch.h>
 #include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
 #include <context.h>
 #include <context_mgmt.h>
 #include <cpu_data.h>
diff --git a/lib/psci/psci_system_off.c b/lib/psci/psci_system_off.c
index 4a55248..ef5d3d1 100644
--- a/lib/psci/psci_system_off.c
+++ b/lib/psci/psci_system_off.c
@@ -4,12 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stddef.h>
 #include <arch_helpers.h>
 #include <assert.h>
 #include <console.h>
 #include <debug.h>
 #include <platform.h>
+#include <stddef.h>
 #include "psci_private.h"
 
 void __dead2 psci_system_off(void)
diff --git a/lib/stdlib/assert.c b/lib/stdlib/assert.c
index 41f7070..97fab4b 100644
--- a/lib/stdlib/assert.c
+++ b/lib/stdlib/assert.c
@@ -17,14 +17,14 @@
 #if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
 void __assert(const char *file, unsigned int line, const char *assertion)
 {
-	tf_printf("ASSERT: %s <%d> : %s\n", file, line, assertion);
+	tf_printf("ASSERT: %s:%d:%s\n", file, line, assertion);
 	console_flush();
 	plat_panic_handler();
 }
 #elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
 void __assert(const char *file, unsigned int line)
 {
-	tf_printf("ASSERT: %s <%d>\n", file, line);
+	tf_printf("ASSERT: %s:%d\n", file, line);
 	console_flush();
 	plat_panic_handler();
 }
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index 9c15624..c7e34f2 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -7,56 +7,17 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
-#include <cassert.h>
 #include <platform_def.h>
 #include <utils.h>
+#include <xlat_tables_arch.h>
 #include <xlat_tables.h>
 #include "../xlat_tables_private.h"
 
-/*
- * Each platform can define the size of the virtual address space, which is
- * defined in PLAT_VIRT_ADDR_SPACE_SIZE. TTBCR.TxSZ is calculated as 32 minus
- * the width of said address space. The value of TTBCR.TxSZ must be in the
- * range 0 to 7 [1], which means that the virtual address space width must be
- * in the range 32 to 25 bits.
- *
- * Here we calculate the initial lookup level from the value of
- * PLAT_VIRT_ADDR_SPACE_SIZE. For a 4 KB page size, level 1 supports virtual
- * address spaces of widths 32 to 31 bits, and level 2 from 30 to 25. Wider or
- * narrower address spaces are not supported. As a result, level 3 cannot be
- * used as initial lookup level with 4 KB granularity [1].
- *
- * For example, for a 31-bit address space (i.e. PLAT_VIRT_ADDR_SPACE_SIZE ==
- * 1 << 31), TTBCR.TxSZ will be programmed to (32 - 31) = 1. According to Table
- * G4-5 in the ARM ARM, the initial lookup level for an address space like that
- * is 1.
- *
- * See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
- * information:
- * [1] Section G4.6.5
- */
+#define XLAT_TABLE_LEVEL_BASE	\
+       GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE)
 
-#if PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << (32 - TTBCR_TxSZ_MIN))
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too big."
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1 << L1_XLAT_ADDRESS_SHIFT)
-
-# define XLAT_TABLE_LEVEL_BASE	1
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT)
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE >= (1 << (32 - TTBCR_TxSZ_MAX))
-
-# define XLAT_TABLE_LEVEL_BASE	2
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L2_XLAT_ADDRESS_SHIFT)
-
-#else
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too small."
-
-#endif
+#define NUM_BASE_LEVEL_ENTRIES	\
+       GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE)
 
 static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES]
 		__aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t));
@@ -127,13 +88,13 @@
 		ttbcr = TTBCR_EAE_BIT |
 			TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
 			TTBCR_RGN0_INNER_NC |
-			(32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+			(32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));
 	} else {
 		/* Inner & outer WBWA & shareable. */
 		ttbcr = TTBCR_EAE_BIT |
 			TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA |
 			TTBCR_RGN0_INNER_WBA |
-			(32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+			(32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));
 	}
 	ttbcr |= TTBCR_EPD1_BIT;
 	write_ttbcr(ttbcr);
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 309cb9b..2ddf8cb 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -8,66 +8,19 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bl_common.h>
-#include <cassert.h>
 #include <common_def.h>
 #include <platform_def.h>
 #include <sys/types.h>
 #include <utils.h>
 #include <xlat_tables.h>
+#include <xlat_tables_arch.h>
 #include "../xlat_tables_private.h"
 
-/*
- * Each platform can define the size of the virtual address space, which is
- * defined in PLAT_VIRT_ADDR_SPACE_SIZE. TCR.TxSZ is calculated as 64 minus the
- * width of said address space. The value of TCR.TxSZ must be in the range 16
- * to 39 [1], which means that the virtual address space width must be in the
- * range 48 to 25 bits.
- *
- * Here we calculate the initial lookup level from the value of
- * PLAT_VIRT_ADDR_SPACE_SIZE. For a 4 KB page size, level 0 supports virtual
- * address spaces of widths 48 to 40 bits, level 1 from 39 to 31, and level 2
- * from 30 to 25. Wider or narrower address spaces are not supported. As a
- * result, level 3 cannot be used as initial lookup level with 4 KB
- * granularity. [2]
- *
- * For example, for a 35-bit address space (i.e. PLAT_VIRT_ADDR_SPACE_SIZE ==
- * 1 << 35), TCR.TxSZ will be programmed to (64 - 35) = 29. According to Table
- * D4-11 in the ARM ARM, the initial lookup level for an address space like
- * that is 1.
- *
- * See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
- * information:
- * [1] Page 1730: 'Input address size', 'For all translation stages'.
- * [2] Section D4.2.5
- */
+#define XLAT_TABLE_LEVEL_BASE	\
+       GET_XLAT_TABLE_LEVEL_BASE(PLAT_VIRT_ADDR_SPACE_SIZE)
 
-#if PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << (64 - TCR_TxSZ_MIN))
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too big."
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << L0_XLAT_ADDRESS_SHIFT)
-
-# define XLAT_TABLE_LEVEL_BASE	0
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L0_XLAT_ADDRESS_SHIFT)
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1 << L1_XLAT_ADDRESS_SHIFT)
-
-# define XLAT_TABLE_LEVEL_BASE	1
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT)
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE >= (1 << (64 - TCR_TxSZ_MAX))
-
-# define XLAT_TABLE_LEVEL_BASE	2
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L2_XLAT_ADDRESS_SHIFT)
-
-#else
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too small."
-
-#endif
+#define NUM_BASE_LEVEL_ENTRIES	\
+       GET_NUM_BASE_LEVEL_ENTRIES(PLAT_VIRT_ADDR_SPACE_SIZE)
 
 static uint64_t base_xlation_table[NUM_BASE_LEVEL_ENTRIES]
 		__aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t));
@@ -192,12 +145,12 @@
 			/* Inner & outer non-cacheable non-shareable. */\
 			tcr = TCR_SH_NON_SHAREABLE |			\
 				TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC |	\
-				(64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
+				(64 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));\
 		} else {						\
 			/* Inner & outer WBWA & shareable. */		\
 			tcr = TCR_SH_INNER_SHAREABLE |			\
 				TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA |	\
-				(64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
+				(64 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));\
 		}							\
 		tcr |= _tcr_extra;					\
 		write_tcr_el##_el(tcr);					\
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index b5c3ac8..50d6bd5 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -9,7 +9,7 @@
 
 #include <cassert.h>
 #include <platform_def.h>
-#include <utils_def.h>
+#include <xlat_tables_arch.h>
 
 /*
  * If the platform hasn't defined a physical and a virtual address space size
@@ -28,41 +28,14 @@
 # endif
 #endif
 
-/* The virtual and physical address space sizes must be powers of two. */
-CASSERT(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE),
+CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(PLAT_VIRT_ADDR_SPACE_SIZE),
 	assert_valid_virt_addr_space_size);
-CASSERT(IS_POWER_OF_TWO(PLAT_PHY_ADDR_SPACE_SIZE),
+
+CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE),
 	assert_valid_phy_addr_space_size);
 
-/*
- * In AArch32 state, the MMU only supports 4KB page granularity, which means
- * that the first translation table level is either 1 or 2. Both of them are
- * allowed to have block and table descriptors. See section G4.5.6 of the
- * ARMv8-A Architecture Reference Manual (DDI 0487A.k) for more information.
- *
- * In AArch64 state, the MMU may support 4 KB, 16 KB and 64 KB page
- * granularity. For 4KB granularity, a level 0 table descriptor doesn't support
- * block translation. For 16KB, the same thing happens to levels 0 and 1. For
- * 64KB, same for level 1. See section D4.3.1 of the ARMv8-A Architecture
- * Reference Manual (DDI 0487A.k) for more information.
- *
- * The define below specifies the first table level that allows block
- * descriptors.
- */
-
-#ifdef AARCH32
-
-# define XLAT_BLOCK_LEVEL_MIN 1
-
-#else /* if AArch64 */
-
-# if PAGE_SIZE == (4*1024) /* 4KB */
-#  define XLAT_BLOCK_LEVEL_MIN 1
-# else /* 16KB or 64KB */
-#  define XLAT_BLOCK_LEVEL_MIN 2
-# endif
-
-#endif /* AARCH32 */
+/* Alias to retain compatibility with the old #define name */
+#define XLAT_BLOCK_LEVEL_MIN	MIN_LVL_BLOCK_DESC
 
 void print_mmap(void);
 
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 40fd2d0..be18552 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -14,7 +14,7 @@
 #include "../xlat_tables_private.h"
 
 #if ENABLE_ASSERTIONS
-static unsigned long long xlat_arch_get_max_supported_pa(void)
+unsigned long long xlat_arch_get_max_supported_pa(void)
 {
 	/* Physical address space size for long descriptor format. */
 	return (1ull << 40) - 1ull;
@@ -81,24 +81,22 @@
 	return UPPER_ATTRS(XN);
 }
 
-void init_xlat_tables_arch(unsigned long long max_pa)
-{
-	assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <=
-	       xlat_arch_get_max_supported_pa());
-}
-
 /*******************************************************************************
- * Function for enabling the MMU in Secure PL1, assuming that the
- * page-tables have already been created.
+ * Function for enabling the MMU in Secure PL1, assuming that the page tables
+ * have already been created.
  ******************************************************************************/
-void enable_mmu_internal_secure(unsigned int flags, uint64_t *base_table)
-
+void enable_mmu_arch(unsigned int flags,
+		uint64_t *base_table,
+		unsigned long long max_pa,
+		uintptr_t max_va)
 {
 	u_register_t mair0, ttbcr, sctlr;
 	uint64_t ttbr0;
 
 	assert(IS_IN_SECURE());
-	assert((read_sctlr() & SCTLR_M_BIT) == 0);
+
+	sctlr = read_sctlr();
+	assert((sctlr & SCTLR_M_BIT) == 0);
 
 	/* Invalidate TLBs at the current exception level */
 	tlbiall();
@@ -109,29 +107,56 @@
 			ATTR_IWBWA_OWBWA_NTR_INDEX);
 	mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE,
 			ATTR_NON_CACHEABLE_INDEX);
-	write_mair0(mair0);
 
 	/*
-	 * Set TTBCR bits as well. Set TTBR0 table properties. Disable TTBR1.
+	 * Configure the control register for stage 1 of the PL1&0 translation
+	 * regime.
+	 */
+
+	/* Use the Long-descriptor translation table format. */
+	ttbcr = TTBCR_EAE_BIT;
+
+	/*
+	 * Disable translation table walk for addresses that are translated
+	 * using TTBR1. Therefore, only TTBR0 is used.
+	 */
+	ttbcr |= TTBCR_EPD1_BIT;
+
+	/*
+	 * Limit the input address ranges and memory region sizes translated
+	 * using TTBR0 to the given virtual address space size, if smaller than
+	 * 32 bits.
+	 */
+	if (max_va != UINT32_MAX) {
+		uintptr_t virtual_addr_space_size = max_va + 1;
+		assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+		/*
+		 * __builtin_ctzll(0) is undefined but here we are guaranteed
+		 * that virtual_addr_space_size is in the range [1, UINT32_MAX].
+		 */
+		ttbcr |= 32 - __builtin_ctzll(virtual_addr_space_size);
+	}
+
+	/*
+	 * Set the cacheability and shareability attributes for memory
+	 * associated with translation table walks using TTBR0.
 	 */
 	if (flags & XLAT_TABLE_NC) {
 		/* Inner & outer non-cacheable non-shareable. */
-		ttbcr = TTBCR_EAE_BIT |
-			TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
-			TTBCR_RGN0_INNER_NC |
-			(32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+		ttbcr |= TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
+			TTBCR_RGN0_INNER_NC;
 	} else {
 		/* Inner & outer WBWA & shareable. */
-		ttbcr = TTBCR_EAE_BIT |
-			TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA |
-			TTBCR_RGN0_INNER_WBA |
-			(32 - __builtin_ctzl((uintptr_t)PLAT_VIRT_ADDR_SPACE_SIZE));
+		ttbcr |= TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA |
+			TTBCR_RGN0_INNER_WBA;
 	}
-	ttbcr |= TTBCR_EPD1_BIT;
-	write_ttbcr(ttbcr);
 
 	/* Set TTBR0 bits as well */
 	ttbr0 = (uint64_t)(uintptr_t) base_table;
+
+	/* Now program the relevant system registers */
+	write_mair0(mair0);
+	write_ttbcr(ttbcr);
 	write64_ttbr0(ttbr0);
 	write64_ttbr1(0);
 
@@ -144,7 +169,6 @@
 	dsbish();
 	isb();
 
-	sctlr = read_sctlr();
 	sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT;
 
 	if (flags & DISABLE_DCACHE)
@@ -157,8 +181,3 @@
 	/* Ensure the MMU enable takes effect immediately */
 	isb();
 }
-
-void enable_mmu_arch(unsigned int flags, uint64_t *base_table)
-{
-	enable_mmu_internal_secure(flags, base_table);
-}
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.h b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.h
deleted file mode 100644
index f75ab79..0000000
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __XLAT_TABLES_ARCH_H__
-#define __XLAT_TABLES_ARCH_H__
-
-#include <arch.h>
-#include <platform_def.h>
-#include <xlat_tables_defs.h>
-#include "../xlat_tables_private.h"
-
-/*
- * In AArch32 state, the MMU only supports 4KB page granularity, which means
- * that the first translation table level is either 1 or 2. Both of them are
- * allowed to have block and table descriptors. See section G4.5.6 of the
- * ARMv8-A Architecture Reference Manual (DDI 0487A.k) for more information.
- *
- * The define below specifies the first table level that allows block
- * descriptors.
- */
-
-#define MIN_LVL_BLOCK_DESC 1
-
-/*
- * Each platform can define the size of the virtual address space, which is
- * defined in PLAT_VIRT_ADDR_SPACE_SIZE. TTBCR.TxSZ is calculated as 32 minus
- * the width of said address space. The value of TTBCR.TxSZ must be in the
- * range 0 to 7 [1], which means that the virtual address space width must be
- * in the range 32 to 25 bits.
- *
- * Here we calculate the initial lookup level from the value of
- * PLAT_VIRT_ADDR_SPACE_SIZE. For a 4 KB page size, level 1 supports virtual
- * address spaces of widths 32 to 31 bits, and level 2 from 30 to 25. Wider or
- * narrower address spaces are not supported. As a result, level 3 cannot be
- * used as initial lookup level with 4 KB granularity [1].
- *
- * For example, for a 31-bit address space (i.e. PLAT_VIRT_ADDR_SPACE_SIZE ==
- * 1 << 31), TTBCR.TxSZ will be programmed to (32 - 31) = 1. According to Table
- * G4-5 in the ARM ARM, the initial lookup level for an address space like that
- * is 1.
- *
- * See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
- * information:
- * [1] Section G4.6.5
- */
-
-#if PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << (32 - TTBCR_TxSZ_MIN))
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too big."
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1 << L1_XLAT_ADDRESS_SHIFT)
-
-# define XLAT_TABLE_LEVEL_BASE	1
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT)
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE >= (1 << (32 - TTBCR_TxSZ_MAX))
-
-# define XLAT_TABLE_LEVEL_BASE	2
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L2_XLAT_ADDRESS_SHIFT)
-
-#else
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too small."
-
-#endif
-
-#endif /* __XLAT_TABLES_ARCH_H__ */
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 14f6cd6..61eac10 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -22,8 +22,6 @@
 # define IMAGE_EL	1
 #endif
 
-static unsigned long long tcr_ps_bits;
-
 static unsigned long long calc_physical_addr_size_bits(
 					unsigned long long max_addr)
 {
@@ -60,7 +58,7 @@
 	PARANGE_0101
 };
 
-static unsigned long long xlat_arch_get_max_supported_pa(void)
+unsigned long long xlat_arch_get_max_supported_pa(void)
 {
 	u_register_t pa_range = read_id_aa64mmfr0_el1() &
 						ID_AA64MMFR0_EL1_PARANGE_MASK;
@@ -146,73 +144,28 @@
 	}
 }
 
-void init_xlat_tables_arch(unsigned long long max_pa)
-{
-	assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <=
-	       xlat_arch_get_max_supported_pa());
-
-	/*
-	 * If dynamic allocation of new regions is enabled the code can't make
-	 * assumptions about the max physical address because it could change
-	 * after adding new regions. If this functionality is disabled it is
-	 * safer to restrict the max physical address as much as possible.
-	 */
-#ifdef PLAT_XLAT_TABLES_DYNAMIC
-	tcr_ps_bits = calc_physical_addr_size_bits(PLAT_PHY_ADDR_SPACE_SIZE);
-#else
-	tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
-#endif
-}
-
 /*******************************************************************************
  * Macro generating the code for the function enabling the MMU in the given
  * exception level, assuming that the pagetables have already been created.
  *
  *   _el:		Exception level at which the function will run
- *   _tcr_extra:	Extra bits to set in the TCR register. This mask will
- *			be OR'ed with the default TCR value.
  *   _tlbi_fct:		Function to invalidate the TLBs at the current
  *			exception level
  ******************************************************************************/
-#define DEFINE_ENABLE_MMU_EL(_el, _tcr_extra, _tlbi_fct)		\
-	void enable_mmu_internal_el##_el(unsigned int flags,		\
-					 uint64_t *base_table)		\
+#define DEFINE_ENABLE_MMU_EL(_el, _tlbi_fct)				\
+	static void enable_mmu_internal_el##_el(int flags,		\
+						uint64_t mair,		\
+						uint64_t tcr,		\
+						uint64_t ttbr)		\
 	{								\
-		uint64_t mair, tcr, ttbr;				\
-		uint32_t sctlr;						\
-									\
-		assert(IS_IN_EL(_el));					\
-		assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0);	\
+		uint32_t sctlr = read_sctlr_el##_el();			\
+		assert((sctlr & SCTLR_M_BIT) == 0);			\
 									\
 		/* Invalidate TLBs at the current exception level */	\
 		_tlbi_fct();						\
 									\
-		/* Set attributes in the right indices of the MAIR */	\
-		mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);	\
-		mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,		\
-				ATTR_IWBWA_OWBWA_NTR_INDEX);		\
-		mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE,		\
-				ATTR_NON_CACHEABLE_INDEX);		\
 		write_mair_el##_el(mair);				\
-									\
-		/* Set TCR bits as well. */				\
-		/* Set T0SZ to (64 - width of virtual address space) */	\
-		if (flags & XLAT_TABLE_NC) {				\
-			/* Inner & outer non-cacheable non-shareable. */\
-			tcr = TCR_SH_NON_SHAREABLE |			\
-				TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC |	\
-				(64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
-		} else {						\
-			/* Inner & outer WBWA & shareable. */		\
-			tcr = TCR_SH_INNER_SHAREABLE |			\
-				TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA |	\
-				(64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE));\
-		}							\
-		tcr |= _tcr_extra;					\
 		write_tcr_el##_el(tcr);					\
-									\
-		/* Set TTBR bits as well */				\
-		ttbr = (uint64_t) base_table;				\
 		write_ttbr0_el##_el(ttbr);				\
 									\
 		/* Ensure all translation table writes have drained */	\
@@ -222,9 +175,7 @@
 		dsbish();						\
 		isb();							\
 									\
-		sctlr = read_sctlr_el##_el();				\
 		sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT;			\
-									\
 		if (flags & DISABLE_DCACHE)				\
 			sctlr &= ~SCTLR_C_BIT;				\
 		else							\
@@ -238,22 +189,69 @@
 
 /* Define EL1 and EL3 variants of the function enabling the MMU */
 #if IMAGE_EL == 1
-DEFINE_ENABLE_MMU_EL(1,
-		(tcr_ps_bits << TCR_EL1_IPS_SHIFT),
-		tlbivmalle1)
+DEFINE_ENABLE_MMU_EL(1, tlbivmalle1)
 #elif IMAGE_EL == 3
-DEFINE_ENABLE_MMU_EL(3,
-		TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT),
-		tlbialle3)
+DEFINE_ENABLE_MMU_EL(3, tlbialle3)
 #endif
 
-void enable_mmu_arch(unsigned int flags, uint64_t *base_table)
+void enable_mmu_arch(unsigned int flags,
+		uint64_t *base_table,
+		unsigned long long max_pa,
+		uintptr_t max_va)
 {
+	uint64_t mair, ttbr, tcr;
+
+	/* Set attributes in the right indices of the MAIR. */
+	mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
+	mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX);
+	mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);
+
+	ttbr = (uint64_t) base_table;
+
+	/*
+	 * Set TCR bits as well.
+	 */
+
+	/*
+	 * Limit the input address ranges and memory region sizes translated
+	 * using TTBR0 to the given virtual address space size.
+	 */
+	assert(max_va < UINTPTR_MAX);
+	uintptr_t virtual_addr_space_size = max_va + 1;
+	assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
+	/*
+	 * __builtin_ctzll(0) is undefined but here we are guaranteed that
+	 * virtual_addr_space_size is in the range [1,UINTPTR_MAX].
+	 */
+	tcr = 64 - __builtin_ctzll(virtual_addr_space_size);
+
+	/*
+	 * Set the cacheability and shareability attributes for memory
+	 * associated with translation table walks.
+	 */
+	if (flags & XLAT_TABLE_NC) {
+		/* Inner & outer non-cacheable non-shareable. */
+		tcr |= TCR_SH_NON_SHAREABLE |
+			TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC;
+	} else {
+		/* Inner & outer WBWA & shareable. */
+		tcr |= TCR_SH_INNER_SHAREABLE |
+			TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA;
+	}
+
+	/*
+	 * It is safer to restrict the max physical address accessible by the
+	 * hardware as much as possible.
+	 */
+	unsigned long long tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
+
 #if IMAGE_EL == 1
 	assert(IS_IN_EL(1));
-	enable_mmu_internal_el1(flags, base_table);
+	tcr |= tcr_ps_bits << TCR_EL1_IPS_SHIFT;
+	enable_mmu_internal_el1(flags, mair, tcr, ttbr);
 #elif IMAGE_EL == 3
 	assert(IS_IN_EL(3));
-	enable_mmu_internal_el3(flags, base_table);
+	tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);
+	enable_mmu_internal_el3(flags, mair, tcr, ttbr);
 #endif
 }
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.h b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.h
deleted file mode 100644
index caccb73..0000000
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __XLAT_TABLES_ARCH_H__
-#define __XLAT_TABLES_ARCH_H__
-
-#include <arch.h>
-#include <platform_def.h>
-#include <xlat_tables_defs.h>
-#include "../xlat_tables_private.h"
-
-/*
- * In AArch64 state, the MMU may support 4 KB, 16 KB and 64 KB page
- * granularity. For 4KB granularity, a level 0 table descriptor doesn't support
- * block translation. For 16KB, the same thing happens to levels 0 and 1. For
- * 64KB, same for level 1. See section D4.3.1 of the ARMv8-A Architecture
- * Reference Manual (DDI 0487A.k) for more information.
- *
- * The define below specifies the first table level that allows block
- * descriptors.
- */
-
-#if PAGE_SIZE == (4*1024) /* 4KB */
-# define MIN_LVL_BLOCK_DESC 1
-#else /* 16KB or 64KB */
-# define MIN_LVL_BLOCK_DESC 2
-#endif
-
-/*
- * Each platform can define the size of the virtual address space, which is
- * defined in PLAT_VIRT_ADDR_SPACE_SIZE. TCR.TxSZ is calculated as 64 minus the
- * width of said address space. The value of TCR.TxSZ must be in the range 16
- * to 39 [1], which means that the virtual address space width must be in the
- * range 48 to 25 bits.
- *
- * Here we calculate the initial lookup level from the value of
- * PLAT_VIRT_ADDR_SPACE_SIZE. For a 4 KB page size, level 0 supports virtual
- * address spaces of widths 48 to 40 bits, level 1 from 39 to 31, and level 2
- * from 30 to 25. Wider or narrower address spaces are not supported. As a
- * result, level 3 cannot be used as initial lookup level with 4 KB
- * granularity. [2]
- *
- * For example, for a 35-bit address space (i.e. PLAT_VIRT_ADDR_SPACE_SIZE ==
- * 1 << 35), TCR.TxSZ will be programmed to (64 - 35) = 29. According to Table
- * D4-11 in the ARM ARM, the initial lookup level for an address space like
- * that is 1.
- *
- * See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
- * information:
- * [1] Page 1730: 'Input address size', 'For all translation stages'.
- * [2] Section D4.2.5
- */
-
-#if PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << (64 - TCR_TxSZ_MIN))
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too big."
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1ULL << L0_XLAT_ADDRESS_SHIFT)
-
-# define XLAT_TABLE_LEVEL_BASE	0
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L0_XLAT_ADDRESS_SHIFT)
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE > (1 << L1_XLAT_ADDRESS_SHIFT)
-
-# define XLAT_TABLE_LEVEL_BASE	1
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L1_XLAT_ADDRESS_SHIFT)
-
-#elif PLAT_VIRT_ADDR_SPACE_SIZE >= (1 << (64 - TCR_TxSZ_MAX))
-
-# define XLAT_TABLE_LEVEL_BASE	2
-# define NUM_BASE_LEVEL_ENTRIES	\
-		(PLAT_VIRT_ADDR_SPACE_SIZE >> L2_XLAT_ADDRESS_SHIFT)
-
-#else
-
-# error "PLAT_VIRT_ADDR_SPACE_SIZE is too small."
-
-#endif
-
-#endif /* __XLAT_TABLES_ARCH_H__ */
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index 4f80434..b94ce5d 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -6,5 +6,4 @@
 
 XLAT_TABLES_LIB_SRCS	:=	$(addprefix lib/xlat_tables_v2/,	\
 				${ARCH}/xlat_tables_arch.c		\
-				xlat_tables_common.c			\
 				xlat_tables_internal.c)
diff --git a/lib/xlat_tables_v2/xlat_tables_common.c b/lib/xlat_tables_v2/xlat_tables_common.c
deleted file mode 100644
index f20bf93..0000000
--- a/lib/xlat_tables_v2/xlat_tables_common.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <assert.h>
-#include <cassert.h>
-#include <common_def.h>
-#include <debug.h>
-#include <errno.h>
-#include <platform_def.h>
-#include <string.h>
-#include <types.h>
-#include <utils.h>
-#include <xlat_tables_v2.h>
-#ifdef AARCH32
-# include "aarch32/xlat_tables_arch.h"
-#else
-# include "aarch64/xlat_tables_arch.h"
-#endif
-#include "xlat_tables_private.h"
-
-/*
- * Private variables used by the TF
- */
-static mmap_region_t tf_mmap[MAX_MMAP_REGIONS + 1];
-
-static uint64_t tf_xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES]
-			__aligned(XLAT_TABLE_SIZE) __section("xlat_table");
-
-static uint64_t tf_base_xlat_table[NUM_BASE_LEVEL_ENTRIES]
-		__aligned(NUM_BASE_LEVEL_ENTRIES * sizeof(uint64_t));
-
-#if PLAT_XLAT_TABLES_DYNAMIC
-static int xlat_tables_mapped_regions[MAX_XLAT_TABLES];
-#endif /* PLAT_XLAT_TABLES_DYNAMIC */
-
-xlat_ctx_t tf_xlat_ctx = {
-
-	.pa_max_address = PLAT_PHY_ADDR_SPACE_SIZE - 1,
-	.va_max_address = PLAT_VIRT_ADDR_SPACE_SIZE - 1,
-
-	.mmap = tf_mmap,
-	.mmap_num = MAX_MMAP_REGIONS,
-
-	.tables = tf_xlat_tables,
-	.tables_num = MAX_XLAT_TABLES,
-#if PLAT_XLAT_TABLES_DYNAMIC
-	.tables_mapped_regions = xlat_tables_mapped_regions,
-#endif /* PLAT_XLAT_TABLES_DYNAMIC */
-
-	.base_table = tf_base_xlat_table,
-	.base_table_entries = NUM_BASE_LEVEL_ENTRIES,
-
-	.max_pa = 0,
-	.max_va = 0,
-
-	.next_table = 0,
-
-	.base_level = XLAT_TABLE_LEVEL_BASE,
-
-	.initialized = 0
-};
-
-void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
-			size_t size, mmap_attr_t attr)
-{
-	mmap_region_t mm = {
-		.base_va = base_va,
-		.base_pa = base_pa,
-		.size = size,
-		.attr = attr,
-	};
-	mmap_add_region_ctx(&tf_xlat_ctx, (mmap_region_t *)&mm);
-}
-
-void mmap_add(const mmap_region_t *mm)
-{
-	while (mm->size) {
-		mmap_add_region_ctx(&tf_xlat_ctx, (mmap_region_t *)mm);
-		mm++;
-	}
-}
-
-#if PLAT_XLAT_TABLES_DYNAMIC
-
-int mmap_add_dynamic_region(unsigned long long base_pa,
-			    uintptr_t base_va, size_t size, mmap_attr_t attr)
-{
-	mmap_region_t mm = {
-		.base_va = base_va,
-		.base_pa = base_pa,
-		.size = size,
-		.attr = attr,
-	};
-	return mmap_add_dynamic_region_ctx(&tf_xlat_ctx, &mm);
-}
-
-int mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
-{
-	return mmap_remove_dynamic_region_ctx(&tf_xlat_ctx, base_va, size);
-}
-
-#endif /* PLAT_XLAT_TABLES_DYNAMIC */
-
-void init_xlat_tables(void)
-{
-	assert(!is_mmu_enabled());
-	assert(!tf_xlat_ctx.initialized);
-	print_mmap(tf_xlat_ctx.mmap);
-	tf_xlat_ctx.execute_never_mask =
-			xlat_arch_get_xn_desc(xlat_arch_current_el());
-	init_xlation_table(&tf_xlat_ctx);
-	xlat_tables_print(&tf_xlat_ctx);
-
-	assert(tf_xlat_ctx.max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1);
-	assert(tf_xlat_ctx.max_pa <= PLAT_PHY_ADDR_SPACE_SIZE - 1);
-
-	init_xlat_tables_arch(tf_xlat_ctx.max_pa);
-}
-
-#ifdef AARCH32
-
-void enable_mmu_secure(unsigned int flags)
-{
-	enable_mmu_arch(flags, tf_xlat_ctx.base_table);
-}
-
-#else
-
-void enable_mmu_el1(unsigned int flags)
-{
-	enable_mmu_arch(flags, tf_xlat_ctx.base_table);
-}
-
-void enable_mmu_el3(unsigned int flags)
-{
-	enable_mmu_arch(flags, tf_xlat_ctx.base_table);
-}
-
-#endif /* AARCH32 */
diff --git a/lib/xlat_tables_v2/xlat_tables_internal.c b/lib/xlat_tables_v2/xlat_tables_internal.c
index f60d78c..940337b 100644
--- a/lib/xlat_tables_v2/xlat_tables_internal.c
+++ b/lib/xlat_tables_v2/xlat_tables_internal.c
@@ -7,7 +7,6 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
-#include <cassert.h>
 #include <common_def.h>
 #include <debug.h>
 #include <errno.h>
@@ -15,14 +14,37 @@
 #include <string.h>
 #include <types.h>
 #include <utils.h>
+#include <xlat_tables_arch.h>
+#include <xlat_tables_defs.h>
 #include <xlat_tables_v2.h>
-#ifdef AARCH32
-# include "aarch32/xlat_tables_arch.h"
-#else
-# include "aarch64/xlat_tables_arch.h"
-#endif
+
 #include "xlat_tables_private.h"
 
+/*
+ * Each platform can define the size of its physical and virtual address spaces.
+ * If the platform hasn't defined one or both of them, default to
+ * ADDR_SPACE_SIZE. The latter is deprecated, though.
+ */
+#if ERROR_DEPRECATED
+# ifdef ADDR_SPACE_SIZE
+#  error "ADDR_SPACE_SIZE is deprecated. Use PLAT_xxx_ADDR_SPACE_SIZE instead."
+# endif
+#elif defined(ADDR_SPACE_SIZE)
+# ifndef PLAT_PHY_ADDR_SPACE_SIZE
+#  define PLAT_PHY_ADDR_SPACE_SIZE	ADDR_SPACE_SIZE
+# endif
+# ifndef PLAT_VIRT_ADDR_SPACE_SIZE
+#  define PLAT_VIRT_ADDR_SPACE_SIZE	ADDR_SPACE_SIZE
+# endif
+#endif
+
+/*
+ * Allocate and initialise the default translation context for the BL image
+ * currently executing.
+ */
+REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
+		PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);
+
 #if PLAT_XLAT_TABLES_DYNAMIC
 
 /*
@@ -335,7 +357,7 @@
  */
 static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
 		const int desc_type, const unsigned long long dest_pa,
-		const uintptr_t table_entry_base_va, const int level)
+		const uintptr_t table_entry_base_va, const unsigned int level)
 {
 	uintptr_t mm_end_va = mm->base_va + mm->size - 1;
 	uintptr_t table_entry_end_va =
@@ -666,7 +688,7 @@
 	return 0;
 }
 
-void mmap_add_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
+void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
 {
 	mmap_region_t *mm_cursor = ctx->mmap;
 	mmap_region_t *mm_last = mm_cursor + ctx->mmap_num;
@@ -743,6 +765,34 @@
 		ctx->max_va = end_va;
 }
 
+void mmap_add_region(unsigned long long base_pa,
+				uintptr_t base_va,
+				size_t size,
+				mmap_attr_t attr)
+{
+	mmap_region_t mm = {
+		.base_va = base_va,
+		.base_pa = base_pa,
+		.size = size,
+		.attr = attr,
+	};
+	mmap_add_region_ctx(&tf_xlat_ctx, &mm);
+}
+
+
+void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
+{
+	while (mm->size) {
+		mmap_add_region_ctx(ctx, mm);
+		mm++;
+	}
+}
+
+void mmap_add(const mmap_region_t *mm)
+{
+	mmap_add_ctx(&tf_xlat_ctx, mm);
+}
+
 #if PLAT_XLAT_TABLES_DYNAMIC
 
 int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
@@ -839,6 +889,18 @@
 	return 0;
 }
 
+int mmap_add_dynamic_region(unsigned long long base_pa,
+			    uintptr_t base_va, size_t size, mmap_attr_t attr)
+{
+	mmap_region_t mm = {
+		.base_va = base_va,
+		.base_pa = base_pa,
+		.size = size,
+		.attr = attr,
+	};
+	return mmap_add_dynamic_region_ctx(&tf_xlat_ctx, &mm);
+}
+
 /*
  * Removes the region with given base Virtual Address and size from the given
  * context.
@@ -914,6 +976,12 @@
 	return 0;
 }
 
+int mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
+{
+	return mmap_remove_dynamic_region_ctx(&tf_xlat_ctx,
+					base_va, size);
+}
+
 #endif /* PLAT_XLAT_TABLES_DYNAMIC */
 
 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
@@ -1042,15 +1110,47 @@
 void xlat_tables_print(xlat_ctx_t *ctx)
 {
 #if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+	VERBOSE("Translation tables state:\n");
+	VERBOSE("  Max allowed PA:  0x%llx\n", ctx->pa_max_address);
+	VERBOSE("  Max allowed VA:  %p\n", (void *) ctx->va_max_address);
+	VERBOSE("  Max mapped PA:   0x%llx\n", ctx->max_pa);
+	VERBOSE("  Max mapped VA:   %p\n", (void *) ctx->max_va);
+
+	VERBOSE("  Initial lookup level: %i\n", ctx->base_level);
+	VERBOSE("  Entries @initial lookup level: %i\n",
+		ctx->base_table_entries);
+
+	int used_page_tables;
+#if PLAT_XLAT_TABLES_DYNAMIC
+	used_page_tables = 0;
+	for (int i = 0; i < ctx->tables_num; ++i) {
+		if (ctx->tables_mapped_regions[i] != 0)
+			++used_page_tables;
+	}
+#else
+	used_page_tables = ctx->next_table;
+#endif
+	VERBOSE("  Used %i sub-tables out of %i (spare: %i)\n",
+		used_page_tables, ctx->tables_num,
+		ctx->tables_num - used_page_tables);
+
 	xlat_tables_print_internal(0, ctx->base_table, ctx->base_table_entries,
 				   ctx->base_level, ctx->execute_never_mask);
 #endif /* LOG_LEVEL >= LOG_LEVEL_VERBOSE */
 }
 
-void init_xlation_table(xlat_ctx_t *ctx)
+void init_xlat_tables_ctx(xlat_ctx_t *ctx)
 {
 	mmap_region_t *mm = ctx->mmap;
 
+	assert(!is_mmu_enabled());
+	assert(!ctx->initialized);
+
+	print_mmap(mm);
+
+	ctx->execute_never_mask =
+			xlat_arch_get_xn_desc(xlat_arch_current_el());
+
 	/* All tables must be zeroed before mapping any region. */
 
 	for (unsigned int i = 0; i < ctx->base_table_entries; i++)
@@ -1078,5 +1178,57 @@
 		mm++;
 	}
 
+	assert(ctx->pa_max_address <= xlat_arch_get_max_supported_pa());
+	assert(ctx->max_va <= ctx->va_max_address);
+	assert(ctx->max_pa <= ctx->pa_max_address);
+
 	ctx->initialized = 1;
+
+	xlat_tables_print(ctx);
 }
+
+void init_xlat_tables(void)
+{
+	init_xlat_tables_ctx(&tf_xlat_ctx);
+}
+
+/*
+ * If dynamic allocation of new regions is disabled then by the time we call the
+ * function enabling the MMU, we'll have registered all the memory regions to
+ * map for the system's lifetime. Therefore, at this point we know the maximum
+ * physical address that will ever be mapped.
+ *
+ * If dynamic allocation is enabled then we can't make any such assumption
+ * because the maximum physical address could get pushed while adding a new
+ * region. Therefore, in this case we have to assume that the whole address
+ * space size might be mapped.
+ */
+#ifdef PLAT_XLAT_TABLES_DYNAMIC
+#define MAX_PHYS_ADDR	tf_xlat_ctx.pa_max_address
+#else
+#define MAX_PHYS_ADDR	tf_xlat_ctx.max_pa
+#endif
+
+#ifdef AARCH32
+
+void enable_mmu_secure(unsigned int flags)
+{
+	enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+			tf_xlat_ctx.va_max_address);
+}
+
+#else
+
+void enable_mmu_el1(unsigned int flags)
+{
+	enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+			tf_xlat_ctx.va_max_address);
+}
+
+void enable_mmu_el3(unsigned int flags)
+{
+	enable_mmu_arch(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+			tf_xlat_ctx.va_max_address);
+}
+
+#endif /* AARCH32 */
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 83e0b6e..d352583 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -7,99 +7,8 @@
 #ifndef __XLAT_TABLES_PRIVATE_H__
 #define __XLAT_TABLES_PRIVATE_H__
 
-#include <cassert.h>
 #include <platform_def.h>
-#include <utils_def.h>
-
-/*
- * If the platform hasn't defined a physical and a virtual address space size
- * default to ADDR_SPACE_SIZE.
- */
-#if ERROR_DEPRECATED
-# ifdef ADDR_SPACE_SIZE
-#  error "ADDR_SPACE_SIZE is deprecated. Use PLAT_xxx_ADDR_SPACE_SIZE instead."
-# endif
-#elif defined(ADDR_SPACE_SIZE)
-# ifndef PLAT_PHY_ADDR_SPACE_SIZE
-#  define PLAT_PHY_ADDR_SPACE_SIZE	ADDR_SPACE_SIZE
-# endif
-# ifndef PLAT_VIRT_ADDR_SPACE_SIZE
-#  define PLAT_VIRT_ADDR_SPACE_SIZE	ADDR_SPACE_SIZE
-# endif
-#endif
-
-/* The virtual and physical address space sizes must be powers of two. */
-CASSERT(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE),
-	assert_valid_virt_addr_space_size);
-CASSERT(IS_POWER_OF_TWO(PLAT_PHY_ADDR_SPACE_SIZE),
-	assert_valid_phy_addr_space_size);
-
-/* Struct that holds all information about the translation tables. */
-typedef struct {
-
-	/*
-	 * Max allowed Virtual and Physical Addresses.
-	 */
-	unsigned long long pa_max_address;
-	uintptr_t va_max_address;
-
-	/*
-	 * Array of all memory regions stored in order of ascending end address
-	 * and ascending size to simplify the code that allows overlapping
-	 * regions. The list is terminated by the first entry with size == 0.
-	 * The max size of the list is stored in `mmap_num`. `mmap` points to an
-	 * array of mmap_num + 1 elements, so that there is space for the final
-	 * null entry.
-	 */
-	mmap_region_t *mmap;
-	unsigned int mmap_num;
-
-	/*
-	 * Array of finer-grain translation tables.
-	 * For example, if the initial lookup level is 1 then this array would
-	 * contain both level-2 and level-3 entries.
-	 */
-	uint64_t (*tables)[XLAT_TABLE_ENTRIES];
-	unsigned int tables_num;
-	/*
-	 * Keep track of how many regions are mapped in each table. The base
-	 * table can't be unmapped so it isn't needed to keep track of it.
-	 */
-#if PLAT_XLAT_TABLES_DYNAMIC
-	int *tables_mapped_regions;
-#endif /* PLAT_XLAT_TABLES_DYNAMIC */
-
-	unsigned int next_table;
-
-	/*
-	 * Base translation table. It doesn't need to have the same amount of
-	 * entries as the ones used for other levels.
-	 */
-	uint64_t *base_table;
-	unsigned int base_table_entries;
-
-	/*
-	 * Max Physical and Virtual addresses currently in use by the
-	 * translation tables. These might get updated as we map/unmap memory
-	 * regions but they will never go beyond pa/va_max_address.
-	 */
-	unsigned long long max_pa;
-	uintptr_t max_va;
-
-	/* Level of the base translation table. */
-	unsigned int base_level;
-
-	/* Set to 1 when the translation tables are initialized. */
-	unsigned int initialized;
-
-	/*
-	 * Bit mask that has to be ORed to the rest of a translation table
-	 * descriptor in order to prohibit execution of code at the exception
-	 * level of this translation context.
-	 */
-	uint64_t execute_never_mask;
-
-} xlat_ctx_t;
+#include <xlat_tables_defs.h>
 
 #if PLAT_XLAT_TABLES_DYNAMIC
 /*
@@ -138,13 +47,6 @@
  */
 void xlat_arch_tlbi_va_sync(void);
 
-/* Add a dynamic region to the specified context. */
-int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
-
-/* Remove a dynamic region from the specified context. */
-int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx, uintptr_t base_va,
-			size_t size);
-
 #endif /* PLAT_XLAT_TABLES_DYNAMIC */
 
 /* Print VA, PA, size and attributes of all regions in the mmap array. */
@@ -157,15 +59,6 @@
 void xlat_tables_print(xlat_ctx_t *ctx);
 
 /*
- * Initialize the translation tables by mapping all regions added to the
- * specified context.
- */
-void init_xlation_table(xlat_ctx_t *ctx);
-
-/* Add a static region to the specified context. */
-void mmap_add_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm);
-
-/*
  * Architecture-specific initialization code.
  */
 
@@ -179,11 +72,15 @@
  */
 uint64_t xlat_arch_get_xn_desc(int el);
 
-/* Execute architecture-specific translation table initialization code. */
-void init_xlat_tables_arch(unsigned long long max_pa);
+/*
+ * Return the maximum physical address supported by the hardware.
+ * This value depends on the execution state (AArch32/AArch64).
+ */
+unsigned long long xlat_arch_get_max_supported_pa(void);
 
 /* Enable MMU and configure it to use the specified translation tables. */
-void enable_mmu_arch(unsigned int flags, uint64_t *base_table);
+void enable_mmu_arch(unsigned int flags, uint64_t *base_table,
+		unsigned long long pa, uintptr_t max_va);
 
 /* Return 1 if the MMU of this Exception Level is enabled, 0 otherwise. */
 int is_mmu_enabled(void);
diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c
index 42f754e..f6a554f 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -19,6 +19,7 @@
 	CSS_MAP_DEVICE,
 	SOC_CSS_MAP_DEVICE,
 #if TRUSTED_BOARD_BOOT
+	/* Map DRAM to authenticate NS_BL2U image. */
 	ARM_MAP_NS_DRAM1,
 #endif
 	{0}
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index eb37f11..2f5d7fc 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -36,6 +36,10 @@
 					DEVICE1_SIZE,			\
 					MT_DEVICE | MT_RW | MT_SECURE)
 
+/*
+ * Need to be mapped with write permissions in order to set a new non-volatile
+ * counter value.
+ */
 #define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\
 					DEVICE2_SIZE,			\
 					MT_DEVICE | MT_RW | MT_SECURE)
@@ -56,8 +60,10 @@
 	V2M_MAP_IOFPGA,
 	MAP_DEVICE0,
 	MAP_DEVICE1,
-	MAP_DEVICE2,
 #if TRUSTED_BOARD_BOOT
+	/* To access the Root of Trust Public Key registers. */
+	MAP_DEVICE2,
+	/* Map DRAM to authenticate NS_BL2U image. */
 	ARM_MAP_NS_DRAM1,
 #endif
 	{0}
@@ -70,9 +76,12 @@
 	V2M_MAP_IOFPGA,
 	MAP_DEVICE0,
 	MAP_DEVICE1,
-	MAP_DEVICE2,
 	ARM_MAP_NS_DRAM1,
 	ARM_MAP_TSP_SEC_MEM,
+#if TRUSTED_BOARD_BOOT
+	/* To access the Root of Trust Public Key registers. */
+	MAP_DEVICE2,
+#endif
 #if ARM_BL31_IN_DRAM
 	ARM_MAP_BL31_SEC_DRAM,
 #endif
diff --git a/plat/arm/board/fvp/fvp_io_storage.c b/plat/arm/board/fvp/fvp_io_storage.c
index 27bab80..aa2ee30 100644
--- a/plat/arm/board/fvp/fvp_io_storage.c
+++ b/plat/arm/board/fvp/fvp_io_storage.c
@@ -8,8 +8,8 @@
 #include <common_def.h>
 #include <debug.h>
 #include <io_driver.h>
-#include <io_storage.h>
 #include <io_semihosting.h>
+#include <io_storage.h>
 #include <plat_arm.h>
 #include <semihosting.h>	/* For FOPEN_MODE_... */
 
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index e39a4d5..9a02089 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -10,8 +10,8 @@
 #include <debug.h>
 #include <errno.h>
 #include <mmio.h>
-#include <platform.h>
 #include <plat_arm.h>
+#include <platform.h>
 #include <psci.h>
 #include <v2m_def.h>
 #include "drivers/pwrc/fvp_pwrc.h"
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index ea128b6..46afb71 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -106,7 +106,7 @@
  * little space for growth.
  */
 #if TRUSTED_BOARD_BOOT
-# define PLAT_ARM_MAX_BL2_SIZE		0x1D000
+# define PLAT_ARM_MAX_BL2_SIZE		0x18000
 #else
 # define PLAT_ARM_MAX_BL2_SIZE		0xC000
 #endif
@@ -172,13 +172,13 @@
  * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
  * SCP_BL2 size plus a little space for growth.
  */
-#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x1D000
+#define PLAT_CSS_MAX_SCP_BL2_SIZE	0x14000
 
 /*
  * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
  * SCP_BL2U size plus a little space for growth.
  */
-#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x1D000
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE	0x14000
 
 /*
  * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 65b956d..7c026bc 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -6,8 +6,8 @@
 
 #include <bl_common.h>
 #include <errno.h>
-#include <platform.h>
 #include <plat_arm.h>
+#include <platform.h>
 #include <sp805.h>
 #include <tbbr_img_def.h>
 #include <v2m_def.h>
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index ba95d25..6860e36 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -9,8 +9,8 @@
 #include <arm_xlat_tables.h>
 #include <bl_common.h>
 #include <console.h>
-#include <platform_def.h>
 #include <plat_arm.h>
+#include <platform_def.h>
 #include <sp805.h>
 #include <utils.h>
 #include "../../../bl1/bl1_private.h"
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index e5619b7..b7621b8 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -12,8 +12,8 @@
 #include <debug.h>
 #include <desc_image_load.h>
 #include <plat_arm.h>
-#include <platform_def.h>
 #include <platform.h>
+#include <platform_def.h>
 #include <string.h>
 #include <utils.h>
 
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index 5dc9eea..03d908b 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -8,8 +8,8 @@
 #include <arm_def.h>
 #include <bl_common.h>
 #include <console.h>
-#include <platform_def.h>
 #include <plat_arm.h>
+#include <platform_def.h>
 #include <string.h>
 
 /* Weak definitions may be overridden in specific ARM standard platform */
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 2eed187..abeaea0 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -7,9 +7,9 @@
 #include <arm_def.h>
 #include <bl_common.h>
 #include <console.h>
+#include <plat_arm.h>
 #include <platform_def.h>
 #include <platform_tsp.h>
-#include <plat_arm.h>
 
 #define BL32_END (unsigned long)(&__BL32_END__)
 
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 73549aa..0712e3a 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -11,7 +11,7 @@
 #include <plat_arm.h>
 #include <string.h>
 #include <utils.h>
-#include "css_scp_bootloader.h"
+#include "../drivers/scp/css_scp.h"
 
 /* Weak definition may be overridden in specific CSS based platform */
 #if LOAD_IMAGE_V2
@@ -34,10 +34,13 @@
 
 	INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
 
-	ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base,
+	ret = css_scp_boot_image_xfer((void *)scp_bl2_image_info->image_base,
 		scp_bl2_image_info->image_size);
 
 	if (ret == 0)
+		ret = css_scp_boot_ready();
+
+	if (ret == 0)
 		INFO("BL2: SCP_BL2 transferred to SCP\n");
 	else
 		ERROR("BL2: SCP_BL2 transfer failure\n");
diff --git a/plat/arm/css/common/css_bl2u_setup.c b/plat/arm/css/common/css_bl2u_setup.c
index cc18758..d225151 100644
--- a/plat/arm/css/common/css_bl2u_setup.c
+++ b/plat/arm/css/common/css_bl2u_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <bl_common.h>
 #include <debug.h>
 #include <plat_arm.h>
-#include "css_scp_bootloader.h"
+#include "../drivers/scp/css_scp.h"
 
 /* Weak definition may be overridden in specific CSS based platform */
 #pragma weak bl2u_plat_handle_scp_bl2u
@@ -40,10 +40,13 @@
 
 	INFO("BL2U: Initiating SCP_BL2U transfer to SCP\n");
 
-	ret = scp_bootloader_transfer((void *)scp_bl2u_image_info.image_base,
+	ret = css_scp_boot_image_xfer((void *)scp_bl2u_image_info.image_base,
 		scp_bl2u_image_info.image_size);
 
 	if (ret == 0)
+		ret = css_scp_boot_ready();
+
+	if (ret == 0)
 		INFO("BL2U: SCP_BL2U transferred to SCP\n");
 	else
 		ERROR("BL2U: SCP_BL2U transfer failure\n");
diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk
index c2ae921..9381e4c 100644
--- a/plat/arm/css/common/css_common.mk
+++ b/plat/arm/css/common/css_common.mk
@@ -56,8 +56,8 @@
     $(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp-fwu-cfg))
   endif
 
-  BL2U_SOURCES		+=	plat/arm/css/common/css_scp_bootloader.c
-  BL2_SOURCES		+=	plat/arm/css/common/css_scp_bootloader.c
+  BL2U_SOURCES		+=	plat/arm/css/drivers/scp/css_bom_bootloader.c
+  BL2_SOURCES		+=	plat/arm/css/drivers/scp/css_bom_bootloader.c
 endif
 
 # Enable option to detect whether the SCP ROM firmware in use predates version
diff --git a/plat/arm/css/common/css_scp_bootloader.h b/plat/arm/css/common/css_scp_bootloader.h
deleted file mode 100644
index 0d6a6a2..0000000
--- a/plat/arm/css/common/css_scp_bootloader.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __CSS_SCP_BOOTLOADER_H__
-#define __CSS_SCP_BOOTLOADER_H__
-
-int scp_bootloader_transfer(void *image, unsigned int image_size);
-
-#endif /* __CSS_SCP_BOOTLOADER_H__ */
diff --git a/plat/arm/css/common/css_scp_bootloader.c b/plat/arm/css/drivers/scp/css_bom_bootloader.c
similarity index 85%
rename from plat/arm/css/common/css_scp_bootloader.c
rename to plat/arm/css/drivers/scp/css_bom_bootloader.c
index 3db5cf5..047e069 100644
--- a/plat/arm/css/common/css_scp_bootloader.c
+++ b/plat/arm/css/drivers/scp/css_bom_bootloader.c
@@ -1,18 +1,17 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch_helpers.h>
 #include <assert.h>
+#include <cassert.h>
 #include <css_def.h>
 #include <debug.h>
 #include <platform.h>
 #include <stdint.h>
-#include "../drivers/scpi/css_mhu.h"
-#include "../drivers/scpi/css_scpi.h"
-#include "css_scp_bootloader.h"
+#include "../scpi/css_mhu.h"
 
 /* ID of the MHU slot used for the BOM protocol */
 #define BOM_MHU_SLOT_ID		0
@@ -46,6 +45,18 @@
 	uint32_t block_size;
 } cmd_data_payload_t;
 
+/*
+ * All CSS platforms load SCP_BL2/SCP_BL2U just below BL rw-data and above
+ * BL2/BL2U (this is where BL31 usually resides except when ARM_BL31_IN_DRAM is
+ * set. Ensure that SCP_BL2/SCP_BL2U do not overflow into BL1 rw-data nor
+ * BL2/BL2U.
+ */
+CASSERT(SCP_BL2_LIMIT <= BL1_RW_BASE, assert_scp_bl2_overwrite_bl1);
+CASSERT(SCP_BL2U_LIMIT <= BL1_RW_BASE, assert_scp_bl2u_overwrite_bl1);
+
+CASSERT(SCP_BL2_BASE >= BL2_LIMIT, assert_scp_bl2_overwrite_bl2);
+CASSERT(SCP_BL2U_BASE >= BL2U_LIMIT, assert_scp_bl2u_overwrite_bl2u);
+
 static void scp_boot_message_start(void)
 {
 	mhu_secure_message_start(BOM_MHU_SLOT_ID);
@@ -88,7 +99,7 @@
 	mhu_secure_message_end(BOM_MHU_SLOT_ID);
 }
 
-int scp_bootloader_transfer(void *image, unsigned int image_size)
+int css_scp_boot_image_xfer(void *image, unsigned int image_size)
 {
 	uint32_t response;
 	uint32_t checksum;
@@ -170,8 +181,5 @@
 		return -1;
 	}
 
-	VERBOSE("Waiting for SCP to signal it is ready to go on\n");
-
-	/* Wait for SCP to signal it's ready */
-	return scpi_wait_ready();
+	return 0;
 }
diff --git a/plat/arm/css/drivers/scp/css_scp.h b/plat/arm/css/drivers/scp/css_scp.h
index 165226d..097a9f5 100644
--- a/plat/arm/css/drivers/scp/css_scp.h
+++ b/plat/arm/css/drivers/scp/css_scp.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,13 +7,31 @@
 #ifndef __CSS_SCP_H__
 #define __CSS_SCP_H__
 
-#include <psci.h>
+#include <types.h>
+#include "../scpi/css_scpi.h"
 
-void css_scp_suspend(const psci_power_state_t *target_state);
-void css_scp_off(const psci_power_state_t *target_state);
+/* Forward declarations */
+struct psci_power_state;
+
+/* API for power management by SCP */
+void css_scp_suspend(const struct psci_power_state *target_state);
+void css_scp_off(const struct psci_power_state *target_state);
 void css_scp_on(u_register_t mpidr);
 int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level);
 void __dead2 css_scp_sys_shutdown(void);
 void __dead2 css_scp_sys_reboot(void);
 
+/* API for SCP Boot Image transfer. Return 0 on success, -1 on error */
+int css_scp_boot_image_xfer(void *image, unsigned int image_size);
+
+/*
+ * API to wait for SCP to signal till it's ready after booting the transferred
+ * image.
+ */
+static inline int css_scp_boot_ready(void)
+{
+	VERBOSE("Waiting for SCP to signal it is ready to go on\n");
+	return scpi_wait_ready();
+}
+
 #endif	/* __CSS_SCP_H__ */
diff --git a/plat/arm/css/drivers/scpi/css_scpi.h b/plat/arm/css/drivers/scpi/css_scpi.h
index 0e26c3d..2a7e624 100644
--- a/plat/arm/css/drivers/scpi/css_scpi.h
+++ b/plat/arm/css/drivers/scpi/css_scpi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,11 +97,11 @@
 	scpi_system_reset = 2
 } scpi_system_state_t;
 
-extern int scpi_wait_ready(void);
-extern void scpi_set_css_power_state(unsigned int mpidr,
-					scpi_power_state_t cpu_state,
-					scpi_power_state_t cluster_state,
-					scpi_power_state_t css_state);
+int scpi_wait_ready(void);
+void scpi_set_css_power_state(unsigned int mpidr,
+				scpi_power_state_t cpu_state,
+				scpi_power_state_t cluster_state,
+				scpi_power_state_t css_state);
 int scpi_get_css_power_state(unsigned int mpidr, unsigned int *cpu_state_p,
 		unsigned int *cluster_state_p);
 uint32_t scpi_sys_power_state(scpi_system_state_t system_state);
diff --git a/plat/hisilicon/hikey/aarch64/hikey_common.c b/plat/hisilicon/hikey/aarch64/hikey_common.c
index d8a68cf..20a95bf 100644
--- a/plat/hisilicon/hikey/aarch64/hikey_common.c
+++ b/plat/hisilicon/hikey/aarch64/hikey_common.c
@@ -24,6 +24,10 @@
 					DEVICE_SIZE,			\
 					MT_DEVICE | MT_RW | MT_SECURE)
 
+#define MAP_TSP_MEM	MAP_REGION_FLAT(TSP_SEC_MEM_BASE,		\
+					TSP_SEC_MEM_SIZE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
 #define MAP_ROM_PARAM	MAP_REGION_FLAT(XG2RAM0_BASE,			\
 					BL1_XG2RAM0_OFFSET,		\
 					MT_DEVICE | MT_RO | MT_SECURE)
@@ -59,6 +63,7 @@
 static const mmap_region_t hikey_mmap[] = {
 	MAP_DDR,
 	MAP_DEVICE,
+	MAP_TSP_MEM,
 	{0}
 };
 #endif
@@ -67,6 +72,15 @@
 static const mmap_region_t hikey_mmap[] = {
 	MAP_DEVICE,
 	MAP_SRAM,
+	MAP_TSP_MEM,
+	{0}
+};
+#endif
+
+#if IMAGE_BL32
+static const mmap_region_t hikey_mmap[] = {
+	MAP_DEVICE,
+	MAP_DDR,
 	{0}
 };
 #endif
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index 9e9909b..13dc6c9 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -144,6 +144,41 @@
 				       DISABLE_ALL_EXCEPTIONS);
 }
 
+/*******************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On Hikey we only set the security state of the entrypoint
+ ******************************************************************************/
+#ifdef BL32_BASE
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+					entry_point_info_t *bl32_ep_info)
+{
+	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+	/*
+	 * The Secure Payload Dispatcher service is responsible for
+	 * setting the SPSR prior to entry into the BL32 image.
+	 */
+	bl32_ep_info->spsr = 0;
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL32
+ ******************************************************************************/
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+	/*
+	 * Populate the extents of memory available for loading BL32.
+	 */
+	bl32_meminfo->total_base = BL32_BASE;
+	bl32_meminfo->free_base = BL32_BASE;
+	bl32_meminfo->total_size =
+			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+	bl32_meminfo->free_size =
+			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+}
+#endif /* BL32_BASE */
+
 void bl2_plat_set_bl33_ep_info(image_info_t *image,
 			       entry_point_info_t *bl33_ep_info)
 {
diff --git a/plat/hisilicon/hikey/hikey_def.h b/plat/hisilicon/hikey/hikey_def.h
index 28ff553..bbad10f 100644
--- a/plat/hisilicon/hikey/hikey_def.h
+++ b/plat/hisilicon/hikey/hikey_def.h
@@ -12,7 +12,7 @@
 
 /* Always assume DDR is 1GB size. */
 #define DDR_BASE			0x0
-#define DDR_SIZE			0x80000000
+#define DDR_SIZE			0x40000000
 
 #define DEVICE_BASE			0xF4000000
 #define DEVICE_SIZE			0x05800000
@@ -20,6 +20,25 @@
 #define XG2RAM0_BASE			0xF9800000
 #define XG2RAM0_SIZE			0x00400000
 
+/* Memory location options for TSP */
+#define HIKEY_SRAM_ID		0
+#define HIKEY_DRAM_ID		1
+
+/*
+ * DDR for OP-TEE (32MB from 0x3E00000-0x3FFFFFFF) is divided in several
+ * regions
+ *   - Secure DDR (default is the top 16MB) used by OP-TEE
+ *   - Non-secure DDR used by OP-TEE (shared memory and padding) (4MB)
+ *   - Secure DDR (4MB aligned on 4MB) for OP-TEE's "Secure Data Path" feature
+ *   - Non-secure DDR (8MB) reserved for OP-TEE's future use
+ */
+#define DDR_SEC_SIZE			0x01000000
+#define DDR_SEC_BASE			(DDR_BASE + DDR_SIZE - DDR_SEC_SIZE)
+
+#define DDR_SDP_SIZE			0x00400000
+#define DDR_SDP_BASE			(DDR_SEC_BASE - 0x400000 /* align */ - \
+					DDR_SDP_SIZE)
+
 #define SRAM_BASE			0xFFF80000
 #define SRAM_SIZE			0x00012000
 
diff --git a/plat/hisilicon/hikey/hikey_io_storage.c b/plat/hisilicon/hikey/hikey_io_storage.c
index 4ca1846..c61ec2c 100644
--- a/plat/hisilicon/hikey/hikey_io_storage.c
+++ b/plat/hisilicon/hikey/hikey_io_storage.c
@@ -73,6 +73,10 @@
 	.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,
 };
@@ -102,6 +106,11 @@
 		(uintptr_t)&bl31_uuid_spec,
 		check_fip
 	},
+	[BL32_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_uuid_spec,
+		check_fip
+	},
 	[BL33_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl33_uuid_spec,
diff --git a/plat/hisilicon/hikey/hisi_pwrc.c b/plat/hisilicon/hikey/hisi_pwrc.c
index fcc9bd8..ade408d 100644
--- a/plat/hisilicon/hikey/hisi_pwrc.c
+++ b/plat/hisilicon/hikey/hisi_pwrc.c
@@ -6,11 +6,13 @@
 
 #include <debug.h>
 #include <mmio.h>
+
+#include <hi6220_regs_acpu.h>
+#include <hi6220_regs_ao.h>
 #include <hisi_ipc.h>
 #include <hisi_pwrc.h>
 #include <hisi_sram_map.h>
-#include <hi6220_regs_acpu.h>
-#include <hi6220_regs_ao.h>
+
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/plat/hisilicon/hikey/hisi_sip_svc.c b/plat/hisilicon/hikey/hisi_sip_svc.c
index 15953af..b3109d6 100644
--- a/plat/hisilicon/hikey/hisi_sip_svc.c
+++ b/plat/hisilicon/hikey/hisi_sip_svc.c
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <hisi_sip_svc.h>
 #include <debug.h>
+#include <hisi_sip_svc.h>
 #include <pmf.h>
 #include <runtime_svc.h>
 #include <stdint.h>
diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h
index a91a9b0..af15232 100644
--- a/plat/hisilicon/hikey/include/platform_def.h
+++ b/plat/hisilicon/hikey/include/platform_def.h
@@ -11,13 +11,6 @@
 #include "../hikey_def.h"
 
 /*
- * Platform binary types for linking
- */
-#define PLATFORM_LINKER_FORMAT          "elf64-littleaarch64"
-#define PLATFORM_LINKER_ARCH            aarch64
-
-
-/*
  * Generic platform constants
  */
 
@@ -104,6 +97,33 @@
 #define BL31_BASE			BL2_LIMIT
 #define BL31_LIMIT			0xF9898000
 
+/*
+ * BL3-2 specific defines.
+ */
+
+/*
+ * The TSP currently executes from TZC secured area of DRAM or SRAM.
+ */
+#define BL32_SRAM_BASE			BL31_LIMIT
+#define BL32_SRAM_LIMIT			(BL31_LIMIT+0x80000) /* 512K */
+
+#define BL32_DRAM_BASE			DDR_SEC_BASE
+#define BL32_DRAM_LIMIT			(DDR_SEC_BASE+DDR_SEC_SIZE)
+
+#if (HIKEY_TSP_RAM_LOCATION_ID == HIKEY_DRAM_ID)
+#define TSP_SEC_MEM_BASE		BL32_DRAM_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_DRAM_LIMIT - BL32_DRAM_BASE)
+#define BL32_BASE			BL32_DRAM_BASE
+#define BL32_LIMIT			BL32_DRAM_LIMIT
+#elif (HIKEY_TSP_RAM_LOCATION_ID == HIKEY_SRAM_ID)
+#define TSP_SEC_MEM_BASE		BL32_SRAM_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_SRAM_LIMIT - BL32_SRAM_BASE)
+#define BL32_BASE			BL32_SRAM_BASE
+#define BL32_LIMIT			BL32_SRAM_LIMIT
+#else
+#error "Currently unsupported HIKEY_TSP_LOCATION_ID value"
+#endif
+
 #define NS_BL1U_BASE			(BL2_BASE)
 #define NS_BL1U_SIZE			(0x00010000)
 #define NS_BL1U_LIMIT			(NS_BL1U_BASE + NS_BL1U_SIZE)
@@ -113,10 +133,14 @@
  */
 #define ADDR_SPACE_SIZE			(1ull << 32)
 
-#if IMAGE_BL1 || IMAGE_BL2 || IMAGE_BL31
+#if IMAGE_BL1 || IMAGE_BL2 || IMAGE_BL32
 #define MAX_XLAT_TABLES			3
 #endif
 
+#if IMAGE_BL31
+#define MAX_XLAT_TABLES			4
+#endif
+
 #define MAX_MMAP_REGIONS		16
 
 #define HIKEY_NS_IMAGE_OFFSET		(DDR_BASE + 0x35000000)
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 08a3047..8da3998 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -4,6 +4,17 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# On Hikey, the TSP can execute from TZC secure area in DRAM (default)
+# or SRAM.
+HIKEY_TSP_RAM_LOCATION	:=	dram
+ifeq (${HIKEY_TSP_RAM_LOCATION}, dram)
+  HIKEY_TSP_RAM_LOCATION_ID = HIKEY_DRAM_ID
+else ifeq (${HIKEY_TSP_RAM_LOCATION}, sram)
+  HIKEY_TSP_RAM_LOCATION_ID := HIKEY_SRAM_ID
+else
+  $(error "Currently unsupported HIKEY_TSP_RAM_LOCATION value")
+endif
+
 CONSOLE_BASE			:=	PL011_UART3_BASE
 CRASH_CONSOLE_BASE		:=	PL011_UART3_BASE
 PLAT_PARTITION_MAX_ENTRIES	:=	12
@@ -12,11 +23,11 @@
 PROGRAMMABLE_RESET_ADDRESS	:=	1
 
 # Process flags
+$(eval $(call add_define,HIKEY_TSP_RAM_LOCATION_ID))
 $(eval $(call add_define,CONSOLE_BASE))
 $(eval $(call add_define,CRASH_CONSOLE_BASE))
 $(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
 $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
-$(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw))
 
 ENABLE_PLAT_COMPAT	:=	0
 
diff --git a/plat/hisilicon/hikey960/aarch64/hikey960_common.c b/plat/hisilicon/hikey960/aarch64/hikey960_common.c
index d7894b3..7068fb6 100644
--- a/plat/hisilicon/hikey960/aarch64/hikey960_common.c
+++ b/plat/hisilicon/hikey960/aarch64/hikey960_common.c
@@ -37,6 +37,10 @@
 					HIKEY960_UFS_DESC_SIZE,		\
 					MT_MEMORY | MT_RW | MT_NS)
 
+#define MAP_TSP_MEM	MAP_REGION_FLAT(TSP_SEC_MEM_BASE,		\
+					TSP_SEC_MEM_SIZE,		\
+					MT_MEMORY | MT_RW | MT_SECURE)
+
 /*
  * Table of regions for different BL stages to map using the MMU.
  * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
@@ -56,6 +60,7 @@
 static const mmap_region_t hikey960_mmap[] = {
 	MAP_DDR,
 	MAP_DEVICE,
+	MAP_TSP_MEM,
 	{0}
 };
 #endif
@@ -63,6 +68,15 @@
 #if IMAGE_BL31
 static const mmap_region_t hikey960_mmap[] = {
 	MAP_DEVICE,
+	MAP_TSP_MEM,
+	{0}
+};
+#endif
+
+#if IMAGE_BL32
+static const mmap_region_t hikey960_mmap[] = {
+	MAP_DEVICE,
+	MAP_DDR,
 	{0}
 };
 #endif
diff --git a/plat/hisilicon/hikey960/drivers/ipc/hisi_ipc.c b/plat/hisilicon/hikey960/drivers/ipc/hisi_ipc.c
index 8ce1e4f..4c664d1 100644
--- a/plat/hisilicon/hikey960/drivers/ipc/hisi_ipc.c
+++ b/plat/hisilicon/hikey960/drivers/ipc/hisi_ipc.c
@@ -6,12 +6,12 @@
 
 #include <arch_helpers.h>
 #include <assert.h>
+#include <debug.h>
 #include <hi3660.h>
+#include <hisi_ipc.h>
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
-#include <hisi_ipc.h>
-#include <debug.h>
 
 #include "../../hikey960_private.h"
 
diff --git a/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c b/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c
index f82144a..9fdc3e7 100644
--- a/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c
+++ b/plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c
@@ -4,13 +4,15 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <../hikey960_def.h>
 #include <arch_helpers.h>
 #include <assert.h>
+#include <hisi_ipc.h>
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
-#include <../hikey960_def.h>
-#include <hisi_ipc.h>
+
+
 #include "hisi_pwrc.h"
 
 
diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
index f9666df..54e7347 100644
--- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
@@ -13,10 +13,10 @@
 #include <delay_timer.h>
 #include <dw_ufs.h>
 #include <errno.h>
+#include <generic_delay_timer.h>
 #include <gicv2.h>
 #include <hi3660.h>
 #include <mmio.h>
-#include <generic_delay_timer.h>
 #include <platform.h>
 #include <platform_def.h>
 #include <string.h>
diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
index e225793..de676a7 100644
--- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
@@ -177,6 +177,41 @@
 				       DISABLE_ALL_EXCEPTIONS);
 }
 
+/*******************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On Hikey we only set the security state of the entrypoint
+ ******************************************************************************/
+#ifdef BL32_BASE
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+					entry_point_info_t *bl32_ep_info)
+{
+	SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+	/*
+	 * The Secure Payload Dispatcher service is responsible for
+	 * setting the SPSR prior to entry into the BL32 image.
+	 */
+	bl32_ep_info->spsr = 0;
+}
+
+/*******************************************************************************
+ * Populate the extents of memory available for loading BL32
+ ******************************************************************************/
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+	/*
+	 * Populate the extents of memory available for loading BL32.
+	 */
+	bl32_meminfo->total_base = BL32_BASE;
+	bl32_meminfo->free_base = BL32_BASE;
+	bl32_meminfo->total_size =
+			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+	bl32_meminfo->free_size =
+			(TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
+}
+#endif /* BL32_BASE */
+
 void bl2_plat_set_bl33_ep_info(image_info_t *image,
 			       entry_point_info_t *bl33_ep_info)
 {
diff --git a/plat/hisilicon/hikey960/hikey960_def.h b/plat/hisilicon/hikey960/hikey960_def.h
index e713e2e..fc46d71 100644
--- a/plat/hisilicon/hikey960/hikey960_def.h
+++ b/plat/hisilicon/hikey960/hikey960_def.h
@@ -16,6 +16,25 @@
 #define DEVICE_BASE			0xE0000000
 #define DEVICE_SIZE			0x20000000
 
+/* Memory location options for TSP */
+#define HIKEY960_SRAM_ID	0
+#define HIKEY960_DRAM_ID	1
+
+/*
+ * DDR for OP-TEE (32MB from 0x3E00000-0x3FFFFFFF) is divided in several
+ * regions:
+ *   - Secure DDR (default is the top 16MB) used by OP-TEE
+ *   - Non-secure DDR used by OP-TEE (shared memory and padding) (4MB)
+ *   - Secure DDR (4MB aligned on 4MB) for OP-TEE's "Secure Data Path" feature
+ *   - Non-secure DDR (8MB) reserved for OP-TEE's future use
+ */
+#define DDR_SEC_SIZE			0x01000000
+#define DDR_SEC_BASE			0x3F000000
+
+#define DDR_SDP_SIZE			0x00400000
+#define DDR_SDP_BASE			(DDR_SEC_BASE - 0x400000 /* align */ - \
+					DDR_SDP_SIZE)
+
 /*
  * PL011 related constants
  */
diff --git a/plat/hisilicon/hikey960/hikey960_io_storage.c b/plat/hisilicon/hikey960/hikey960_io_storage.c
index de54e88..57d97e5 100644
--- a/plat/hisilicon/hikey960/hikey960_io_storage.c
+++ b/plat/hisilicon/hikey960/hikey960_io_storage.c
@@ -69,6 +69,10 @@
 	.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,
 };
@@ -94,6 +98,11 @@
 		(uintptr_t)&bl31_uuid_spec,
 		check_fip
 	},
+	[BL32_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_uuid_spec,
+		check_fip
+	},
 	[BL33_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl33_uuid_spec,
diff --git a/plat/hisilicon/hikey960/include/plat_macros.S b/plat/hisilicon/hikey960/include/plat_macros.S
index 9f1befd..5137f9e 100644
--- a/plat/hisilicon/hikey960/include/plat_macros.S
+++ b/plat/hisilicon/hikey960/include/plat_macros.S
@@ -8,8 +8,8 @@
 #define __PLAT_MACROS_S__
 
 #include <cci.h>
-#include <hi3660.h>
 #include <gic_v2.h>
+#include <hi3660.h>
 #include <platform_def.h>
 
 .section .rodata.gic_reg_name, "aS"
diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h
index 369117b..8bf32c3 100644
--- a/plat/hisilicon/hikey960/include/platform_def.h
+++ b/plat/hisilicon/hikey960/include/platform_def.h
@@ -63,6 +63,27 @@
 #define BL31_BASE			(BL2_LIMIT)		/* 1AC5_8000 */
 #define BL31_LIMIT			(BL31_BASE + 0x40000)	/* 1AC9_8000 */
 
+/*
+ * BL3-2 specific defines.
+ */
+
+/*
+ * The TSP currently executes from TZC secured area of DRAM.
+ */
+#define BL32_DRAM_BASE                  DDR_SEC_BASE
+#define BL32_DRAM_LIMIT                 (DDR_SEC_BASE+DDR_SEC_SIZE)
+
+#if (HIKEY960_TSP_RAM_LOCATION_ID == HIKEY960_DRAM_ID)
+#define TSP_SEC_MEM_BASE		BL32_DRAM_BASE
+#define TSP_SEC_MEM_SIZE		(BL32_DRAM_LIMIT - BL32_DRAM_BASE)
+#define BL32_BASE			BL32_DRAM_BASE
+#define BL32_LIMIT			BL32_DRAM_LIMIT
+#elif (HIKEY960_TSP_RAM_LOCATION_ID == HIKEY960_SRAM_ID)
+#error "SRAM storage of TSP payload is currently unsupported"
+#else
+#error "Currently unsupported HIKEY960_TSP_LOCATION_ID value"
+#endif
+
 #define NS_BL1U_BASE			(BL31_LIMIT)		/* 1AC9_8000 */
 #define NS_BL1U_SIZE			(0x00100000)
 #define NS_BL1U_LIMIT			(NS_BL1U_BASE + NS_BL1U_SIZE)
@@ -70,7 +91,7 @@
 #define HIKEY960_NS_IMAGE_OFFSET	(0x1AC18000)	/* offset in l-loader */
 #define HIKEY960_NS_TMP_OFFSET		(0x1AE00000)
 
-#define SCP_BL2_BASE			BL31_BASE
+#define SCP_BL2_BASE			BL31_BASE /* 1AC5_8000 */
 
 #define SCP_MEM_BASE			(0x89C80000)
 #define SCP_MEM_SIZE			(0x00040000)
@@ -80,7 +101,7 @@
  */
 #define ADDR_SPACE_SIZE			(1ull << 32)
 
-#if IMAGE_BL1 || IMAGE_BL2 || IMAGE_BL31
+#if IMAGE_BL1 || IMAGE_BL2 || IMAGE_BL31 || IMAGE_BL32
 #define MAX_XLAT_TABLES			3
 #endif
 
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index 145eee0..edbce63 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -4,13 +4,23 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+# On Hikey960, the TSP can execute from TZC secure area in DRAM.
+HIKEY960_TSP_RAM_LOCATION	:=	dram
+ifeq (${HIKEY960_TSP_RAM_LOCATION}, dram)
+  HIKEY960_TSP_RAM_LOCATION_ID = HIKEY960_DRAM_ID
+else ifeq (${HIKEY960_TSP_RAM_LOCATION}, sram)
+  HIKEY960_TSP_RAM_LOCATION_ID := HIKEY960_SRAM_ID
+else
+  $(error "Currently unsupported HIKEY960_TSP_RAM_LOCATION value")
+endif
+
 CRASH_CONSOLE_BASE		:=	PL011_UART6_BASE
 COLD_BOOT_SINGLE_CPU		:=	1
 PROGRAMMABLE_RESET_ADDRESS	:=	1
 
 # Process flags
+$(eval $(call add_define,HIKEY960_TSP_RAM_LOCATION_ID))
 $(eval $(call add_define,CRASH_CONSOLE_BASE))
-$(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw))
 
 ENABLE_PLAT_COMPAT	:=	0
 
@@ -63,3 +73,8 @@
 				plat/hisilicon/hikey960/drivers/pwrc/hisi_pwrc.c \
 				plat/hisilicon/hikey960/drivers/ipc/hisi_ipc.c \
 				${HIKEY960_GIC_SOURCES}
+
+# Enable workarounds for selected Cortex-A53 errata.
+ERRATA_A53_836870		:=	1
+ERRATA_A53_843419		:=	1
+ERRATA_A53_855873		:=	1
diff --git a/plat/hisilicon/poplar/aarch64/platform_common.c b/plat/hisilicon/poplar/aarch64/platform_common.c
new file mode 100644
index 0000000..a7dac4f
--- /dev/null
+++ b/plat/hisilicon/poplar/aarch64/platform_common.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <platform.h>
+#include <xlat_tables.h>
+#include "hi3798cv200.h"
+#include "platform_def.h"
+
+#define MAP_DDR		MAP_REGION_FLAT(DDR_BASE,			\
+					DDR_SIZE,			\
+					MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_DEVICE	MAP_REGION_FLAT(DEVICE_BASE,			\
+					DEVICE_SIZE,			\
+					MT_DEVICE | MT_RW | MT_SECURE)
+
+static const mmap_region_t poplar_mmap[] = {
+	MAP_DDR,
+	MAP_DEVICE,
+	{0}
+};
+
+#define DEFINE_CONFIGURE_MMU_EL(_el)					\
+	void plat_configure_mmu_el##_el(unsigned long total_base,	\
+				  unsigned long total_size,		\
+				  unsigned long ro_start,		\
+				  unsigned long ro_limit,		\
+				  unsigned long coh_start,		\
+				  unsigned long coh_limit)		\
+	{								\
+		mmap_add_region(total_base, total_base,			\
+				total_size,				\
+				MT_MEMORY | MT_RW | MT_SECURE);		\
+		mmap_add_region(ro_start, ro_start,			\
+				ro_limit - ro_start,			\
+				MT_MEMORY | MT_RO | MT_SECURE);		\
+		mmap_add_region(coh_start, coh_start,			\
+				coh_limit - coh_start,			\
+				MT_DEVICE | MT_RW | MT_SECURE);		\
+		mmap_add(poplar_mmap);					\
+		init_xlat_tables();					\
+									\
+		enable_mmu_el##_el(0);					\
+	}
+
+DEFINE_CONFIGURE_MMU_EL(3)
+DEFINE_CONFIGURE_MMU_EL(1)
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+	return SYS_COUNTER_FREQ_IN_TICKS;
+}
diff --git a/plat/hisilicon/poplar/bl1_plat_setup.c b/plat/hisilicon/poplar/bl1_plat_setup.c
new file mode 100644
index 0000000..c65e29e
--- /dev/null
+++ b/plat/hisilicon/poplar/bl1_plat_setup.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 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 <errno.h>
+#include <generic_delay_timer.h>
+#include <mmio.h>
+#include <pl061_gpio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <string.h>
+#include <tbbr_img_def.h>
+#include "../../bl1/bl1_private.h"
+#include "hi3798cv200.h"
+#include "plat_private.h"
+
+/* Symbols from link script for conherent section */
+extern unsigned long __COHERENT_RAM_START__;
+extern unsigned long __COHERENT_RAM_END__;
+
+#define BL1_COHERENT_RAM_BASE	(unsigned long)(&__COHERENT_RAM_START__)
+#define BL1_COHERENT_RAM_LIMIT	(unsigned long)(&__COHERENT_RAM_END__)
+
+/* Data structure which holds the extents of the trusted RAM for BL1 */
+static meminfo_t bl1_tzram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+	return &bl1_tzram_layout;
+}
+
+void bl1_early_platform_setup(void)
+{
+	/* Initialize the console to provide early debug support */
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Allow BL1 to see the whole Trusted RAM */
+	bl1_tzram_layout.total_base = BL_MEM_BASE;
+	bl1_tzram_layout.total_size = BL_MEM_SIZE;
+
+	/* Calculate how much RAM BL1 is using and how much remains free */
+	bl1_tzram_layout.free_base = BL_MEM_BASE;
+	bl1_tzram_layout.free_size = BL_MEM_SIZE;
+
+	reserve_mem(&bl1_tzram_layout.free_base,
+		    &bl1_tzram_layout.free_size,
+		    BL1_RAM_BASE,
+		    BL1_RAM_LIMIT - BL1_RAM_BASE);
+
+	INFO("BL1: 0x%lx - 0x%lx [size = %zu]\n", BL1_RAM_BASE, BL1_RAM_LIMIT,
+	     BL1_RAM_LIMIT - BL1_RAM_BASE);
+}
+
+void bl1_plat_arch_setup(void)
+{
+	plat_configure_mmu_el3(bl1_tzram_layout.total_base,
+			       bl1_tzram_layout.total_size,
+			       BL_MEM_BASE, /* l-loader and BL1 ROM */
+			       BL1_RO_LIMIT,
+			       BL1_COHERENT_RAM_BASE,
+			       BL1_COHERENT_RAM_LIMIT);
+}
+
+void bl1_platform_setup(void)
+{
+	int i;
+
+	generic_delay_timer_init();
+
+	pl061_gpio_init();
+	for (i = 0; i < GPIO_MAX; i++)
+		pl061_gpio_register(GPIO_BASE(i), i);
+
+	plat_io_setup();
+}
+
+unsigned int bl1_plat_get_next_image_id(void)
+{
+	return BL2_IMAGE_ID;
+}
diff --git a/plat/hisilicon/poplar/bl2_plat_setup.c b/plat/hisilicon/poplar/bl2_plat_setup.c
new file mode 100644
index 0000000..1741475
--- /dev/null
+++ b/plat/hisilicon/poplar/bl2_plat_setup.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 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 <errno.h>
+#include <generic_delay_timer.h>
+#include <mmio.h>
+#include <partition/partition.h>
+#include <platform.h>
+#include <string.h>
+#include "hi3798cv200.h"
+#include "plat_private.h"
+
+/* Memory ranges for code and read only data sections */
+#define BL2_RO_BASE	(unsigned long)(&__RO_START__)
+#define BL2_RO_LIMIT	(unsigned long)(&__RO_END__)
+
+/* Memory ranges for coherent memory section */
+#define BL2_COHERENT_RAM_BASE	(unsigned long)(&__COHERENT_RAM_START__)
+#define BL2_COHERENT_RAM_LIMIT	(unsigned long)(&__COHERENT_RAM_END__)
+
+typedef struct bl2_to_bl31_params_mem {
+	bl31_params_t		bl31_params;
+	image_info_t		bl31_image_info;
+	image_info_t		bl33_image_info;
+	entry_point_info_t	bl33_ep_info;
+	entry_point_info_t	bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+static bl2_to_bl31_params_mem_t bl31_params_mem;
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+	return &bl2_tzram_layout;
+}
+
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+	bl31_params_t *bl2_to_bl31_params = NULL;
+
+	/*
+	 * Initialise the memory for all the arguments that needs to
+	 * be passed to BL3-1
+	 */
+	memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+	/* Assign memory for TF related information */
+	bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+	SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+	/* Fill BL3-1 related information */
+	bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
+		       PARAM_IMAGE_BINARY, VERSION_1, 0);
+
+	/* Fill BL3-3 related information */
+	bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+		       PARAM_EP, VERSION_1, 0);
+
+	/* BL3-3 expects to receive the primary CPU MPID (through x0) */
+	bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+
+	bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+	SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
+		       PARAM_IMAGE_BINARY, VERSION_1, 0);
+
+	return bl2_to_bl31_params;
+}
+
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+	return &bl31_params_mem.bl31_ep_info;
+}
+
+void bl2_plat_set_bl31_ep_info(image_info_t *image,
+			       entry_point_info_t *bl31_ep_info)
+{
+	SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+	bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+				     DISABLE_ALL_EXCEPTIONS);
+}
+
+static uint32_t hisi_get_spsr_for_bl33_entry(void)
+{
+	unsigned long el_status;
+	unsigned int mode;
+	uint32_t spsr;
+
+	/* Figure out what mode we enter the non-secure world in */
+	el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+	el_status &= ID_AA64PFR0_ELX_MASK;
+
+	mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+	/*
+	 * TODO: Consider the possibility of specifying the SPSR in
+	 * the FIP ToC and allowing the platform to have a say as
+	 * well.
+	 */
+	spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+	return spsr;
+}
+
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+			       entry_point_info_t *bl33_ep_info)
+{
+	SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+	bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry();
+	bl33_ep_info->args.arg2 = image->image_size;
+}
+
+void bl2_plat_flush_bl31_params(void)
+{
+	flush_dcache_range((unsigned long)&bl31_params_mem,
+			   sizeof(bl2_to_bl31_params_mem_t));
+}
+
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+	bl33_meminfo->total_base = DDR_BASE;
+	bl33_meminfo->total_size = DDR_SIZE;
+	bl33_meminfo->free_base  = DDR_BASE;
+	bl33_meminfo->free_size  = DDR_SIZE;
+}
+
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Enable arch timer */
+	generic_delay_timer_init();
+
+	bl2_tzram_layout = *mem_layout;
+}
+
+void bl2_plat_arch_setup(void)
+{
+	plat_configure_mmu_el1(bl2_tzram_layout.total_base,
+			       bl2_tzram_layout.total_size,
+			       BL2_RO_BASE,
+			       BL2_RO_LIMIT,
+			       BL2_COHERENT_RAM_BASE,
+			       BL2_COHERENT_RAM_LIMIT);
+}
+
+void bl2_platform_setup(void)
+{
+	plat_io_setup();
+}
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+	return PLAT_ARM_NS_IMAGE_OFFSET;
+}
diff --git a/plat/hisilicon/poplar/bl31_plat_setup.c b/plat/hisilicon/poplar/bl31_plat_setup.c
new file mode 100644
index 0000000..b9a0e18
--- /dev/null
+++ b/plat/hisilicon/poplar/bl31_plat_setup.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl31.h>
+#include <bl_common.h>
+#include <console.h>
+#include <cortex_a53.h>
+#include <debug.h>
+#include <errno.h>
+#include <generic_delay_timer.h>
+#include <mmio.h>
+#include <plat_arm.h>
+#include <platform.h>
+#include <stddef.h>
+#include <string.h>
+#include "hi3798cv200.h"
+#include "plat_private.h"
+#include "platform_def.h"
+
+/* Memory ranges for code and RO data sections */
+#define BL31_RO_BASE	(unsigned long)(&__RO_START__)
+#define BL31_RO_LIMIT	(unsigned long)(&__RO_END__)
+
+/* Memory ranges for coherent memory section */
+#define BL31_COHERENT_RAM_BASE	(unsigned long)(&__COHERENT_RAM_START__)
+#define BL31_COHERENT_RAM_LIMIT	(unsigned long)(&__COHERENT_RAM_END__)
+
+static entry_point_info_t bl33_image_ep_info;
+
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+	return &bl33_image_ep_info;
+}
+
+void bl31_early_platform_setup(bl31_params_t *from_bl2,
+			       void *plat_params_from_bl2)
+{
+	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
+
+	/* Init console for crash report */
+	plat_crash_console_init();
+
+	bl33_image_ep_info = *from_bl2->bl33_ep_info;
+}
+
+void bl31_platform_setup(void)
+{
+	/* Init arch timer */
+	generic_delay_timer_init();
+
+	/* Init GIC distributor and CPU interface */
+	plat_arm_gic_driver_init();
+	plat_arm_gic_init();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+	/* do nothing */
+}
+
+void bl31_plat_arch_setup(void)
+{
+	plat_configure_mmu_el3(BL31_RO_BASE,
+			       (BL31_COHERENT_RAM_LIMIT - BL31_RO_BASE),
+			       BL31_RO_BASE,
+			       BL31_RO_LIMIT,
+			       BL31_COHERENT_RAM_BASE,
+			       BL31_COHERENT_RAM_LIMIT);
+
+	INFO("Boot BL33 from 0x%lx for %lu Bytes\n",
+	     bl33_image_ep_info.pc, bl33_image_ep_info.args.arg2);
+}
diff --git a/plat/hisilicon/poplar/include/hi3798cv200.h b/plat/hisilicon/poplar/include/hi3798cv200.h
new file mode 100644
index 0000000..6318b9c
--- /dev/null
+++ b/plat/hisilicon/poplar/include/hi3798cv200.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __HI3798cv200_H__
+#define __HI3798cv200_H__
+
+/* PL011 */
+#define PL011_UART0_BASE		(0xF8B00000)
+#define PL011_BAUDRATE			(115200)
+#define PL011_UART0_CLK_IN_HZ		(75000000)
+
+/* Sys Counter */
+#define SYS_COUNTER_FREQ_IN_TICKS	(24000000)
+#define SYS_COUNTER_FREQ_IN_MHZ		(24)
+
+/* Timer */
+#define SEC_TIMER0_BASE			(0xF8008000)
+#define TIMER00_LOAD			(SEC_TIMER0_BASE + 0x000)
+#define TIMER00_VALUE			(SEC_TIMER0_BASE + 0x004)
+#define TIMER00_CONTROL			(SEC_TIMER0_BASE + 0x008)
+#define TIMER00_BGLOAD			(SEC_TIMER0_BASE + 0x018)
+
+#define SEC_TIMER2_BASE			(0xF8009000)
+#define TIMER20_LOAD			(SEC_TIMER2_BASE + 0x000)
+#define TIMER20_VALUE			(SEC_TIMER2_BASE + 0x004)
+#define TIMER20_CONTROL			(SEC_TIMER2_BASE + 0x008)
+#define TIMER20_BGLOAD			(SEC_TIMER2_BASE + 0x018)
+
+/* GPIO */
+#define	GPIO_MAX			(12)
+#define	GPIO_BASE(x)			(x != 5 ?			\
+					0xf820000 + x * 0x1000 : 0xf8004000)
+
+/* SCTL */
+#define REG_BASE_SCTL			(0xF8000000)
+#define REG_SC_GEN12			(0x00B0)
+
+/* CRG */
+#define REG_BASE_CRG			(0xF8A22000)
+#define REG_CPU_LP			(0x48)
+#define REG_CPU_RST			(0x50)
+#define REG_PERI_CRG39			(0x9C)
+#define REG_PERI_CRG40			(0xA0)
+
+/* MCI */
+#define REG_BASE_MCI			(0xF9830000)
+#define MCI_CDETECT			(0x50)
+#define MCI_VERID			(0x6C)
+#define MCI_VERID_VALUE			(0x5342250A)
+#define MCI_VERID_VALUE2		(0x5342270A)
+
+/* EMMC */
+#define REG_EMMC_PERI_CRG		REG_PERI_CRG40
+#define REG_SDCARD_PERI_CRG		REG_PERI_CRG39
+#define EMMC_CLK_MASK			(0x7 << 8)
+#define EMMC_SRST_REQ			(0x1 << 4)
+#define EMMC_CKEN			(0x1 << 1)
+#define EMMC_BUS_CKEN			(0x1 << 0)
+#define EMMC_CLK_100M			(0 << 8)
+#define EMMC_CLK_50M			(1 << 8)
+#define EMMC_CLK_25M			(2 << 8)
+
+#define EMMC_DESC_SIZE			(0xF0000)
+#define EMMC_INIT_PARAMS(base)				\
+	{	.bus_width = EMMC_BUS_WIDTH_8,		\
+		.clk_rate = 25 * 1000 * 1000,		\
+		.desc_base = (base) - EMMC_DESC_SIZE,	\
+		.desc_size = EMMC_DESC_SIZE,		\
+		.flags =  EMMC_FLAG_CMD23,		\
+		.reg_base = REG_BASE_MCI,		\
+	}
+
+/* GIC-400 */
+#define GICD_BASE			(0xF1001000)
+#define GICC_BASE			(0xF1002000)
+#define GICR_BASE			(0xF1000000)
+
+/* FIQ platform related define */
+#define HISI_IRQ_SEC_SGI_0		8
+#define HISI_IRQ_SEC_SGI_1		9
+#define HISI_IRQ_SEC_SGI_2		10
+#define HISI_IRQ_SEC_SGI_3		11
+#define HISI_IRQ_SEC_SGI_4		12
+#define HISI_IRQ_SEC_SGI_5		13
+#define HISI_IRQ_SEC_SGI_6		14
+#define HISI_IRQ_SEC_SGI_7		15
+#define HISI_IRQ_SEC_PPI_0		29
+#define HISI_IRQ_SEC_TIMER0		60
+#define HISI_IRQ_SEC_TIMER1		50
+#define HISI_IRQ_SEC_TIMER2		52
+#define HISI_IRQ_SEC_TIMER3		88
+#define HISI_IRQ_SEC_AXI		110
+
+/* Watchdog */
+#define HISI_WDG0_BASE			(0xF8A2C000)
+
+#endif	/* __HI3798cv200_H__ */
diff --git a/plat/hisilicon/poplar/include/plat_macros.S b/plat/hisilicon/poplar/include/plat_macros.S
new file mode 100644
index 0000000..82d10c1
--- /dev/null
+++ b/plat/hisilicon/poplar/include/plat_macros.S
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+.section .rodata.gic_reg_name, "aS"
+	.macro plat_crash_print_regs
+	nop
+	.endm
diff --git a/plat/hisilicon/poplar/include/plat_private.h b/plat/hisilicon/poplar/include/plat_private.h
new file mode 100644
index 0000000..e2272cc
--- /dev/null
+++ b/plat/hisilicon/poplar/include/plat_private.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_PRIVATE_H__
+#define __PLAT_PRIVATE_H__
+
+#include <bl_common.h>
+#include "hi3798cv200.h"
+
+void plat_configure_mmu_el3(unsigned long total_base,
+			    unsigned long total_size,
+			    unsigned long ro_start,
+			    unsigned long ro_limit,
+			    unsigned long coh_start,
+			    unsigned long coh_limit);
+
+void plat_configure_mmu_el1(unsigned long total_base,
+			    unsigned long total_size,
+			    unsigned long ro_start,
+			    unsigned long ro_limit,
+			    unsigned long coh_start,
+			    unsigned long coh_limit);
+
+void plat_delay_timer_init(void);
+void plat_io_setup(void);
+
+#endif /* __PLAT_PRIVATE_H__ */
diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h
new file mode 100644
index 0000000..1b44dd7
--- /dev/null
+++ b/plat/hisilicon/poplar/include/platform_def.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 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/tbbr_img_def.h>
+#include "hi3798cv200.h"
+#include "poplar_layout.h"		/* BL memory region sizes, etc */
+
+#define PLATFORM_LINKER_FORMAT		"elf64-littleaarch64"
+#define PLATFORM_LINKER_ARCH		aarch64
+
+#define PLAT_ARM_CRASH_UART_BASE	PL011_UART0_BASE
+#define PLAT_ARM_CRASH_UART_CLK_IN_HZ	PL011_UART0_CLK_IN_HZ
+#define ARM_CONSOLE_BAUDRATE		PL011_BAUDRATE
+
+/* Generic platform constants */
+#define PLATFORM_STACK_SIZE		(0x800)
+
+#define FIRMWARE_WELCOME_STR		"Booting Trusted Firmware\n"
+#define BOOT_EMMC_NAME			"l-loader.bin"
+
+#define PLATFORM_CACHE_LINE_SIZE	(64)
+#define PLATFORM_CLUSTER_COUNT		(1)
+#define PLATFORM_CORE_COUNT		(4)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	(4)
+
+/* IO framework user */
+#define MAX_IO_DEVICES			(4)
+#define MAX_IO_HANDLES			(4)
+#define MAX_IO_BLOCK_DEVICES		(2)
+
+/* Memory map related constants */
+#define DDR_BASE			(0x00000000)
+#define DDR_SIZE			(0x40000000)
+
+#define DEVICE_BASE			(0xF0000000)
+#define DEVICE_SIZE			(0x0F000000)
+
+#define TEE_SEC_MEM_BASE		(0x70000000)
+#define TEE_SEC_MEM_SIZE		(0x10000000)
+
+#define BL_MEM_BASE			(BL1_RO_BASE)
+#define BL_MEM_LIMIT			(BL31_LIMIT)
+#define BL_MEM_SIZE			(BL_MEM_LIMIT - BL_MEM_BASE)
+
+#define PLAT_ARM_NS_IMAGE_OFFSET	0x37000000
+
+/* Page table and MMU setup constants */
+#define ADDR_SPACE_SIZE			(1ull << 32)
+#define MAX_XLAT_TABLES			(4)
+#define MAX_MMAP_REGIONS		(16)
+
+#define CACHE_WRITEBACK_SHIFT		(6)
+#define CACHE_WRITEBACK_GRANULE		(1 << CACHE_WRITEBACK_SHIFT)
+
+/* Power states */
+#define PLAT_MAX_PWR_LVL		(MPIDR_AFFLVL1)
+#define PLAT_MAX_OFF_STATE		2
+#define PLAT_MAX_RET_STATE		1
+
+/* Interrupt controller */
+#define PLAT_ARM_GICD_BASE	GICD_BASE
+#define PLAT_ARM_GICC_BASE	GICC_BASE
+
+#define PLAT_ARM_G1S_IRQS	HISI_IRQ_SEC_SGI_0,  \
+				HISI_IRQ_SEC_SGI_1,  \
+				HISI_IRQ_SEC_SGI_2,  \
+				HISI_IRQ_SEC_SGI_3,  \
+				HISI_IRQ_SEC_SGI_4,  \
+				HISI_IRQ_SEC_SGI_5,  \
+				HISI_IRQ_SEC_SGI_6,  \
+				HISI_IRQ_SEC_SGI_7,  \
+				HISI_IRQ_SEC_TIMER0, \
+				HISI_IRQ_SEC_TIMER1, \
+				HISI_IRQ_SEC_TIMER2, \
+				HISI_IRQ_SEC_TIMER3, \
+				HISI_IRQ_SEC_AXI
+
+#define PLAT_ARM_G0_IRQS
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/hisilicon/poplar/include/poplar_layout.h b/plat/hisilicon/poplar/include/poplar_layout.h
new file mode 100644
index 0000000..192bcb9
--- /dev/null
+++ b/plat/hisilicon/poplar/include/poplar_layout.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __POPLAR_LAYOUT_H
+#define __POPLAR_LAYOUT_H
+
+/*
+ * Boot memory layout definitions for the HiSilicon Poplar board
+ */
+
+/*
+ * When Poplar is powered on, boot ROM loads the initial content of
+ * boot media into low memory, verifies it, and begins executing it
+ * in 32-bit mode.  The image loaded is "l-loader.bin", which contains
+ * a small amount code along with an embedded ARM Trusted Firmware
+ * BL1 image.  The main purpose of "l-loader" is to prepare the
+ * processor to execute the BL1 image in 64-bit mode, and to trigger
+ * that execution.
+ *
+ * Also embedded in "l-loader.bin" is a FIP image that contains
+ * other ARM Trusted Firmware images:  BL2; BL31; and for BL33,
+ * U-Boot.  When BL1 executes, it unpacks the BL2 image from the FIP
+ * image into a region of memory set aside to hold it.  Similarly,
+ * BL2 unpacks BL31 into memory reserved for it, and unpacks U-Boot
+ * into high memory.
+ *
+ * Because the BL1 code is embedded in "l-loader", its base address
+ * in memory is derived from the base address of the "l-loader"
+ * text section, together with an offset.  Memory space for BL2 is
+ * reserved immediately following BL1, and memory space is reserved
+ * for BL31 after that.  ARM Trusted Firmware requires each of these
+ * memory regions to be aligned on page boundaries, so the size of
+ * each region is a multiple of a page size (ending in 000).  Note
+ * that ARM Trusted Firmware requires the read-only and read-write
+ * regions of memory used for BL1 to be defined separately.
+ *
+ *    ---------------------
+ *    |  (unused memory)  |
+ *    +-------------------+	- - - - -
+ *    |  (l-loader text)  |               \
+ *    +-------------------+                \
+ *    |  BL1 (read-only)  | \               \
+ *    |- - - - - - - - - -| |               |
+ *    |  BL1 (read-write) | |               |
+ *    +-------------------+  >  BL Memory   |
+ *    |  Reserved for BL2 | |                > "l-loader.bin" image
+ *    +-------------------+ |               |
+ *    | Reserved for BL31 | /               |
+ *    +-------------------+                 |
+ *           . . .                          /
+ *    +-------------------+                /
+ *    |        FIP        |               /
+ *    +-------------------+	- - - - -
+ *           . . .
+ *    |  (unused memory)  |
+ *           . . .
+ *    +-------------------+
+ *    |Reserved for U-Boot|
+ *    +-------------------+
+ *           . . .
+ *    |  (unused memory)  |
+ *    ---------------------
+ *
+ * The size of each of these regions is defined below.  The base
+ * address of the "l-loader" TEXT section and the offset of the BL1
+ * image within that serve as anchors for defining the positions of
+ * all other regions.  The FIP is placed in a section of its own.
+ *
+ * A "BASE" is the memory address of the start of a region; a "LIMIT"
+ * marks its end.  A "SIZE" is the size of a region (in bytes).  An
+ * "OFFSET" is an offset to the start of a region relative to the
+ * base of the "l-loader" TEXT section (also a multiple of page size).
+ */
+#define LLOADER_TEXT_BASE		0x00001000	/* page aligned */
+#define BL1_OFFSET			0x0000D000	/* page multiple */
+#define FIP_BASE			0x00040000
+
+#define BL1_RO_SIZE			0x00008000	/* page multiple */
+#define BL1_RW_SIZE			0x00008000	/* page multiple */
+#define BL1_SIZE			(BL1_RO_SIZE + BL1_RW_SIZE)
+#define BL2_SIZE			0x0000c000	/* page multiple */
+#define BL31_SIZE			0x00014000
+#define FIP_SIZE			0x00068000
+
+     /* BL1_OFFSET */			/* (Defined above) */
+#define BL1_BASE			(LLOADER_TEXT_BASE + BL1_OFFSET)
+#define BL1_LIMIT			(BL1_BASE + BL1_SIZE)
+
+#define BL1_RO_OFFSET			(BL1_OFFSET)
+#define BL1_RO_BASE			(LLOADER_TEXT_BASE + BL1_RO_OFFSET)
+#define BL1_RO_LIMIT			(BL1_RO_BASE + BL1_RO_SIZE)
+
+#define BL1_RW_OFFSET			(BL1_RO_OFFSET + BL1_RO_SIZE)
+#define BL1_RW_BASE			(LLOADER_TEXT_BASE + BL1_RW_OFFSET)
+#define BL1_RW_LIMIT			(BL1_RW_BASE + BL1_RW_SIZE)
+
+#define BL2_OFFSET			(BL1_OFFSET + BL1_SIZE)
+#define BL2_BASE			(LLOADER_TEXT_BASE + BL2_OFFSET)
+#define BL2_LIMIT			(BL2_BASE + BL2_SIZE)
+
+#define BL31_OFFSET			(BL2_OFFSET + BL2_SIZE)
+#define BL31_BASE			(LLOADER_TEXT_BASE + BL31_OFFSET)
+#define BL31_LIMIT			(BL31_BASE + BL31_SIZE)
+
+#endif /* !__POPLAR_LAYOUT_H */
diff --git a/plat/hisilicon/poplar/plat_pm.c b/plat/hisilicon/poplar/plat_pm.c
new file mode 100644
index 0000000..3e43d4d
--- /dev/null
+++ b/plat/hisilicon/poplar/plat_pm.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <mmio.h>
+#include <plat_arm.h>
+#include <platform.h>
+#include <psci.h>
+#include "hi3798cv200.h"
+#include "plat_private.h"
+#include "platform_def.h"
+
+#define REG_PERI_CPU_RVBARADDR		0xF8A80034
+#define REG_PERI_CPU_AARCH_MODE		0xF8A80030
+
+#define REG_CPU_LP_CPU_SW_BEGIN		10
+#define CPU_REG_COREPO_SRST		12
+#define CPU_REG_CORE_SRST		8
+
+static void poplar_cpu_standby(plat_local_state_t cpu_state)
+{
+	dsb();
+	wfi();
+}
+
+static int poplar_pwr_domain_on(u_register_t mpidr)
+{
+	unsigned int cpu = plat_core_pos_by_mpidr(mpidr);
+	unsigned int regval, regval_bak;
+
+	/* Select 400MHz before start slave cores */
+	regval_bak = mmio_read_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP));
+	mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), 0x206);
+	mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), 0x606);
+
+	/* Clear the slave cpu arm_por_srst_req reset */
+	regval = mmio_read_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST));
+	regval &= ~(1 << (cpu + CPU_REG_COREPO_SRST));
+	mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST), regval);
+
+	/* Clear the slave cpu reset */
+	regval = mmio_read_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST));
+	regval &= ~(1 << (cpu + CPU_REG_CORE_SRST));
+	mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_RST), regval);
+
+	/* Restore cpu frequency */
+	regval = regval_bak & (~(1 << REG_CPU_LP_CPU_SW_BEGIN));
+	mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), regval);
+	mmio_write_32((uintptr_t)(REG_BASE_CRG + REG_CPU_LP), regval_bak);
+
+	return PSCI_E_SUCCESS;
+}
+
+static void poplar_pwr_domain_off(const psci_power_state_t *target_state)
+{
+	assert(0);
+}
+
+static void poplar_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+	assert(0);
+}
+
+static void poplar_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+	assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] ==
+					PLAT_MAX_OFF_STATE);
+
+	/* Enable the gic cpu interface */
+	plat_arm_gic_pcpu_init();
+
+	/* Program the gic per-cpu distributor or re-distributor interface */
+	plat_arm_gic_cpuif_enable();
+}
+
+static void poplar_pwr_domain_suspend_finish(
+		const psci_power_state_t *target_state)
+{
+	assert(0);
+}
+
+static void __dead2 poplar_system_off(void)
+{
+	ERROR("Poplar System Off: operation not handled.\n");
+	panic();
+}
+
+static void __dead2 poplar_system_reset(void)
+{
+	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0xc00), 0x1ACCE551);
+	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x0),   0x00000100);
+	mmio_write_32((uintptr_t)(HISI_WDG0_BASE + 0x8),   0x00000003);
+
+	wfi();
+	ERROR("Poplar System Reset: operation not handled.\n");
+	panic();
+}
+
+static int32_t poplar_validate_power_state(unsigned int power_state,
+					   psci_power_state_t *req_state)
+{
+	VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
+
+	int pstate = psci_get_pstate_type(power_state);
+
+	assert(req_state);
+
+	/* Sanity check the requested state */
+	if (pstate == PSTATE_TYPE_STANDBY)
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
+	else
+		req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE;
+
+	/* We expect the 'state id' to be zero */
+	if (psci_get_pstate_id(power_state))
+		return PSCI_E_INVALID_PARAMS;
+
+	return PSCI_E_SUCCESS;
+}
+
+static int poplar_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+	/*
+	 * Check if the non secure entrypoint lies within the non
+	 * secure DRAM.
+	 */
+	if ((entrypoint >= DDR_BASE) && (entrypoint < (DDR_BASE + DDR_SIZE)))
+		return PSCI_E_SUCCESS;
+
+	return PSCI_E_INVALID_ADDRESS;
+}
+
+static void poplar_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+	int i;
+
+	for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+		req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+}
+
+static const plat_psci_ops_t poplar_plat_psci_ops = {
+	.cpu_standby			= poplar_cpu_standby,
+	.pwr_domain_on			= poplar_pwr_domain_on,
+	.pwr_domain_off			= poplar_pwr_domain_off,
+	.pwr_domain_suspend		= poplar_pwr_domain_suspend,
+	.pwr_domain_on_finish		= poplar_pwr_domain_on_finish,
+	.pwr_domain_suspend_finish	= poplar_pwr_domain_suspend_finish,
+	.system_off			= poplar_system_off,
+	.system_reset			= poplar_system_reset,
+	.validate_power_state		= poplar_validate_power_state,
+	.validate_ns_entrypoint		= poplar_validate_ns_entrypoint,
+	.get_sys_suspend_power_state	= poplar_get_sys_suspend_power_state,
+};
+
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+			const plat_psci_ops_t **psci_ops)
+{
+	*psci_ops = &poplar_plat_psci_ops;
+
+	mmio_write_32((uintptr_t)REG_PERI_CPU_AARCH_MODE, 0xF);
+	mmio_write_32((uintptr_t)REG_PERI_CPU_RVBARADDR, sec_entrypoint);
+	return 0;
+}
diff --git a/plat/hisilicon/poplar/plat_storage.c b/plat/hisilicon/poplar/plat_storage.c
new file mode 100644
index 0000000..623a61b
--- /dev/null
+++ b/plat/hisilicon/poplar/plat_storage.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <firmware_image_package.h>
+#include <io_block.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <mmio.h>
+#include <partition/partition.h>
+#include <semihosting.h>
+#include <string.h>
+#include <tbbr_img_def.h>
+#include <utils.h>
+#include "platform_def.h"
+
+static const io_dev_connector_t *mmap_dev_con;
+static const io_dev_connector_t *fip_dev_con;
+
+static uintptr_t mmap_dev_handle;
+static uintptr_t fip_dev_handle;
+
+static int open_mmap(const uintptr_t spec);
+static int open_fip(const uintptr_t spec);
+
+static const io_block_spec_t loader_fip_spec = {
+	.offset		= FIP_BASE,
+	.length		= FIP_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 bl33_uuid_spec = {
+	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+struct plat_io_policy {
+	uintptr_t	*dev_handle;
+	uintptr_t	image_spec;
+	int		(*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+	[FIP_IMAGE_ID] = {
+		&mmap_dev_handle,
+		(uintptr_t)&loader_fip_spec,
+		open_mmap
+	},
+	[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
+	},
+	[BL33_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl33_uuid_spec,
+		open_fip
+	},
+};
+
+static int open_mmap(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(mmap_dev_handle, (uintptr_t)NULL);
+	if (result == 0) {
+		result = io_open(mmap_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			io_close(local_image_handle);
+		}
+	}
+	return result;
+}
+
+static int open_fip(const uintptr_t spec)
+{
+	uintptr_t local_image_handle;
+	int result;
+
+	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) {
+			io_close(local_image_handle);
+		} else {
+			VERBOSE("error opening fip\n");
+		}
+	} else {
+		VERBOSE("error initializing fip\n");
+	}
+
+	return result;
+}
+
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+			  uintptr_t *image_spec)
+{
+	const struct plat_io_policy *policy;
+	int result;
+
+	assert(image_id < ARRAY_SIZE(policies));
+
+	policy = &policies[image_id];
+	result = policy->check(policy->image_spec);
+	assert(result == 0);
+
+	*image_spec = policy->image_spec;
+	*dev_handle = *(policy->dev_handle);
+
+	return result;
+}
+
+void plat_io_setup(void)
+{
+	int result;
+
+	result = register_io_dev_memmap(&mmap_dev_con);
+	assert(result == 0);
+
+	result = register_io_dev_fip(&fip_dev_con);
+	assert(result == 0);
+
+	result = io_dev_open(fip_dev_con, (uintptr_t)&loader_fip_spec,
+				&fip_dev_handle);
+	assert(result == 0);
+
+	result = io_dev_open(mmap_dev_con, (uintptr_t)NULL, &mmap_dev_handle);
+	assert(result == 0);
+
+	(void) result;
+}
diff --git a/plat/hisilicon/poplar/plat_topology.c b/plat/hisilicon/poplar/plat_topology.c
new file mode 100644
index 0000000..3dd818e
--- /dev/null
+++ b/plat/hisilicon/poplar/plat_topology.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <plat_arm.h>
+#include <psci.h>
+#include "platform_def.h"
+
+const unsigned char hisi_power_domain_tree_desc[] = {
+	PLATFORM_CLUSTER_COUNT,
+	PLATFORM_CORE_COUNT,
+};
+
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+	return hisi_power_domain_tree_desc;
+}
+
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+	if (mpidr & MPIDR_CLUSTER_MASK)
+		return -1;
+
+	if ((mpidr & MPIDR_CPU_MASK) >= PLATFORM_CORE_COUNT)
+		return -1;
+
+	return plat_arm_calc_core_pos(mpidr);
+}
diff --git a/plat/hisilicon/poplar/platform.mk b/plat/hisilicon/poplar/platform.mk
new file mode 100644
index 0000000..fc75ff3
--- /dev/null
+++ b/plat/hisilicon/poplar/platform.mk
@@ -0,0 +1,72 @@
+#
+# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+NEED_BL33			:= yes
+
+COLD_BOOT_SINGLE_CPU		:= 1
+PROGRAMMABLE_RESET_ADDRESS	:= 1
+CTX_INCLUDE_FPREGS		:= 1
+ENABLE_PLAT_COMPAT		:= 0
+ERRATA_A53_855873		:= 1
+ERRATA_A53_835769		:= 1
+ERRATA_A53_843419		:= 1
+
+ARM_GIC_ARCH			:= 2
+$(eval $(call add_define,ARM_GIC_ARCH))
+
+PLAT_PL061_MAX_GPIOS 		:= 104
+$(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
+
+PLAT_INCLUDES	:=	-Iplat/hisilicon/poplar/include		\
+			-Iinclude/plat/arm/common/		\
+			-Iplat/hisilicon/poplar			\
+			-Iinclude/common/tbbr			\
+			-Iinclude/drivers/io
+
+PLAT_BL_COMMON_SOURCES	:=						\
+		lib/aarch64/xlat_tables.c				\
+		drivers/delay_timer/generic_delay_timer.c		\
+		drivers/arm/gic/common/gic_common.c			\
+		drivers/arm/gic/v2/gicv2_helpers.c			\
+		drivers/delay_timer/delay_timer.c			\
+		drivers/arm/pl011/pl011_console.S			\
+		drivers/arm/gic/v2/gicv2_main.c				\
+		plat/arm/common/aarch64/arm_helpers.S			\
+		plat/arm/common/arm_gicv2.c				\
+		plat/common/plat_gicv2.c				\
+		plat/hisilicon/poplar/aarch64/platform_common.c
+
+BL1_SOURCES	+=							\
+		lib/cpus/aarch64/cortex_a53.S				\
+		drivers/arm/pl061/pl061_gpio.c				\
+		drivers/io/io_storage.c					\
+		drivers/io/io_block.c					\
+		drivers/gpio/gpio.c					\
+		drivers/io/io_fip.c					\
+		drivers/io/io_memmap.c					\
+		plat/hisilicon/poplar/bl1_plat_setup.c			\
+		plat/hisilicon/poplar/plat_storage.c			\
+
+
+BL2_SOURCES	+=      						\
+		drivers/arm/pl061/pl061_gpio.c				\
+		drivers/io/io_storage.c					\
+		drivers/io/io_block.c					\
+		drivers/io/io_fip.c					\
+		drivers/gpio/gpio.c					\
+		drivers/io/io_memmap.c					\
+		plat/hisilicon/poplar/bl2_plat_setup.c			\
+		plat/hisilicon/poplar/plat_storage.c
+
+
+BL31_SOURCES	+=							\
+		lib/cpus/aarch64/aem_generic.S				\
+		lib/cpus/aarch64/cortex_a53.S				\
+		plat/common/aarch64/plat_psci_common.c			\
+		plat/hisilicon/poplar/bl31_plat_setup.c			\
+		plat/hisilicon/poplar/plat_topology.c			\
+		plat/hisilicon/poplar/plat_pm.c
+
diff --git a/plat/mediatek/common/mtk_plat_common.c b/plat/mediatek/common/mtk_plat_common.c
index 4e8aaec..6a13192 100644
--- a/plat/mediatek/common/mtk_plat_common.c
+++ b/plat/mediatek/common/mtk_plat_common.c
@@ -12,8 +12,8 @@
 #include <mmio.h>
 #include <mtk_plat_common.h>
 #include <mtk_sip_svc.h>
-#include <platform.h>
 #include <plat_private.h>
+#include <platform.h>
 #include <xlat_tables.h>
 
 struct atf_arg_t gteearg;
diff --git a/plat/mediatek/mt6795/bl31_plat_setup.c b/plat/mediatek/mt6795/bl31_plat_setup.c
index a70d103..803f1ed 100644
--- a/plat/mediatek/mt6795/bl31_plat_setup.c
+++ b/plat/mediatek/mt6795/bl31_plat_setup.c
@@ -3,9 +3,9 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <arch_helpers.h>
 #include <arm_gic.h>
 #include <assert.h>
-#include <arch_helpers.h>
 #include <bl_common.h>
 #include <cci.h>
 #include <common_def.h>
@@ -15,11 +15,11 @@
 #include <generic_delay_timer.h>
 #include <mcucfg.h>
 #include <mmio.h>
-#include <mtk_sip_svc.h>
-#include <mtk_plat_common.h>
 #include <mt_cpuxgpt.h>
-#include <platform.h>
+#include <mtk_plat_common.h>
+#include <mtk_sip_svc.h>
 #include <plat_private.h>
+#include <platform.h>
 #include <string.h>
 #include <xlat_tables.h>
 /*******************************************************************************
diff --git a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
index 1f64558..b357972 100644
--- a/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
+++ b/plat/mediatek/mt6795/drivers/timer/mt_cpuxgpt.c
@@ -4,13 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stdint.h>
+
 #include <arch_helpers.h>
+#include <debug.h>
 #include <mmio.h>
 #include <mt_cpuxgpt.h>
-#include <stdint.h>
 #include <platform.h>
-#include <debug.h>
+#include <stdint.h>
 #define CPUXGPT_BASE	0x10200000
 #define INDEX_BASE		(CPUXGPT_BASE+0x0674)
 #define CTL_BASE		(CPUXGPT_BASE+0x0670)
diff --git a/plat/mediatek/mt6795/plat_pm.c b/plat/mediatek/mt6795/plat_pm.c
index a0b7775..bd47bd8 100644
--- a/plat/mediatek/mt6795/plat_pm.c
+++ b/plat/mediatek/mt6795/plat_pm.c
@@ -14,8 +14,8 @@
 #include <errno.h>
 #include <mcucfg.h>
 #include <mmio.h>
-#include <platform_def.h>
 #include <plat_private.h>
+#include <platform_def.h>
 #include <power_tracer.h>
 #include <psci.h>
 #include <scu.h>
diff --git a/plat/mediatek/mt8173/drivers/mtcmos/mtcmos.c b/plat/mediatek/mt8173/drivers/mtcmos/mtcmos.c
index 6330b7b..25f2509 100644
--- a/plat/mediatek/mt8173/drivers/mtcmos/mtcmos.c
+++ b/plat/mediatek/mt8173/drivers/mtcmos/mtcmos.c
@@ -3,13 +3,14 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+
+#include <debug.h>
+#include <delay_timer.h>
 #include <mmio.h>
 #include <mt8173_def.h>
-#include <debug.h>
 #include <mtcmos.h>
 #include <spm.h>
 #include <spm_mcdi.h>
-#include <delay_timer.h>
 
 enum {
 	SRAM_ISOINT_B	= 1U << 6,
diff --git a/plat/mediatek/mt8173/plat_sip_calls.c b/plat/mediatek/mt8173/plat_sip_calls.c
index 76200ec..1d51cb5 100644
--- a/plat/mediatek/mt8173/plat_sip_calls.c
+++ b/plat/mediatek/mt8173/plat_sip_calls.c
@@ -6,8 +6,8 @@
 #include <crypt.h>
 #include <debug.h>
 #include <mmio.h>
-#include <mtk_sip_svc.h>
 #include <mtcmos.h>
+#include <mtk_sip_svc.h>
 #include <plat_sip_calls.h>
 #include <runtime_svc.h>
 
diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
index 22389f2..e5e5126 100644
--- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
+++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S
@@ -7,8 +7,8 @@
 #include <asm_macros.S>
 #include <assert_macros.S>
 #include <cpu_macros.S>
-#include <cortex_a57.h>
 #include <cortex_a53.h>
+#include <cortex_a57.h>
 #include <platform_def.h>
 #include <tegra_def.h>
 
diff --git a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c b/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
index 585c115..2d827da 100644
--- a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
+++ b/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
@@ -6,12 +6,12 @@
 
 #include <arch_helpers.h>
 #include <assert.h>
+#include <cortex_a53.h>
 #include <debug.h>
 #include <delay_timer.h>
+#include <flowctrl.h>
 #include <mmio.h>
 #include <pmc.h>
-#include <cortex_a53.h>
-#include <flowctrl.h>
 #include <tegra_def.h>
 
 #define CLK_RST_DEV_L_SET		0x300
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index bc16857..d5d3d53 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -10,8 +10,8 @@
 #include <bl31.h>
 #include <bl_common.h>
 #include <console.h>
-#include <cortex_a57.h>
 #include <cortex_a53.h>
+#include <cortex_a57.h>
 #include <debug.h>
 #include <denver.h>
 #include <errno.h>
diff --git a/plat/nvidia/tegra/common/tegra_gic.c b/plat/nvidia/tegra/common/tegra_gic.c
index ae56d55..e480e77 100644
--- a/plat/nvidia/tegra/common/tegra_gic.c
+++ b/plat/nvidia/tegra/common/tegra_gic.c
@@ -5,16 +5,16 @@
  */
 
 #include <arch_helpers.h>
-#include <assert.h>
 #include <arm_gic.h>
+#include <assert.h>
 #include <bl_common.h>
 #include <debug.h>
 #include <gic_v2.h>
 #include <interrupt_mgmt.h>
 #include <platform.h>
 #include <stdint.h>
-#include <tegra_private.h>
 #include <tegra_def.h>
+#include <tegra_private.h>
 
 /* Value used to initialize Non-Secure IRQ priorities four at a time */
 #define GICD_IPRIORITYR_DEF_VAL \
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index 6f841ef..0c25934 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -7,9 +7,9 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bl_common.h>
+#include <console.h>
 #include <context.h>
 #include <context_mgmt.h>
-#include <console.h>
 #include <debug.h>
 #include <memctrl.h>
 #include <mmio.h>
diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c
index dcad21e..d96ce7a 100644
--- a/plat/nvidia/tegra/common/tegra_sip_calls.c
+++ b/plat/nvidia/tegra/common/tegra_sip_calls.c
@@ -13,8 +13,8 @@
 #include <memctrl.h>
 #include <mmio.h>
 #include <runtime_svc.h>
-#include <tegra_private.h>
 #include <tegra_platform.h>
+#include <tegra_private.h>
 
 /*******************************************************************************
  * Common Tegra SiP SMCs
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index 9b7dc85..1cffb74 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -7,9 +7,9 @@
 #include <arch.h>
 #include <arch_helpers.h>
 #include <assert.h>
-#include <denver.h>
 #include <debug.h>
 #include <delay_timer.h>
+#include <denver.h>
 #include <flowctrl.h>
 #include <mmio.h>
 #include <platform_def.h>
diff --git a/plat/nvidia/tegra/soc/t132/plat_secondary.c b/plat/nvidia/tegra/soc/t132/plat_secondary.c
index 96f514d..d5ca30c 100644
--- a/plat/nvidia/tegra/soc/t132/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t132/plat_secondary.c
@@ -10,8 +10,8 @@
 #include <denver.h>
 #include <mmio.h>
 #include <platform.h>
-#include <psci.h>
 #include <pmc.h>
+#include <psci.h>
 #include <tegra_def.h>
 
 #define SB_CSR				0x0
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 2803f4e..d34f7e2 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -10,8 +10,8 @@
 #include <debug.h>
 #include <delay_timer.h>
 #include <denver.h>
-#include <mmio.h>
 #include <mce_private.h>
+#include <mmio.h>
 #include <platform.h>
 #include <sys/errno.h>
 #include <t18x_ari.h>
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
index 9c115bd..243c8f3 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
@@ -8,8 +8,8 @@
 #include <arch_helpers.h>
 #include <debug.h>
 #include <denver.h>
-#include <mmio.h>
 #include <mce_private.h>
+#include <mmio.h>
 #include <sys/errno.h>
 #include <t18x_ari.h>
 
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 3dff653..f77746c 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -8,12 +8,12 @@
 #include <assert.h>
 #include <debug.h>
 #include <delay_timer.h>
+#include <flowctrl.h>
 #include <mmio.h>
 #include <platform.h>
 #include <platform_def.h>
-#include <psci.h>
 #include <pmc.h>
-#include <flowctrl.h>
+#include <psci.h>
 #include <tegra_def.h>
 #include <tegra_private.h>
 
diff --git a/plat/qemu/dt.c b/plat/qemu/dt.c
index f732a6d..c544d9f 100644
--- a/plat/qemu/dt.c
+++ b/plat/qemu/dt.c
@@ -7,8 +7,8 @@
 #include <debug.h>
 #include <libfdt.h>
 #include <psci.h>
-#include "qemu_private.h"
 #include <string.h>
+#include "qemu_private.h"
 
 static int append_psci_compatible(void *fdt, int offs, const char *str)
 {
diff --git a/plat/qemu/qemu_bl2_setup.c b/plat/qemu/qemu_bl2_setup.c
index 2557a71..f928b10 100644
--- a/plat/qemu/qemu_bl2_setup.c
+++ b/plat/qemu/qemu_bl2_setup.c
@@ -9,9 +9,9 @@
 #include <debug.h>
 #include <libfdt.h>
 #include <platform_def.h>
-#include "qemu_private.h"
 #include <string.h>
 #include <utils.h>
+#include "qemu_private.h"
 
 /*
  * The next 2 constants identify the extents of the code & RO data region.
diff --git a/plat/qemu/qemu_common.c b/plat/qemu/qemu_common.c
index 39df1f1..daa9fc1 100644
--- a/plat/qemu/qemu_common.c
+++ b/plat/qemu/qemu_common.c
@@ -7,8 +7,8 @@
 #include <arch_helpers.h>
 #include <bl_common.h>
 #include <platform_def.h>
-#include "qemu_private.h"
 #include <xlat_tables.h>
+#include "qemu_private.h"
 
 #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
 					DEVICE0_SIZE,			\
diff --git a/plat/qemu/qemu_pm.c b/plat/qemu/qemu_pm.c
index f735391..c184f1c 100644
--- a/plat/qemu/qemu_pm.c
+++ b/plat/qemu/qemu_pm.c
@@ -8,8 +8,8 @@
 #include <assert.h>
 #include <debug.h>
 #include <gicv2.h>
-#include <platform_def.h>
 #include <platform.h>
+#include <platform_def.h>
 #include <psci.h>
 
 /*
diff --git a/plat/qemu/topology.c b/plat/qemu/topology.c
index 05ff4e1..d7ba9b7 100644
--- a/plat/qemu/topology.c
+++ b/plat/qemu/topology.c
@@ -6,8 +6,8 @@
 
 #include <arch.h>
 #include <platform_def.h>
-#include "qemu_private.h"
 #include <sys/types.h>
+#include "qemu_private.h"
 
 /* The power domain tree descriptor */
 static unsigned char power_domain_tree_desc[] = {
diff --git a/plat/rockchip/common/aarch64/platform_common.c b/plat/rockchip/common/aarch64/platform_common.c
index a756f40..25eab43 100644
--- a/plat/rockchip/common/aarch64/platform_common.c
+++ b/plat/rockchip/common/aarch64/platform_common.c
@@ -9,11 +9,11 @@
 #include <bl_common.h>
 #include <cci.h>
 #include <debug.h>
-#include <string.h>
-#include <xlat_tables.h>
-#include <platform_def.h>
 #include <plat_private.h>
+#include <platform_def.h>
+#include <string.h>
 #include <utils.h>
+#include <xlat_tables.h>
 
 #ifdef PLAT_RK_CCI_BASE
 static const int cci_map[] = {
diff --git a/plat/rockchip/common/bl31_plat_setup.c b/plat/rockchip/common/bl31_plat_setup.c
index f7564e8..292f0dd 100644
--- a/plat/rockchip/common/bl31_plat_setup.c
+++ b/plat/rockchip/common/bl31_plat_setup.c
@@ -11,8 +11,8 @@
 #include <debug.h>
 #include <generic_delay_timer.h>
 #include <mmio.h>
-#include <platform.h>
 #include <plat_private.h>
+#include <platform.h>
 #include <platform_def.h>
 
 /*******************************************************************************
diff --git a/plat/rockchip/common/drivers/parameter/ddr_parameter.c b/plat/rockchip/common/drivers/parameter/ddr_parameter.c
index 5069a92..ea77757 100644
--- a/plat/rockchip/common/drivers/parameter/ddr_parameter.c
+++ b/plat/rockchip/common/drivers/parameter/ddr_parameter.c
@@ -9,8 +9,8 @@
 #include <debug.h>
 #include <delay_timer.h>
 #include <mmio.h>
-#include <platform_def.h>
 #include <plat_private.h>
+#include <platform_def.h>
 #include <soc.h>
 #include <string.h>
 #include "ddr_parameter.h"
diff --git a/plat/rockchip/common/drivers/parameter/ddr_parameter.h b/plat/rockchip/common/drivers/parameter/ddr_parameter.h
index f8eacd4..f8e3be9 100644
--- a/plat/rockchip/common/drivers/parameter/ddr_parameter.h
+++ b/plat/rockchip/common/drivers/parameter/ddr_parameter.h
@@ -12,8 +12,8 @@
 #include <debug.h>
 #include <delay_timer.h>
 #include <mmio.h>
-#include <platform_def.h>
 #include <plat_private.h>
+#include <platform_def.h>
 #include <soc.h>
 #include <string.h>
 
diff --git a/plat/rockchip/common/include/plat_private.h b/plat/rockchip/common/include/plat_private.h
index b9540f2..290811a 100644
--- a/plat/rockchip/common/include/plat_private.h
+++ b/plat/rockchip/common/include/plat_private.h
@@ -9,9 +9,9 @@
 
 #ifndef __ASSEMBLY__
 #include <mmio.h>
+#include <psci.h>
 #include <stdint.h>
 #include <xlat_tables.h>
-#include <psci.h>
 
 #define __sramdata __attribute__((section(".sram.data")))
 #define __sramconst __attribute__((section(".sram.rodata")))
diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c
index ad4ef7f..b37acb7 100644
--- a/plat/rockchip/common/params_setup.c
+++ b/plat/rockchip/common/params_setup.c
@@ -11,9 +11,9 @@
 #include <debug.h>
 #include <gpio.h>
 #include <mmio.h>
-#include <platform.h>
 #include <plat_params.h>
 #include <plat_private.h>
+#include <platform.h>
 #include <string.h>
 
 static struct gpio_info param_reset;
diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c
index 4133fd0..cd88f60 100644
--- a/plat/rockchip/common/plat_pm.c
+++ b/plat/rockchip/common/plat_pm.c
@@ -7,12 +7,12 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <console.h>
-#include <errno.h>
 #include <debug.h>
-#include <psci.h>
 #include <delay_timer.h>
-#include <platform_def.h>
+#include <errno.h>
 #include <plat_private.h>
+#include <platform_def.h>
+#include <psci.h>
 
 /* Macros to read the rk power domain state */
 #define RK_CORE_PWR_STATE(state) \
diff --git a/plat/rockchip/common/plat_topology.c b/plat/rockchip/common/plat_topology.c
index 3d0f208..49d063c 100644
--- a/plat/rockchip/common/plat_topology.c
+++ b/plat/rockchip/common/plat_topology.c
@@ -5,8 +5,8 @@
  */
 
 #include <arch.h>
-#include <platform_def.h>
 #include <plat_private.h>
+#include <platform_def.h>
 #include <psci.h>
 
 /*******************************************************************************
diff --git a/plat/rockchip/rk3328/drivers/pmu/pmu.c b/plat/rockchip/rk3328/drivers/pmu/pmu.c
index 60f36d3..f576fe4 100644
--- a/plat/rockchip/rk3328/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3328/drivers/pmu/pmu.c
@@ -5,20 +5,20 @@
  */
 
 #include <arch_helpers.h>
-#include <debug.h>
 #include <assert.h>
 #include <bakery_lock.h>
 #include <bl31.h>
 #include <console.h>
+#include <debug.h>
 #include <delay_timer.h>
 #include <errno.h>
 #include <mmio.h>
+#include <plat_private.h>
 #include <platform.h>
 #include <platform_def.h>
-#include <plat_private.h>
 #include <pmu.h>
-#include <rk3328_def.h>
 #include <pmu_com.h>
+#include <rk3328_def.h>
 
 DEFINE_BAKERY_LOCK(rockchip_pd_lock);
 
diff --git a/plat/rockchip/rk3328/drivers/soc/soc.c b/plat/rockchip/rk3328/drivers/soc/soc.c
index d4cba99..ce344d6 100644
--- a/plat/rockchip/rk3328/drivers/soc/soc.c
+++ b/plat/rockchip/rk3328/drivers/soc/soc.c
@@ -6,12 +6,12 @@
 
 #include <arch_helpers.h>
 #include <console.h>
+#include <ddr_parameter.h>
 #include <debug.h>
 #include <delay_timer.h>
 #include <mmio.h>
-#include <platform_def.h>
 #include <plat_private.h>
-#include <ddr_parameter.h>
+#include <platform_def.h>
 #include <rk3328_def.h>
 #include <soc.h>
 
diff --git a/plat/rockchip/rk3368/drivers/ddr/ddr_rk3368.c b/plat/rockchip/rk3368/drivers/ddr/ddr_rk3368.c
index b902bba..1c33763 100644
--- a/plat/rockchip/rk3368/drivers/ddr/ddr_rk3368.c
+++ b/plat/rockchip/rk3368/drivers/ddr/ddr_rk3368.c
@@ -7,12 +7,12 @@
 #include <mmio.h>
 #include <ddr_rk3368.h>
 #include <debug.h>
-#include <stdint.h>
-#include <string.h>
 #include <platform_def.h>
 #include <pmu.h>
 #include <rk3368_def.h>
 #include <soc.h>
+#include <stdint.h>
+#include <string.h>
 
 /* GRF_SOC_STATUS0 */
 #define DPLL_LOCK		(0x1 << 2)
diff --git a/plat/rockchip/rk3368/drivers/pmu/pmu.c b/plat/rockchip/rk3368/drivers/pmu/pmu.c
index 1767967..cb323e6 100644
--- a/plat/rockchip/rk3368/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3368/drivers/pmu/pmu.c
@@ -6,18 +6,18 @@
 
 #include <arch_helpers.h>
 #include <assert.h>
+#include <ddr_rk3368.h>
 #include <debug.h>
 #include <delay_timer.h>
 #include <errno.h>
 #include <mmio.h>
+#include <plat_private.h>
 #include <platform.h>
 #include <platform_def.h>
-#include <plat_private.h>
+#include <pmu.h>
+#include <pmu_com.h>
 #include <rk3368_def.h>
 #include <soc.h>
-#include <pmu.h>
-#include <ddr_rk3368.h>
-#include <pmu_com.h>
 
 DEFINE_BAKERY_LOCK(rockchip_pd_lock);
 
diff --git a/plat/rockchip/rk3368/drivers/soc/soc.c b/plat/rockchip/rk3368/drivers/soc/soc.c
index 9e1e583..d6979a8 100644
--- a/plat/rockchip/rk3368/drivers/soc/soc.c
+++ b/plat/rockchip/rk3368/drivers/soc/soc.c
@@ -7,8 +7,8 @@
 #include <arch_helpers.h>
 #include <debug.h>
 #include <mmio.h>
-#include <platform_def.h>
 #include <plat_private.h>
+#include <platform_def.h>
 #include <rk3368_def.h>
 #include <soc.h>
 
diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c
index 481dcc6..d629e4b 100644
--- a/plat/rockchip/rk3399/drivers/dram/dfs.c
+++ b/plat/rockchip/rk3399/drivers/dram/dfs.c
@@ -6,17 +6,16 @@
 
 #include <arch_helpers.h>
 #include <debug.h>
-#include <mmio.h>
+#include <delay_timer.h>
 #include <m0_ctl.h>
+#include <mmio.h>
 #include <plat_private.h>
 #include "dfs.h"
 #include "dram.h"
 #include "dram_spec_timing.h"
-#include "string.h"
-#include "soc.h"
 #include "pmu.h"
-
-#include <delay_timer.h>
+#include "soc.h"
+#include "string.h"
 
 #define ENPER_CS_TRAINING_FREQ	(666)
 #define TDFI_LAT_THRESHOLD_FREQ	(928)
diff --git a/plat/rockchip/rk3399/drivers/dram/dram.c b/plat/rockchip/rk3399/drivers/dram/dram.c
index ad79f9e..42b6294 100644
--- a/plat/rockchip/rk3399/drivers/dram/dram.c
+++ b/plat/rockchip/rk3399/drivers/dram/dram.c
@@ -6,9 +6,9 @@
 
 #include <dram.h>
 #include <plat_private.h>
+#include <rk3399_def.h>
 #include <secure.h>
 #include <soc.h>
-#include <rk3399_def.h>
 
 __pmusramdata struct rk3399_sdram_params sdram_config;
 
diff --git a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
index a2b28b7..2e196b5 100644
--- a/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
+++ b/plat/rockchip/rk3399/drivers/dram/dram_spec_timing.c
@@ -4,9 +4,9 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <string.h>
-#include <stdint.h>
 #include <dram.h>
+#include <stdint.h>
+#include <string.h>
 #include <utils.h>
 #include "dram_spec_timing.h"
 
diff --git a/plat/rockchip/rk3399/drivers/dram/suspend.c b/plat/rockchip/rk3399/drivers/dram/suspend.c
index 617e39b..6867744 100644
--- a/plat/rockchip/rk3399/drivers/dram/suspend.c
+++ b/plat/rockchip/rk3399/drivers/dram/suspend.c
@@ -3,11 +3,12 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-#include <debug.h>
+
 #include <arch_helpers.h>
-#include <platform_def.h>
-#include <plat_private.h>
+#include <debug.h>
 #include <dram.h>
+#include <plat_private.h>
+#include <platform_def.h>
 #include <pmu_regs.h>
 #include <rk3399_def.h>
 #include <secure.h>
diff --git a/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c b/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c
index 2d8b439..d5a2660 100644
--- a/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c
+++ b/plat/rockchip/rk3399/drivers/gpio/rk3399_gpio.c
@@ -9,9 +9,9 @@
 #include <errno.h>
 #include <gpio.h>
 #include <mmio.h>
+#include <plat_private.h>
 #include <platform.h>
 #include <platform_def.h>
-#include <plat_private.h>
 #include <soc.h>
 
 uint32_t gpio_port[] = {
diff --git a/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c b/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c
index 99a5b63..61849e5 100644
--- a/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c
+++ b/plat/rockchip/rk3399/drivers/pmu/m0_ctl.c
@@ -8,8 +8,8 @@
 #include <assert.h>
 #include <debug.h>
 #include <delay_timer.h>
-#include <mmio.h>
 #include <m0_ctl.h>
+#include <mmio.h>
 #include <plat_private.h>
 #include <rk3399_def.h>
 #include <secure.h>
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index 37977e1..6b420c2 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -7,25 +7,25 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <bakery_lock.h>
+#include <bl31.h>
 #include <debug.h>
 #include <delay_timer.h>
 #include <dfs.h>
 #include <errno.h>
 #include <gpio.h>
-#include <mmio.h>
 #include <m0_ctl.h>
-#include <platform.h>
-#include <platform_def.h>
+#include <mmio.h>
 #include <plat_params.h>
 #include <plat_private.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <pmu.h>
+#include <pmu_com.h>
+#include <pwm.h>
 #include <rk3399_def.h>
 #include <secure.h>
 #include <soc.h>
 #include <string.h>
-#include <pmu.h>
-#include <pmu_com.h>
-#include <pwm.h>
-#include <bl31.h>
 #include <suspend.h>
 
 DEFINE_BAKERY_LOCK(rockchip_pd_lock);
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index b3e9e95..993b80a 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -10,10 +10,10 @@
 #include <delay_timer.h>
 #include <dfs.h>
 #include <dram.h>
-#include <mmio.h>
 #include <m0_ctl.h>
-#include <platform_def.h>
+#include <mmio.h>
 #include <plat_private.h>
+#include <platform_def.h>
 #include <rk3399_def.h>
 #include <secure.h>
 #include <soc.h>
diff --git a/plat/rockchip/rk3399/plat_sip_calls.c b/plat/rockchip/rk3399/plat_sip_calls.c
index 1a01604..074dc19 100644
--- a/plat/rockchip/rk3399/plat_sip_calls.c
+++ b/plat/rockchip/rk3399/plat_sip_calls.c
@@ -6,11 +6,11 @@
 
 #include <cdn_dp.h>
 #include <debug.h>
+#include <dfs.h>
 #include <mmio.h>
 #include <plat_sip_calls.h>
 #include <rockchip_sip_svc.h>
 #include <runtime_svc.h>
-#include <dfs.h>
 
 #define RK_SIP_DDR_CFG		0x82000008
 #define DRAM_INIT		0x00
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index 7ea0f10..72792f8 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -38,7 +38,6 @@
 # common sources for BL1, BL2, BL31
 PLAT_BL_COMMON_SOURCES	+=	drivers/console/aarch64/console.S	\
 				lib/xlat_tables_v2/aarch64/xlat_tables_arch.c \
-				lib/xlat_tables_v2/xlat_tables_common.c	\
 				lib/xlat_tables_v2/xlat_tables_internal.c \
 				$(PLAT_PATH)/uniphier_console.S		\
 				$(PLAT_PATH)/uniphier_helpers.S		\
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 6137229..1edbd0f 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -5,8 +5,8 @@
  */
 
 #include <assert.h>
-#include <bl_common.h>
 #include <bl31.h>
+#include <bl_common.h>
 #include <console.h>
 #include <debug.h>
 #include <errno.h>
diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c
index d334a10..c9fd361 100644
--- a/plat/xilinx/zynqmp/plat_psci.c
+++ b/plat/xilinx/zynqmp/plat_psci.c
@@ -5,9 +5,9 @@
  */
 
 #include <arch_helpers.h>
-#include <errno.h>
 #include <assert.h>
 #include <debug.h>
+#include <errno.h>
 #include <gicv2.h>
 #include <mmio.h>
 #include <plat_arm.h>
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 40f4da7..90c670d 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -11,10 +11,10 @@
 
 #include <arch_helpers.h>
 #include <platform.h>
-#include "pm_client.h"
-#include "pm_ipi.h"
-#include "pm_common.h"
 #include "pm_api_sys.h"
+#include "pm_client.h"
+#include "pm_common.h"
+#include "pm_ipi.h"
 
 /**
  * Assigning of argument values into array elements.
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c
index 08369b9..9016fd6 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.c
@@ -11,16 +11,16 @@
 
 #include <assert.h>
 #include <bakery_lock.h>
-#include <gicv2.h>
-#include <gic_common.h>
 #include <bl_common.h>
+#include <gic_common.h>
+#include <gicv2.h>
 #include <mmio.h>
 #include <string.h>
 #include <utils.h>
+#include "../zynqmp_def.h"
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
-#include "../zynqmp_def.h"
 
 #define IRQ_MAX		84
 #define NUM_GICD_ISENABLER	((IRQ_MAX >> 5) + 1)
diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.h b/plat/xilinx/zynqmp/pm_service/pm_client.h
index 03dec4c..16e37d5 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_client.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_client.h
@@ -12,8 +12,8 @@
 #ifndef _PM_CLIENT_H_
 #define _PM_CLIENT_H_
 
-#include "pm_defs.h"
 #include "pm_common.h"
+#include "pm_defs.h"
 
 /* Functions to be implemented by each PU */
 void pm_client_suspend(const struct pm_proc *proc, unsigned int state);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_ipi.c b/plat/xilinx/zynqmp/pm_service/pm_ipi.c
index ba72491..fdffde7 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_ipi.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_ipi.c
@@ -4,12 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <arch_helpers.h>
 #include <bakery_lock.h>
 #include <mmio.h>
 #include <platform.h>
-#include <arch_helpers.h>
-#include "pm_ipi.h"
 #include "../zynqmp_private.h"
+#include "pm_ipi.h"
 
 /* IPI message buffers */
 #define IPI_BUFFER_BASEADDR	0xFF990000U
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index b838171..f4e679b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -13,10 +13,10 @@
 #include <gic_common.h>
 #include <runtime_svc.h>
 #include <string.h>
+#include "../zynqmp_private.h"
 #include "pm_api_sys.h"
 #include "pm_client.h"
 #include "pm_ipi.h"
-#include "../zynqmp_private.h"
 
 #define PM_GET_CALLBACK_DATA	0xa01
 
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 27736f7..ecc4d0a 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -7,8 +7,8 @@
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
-#include <platform_tsp.h>
 #include <plat_arm.h>
+#include <platform_tsp.h>
 #include "../zynqmp_private.h"
 
 #define BL32_END (unsigned long)(&__BL32_END__)
diff --git a/readme.rst b/readme.rst
index a83338f..c3c0319 100644
--- a/readme.rst
+++ b/readme.rst
@@ -27,13 +27,15 @@
 This project contains code from other projects as listed below. The original
 license text is included in those source files.
 
--  The stdlib source code is derived from FreeBSD code.
+-  The stdlib source code is derived from FreeBSD code, which uses various
+   BSD licenses, including BSD-3-Clause and BSD-2-Clause.
 
 -  The libfdt source code is dual licensed. It is used by this project under
    the terms of the BSD-2-Clause license.
 
 -  The LLVM compiler-rt source code is dual licensed. It is used by this
-   project under the terms of the University of Illinois "BSD-Like" license.
+   project under the terms of the NCSA license (also known as the University of
+   Illinois/NCSA Open Source License).
 
 This Release
 ------------
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index 418e482..e2a2035 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -16,8 +16,8 @@
  ******************************************************************************/
 #include <arch_helpers.h>
 #include <assert.h>
-#include <bl_common.h>
 #include <bl31.h>
+#include <bl_common.h>
 #include <context_mgmt.h>
 #include <debug.h>
 #include <errno.h>
@@ -26,8 +26,9 @@
 #include <stddef.h>
 #include <uuid.h>
 #include "opteed_private.h"
-#include "teesmc_opteed_macros.h"
 #include "teesmc_opteed.h"
+#include "teesmc_opteed_macros.h"
+
 
 /*******************************************************************************
  * Address of the entrypoint vector table in OPTEE. It is
diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c
index 948be5d..78e9853 100644
--- a/services/spd/tlkd/tlkd_main.c
+++ b/services/spd/tlkd/tlkd_main.c
@@ -15,8 +15,8 @@
  ******************************************************************************/
 #include <arch_helpers.h>
 #include <assert.h>
-#include <bl_common.h>
 #include <bl31.h>
+#include <bl_common.h>
 #include <context_mgmt.h>
 #include <debug.h>
 #include <errno.h>
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index a95141b..e386f71 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -6,8 +6,8 @@
 
 #include <arch_helpers.h>
 #include <assert.h> /* for context_mgmt.h */
-#include <bl_common.h>
 #include <bl31.h>
+#include <bl_common.h>
 #include <context_mgmt.h>
 #include <debug.h>
 #include <interrupt_mgmt.h>
@@ -15,8 +15,8 @@
 #include <runtime_svc.h>
 #include <string.h>
 
-#include "smcall.h"
 #include "sm_err.h"
+#include "smcall.h"
 
 /* macro to check if Hypervisor is enabled in the HCR_EL2 register */
 #define HYP_ENABLE_FLAG		0x286001
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index afa7e2a..2ba9f84 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -16,8 +16,8 @@
  ******************************************************************************/
 #include <arch_helpers.h>
 #include <assert.h>
-#include <bl_common.h>
 #include <bl31.h>
+#include <bl_common.h>
 #include <context_mgmt.h>
 #include <debug.h>
 #include <errno.h>
diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h
index 2aa17e2..d432e63 100644
--- a/tools/cert_create/include/ext.h
+++ b/tools/cert_create/include/ext.h
@@ -7,8 +7,8 @@
 #ifndef EXT_H_
 #define EXT_H_
 
-#include "key.h"
 #include <openssl/x509v3.h>
+#include "key.h"
 
 /* Extension types supported */
 enum ext_type_e {
diff --git a/tools/cert_create/src/cmd_opt.c b/tools/cert_create/src/cmd_opt.c
index 0d47872..64180d1 100644
--- a/tools/cert_create/src/cmd_opt.c
+++ b/tools/cert_create/src/cmd_opt.c
@@ -5,10 +5,10 @@
  */
 
 #include <assert.h>
+#include <cmd_opt.h>
 #include <getopt.h>
 #include <stddef.h>
 #include <stdlib.h>
-#include <cmd_opt.h>
 #include "debug.h"
 
 /* Command line options */
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index 9923637..f14601c 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -30,8 +30,8 @@
 #include "ext.h"
 #include "key.h"
 #include "sha.h"
-#include "tbbr/tbb_ext.h"
 #include "tbbr/tbb_cert.h"
+#include "tbbr/tbb_ext.h"
 #include "tbbr/tbb_key.h"
 
 /*
diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c
index 5d5e9e2..2971593 100644
--- a/tools/cert_create/src/sha.c
+++ b/tools/cert_create/src/sha.c
@@ -4,8 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stdio.h>
 #include <openssl/sha.h>
+#include <stdio.h>
 
 #include "debug.h"
 
diff --git a/tools/fiptool/fiptool.c b/tools/fiptool/fiptool.c
index 4d80f2f..65e4a25 100644
--- a/tools/fiptool/fiptool.c
+++ b/tools/fiptool/fiptool.c
@@ -19,7 +19,6 @@
 #include <unistd.h>
 
 #include <openssl/sha.h>
-
 #include <firmware_image_package.h>
 
 #include "fiptool.h"
diff --git a/tools/fiptool/fiptool.h b/tools/fiptool/fiptool.h
index 4b5cdd9..889b0fd 100644
--- a/tools/fiptool/fiptool.h
+++ b/tools/fiptool/fiptool.h
@@ -7,10 +7,11 @@
 #ifndef __FIPTOOL_H__
 #define __FIPTOOL_H__
 
+#include <firmware_image_package.h>
+
 #include <stddef.h>
 #include <stdint.h>
 
-#include <firmware_image_package.h>
 #include <uuid.h>
 
 #define NELEM(x) (sizeof (x) / sizeof *(x))
diff --git a/tools/fiptool/tbbr_config.c b/tools/fiptool/tbbr_config.c
index 7c6c24b..6231cd4 100644
--- a/tools/fiptool/tbbr_config.c
+++ b/tools/fiptool/tbbr_config.c
@@ -4,9 +4,8 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stddef.h>
-
 #include <firmware_image_package.h>
+#include <stddef.h>
 
 #include "tbbr_config.h"