Merge pull request #724 from rockchip-linux/support-rk3399-sdram

rockchip: optimize the link mechanism for SRAM code
diff --git a/Makefile b/Makefile
index 2b630b3..b73a4dd 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,7 @@
 # Trusted Firmware Version
 #
 VERSION_MAJOR			:= 1
-VERSION_MINOR			:= 2
+VERSION_MINOR			:= 3
 
 # Default goal is build all images
 .DEFAULT_GOAL			:= all
@@ -117,6 +117,12 @@
 SEPARATE_CODE_AND_RODATA	:= 0
 # Flag to enable new version of image loading
 LOAD_IMAGE_V2		:= 0
+# Flag to enable runtime instrumentation using PMF
+ENABLE_RUNTIME_INSTRUMENTATION	:= 0
+
+ifeq (${ENABLE_RUNTIME_INSTRUMENTATION}, 1)
+ENABLE_PMF			:= 1
+endif
 
 ################################################################################
 # Checkpatch script options
@@ -466,6 +472,7 @@
 $(eval $(call assert_boolean,ENABLE_PSCI_STAT))
 $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
 $(eval $(call assert_boolean,LOAD_IMAGE_V2))
+$(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION))
 
 
 ################################################################################
@@ -497,6 +504,7 @@
 $(eval $(call add_define,ENABLE_PSCI_STAT))
 $(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
 $(eval $(call add_define,LOAD_IMAGE_V2))
+$(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
 ifdef EL3_PAYLOAD_BASE
         $(eval $(call add_define,EL3_PAYLOAD_BASE))
@@ -743,7 +751,7 @@
 	@echo "  cscope         Generate cscope index"
 	@echo "  distclean      Remove all build artifacts for all platforms"
 	@echo "  certtool       Build the Certificate generation tool"
-	@echo "  fiptool        Build the Firmware Image Package(FIP) creation tool"
+	@echo "  fiptool        Build the Firmware Image Package (FIP) creation tool"
 	@echo ""
 	@echo "Note: most build targets require PLAT to be set to a specific platform."
 	@echo ""
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index 4c3a515..d14a68d 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -31,6 +31,8 @@
 #include <arch.h>
 #include <bl_common.h>
 #include <el3_common_macros.S>
+#include <pmf_asm_macros.S>
+#include <runtime_instr.h>
 #include <xlat_tables.h>
 
 	.globl	bl31_entrypoint
@@ -141,6 +143,18 @@
 	 * --------------------------------------------------------------------
 	 */
 func bl31_warm_entrypoint
+#if ENABLE_RUNTIME_INSTRUMENTATION
+
+	/*
+	 * This timestamp update happens with cache off.  The next
+	 * timestamp collection will need to do cache maintenance prior
+	 * to timestamp update.
+	 */
+	pmf_calc_timestamp_addr rt_instr_svc RT_INSTR_EXIT_HW_LOW_PWR
+	mrs	x1, cntpct_el0
+	str	x1, [x0]
+#endif
+
 	/*
 	 * On the warm boot path, most of the EL3 initialisations performed by
 	 * 'el3_entrypoint_common' must be skipped:
@@ -188,5 +202,23 @@
 
 	bl	psci_warmboot_entrypoint
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	pmf_calc_timestamp_addr rt_instr_svc RT_INSTR_EXIT_PSCI
+	mov	x19, x0
+
+	/*
+	 * Invalidate before updating timestamp to ensure previous timestamp
+	 * updates on the same cache line with caches disabled are properly
+	 * seen by the same core. Without the cache invalidate, the core might
+	 * write into a stale cache line.
+	 */
+	mov	x1, #PMF_TS_SIZE
+	mov	x20, x30
+	bl	inv_dcache_range
+	mov	x30, x20
+
+	mrs	x0, cntpct_el0
+	str	x0, [x19]
+#endif
 	b	el3_exit
 endfunc bl31_warm_entrypoint
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 799062e..f333bf1 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -31,6 +31,7 @@
 #include <arch.h>
 #include <asm_macros.S>
 #include <context.h>
+#include <cpu_data.h>
 #include <interrupt_mgmt.h>
 #include <platform_def.h>
 #include <runtime_svc.h>
@@ -47,6 +48,21 @@
 	msr	daifclr, #DAIF_ABT_BIT
 
 	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+
+	/*
+	 * Read the timestamp value and store it in per-cpu data.
+	 * The value will be extracted from per-cpu data by the
+	 * C level SMC handler and saved to the PMF timestamp region.
+	 */
+	mrs	x30, cntpct_el0
+	str	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+	mrs	x29, tpidr_el3
+	str	x30, [x29, #CPU_DATA_PMF_TS0_OFFSET]
+	ldr	x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+#endif
+
 	mrs	x30, esr_el3
 	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
 
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index fae5ee4..85b3ea1 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -36,9 +36,16 @@
 #include <context_mgmt.h>
 #include <debug.h>
 #include <platform.h>
+#include <pmf.h>
+#include <runtime_instr.h>
 #include <runtime_svc.h>
 #include <string.h>
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+PMF_REGISTER_SERVICE_SMC(rt_instr_svc, PMF_RT_INSTR_SVC_ID,
+	RT_INSTR_TOTAL_IDS, PMF_STORE_ENABLE)
+#endif
+
 /*******************************************************************************
  * This function pointer is used to initialise the BL32 image. It's initialized
  * by SPD calling bl31_register_bl32_init after setting up all things necessary
diff --git a/docs/change-log.md b/docs/change-log.md
index 627b1c2..74edf98 100644
--- a/docs/change-log.md
+++ b/docs/change-log.md
@@ -1,3 +1,229 @@
+
+ARM Trusted Firmware - version 1.3
+==================================
+
+New features
+------------
+
+*   Added support for running Trusted Firmware in AArch32 execution state.
+
+    The PSCI library has been refactored to allow integration with **EL3 Runtime
+    Software**. This is software that is executing at the highest secure
+    privilege which is EL3 in AArch64 or Secure SVC/Monitor mode in AArch32. See
+    [PSCI Integration Guide].
+
+    Included is a minimal AArch32 Secure Payload, **SP-MIN**, that illustrates
+    the usage and integration of the PSCI library with EL3 Runtime Software
+    running in AArch32 state.
+
+    Booting to the BL1/BL2 images as well as booting straight to the Secure
+    Payload is supported.
+
+*   Improvements to the initialization framework for the PSCI service and ARM
+    Standard Services in general.
+
+    The PSCI service is now initialized as part of ARM Standard Service
+    initialization. This consolidates the initializations of any ARM Standard
+    Service that may be added in the future.
+
+    A new function `get_arm_std_svc_args()` is introduced to get arguments
+    corresponding to each standard service and must be implemented by the EL3
+    Runtime Software.
+
+    For PSCI, a new versioned structure `psci_lib_args_t` is introduced to
+    initialize the PSCI Library. **Note** this is a compatibility break due to
+    the change in the prototype of `psci_setup()`.
+
+*   To support AArch32 builds of BL1 and BL2, implemented a new, alternative
+    firmware image loading mechanism that adds flexibility.
+
+    The current mechanism has a hard-coded set of images and execution order
+    (BL31, BL32, etc). The new mechanism is data-driven by a list of image
+    descriptors provided by the platform code.
+
+    ARM platforms have been updated to support the new loading mechanism.
+
+    The new mechanism is enabled by a build flag (`LOAD_IMAGE_V2`) which is
+    currently off by default for the AArch64 build.
+
+    **Note** `TRUSTED_BOARD_BOOT` is currently not supported when
+    `LOAD_IMAGE_V2` is enabled.
+
+*   Updated requirements for making contributions to ARM TF.
+
+    Commits now must have a 'Signed-off-by:' field to certify that the
+    contribution has been made under the terms of the
+    [Developer Certificate of Origin].
+
+    A signed CLA is no longer required.
+
+    The [Contribution Guide] has been updated to reflect this change.
+
+*   Introduced Performance Measurement Framework (PMF) which provides support
+    for capturing, storing, dumping and retrieving time-stamps to measure the
+    execution time of critical paths in the firmware. This relies on defining
+    fixed sample points at key places in the code.
+
+*   To support the QEMU platform port, imported libfdt v1.4.1 from
+    https://git.kernel.org/cgit/utils/dtc/dtc.git
+
+*   Updated PSCI support:
+
+    *   Added support for PSCI NODE_HW_STATE API for ARM platforms.
+
+    *   New optional platform hook, `pwr_domain_pwr_down_wfi()`, in
+        `plat_psci_ops` to enable platforms to perform platform-specific actions
+        needed to enter powerdown, including the 'wfi' invocation.
+
+    *   PSCI STAT residency and count functions have been added on ARM platforms
+        by using PMF.
+
+*   Enhancements to the translation table library:
+
+    *   Limited memory mapping support for region overlaps to only allow regions
+        to overlap that are identity mapped or have the same virtual to physical
+        address offset, and overlap completely but must not cover the same area.
+
+        This limitation will enable future enhancements without having to
+        support complex edge cases that may not be necessary.
+
+    *   The initial translation lookup level is now inferred from the virtual
+        address space size. Previously, it was hard-coded.
+
+    *   Added support for mapping Normal, Inner Non-cacheable, Outer
+        Non-cacheable memory in the translation table library.
+
+        This can be useful to map a non-cacheable memory region, such as a DMA
+        buffer.
+
+    *   Introduced the MT_EXECUTE/MT_EXECUTE_NEVER memory mapping attributes to
+        specify the access permissions for instruction execution of a memory
+        region.
+
+*   Enabled support to isolate code and read-only data on separate memory pages,
+    allowing independent access control to be applied to each.
+
+*   Enabled SCR_EL3.SIF (Secure Instruction Fetch) bit in BL1 and BL31 common
+    architectural setup code, preventing fetching instructions from non-secure
+    memory when in secure state.
+
+*   Enhancements to FIP support:
+
+    *   Replaced `fip_create` with `fiptool` which provides a more consistent
+        and intuitive interface as well as additional support to remove an image
+        from a FIP file.
+
+    *   Enabled printing the SHA256 digest with info command, allowing quick
+        verification of an image within a FIP without having to extract the
+        image and running sha256sum on it.
+
+    *   Added support for unpacking the contents of an existing FIP file into
+        the working directory.
+
+    *   Aligned command line options for specifying images to use same naming
+        convention as specified by TBBR and already used in cert_create tool.
+
+*   Refactored the TZC-400 driver to also support memory controllers that
+    integrate TZC functionality, for example ARM CoreLink DMC-500. Also added
+    DMC-500 specific support.
+
+*   Implemented generic delay timer based on the system generic counter and
+    migrated all platforms to use it.
+
+*   Enhanced support for ARM platforms:
+
+    *   Updated image loading support to make SCP images (SCP_BL2 and SCP_BL2U)
+        optional.
+
+    *   Enhanced topology description support to allow multi-cluster topology
+        definitions.
+
+    *   Added interconnect abstraction layer to help platform ports select the
+        right interconnect driver, CCI or CCN, for the platform.
+
+    *   Added support to allow loading BL31 in the TZC-secured DRAM instead of
+        the default secure SRAM.
+
+    *   Added support to use a System Security Control (SSC) Registers Unit
+        enabling ARM TF to be compiled to support multiple ARM platforms and
+        then select one at runtime.
+
+    *   Restricted mapping of Trusted ROM in BL1 to what is actually needed by
+        BL1 rather than entire Trusted ROM region.
+
+    *   Flash is now mapped as execute-never by default. This increases security
+        by restricting the executable region to what is strictly needed.
+
+*   Applied following erratum workarounds for Cortex-A57: 833471, 826977,
+    829520, 828024 and 826974.
+
+*   Added support for Mediatek MT6795 platform.
+
+*   Added support for QEMU virtualization ARMv8-A target.
+
+*   Added support for Rockchip RK3368 and RK3399 platforms.
+
+*   Added support for Xilinx Zynq UltraScale+ MPSoC platform.
+
+*   Added support for ARM Cortex-A73 MPCore Processor.
+
+*   Added support for ARM Cortex-A72 processor.
+
+*   Added support for ARM Cortex-A35 processor.
+
+*   Added support for ARM Cortex-A32 MPCore Processor.
+
+*   Enabled preloaded BL33 alternative boot flow, in which BL2 does not load
+    BL33 from non-volatile storage and BL31 hands execution over to a preloaded
+    BL33. The User Guide has been updated with an example of how to use this
+    option with a bootwrapped kernel.
+
+*   Added support to build ARM TF on a Windows-based host machine.
+
+*   Updated Trusted Board Boot prototype implementation:
+
+    *   Enabled the ability for a production ROM with TBBR enabled to boot test
+        software before a real ROTPK is deployed (e.g. manufacturing mode).
+        Added support to use ROTPK in certificate without verifying against the
+        platform value when `ROTPK_NOT_DEPLOYED` bit is set.
+
+    *   Added support for non-volatile counter authentication to the
+        Authentication Module to protect against roll-back.
+
+*   Updated GICv3 support:
+
+    *   Enabled processor power-down and automatic power-on using GICv3.
+
+    *   Enabled G1S or G0 interrupts to be configured independently.
+
+    *   Changed FVP default interrupt driver to be the GICv3-only driver.
+        **Note** the default build of Trusted Firmware will not be able to boot
+        Linux kernel with GICv2 FDT blob.
+
+    *   Enabled wake-up from CPU_SUSPEND to stand-by by temporarily re-routing
+        interrupts and then restoring after resume.
+
+Issues resolved since last release
+----------------------------------
+
+Known issues
+------------
+
+*   The version of the AEMv8 Base FVP used in this release resets the model
+    instead of terminating its execution in response to a shutdown request using
+    the PSCI `SYSTEM_OFF` API. This issue will be fixed in a future version of
+    the model.
+
+*   Building TF with compiler optimisations disabled (`-O0`) fails.
+
+
+*   ARM TF cannot be built with mbed TLS version v2.3.0 due to build warnings
+    that the ARM TF build system interprets as errors.
+
+*   TBBR is not currently supported when running Trusted Firmware in AArch32
+    state.
+
+
 ARM Trusted Firmware - version 1.2
 ==================================
 
@@ -860,7 +1086,7 @@
 
 - - - - - - - - - - - - - - - - - - - - - - - - - -
 
-_Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved._
+_Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved._
 
 [OP-TEE Dispatcher]:                  optee-dispatcher.md
 [Power Domain Topology Design]:       psci-pd-tree.md
@@ -868,3 +1094,10 @@
 [Authentication Framework]:           auth-framework.md
 [Firmware Update]:                    firmware-update.md
 [TF Reset Design]:                    reset-design.md
+[PSCI Integration Guide]:             psci-lib-integration-guide.md
+[Firmware Design]:                    firmware-design.md
+[CPU Specific Build Macros]:          cpu-specific-build-macros.md
+[User Guide]:                         user-guide.md
+[Porting Guide]:                      porting-guide.md
+[Developer Certificate of Origin]:    ../dco.txt
+[Contribution Guide]:                 ../contributing.md
diff --git a/docs/firmware-design.md b/docs/firmware-design.md
index 52667e2..abe7dc5 100644
--- a/docs/firmware-design.md
+++ b/docs/firmware-design.md
@@ -15,8 +15,9 @@
 10. [Firmware Image Package (FIP)](#10--firmware-image-package-fip)
 11. [Use of coherent memory in Trusted Firmware](#11--use-of-coherent-memory-in-trusted-firmware)
 12. [Isolating code and read-only data on separate memory pages](#12--isolating-code-and-read-only-data-on-separate-memory-pages)
-13. [Code Structure](#13--code-structure)
-14. [References](#14--references)
+13. [Performance Measurement Framework](#13--performance-measurement-framework)
+14. [Code Structure](#14--code-structure)
+15. [References](#15--references)
 
 
 1.  Introduction
@@ -41,6 +42,9 @@
 management framework and its design can be found in [ARM Trusted
 Firmware Interrupt Management Design guide][INTRG] [4].
 
+The ARM Trusted Firmware can be built to support either AArch64 or AArch32
+execution state.
+
 2.  Cold boot
 -------------
 
@@ -55,15 +59,23 @@
 Refer to the [Reset Design] for more information on the effect of the
 `COLD_BOOT_SINGLE_CPU` platform build option.
 
-The cold boot path in this implementation of the ARM Trusted Firmware is divided
-into five steps (in order of execution):
+The cold boot path in this implementation of the ARM Trusted Firmware,
+depends on the execution state.
+For AArch64, it is divided into five steps (in order of execution):
 
 *   Boot Loader stage 1 (BL1) _AP Trusted ROM_
 *   Boot Loader stage 2 (BL2) _Trusted Boot Firmware_
-*   Boot Loader stage 3-1 (BL31) _EL3 Runtime Firmware_
+*   Boot Loader stage 3-1 (BL31) _EL3 Runtime Software_
 *   Boot Loader stage 3-2 (BL32) _Secure-EL1 Payload_ (optional)
 *   Boot Loader stage 3-3 (BL33) _Non-trusted Firmware_
 
+For AArch32, it is divided into four steps (in order of execution):
+
+*   Boot Loader stage 1 (BL1) _AP Trusted ROM_
+*   Boot Loader stage 2 (BL2) _Trusted Boot Firmware_
+*   Boot Loader stage 3-2 (BL32) _EL3 Runtime Software_
+*   Boot Loader stage 3-3 (BL33) _Non-trusted Firmware_
+
 ARM development platforms (Fixed Virtual Platforms (FVPs) and Juno) implement a
 combination of the following types of memory regions. Each bootloader stage uses
 one or more of these memory regions.
@@ -80,8 +92,9 @@
 The sections below provide the following details:
 
 *   initialization and execution of the first three stages during cold boot
-*   specification of the BL31 entrypoint requirements for use by alternative
-    Trusted Boot Firmware in place of the provided BL1 and BL2
+*   specification of the EL3 Runtime Software (BL31 for AArch64 and BL32 for
+    AArch32) entrypoint requirements for use by alternative Trusted Boot
+    Firmware in place of the provided BL1 and BL2
 
 
 ### BL1
@@ -119,10 +132,11 @@
 
     BL1 sets up simple exception vectors for both synchronous and asynchronous
     exceptions. The default behavior upon receiving an exception is to populate
-    a status code in the general purpose register `X0` and call the
+    a status code in the general purpose register `X0/R0` and call the
     `plat_report_exception()` function (see the [Porting Guide]). The status
     code is one of:
 
+    For AArch64:
         0x0 : Synchronous exception from Current EL with SP_EL0
         0x1 : IRQ exception from Current EL with SP_EL0
         0x2 : FIQ exception from Current EL with SP_EL0
@@ -140,12 +154,24 @@
         0xe : FIQ exception from Lower EL using aarch32
         0xf : System Error exception from Lower EL using aarch32
 
+    For AArch32:
+        0x10 : User mode
+        0x11 : FIQ mode
+        0x12 : IRQ mode
+        0x13 : SVC mode
+        0x16 : Monitor mode
+        0x17 : Abort mode
+        0x1a : Hypervisor mode
+        0x1b : Undefined mode
+        0x1f : System mode
+
     The `plat_report_exception()` implementation on the ARM FVP port programs
     the Versatile Express System LED register in the following format to
     indicate the occurence of an unexpected exception:
 
         SYS_LED[0]   - Security state (Secure=0/Non-Secure=1)
         SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0)
+                       For AArch32 it is always 0x0
         SYS_LED[7:3] - Exception Class (Sync/Async & origin). This is the value
                        of the status code
 
@@ -155,11 +181,12 @@
     BL1 does not expect to receive any exceptions other than the SMC exception.
     For the latter, BL1 installs a simple stub. The stub expects to receive a
     limited set of SMC types (determined by their function IDs in the general
-    purpose register `X0`):
+    purpose register `X0/R0`):
     -   `BL1_SMC_RUN_IMAGE`: This SMC is raised by BL2 to make BL1 pass control
-        to BL31 (loaded by BL2) at EL3.
+        to EL3 Runtime Software.
     -   All SMCs listed in section "BL1 SMC Interface" in the [Firmware Update]
-        Design Guide.
+        Design Guide are supported for AArch64 only. These SMCs are currently
+        not supported when BL1 is built for AArch32.
 
     Any other SMC leads to an assertion failure.
 
@@ -169,7 +196,7 @@
     specific reset handler function (see the section: "CPU specific operations
     framework").
 
-*   Control register setup
+*   Control register setup (for AArch64)
     -   `SCTLR_EL3`. Instruction cache is enabled by setting the `SCTLR_EL3.I`
         bit. Alignment and stack alignment checking is enabled by setting the
         `SCTLR_EL3.A` and `SCTLR_EL3.SA` bits. Exception endianness is set to
@@ -192,6 +219,29 @@
     -   `DAIF`. The SError interrupt is enabled by clearing the SError interrupt
         mask bit.
 
+*   Control register setup (for AArch32)
+    -   `SCTLR`. Instruction cache is enabled by setting the `SCTLR.I` bit.
+        Alignment checking is enabled by setting the `SCTLR.A` bit.
+        Exception endianness is set to little-endian by clearing the
+        `SCTLR.EE` bit.
+
+    -   `SCR`. The `SCR.SIF` bit is set to disable instruction fetches from
+        Non-secure memory when in secure state.
+
+    -   `CPACR`. Allow execution of Advanced SIMD instructions at PL0 and PL1,
+        by clearing the `CPACR.ASEDIS` bit. Access to the trace functionality
+        is configured not to trap to undefined mode by clearing the
+        `CPACR.TRCDIS` bit.
+
+    -   `NSACR`. Enable non-secure access to Advanced SIMD functionality and
+        system register access to implemented trace registers.
+
+    -   `FPEXC`. Enable access to the Advanced SIMD and floating-point
+        functionality from all Exception levels.
+
+    -   `CPSR.A`. The Asynchronous data abort interrupt is enabled by clearing
+        the Asynchronous data abort interrupt mask bit.
+
 #### Platform initialization
 
 On ARM platforms, BL1 performs the following platform initializations:
@@ -233,14 +283,13 @@
 
         "Failed to load BL2 firmware."
 
-    If the load is successful, BL1 updates the limits of the remaining free
-    trusted SRAM. It also populates information about the amount of trusted
-    SRAM used by the BL2 image. The exact load location of the image is
-    provided as a base address in the platform header. Further description of
-    the memory layout can be found later in this document.
+    BL1 calculates the amount of Trusted SRAM that can be used by the BL2
+    image. The exact load location of the image is provided as a base address
+    in the platform header. Further description of the memory layout can be
+    found later in this document.
 
-3.  BL1 passes control to the BL2 image at Secure EL1, starting from its load
-    address.
+3.  BL1 passes control to the BL2 image at Secure EL1 (for AArch64) or  at
+    Secure SVC mode (for AArch32), starting from its load address.
 
 4.  BL1 also passes information about the amount of trusted SRAM used and
     available for use. This information is populated at a platform-specific
@@ -249,16 +298,21 @@
 
 ### BL2
 
-BL1 loads and passes control to BL2 at Secure-EL1. BL2 is linked against and
-loaded at a platform-specific base address (more information can be found later
-in this document). The functionality implemented by BL2 is as follows.
+BL1 loads and passes control to BL2 at Secure-EL1 (for AArch64) or at Secure
+SVC mode (for AArch32) . BL2 is linked against and loaded at a platform-specific
+base address (more information can be found later in this document).
+The functionality implemented by BL2 is as follows.
 
 #### Architectural initialization
 
+For AArch64, BL2 performs the minimal architectural initialization required
+for subsequent stages of the ARM Trusted Firmware and normal world software.
+EL1 and EL0 are given access to Floating Point and Advanced SIMD registers
+by clearing the `CPACR.FPEN` bits.
+
-BL2 performs minimal architectural initialization required for subsequent
-stages of the ARM Trusted Firmware and normal world software. EL1 and EL0 are
-given access to Floating Point & Advanced SIMD registers by clearing the
-`CPACR.FPEN` bits.
+For AArch32, the minimal architectural initialization required for subsequent
+stages of the ARM Trusted Firmware and normal world software is taken care of
+in BL1 as both BL1 and BL2 execute at PL1.
 
 #### Platform initialization
 
@@ -270,10 +324,20 @@
 *   Enable the MMU and map the memory it needs to access.
 *   Perform platform security setup to allow access to controlled components.
 *   Reserve some memory for passing information to the next bootloader image
-    (BL31) and populate it.
+    EL3 Runtime Software and populate it.
 *   Define the extents of memory available for loading each subsequent
     bootloader image.
 
+#### Image loading in BL2
+
+Image loading scheme in BL2 depends on `LOAD_IMAGE_V2` build option. If the
+flag is disabled, the BLxx images are loaded, by calling the respective
+load_blxx() function from BL2 generic code. If the flag is enabled, the BL2
+generic code loads the images based on the list of loadable images provided
+by the platform. BL2 passes the list of executable images provided by the
+platform to the next handover BL image. By default, this flag is disabled for
+AArch64 and the AArch32 build is supported only if this flag is enabled.
+
 #### SCP_BL2 (System Control Processor Firmware) image load
 
 Some systems have a separate System Control Processor (SCP) for power, clock,
@@ -285,15 +349,16 @@
 memory. The SCP executes SCP_BL2 and signals to the Application Processor (AP)
 for BL2 execution to continue.
 
-#### BL31 (EL3 Runtime Firmware) image load
+#### EL3 Runtime Software image load
 
-BL2 loads the BL31 image from platform storage into a platform-specific address
-in trusted SRAM. If there is not enough memory to load the image or image is
-missing it leads to an assertion failure. If the BL31 image loads successfully,
-BL2 updates the amount of trusted SRAM used and available for use by BL31.
-This information is populated at a platform-specific memory address.
+BL2 loads the EL3 Runtime Software image from platform storage into a platform-
+specific address in trusted SRAM. If there is not enough memory to load the
+image or image is missing it leads to an assertion failure. If `LOAD_IMAGE_V2`
+is disabled and if image loads successfully, BL2 updates the amount of trusted
+SRAM used and available for use by EL3 Runtime Software. This information is
+populated at a platform-specific memory address.
 
-#### BL32 (Secure-EL1 Payload) image load
+#### AArch64 BL32 (Secure-EL1 Payload) image load
 
 BL2 loads the optional BL32 image from platform storage into a platform-
 specific region of secure memory. The image executes in the secure world. BL2
@@ -309,14 +374,14 @@
 BL2 loads the BL33 image (e.g. UEFI or other test or boot software) from
 platform storage into non-secure memory as defined by the platform.
 
-BL2 relies on BL31 to pass control to BL33 once secure state initialization is
-complete. Hence, BL2 populates a platform-specific area of memory with the
-entrypoint and Saved Program Status Register (`SPSR`) of the normal world
-software image. The entrypoint is the load address of the BL33 image. The
-`SPSR` is determined as specified in Section 5.13 of the [PSCI PDD] [PSCI]. This
-information is passed to BL31.
+BL2 relies on EL3 Runtime Software to pass control to BL33 once secure state
+initialization is complete. Hence, BL2 populates a platform-specific area of
+memory with the entrypoint and Saved Program Status Register (`SPSR`) of the
+normal world software image. The entrypoint is the load address of the BL33
+image. The `SPSR` is determined as specified in Section 5.13 of the [PSCI PDD]
+[PSCI]. This information is passed to the EL3 Runtime Software.
 
-#### BL31 (EL3 Runtime Firmware) execution
+#### AArch64 BL31 (EL3 Runtime Software) execution
 
 BL2 execution continues as follows:
 
@@ -331,7 +396,7 @@
 3.  BL1 passes control to BL31 at the specified entrypoint at EL3.
 
 
-### BL31
+### AArch64 BL31
 
 The image for this stage is loaded by BL2 and BL1 passes control to BL31 at
 EL3. BL31 executes solely in trusted SRAM. BL31 is linked against and
@@ -394,29 +459,30 @@
 Details about the status of the PSCI implementation are provided in the
 "Power State Coordination Interface" section below.
 
-#### BL32 (Secure-EL1 Payload) image initialization
+#### AArch64 BL32 (Secure-EL1 Payload) image initialization
 
 If a BL32 image is present then there must be a matching Secure-EL1 Payload
 Dispatcher (SPD) service (see later for details). During initialization
 that service must register a function to carry out initialization of BL32
 once the runtime services are fully initialized. BL31 invokes such a
-registered function to initialize BL32 before running BL33.
+registered function to initialize BL32 before running BL33. This initialization
+is not necessary for AArch32 SPs.
 
 Details on BL32 initialization and the SPD's role are described in the
 "Secure-EL1 Payloads and Dispatchers" section below.
 
 #### BL33 (Non-trusted Firmware) execution
 
-BL31 initializes the EL2 or EL1 processor context for normal-world cold
-boot, ensuring that no secure state information finds its way into the
-non-secure execution state. BL31 uses the entrypoint information provided
-by BL2 to jump to the Non-trusted firmware image (BL33) at the highest
-available Exception Level (EL2 if available, otherwise EL1).
+EL3 Runtime Software initializes the EL2 or EL1 processor context for normal-
+world cold boot, ensuring that no secure state information finds its way into
+the non-secure execution state. EL3 Runtime Software uses the entrypoint
+information provided by BL2 to jump to the Non-trusted firmware image (BL33)
+at the highest available Exception Level (EL2 if available, otherwise EL1).
 
-### Using alternative Trusted Boot Firmware in place of BL1 and BL2
+### Using alternative Trusted Boot Firmware in place of BL1 & BL2 (AArch64 only)
 
 Some platforms have existing implementations of Trusted Boot Firmware that
-would like to use ARM Trusted Firmware BL31 for the EL3 Runtime Firmware. To
+would like to use ARM Trusted Firmware BL31 for the EL3 Runtime Software. To
 enable this firmware architecture it is important to provide a fully documented
 and stable interface between the Trusted Boot Firmware and BL31.
 
@@ -521,6 +587,85 @@
 platform power management code is then invoked as required to initialize all
 necessary system, cluster and CPU resources.
 
+### AArch32 EL3 Runtime Software entrypoint interface
+
+To enable this firmware architecture it is important to provide a fully
+documented and stable interface between the Trusted Boot Firmware and the
+AArch32 EL3 Runtime Software.
+
+Future changes to the entrypoint interface will be done in a backwards
+compatible way, and this enables these firmware components to be independently
+enhanced/updated to develop and exploit new functionality.
+
+#### Required CPU state when entering during cold boot
+
+This function must only be called by the primary CPU.
+
+On entry to this function the calling primary CPU must be executing in AArch32
+EL3, little-endian data access, and all interrupt sources masked:
+
+    PSTATE.AIF = 0x7
+    SCTLR.EE = 0
+
+R0 and R1 are used to pass information from the Trusted Boot Firmware to the
+platform code in AArch32 EL3 Runtime Software:
+
+    R0 : Reserved for common Trusted Firmware information
+    R1 : Platform specific information
+
+##### Use of the R0 and R1 parameters
+
+The parameters are platform specific and the convention is that `R0` conveys
+information regarding the BL3x images from the Trusted Boot firmware and `R1`
+can be used for other platform specific purpose. This convention allows
+platforms which use ARM Trusted Firmware's BL1 and BL2 images to transfer
+additional platform specific information from Secure Boot without conflicting
+with future evolution of the Trusted Firmware using `R0` to pass a `bl_params`
+structure.
+
+The AArch32 EL3 Runtime Software is responsible for entry into BL33. This
+information can be obtained in a platform defined manner, e.g. compiled into
+the AArch32 EL3 Runtime Software, or provided in a platform defined memory
+location by the Trusted Boot firmware, or passed from the Trusted Boot Firmware
+via the Cold boot Initialization parameters. This data may need to be cleaned
+out of the CPU caches if it is provided by an earlier boot stage and then
+accessed by AArch32 EL3 Runtime Software before the caches are enabled.
+
+When using AArch32 EL3 Runtime Software, the ARM development platforms pass a
+`bl_params` structure in `R0` from BL2 to be interpreted by AArch32 EL3 Runtime
+Software platform code.
+
+##### MMU, Data caches & Coherency
+
+AArch32 EL3 Runtime Software must not depend on the enabled state of the MMU,
+data caches or interconnect coherency in its entrypoint. They must be explicitly
+enabled if required.
+
+##### Data structures used in cold boot interface
+
+The AArch32 EL3 Runtime Software cold boot interface uses `bl_params` instead
+of `bl31_params`. The `bl_params` structure is based on the convention
+described in AArch64 BL31 cold boot interface section.
+
+#### Required CPU state for warm boot initialization
+
+When requesting a CPU power-on, or suspending a running CPU, AArch32 EL3
+Runtime Software must ensure execution of a warm boot initialization entrypoint.
+If ARM Trusted Firmware BL1 is used and the PROGRAMMABLE_RESET_ADDRESS build
+flag is false, then AArch32 EL3 Runtime Software must ensure that BL1 branches
+to the warm boot entrypoint by arranging for the BL1 platform function,
+plat_get_my_entrypoint(), to return a non-zero value.
+
+In this case, the warm boot entrypoint must be in AArch32 EL3, little-endian
+data access and all interrupt sources masked:
+
+    PSTATE.AIF = 0x7
+    SCTLR.EE = 0
+
+The warm boot entrypoint may be implemented by using the ARM Trusted Firmware
+`psci_warmboot_entrypoint()` function. In that case, the platform must fulfil
+the pre-requisites mentioned in the [PSCI Library integration guide]
+[PSCI Lib guide].
 
 3.  EL3 runtime services framework
 ----------------------------------
@@ -536,7 +681,7 @@
 different providers that can be easily integrated into final product firmware.
 The following sections describe the framework which facilitates the
 registration, initialization and use of runtime services in EL3 Runtime
-Firmware (BL31).
+Software (BL31).
 
 The design of the runtime services depends heavily on the concepts and
 definitions described in the [SMCCC], in particular SMC Function IDs, Owning
@@ -562,7 +707,7 @@
     [SMCCC] provides for such SMCs with the Trusted OS Call and Trusted
     Application Call OEN ranges.
 
-    The interface between the EL3 Runtime Firmware and the Secure-EL1 Payload is
+    The interface between the EL3 Runtime Software and the Secure-EL1 Payload is
     not defined by the [SMCCC] or any other standard. As a result, each
     Secure-EL1 Payload requires a specific Secure Monitor that runs as a runtime
     service - within ARM Trusted Firmware this service is referred to as the
@@ -1192,13 +1337,13 @@
 on FVP, BL31 and TSP need to know the limit address that their PROGBITS
 sections must not overstep. The platform code must provide those.
 
-Trusted Firmware provides a mechanism to verify at boot time that the memory
-to load a new image is free to prevent overwriting a previously loaded image.
-For this mechanism to work, the platform must specify the memory available in
-the system as regions, where each region consists of base address, total size
-and the free area within it (as defined in the `meminfo_t` structure). Trusted
-Firmware retrieves these memory regions by calling the corresponding platform
-API:
+When LOAD_IMAGE_V2 is disabled, Trusted Firmware provides a mechanism to
+verify at boot time that the memory to load a new image is free to prevent
+overwriting a previously loaded image. For this mechanism to work, the platform
+must specify the memory available in the system as regions, where each region
+consists of base address, total size and the free area within it (as defined
+in the `meminfo_t` structure). Trusted Firmware retrieves these memory regions
+by calling the corresponding platform API:
 
 *   `meminfo_t *bl1_plat_sec_mem_layout(void)`
 *   `meminfo_t *bl2_plat_sec_mem_layout(void)`
@@ -1259,6 +1404,17 @@
                +----------+
 
 
+When LOAD_IMAGE_V2 is enabled, Trusted Firmware does not provide any mechanism
+to verify at boot time that the memory to load a new image is free to prevent
+overwriting a previously loaded image. The platform must specify the memory
+available in the system for all the relevant BL images to be loaded.
+
+For example, in the case of BL1 loading BL2, `bl1_plat_sec_mem_layout()` will
+return the region defined by the platform where BL1 intends to load BL2. The
+`load_image()` function performs bounds check for the image size based on the
+base and maximum image size provided by the platforms. Platforms must take
+this behaviour into account when defining the base/size for each of the images.
+
 ####  Memory layout on ARM development platforms
 
 The following list describes the memory layout on the ARM development platforms:
@@ -1276,29 +1432,31 @@
     Juno, BL1 resides in flash memory at address `0x0BEC0000`. BL1 read-write
     data are relocated to the top of Trusted SRAM at runtime.
 
-*   BL31 is loaded at the top of the Trusted SRAM, such that its NOBITS
-    sections will overwrite BL1 R/W data. This implies that BL1 global variables
-    remain valid only until execution reaches the BL31 entry point during
-    a cold boot.
+*   EL3 Runtime Software, BL31 for AArch64 and BL32 for AArch32 (e.g. SP_MIN),
+    is loaded at the top of the Trusted SRAM, such that its NOBITS sections will
+    overwrite BL1 R/W data. This implies that BL1 global variables remain valid
+    only until execution reaches the EL3 Runtime Software entry point during a
+    cold boot.
 
-*   BL2 is loaded below BL31.
+*   BL2 is loaded below EL3 Runtime Software.
 
-*   On Juno, SCP_BL2 is loaded temporarily into the BL31 memory region and
-    transfered to the SCP before being overwritten by BL31.
+*   On Juno, SCP_BL2 is loaded temporarily into the EL3 Runtime Software memory
+    region and transfered to the SCP before being overwritten by EL3 Runtime
+    Software.
 
-*   BL32 can be loaded in one of the following locations:
+*   BL32 (for AArch64) can be loaded in one of the following locations:
 
     *   Trusted SRAM
     *   Trusted DRAM (FVP only)
     *   Secure region of DRAM (top 16MB of DRAM configured by the TrustZone
         controller)
 
-    When BL32 is loaded into Trusted SRAM, its NOBITS sections are allowed to
-    overlay BL2. This memory layout is designed to give the BL32 image as much
-    memory as possible when it is loaded into Trusted SRAM.
+    When BL32 (for AArch64) is loaded into Trusted SRAM, its NOBITS sections
+    are allowed to overlay BL2. This memory layout is designed to give the
+    BL32 image as much memory as possible when it is loaded into Trusted SRAM.
 
-The memory regions for the overlap detection mechanism at boot time are
-defined as follows (shown per API):
+When LOAD_IMAGE_V2 is disabled the memory regions for the overlap detection
+mechanism at boot time are defined as follows (shown per API):
 
 *   `meminfo_t *bl1_plat_sec_mem_layout(void)`
 
@@ -1343,6 +1501,7 @@
 layout of the other images in Trusted SRAM.
 
 **FVP with TSP in Trusted SRAM (default option):**
+(These diagrams only cover the AArch64 case)
 
                Trusted SRAM
     0x04040000 +----------+  loaded by BL2  ------------------
@@ -1857,8 +2016,129 @@
 This build flag is disabled by default, minimising memory footprint. On ARM
 platforms, it is enabled.
 
+
+13.  Performance Measurement Framework
+--------------------------------------
+
+The Performance Measurement Framework (PMF) facilitates collection of
+timestamps by registered services and provides interfaces to retrieve
+them from within the ARM Trusted Firmware.  A platform can choose to
+expose appropriate SMCs to retrieve these collected timestamps.
+
+By default, the global physical counter is used for the timestamp
+value and is read via `CNTPCT_EL0`.  The framework allows to retrieve
+timestamps captured by other CPUs.
+
+### Timestamp identifier format
+
+A PMF timestamp is uniquely identified across the system via the
+timestamp ID or `tid`. The `tid` is composed as follows:
+
+    Bits 0-7: The local timestamp identifier.
+    Bits 8-9: Reserved.
+    Bits 10-15: The service identifier.
+    Bits 16-31: Reserved.
+
+1.  The service identifier. Each PMF service is identified by a
+    service name and a service identifier.  Both the service name and
+    identifier are unique within the system as a whole.
+
+2.  The local timestamp identifier. This identifier is unique within a given
+    service.
+
+### Registering a PMF service
+
+To register a PMF service, the `PMF_REGISTER_SERVICE()` macro from `pmf.h`
+is used. The arguments required are the service name, the service ID,
+the total number of local timestamps to be captured and a set of flags.
+
+The `flags` field can be specified as a bitwise-OR of the following values:
+
+    PMF_STORE_ENABLE: The timestamp is stored in memory for later retrieval.
+    PMF_DUMP_ENABLE: The timestamp is dumped on the serial console.
+
+The `PMF_REGISTER_SERVICE()` reserves memory to store captured
+timestamps in a PMF specific linker section at build time.
+Additionally, it defines necessary functions to capture and
+retrieve a particular timestamp for the given service at runtime.
 
-13.  Code Structure
+The macro `PMF_REGISTER_SERVICE()` only enables capturing PMF
+timestamps from within ARM Trusted Firmware. In order to retrieve
+timestamps from outside of ARM Trusted Firmware, the
+`PMF_REGISTER_SERVICE_SMC()` macro must be used instead. This macro
+accepts the same set of arguments as the `PMF_REGISTER_SERVICE()`
+macro but additionally supports retrieving timestamps using SMCs.
+
+### Capturing a timestamp
+
+PMF timestamps are stored in a per-service timestamp region. On a
+system with multiple CPUs, each timestamp is captured and stored
+in a per-CPU cache line aligned memory region.
+
+Having registered the service, the `PMF_CAPTURE_TIMESTAMP()` macro can be
+used to capture a timestamp at the location where it is used.  The macro
+takes the service name, a local timestamp identifier and a flag as arguments.
+
+The `flags` field argument can be zero, or `PMF_CACHE_MAINT` which
+instructs PMF to do cache maintenance following the capture.  Cache
+maintenance is required if any of the service's timestamps are captured
+with data cache disabled.
+
+To capture a timestamp in assembly code, the caller should use
+`pmf_calc_timestamp_addr` macro (defined in `pmf_asm_macros.S`) to
+calculate the address of where the timestamp would be stored. The
+caller should then read `CNTPCT_EL0` register to obtain the timestamp
+and store it at the determined address for later retrieval.
+
+### Retrieving a timestamp
+
+From within ARM Trusted Firmware, timestamps for individual CPUs can
+be retrieved using either `PMF_GET_TIMESTAMP_BY_MPIDR()` or
+`PMF_GET_TIMESTAMP_BY_INDEX()` macros. These macros accept the CPU's MPIDR
+value, or its ordinal position, respectively.
+
+From outside ARM Trusted Firmware, timestamps for individual CPUs can be
+retrieved by calling into `pmf_smc_handler()`.
+
+    Interface : pmf_smc_handler()
+    Argument  : unsigned int smc_fid, u_register_t x1,
+                u_register_t x2, u_register_t x3,
+                u_register_t x4, void *cookie,
+                void *handle, u_register_t flags
+    Return    : uintptr_t
+
+    smc_fid: Holds the SMC identifier which is either `PMF_SMC_GET_TIMESTAMP_32`
+        when the caller of the SMC is running in AArch32 mode
+        or `PMF_SMC_GET_TIMESTAMP_64` when the caller is running in AArch64 mode.
+    x1: Timestamp identifier.
+    x2: The `mpidr` of the CPU for which the timestamp has to be retrieved.
+        This can be the `mpidr` of a different core to the one initiating
+        the SMC.  In that case, service specific cache maintenance may be
+        required to ensure the updated copy of the timestamp is returned.
+    x3: A flags value that is either 0 or `PMF_CACHE_MAINT`.  If
+        `PMF_CACHE_MAINT` is passed, then the PMF code will perform a
+        cache invalidate before reading the timestamp.  This ensures
+        an updated copy is returned.
+
+The remaining arguments, `x4`, `cookie`, `handle` and `flags` are unused
+in this implementation.
+
+### PMF code structure
+
+1.  `pmf_main.c` consists of core functions that implement service registration,
+    initialization, storing, dumping and retrieving timestamps.
+
+2.  `pmf_smc.c` contains the SMC handling for registered PMF services.
+
+3.  `pmf.h` contains the public interface to Performance Measurement Framework.
+
+4.  `pmf_asm_macros.S` consists of macros to facilitate capturing timestamps in
+    assembly code.
+
+5.  `pmf_helpers.h` is an internal header used by `pmf.h`.
+
+
+14.  Code Structure
 -------------------
 
 Trusted Firmware code is logically divided between the three boot loader
@@ -1902,7 +2182,7 @@
 kernel at boot time. These can be found in the `fdts` directory.
 
 
-14.  References
+15.  References
 ---------------
 
 1.  Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 93c0169..1247baf 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -8,7 +8,7 @@
 2.  [Common Modifications](#2--common-modifications)
     *   [Common mandatory modifications](#21-common-mandatory-modifications)
     *   [Handling reset](#22-handling-reset)
-    *   [Common mandatory modifications](#23-common-mandatory-modifications)
+    *   [Common mandatory function modifications](#23-common-mandatory-function-modifications)
     *   [Common optional modifications](#24-common-optional-modifications)
 3.  [Boot Loader stage specific modifications](#3--modifications-specific-to-a-boot-loader-stage)
     *   [Boot Loader stage 1 (BL1)](#31-boot-loader-stage-1-bl1)
@@ -501,6 +501,17 @@
     PLAT_PL061_MAX_GPIOS    :=      160
     $(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
 
+If the platform port uses the partition driver, the following constant may
+optionally be defined:
+
+*   **PLAT_PARTITION_MAX_ENTRIES**
+    Maximum number of partition entries required by the platform. This allows
+    control how much memory is allocated for partition entries. The default
+    value is 128.
+    [For example, define the build flag in platform.mk]:
+    PLAT_PARTITION_MAX_ENTRIES	:=	12
+    $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
+
 
 ### File : plat_macros.S [mandatory]
 
@@ -685,7 +696,7 @@
 not be updated.
 
 
-2.3 Common mandatory modifications
+2.3 Common mandatory function modifications
 ---------------------------------
 
 The following functions are mandatory functions which need to be implemented
diff --git a/docs/user-guide.md b/docs/user-guide.md
index a07185d..5b73b66 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -89,23 +89,46 @@
 ---------------------------------
 
 *   Before building Trusted Firmware, the environment variable `CROSS_COMPILE`
-    must point to the Linaro cross compiler:
+    must point to the Linaro cross compiler.
+
+    For AArch64:
 
         export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
 
+    For AArch32:
+
-*   Change to the root directory of the Trusted Firmware source tree and build:
+        export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
+
+*   Change to the root directory of the Trusted Firmware source tree and build.
+
+    For AArch64:
 
         make PLAT=<platform> all
 
+    For AArch32:
+
-    Notes:
+        make PLAT=<platform> ARCH=aarch32 AARCH32_SP=sp_min all
+
+
+   Notes:
 
     *   If `PLAT` is not specified, `fvp` is assumed by default. See the
         "Summary of build options" for more information on available build
         options.
 
-    *   The TSP (Test Secure Payload), corresponding to the BL32 image, is not
-        compiled in by default. Refer to the "Building the Test Secure Payload"
-        section below.
+    *   (AArch32 only) Currently only `PLAT=fvp` is supported.
+
+    *   (AArch32 only) `AARCH32_SP` is the AArch32 EL3 Runtime Software and it
+        corresponds to the BL32 image. A minimal `AARCH32_SP`, sp_min, is
+        provided by ARM Trusted Firmware to demonstrate how PSCI Library can
+        be integrated with an AArch32 EL3 Runtime Software. Some AArch32 EL3
+        Runtime Software may include other runtime services, for example
+        Trusted OS services. A guide to integrate PSCI library with AArch32
+        EL3 Runtime Software can be found [here][PSCI Lib Integration].
+
+    *   (AArch64 only) The TSP (Test Secure Payload), corresponding to the BL32
+        image, is not compiled in by default. Refer to the "Building the Test
+        Secure Payload" section below.
 
     *   By default this produces a release version of the build. To produce a
         debug version instead, refer to the "Debugging options" section below.
@@ -117,7 +140,8 @@
 
         *   `build/<platform>/<build-type>/bl1.bin`
         *   `build/<platform>/<build-type>/bl2.bin`
-        *   `build/<platform>/<build-type>/bl31.bin`
+        *   `build/<platform>/<build-type>/bl31.bin` (AArch64 only)
+        *   `build/<platform>/<build-type>/bl32.bin` (mandatory for AArch32)
 
         where `<platform>` is the name of the chosen platform and `<build-type>`
         is either `debug` or `release`. The actual number of images might differ
@@ -238,6 +262,12 @@
     entrypoint) or 1 (CPU reset to BL31 entrypoint).
     The default value is 0.
 
+*   `RESET_TO_SP_MIN`: SP_MIN is the minimal AArch32 Secure Payload provided in
+    ARM Trusted Firmware. This flag configures SP_MIN entrypoint as the CPU
+    reset vector instead of the BL1 entrypoint.  It can take the value 0 (CPU
+    reset to BL1 entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default
+    value is 0.
+
 *   `CRASH_REPORTING`: A non-zero value enables a console dump of processor
     register state when an unexpected exception occurs during execution of
     BL31. This option defaults to the value of `DEBUG` - i.e. by default
@@ -598,8 +628,7 @@
 
 An additional boot loader binary file is created in the `build` directory:
 
-    `build/<platform>/<build-type>/bl32.bin`
-
+    build/<platform>/<build-type>/bl32.bin
 
 ### Checking source code style
 
@@ -634,14 +663,26 @@
 (e.g. UEFI or U-Boot).
 
 The TF build system provides the make target `fip` to create a FIP file for the
-specified platform using the FIP creation tool included in the TF project. For
-example, to build a FIP file for FVP, packaging TF images and a BL33 image:
+specified platform using the FIP creation tool included in the TF project.
+Examples below show how to build a FIP file for FVP, packaging TF images and a
+BL33 image.
+
+For AArch64:
 
     make PLAT=fvp BL33=<path/to/bl33.bin> fip
 
+For AArch32:
+
+    make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=<path/to/bl33.bin> fip
+
+Note that AArch32 support for Normal world boot loader (BL33), like U-boot or
+UEFI, on FVP is not available upstream. Hence custom solutions are required to
+allow Linux boot on FVP. These instructions assume such a custom boot loader
+(BL33) is available.
+
 The resulting FIP may be found in:
 
-    `build/fvp/<build-type>/fip.bin`
+    build/fvp/<build-type>/fip.bin
 
 For advanced operations on FIP files, it is also possible to independently build
 the tool and create or modify FIPs using this tool. To do this, follow these
@@ -830,6 +871,9 @@
 a single FIP binary. It assumes that a [Linaro Release][Linaro Release Notes]
 has been installed.
 
+Note currently [Linaro Release][Linaro Release Notes] only includes pre-built
+binaries for AArch64. For AArch32, pre-built binaries are not available.
+
 Note: follow the full instructions for one platform before switching to a
 different one. Mixing instructions for different platforms may result in
 corrupted binaries.
@@ -858,14 +902,20 @@
     exist in the current directory. If that is the case, either delete those
     files or use the `--force` option to overwrite.
 
+    Note for AArch32, the instructions below assume that nt-fw.bin is a custom
+    Normal world boot loader that supports AArch32.
+
 3.  Build TF images and create a new FIP
 
         # Juno
         make PLAT=juno SCP_BL2=scp-fw.bin BL33=nt-fw.bin all fip
 
-        # FVP
+        # FVP AArch64
         make PLAT=fvp BL33=nt-fw.bin all fip
 
+        # FVP AArch32
+        make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=nt-fw.bin all fip
+
 The resulting BL1 and FIP images may be found in:
 
     # Juno
@@ -1034,16 +1084,16 @@
 #### Boot of a preloaded bootwrapped kernel image on Juno
 
 The procedure to obtain and compile the boot wrapper is very similar to the case
-of the FVP. Once compiled, the `SPIN_ON_BL1_EXIT=1` loading method explained
-above in the EL3 payload boot flow section may be used to load the ELF file over
-JTAG on Juno.
+of the FVP. The execution must be stopped at the end of bl2_main(), and the
+loading method explained above in the EL3 payload boot flow section may be used
+to load the ELF file over JTAG on Juno.
 
 
 9.  Running the software on FVP
 -------------------------------
 
-This version of the ARM Trusted Firmware has been tested on the following ARM
-FVPs (64-bit versions only).
+The AArch64 build of this version of ARM Trusted Firmware has been tested on
+the following ARM FVPs (64-bit host machine only).
 
 *   `Foundation_Platform` (Version 10.1, Build 10.1.32)
 *   `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701)
@@ -1051,6 +1101,12 @@
 *   `FVP_Base_Cortex-A57x1-A53x1` (Version 7.7, Build 0.8.7701)
 *   `FVP_Base_Cortex-A57x2-A53x4` (Version 7.7, Build 0.8.7701)
 
+The AArch32 build of this version of ARM Trusted Firmware has been tested on
+the following ARM FVPs (64-bit host machine only).
+
+*   `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701)
+*   `FVP_Base_Cortex-A32x4` (Version 10.1, Build 10.1.32)
+
 NOTE: The build numbers quoted above are those reported by launching the FVP
 with the `--version` parameter.
 
@@ -1082,11 +1138,21 @@
     For use with both AEMv8 and Cortex-A57-A53 Base FVPs with
     Base memory map configuration.
 
+*   `fvp-base-gicv2-psci-aarch32.dtb`
+
+    For use with AEMv8 and Cortex-A32 Base FVPs running Linux in AArch32 state
+    with Base memory map configuration.
+
 *   `fvp-base-gicv3-psci.dtb`
 
     (Default) For use with both AEMv8 and Cortex-A57-A53 Base FVPs with Base
     memory map configuration and Linux GICv3 support.
 
+*   `fvp-base-gicv3-psci-aarch32.dtb`
+
+    For use with AEMv8 and Cortex-A32 Base FVPs running Linux in AArch32 state
+    with Base memory map configuration and Linux GICv3 support.
+
 *   `fvp-foundation-gicv2-psci.dtb`
 
     For use with Foundation FVP with Base memory map configuration.
@@ -1099,7 +1165,7 @@
 ### Running on the Foundation FVP with reset to BL1 entrypoint
 
 The following `Foundation_Platform` parameters should be used to boot Linux with
-4 CPUs using the ARM Trusted Firmware.
+4 CPUs using the AArch64 build of ARM Trusted Firmware.
 
     <path-to>/Foundation_Platform                   \
     --cores=4                                       \
@@ -1124,7 +1190,7 @@
 ### Running on the AEMv8 Base FVP with reset to BL1 entrypoint
 
 The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
-with 8 CPUs using the ARM Trusted Firmware.
+with 8 CPUs using the AArch64 build of ARM Trusted Firmware.
 
     <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
     -C pctl.startup=0.0.0.0                                     \
@@ -1139,10 +1205,36 @@
     --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
     -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
 
+### Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint
+
+The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                            \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cluster0.NUM_CORES=4                                     \
+    -C cluster1.NUM_CORES=4                                     \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.CONFIG64=0                                 \
+    -C cluster0.cpu1.CONFIG64=0                                 \
+    -C cluster0.cpu2.CONFIG64=0                                 \
+    -C cluster0.cpu3.CONFIG64=0                                 \
+    -C cluster1.cpu0.CONFIG64=0                                 \
+    -C cluster1.cpu1.CONFIG64=0                                 \
+    -C cluster1.cpu2.CONFIG64=0                                 \
+    -C cluster1.cpu3.CONFIG64=0                                 \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x83000000           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
 ### Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
 
 The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to
-boot Linux with 8 CPUs using the ARM Trusted Firmware.
+boot Linux with 8 CPUs using the AArch64 build of ARM Trusted Firmware.
 
     <path-to>/FVP_Base_Cortex-A57x4-A53x4                       \
     -C pctl.startup=0.0.0.0                                     \
@@ -1155,10 +1247,26 @@
     --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
     -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
 
+### Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint
+
+The following `FVP_Base_Cortex-A32x4` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C bp.secureflashloader.fname="<path-to>/<bl1-binary>"      \
+    -C bp.flashloader0.fname="<path-to>/<FIP-binary>"           \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x83000000           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
 ### Running on the AEMv8 Base FVP with reset to BL31 entrypoint
 
 The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
-with 8 CPUs using the ARM Trusted Firmware.
+with 8 CPUs using the AArch64 build of ARM Trusted Firmware.
 
     <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
     -C pctl.startup=0.0.0.0                                      \
@@ -1199,10 +1307,47 @@
     `--data="<path-to><bl32-binary>"@<base-address-of-bl32>` to the new value of
     `BL32_BASE`.
 
+### Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint
+
+The following `FVP_Base_AEMv8A-AEMv8A` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_AEMv8A-AEMv8A                             \
+    -C pctl.startup=0.0.0.0                                      \
+    -C bp.secure_memory=1                                        \
+    -C bp.tzc_400.diagnostics=1                                  \
+    -C cluster0.NUM_CORES=4                                      \
+    -C cluster1.NUM_CORES=4                                      \
+    -C cache_state_modelled=1                                    \
+    -C cluster0.cpu0.CONFIG64=0                                  \
+    -C cluster0.cpu1.CONFIG64=0                                  \
+    -C cluster0.cpu2.CONFIG64=0                                  \
+    -C cluster0.cpu3.CONFIG64=0                                  \
+    -C cluster1.cpu0.CONFIG64=0                                  \
+    -C cluster1.cpu1.CONFIG64=0                                  \
+    -C cluster1.cpu2.CONFIG64=0                                  \
+    -C cluster1.cpu3.CONFIG64=0                                  \
+    -C cluster0.cpu0.RVBAR=0x04001000                            \
+    -C cluster0.cpu1.RVBAR=0x04001000                            \
+    -C cluster0.cpu2.RVBAR=0x04001000                            \
+    -C cluster0.cpu3.RVBAR=0x04001000                            \
+    -C cluster1.cpu0.RVBAR=0x04001000                            \
+    -C cluster1.cpu1.RVBAR=0x04001000                            \
+    -C cluster1.cpu2.RVBAR=0x04001000                            \
+    -C cluster1.cpu3.RVBAR=0x04001000                            \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04001000    \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000    \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x83000000            \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
+
+Note: The load address of `<bl32-binary>` depends on the value `BL32_BASE`.
+It should match the address programmed into the RVBAR register as well.
+
 ### Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
 
 The following `FVP_Base_Cortex-A57x4-A53x4` model parameters should be used to
-boot Linux with 8 CPUs using the ARM Trusted Firmware.
+boot Linux with 8 CPUs using the AArch64 build of ARM Trusted Firmware.
 
     <path-to>/FVP_Base_Cortex-A57x4-A53x4                        \
     -C pctl.startup=0.0.0.0                                      \
@@ -1224,6 +1369,25 @@
     --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000  \
     -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
 
+### Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint
+
+The following `FVP_Base_Cortex-A32x4` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of ARM Trusted Firmware.
+
+    <path-to>/FVP_Base_Cortex-A32x4                             \
+    -C pctl.startup=0.0.0.0                                     \
+    -C bp.secure_memory=1                                       \
+    -C bp.tzc_400.diagnostics=1                                 \
+    -C cache_state_modelled=1                                   \
+    -C cluster0.cpu0.RVBARADDR=0x04001000                       \
+    -C cluster0.cpu1.RVBARADDR=0x04001000                       \
+    -C cluster0.cpu2.RVBARADDR=0x04001000                       \
+    -C cluster0.cpu3.RVBARADDR=0x04001000                       \
+    --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04001000   \
+    --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000   \
+    --data cluster0.cpu0="<path-to>/<fdt>"@0x83000000           \
+    --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+    -C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>"
 
 10.  Running the software on Juno
 ---------------------------------
@@ -1280,3 +1444,4 @@
 [PSCI]:                        http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf "Power State Coordination Interface PDD (ARM DEN 0022C)"
 [Trusted Board Boot]:          trusted-board-boot.md
 [Firmware Update]:             ./firmware-update.md
+[PSCI Lib Integration]:        ./psci-lib-integration-guide.md
diff --git a/drivers/partition/gpt.c b/drivers/partition/gpt.c
new file mode 100644
index 0000000..9240d5a
--- /dev/null
+++ b/drivers/partition/gpt.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <gpt.h>
+#include <string.h>
+
+static int unicode_to_ascii(unsigned short *str_in, unsigned char *str_out)
+{
+	uint8_t *name = (uint8_t *)str_in;
+	int i;
+
+	assert((str_in != NULL) && (str_out != NULL) && (name[0] != '\0'));
+
+	/* check whether the unicode string is valid */
+	for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
+		if (name[i] != '\0')
+			return -EINVAL;
+	}
+	/* convert the unicode string to ascii string */
+	for (i = 0; i < (EFI_NAMELEN << 1); i += 2) {
+		str_out[i >> 1] = name[i];
+		if (name[i] == '\0')
+			break;
+	}
+	return 0;
+}
+
+int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry)
+{
+	int result;
+
+	assert((gpt_entry != 0) && (entry != 0));
+
+	if ((gpt_entry->first_lba == 0) && (gpt_entry->last_lba == 0)) {
+		return -EINVAL;
+	}
+
+	memset(entry, 0, sizeof(partition_entry_t));
+	result = unicode_to_ascii(gpt_entry->name, (uint8_t *)entry->name);
+	if (result != 0) {
+		return result;
+	}
+	entry->start = (uint64_t)gpt_entry->first_lba * PARTITION_BLOCK_SIZE;
+	entry->length = (uint64_t)(gpt_entry->last_lba -
+				   gpt_entry->first_lba + 1) *
+			PARTITION_BLOCK_SIZE;
+	return 0;
+}
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
new file mode 100644
index 0000000..8bf6848
--- /dev/null
+++ b/drivers/partition/partition.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <io_storage.h>
+#include <gpt.h>
+#include <mbr.h>
+#include <partition.h>
+#include <platform.h>
+#include <string.h>
+
+static uint8_t mbr_sector[PARTITION_BLOCK_SIZE];
+partition_entry_list_t list;
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+static void dump_entries(int num)
+{
+	char name[EFI_NAMELEN];
+	int i, j, len;
+
+	VERBOSE("Partition table with %d entries:\n", num);
+	for (i = 0; i < num; i++) {
+		len = snprintf(name, EFI_NAMELEN, "%s", list.list[i].name);
+		for (j = 0; j < EFI_NAMELEN - len - 1; j++) {
+			name[len + j] = ' ';
+		}
+		name[EFI_NAMELEN - 1] = '\0';
+		VERBOSE("%d: %s %lx-%lx\n", i + 1, name, list.list[i].start,
+			list.list[i].start + list.list[i].length - 4);
+	}
+}
+#else
+#define dump_entries(num)	((void)num)
+#endif
+
+/*
+ * Load the first sector that carries MBR header.
+ * The MBR boot signature should be always valid whether it's MBR or GPT.
+ */
+static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry)
+{
+	size_t bytes_read;
+	uintptr_t offset;
+	int result;
+
+	assert(mbr_entry != NULL);
+	/* MBR partition table is in LBA0. */
+	result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
+	if (result != 0) {
+		WARN("Failed to seek (%i)\n", result);
+		return result;
+	}
+	result = io_read(image_handle, (uintptr_t)&mbr_sector,
+			 PARTITION_BLOCK_SIZE, &bytes_read);
+	if (result != 0) {
+		WARN("Failed to read data (%i)\n", result);
+		return result;
+	}
+
+	/* Check MBR boot signature. */
+	if ((mbr_sector[PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
+	    (mbr_sector[PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
+		return -ENOENT;
+	}
+	offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET;
+	memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));
+	return 0;
+}
+
+/*
+ * Load GPT header and check the GPT signature.
+ * If partiton numbers could be found, check & update it.
+ */
+static int load_gpt_header(uintptr_t image_handle)
+{
+	gpt_header_t header;
+	size_t bytes_read;
+	int result;
+
+	result = io_seek(image_handle, IO_SEEK_SET, GPT_HEADER_OFFSET);
+	if (result != 0) {
+		return result;
+	}
+	result = io_read(image_handle, (uintptr_t)&header,
+			 sizeof(gpt_header_t), &bytes_read);
+	if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) {
+		return result;
+	}
+	if (memcmp(header.signature, GPT_SIGNATURE,
+		   sizeof(header.signature)) != 0) {
+		return -EINVAL;
+	}
+
+	/* partition numbers can't exceed PLAT_PARTITION_MAX_ENTRIES */
+	list.entry_count = header.list_num;
+	if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
+		list.entry_count = PLAT_PARTITION_MAX_ENTRIES;
+	}
+	return 0;
+}
+
+static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry)
+{
+	size_t bytes_read;
+	int result;
+
+	assert(entry != NULL);
+	result = io_read(image_handle, (uintptr_t)entry, sizeof(gpt_entry_t),
+			 &bytes_read);
+	if (sizeof(gpt_entry_t) != bytes_read)
+		return -EINVAL;
+	return result;
+}
+
+static int verify_partition_gpt(uintptr_t image_handle)
+{
+	gpt_entry_t entry;
+	int result, i;
+
+	for (i = 0; i < list.entry_count; i++) {
+		result = load_gpt_entry(image_handle, &entry);
+		assert(result == 0);
+		result = parse_gpt_entry(&entry, &list.list[i]);
+		if (result != 0) {
+			break;
+		}
+	}
+	if (i == 0) {
+		return -EINVAL;
+	}
+	/*
+	 * Only records the valid partition number that is loaded from
+	 * partition table.
+	 */
+	list.entry_count = i;
+	dump_entries(list.entry_count);
+
+	return 0;
+}
+
+int load_partition_table(unsigned int image_id)
+{
+	uintptr_t dev_handle, image_handle, image_spec = 0;
+	mbr_entry_t mbr_entry;
+	int result;
+
+	result = plat_get_image_source(image_id, &dev_handle, &image_spec);
+	if (result != 0) {
+		WARN("Failed to obtain reference to image id=%u (%i)\n",
+			image_id, result);
+		return result;
+	}
+
+	result = io_open(dev_handle, image_spec, &image_handle);
+	if (result != 0) {
+		WARN("Failed to access image id=%u (%i)\n", image_id, result);
+		return result;
+	}
+
+	result = load_mbr_header(image_handle, &mbr_entry);
+	if (result != 0) {
+		WARN("Failed to access image id=%u (%i)\n", image_id, result);
+		return result;
+	}
+	if (mbr_entry.type == PARTITION_TYPE_GPT) {
+		result = load_gpt_header(image_handle);
+		assert(result == 0);
+		result = io_seek(image_handle, IO_SEEK_SET, GPT_ENTRY_OFFSET);
+		assert(result == 0);
+		result = verify_partition_gpt(image_handle);
+	} else {
+		/* MBR type isn't supported yet. */
+		result = -EINVAL;
+		goto exit;
+	}
+exit:
+	io_close(image_handle);
+	return result;
+}
+
+const partition_entry_t *get_partition_entry(const char *name)
+{
+	int i;
+
+	for (i = 0; i < list.entry_count; i++) {
+		if (strcmp(name, list.list[i].name) == 0) {
+			return &list.list[i];
+		}
+	}
+	return NULL;
+}
+
+const partition_entry_list_t *get_partition_entry_list(void)
+{
+	return &list;
+}
+
+void partition_init(unsigned int image_id)
+{
+	load_partition_table(image_id);
+}
diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dtb b/fdts/fvp-base-gicv2-psci-aarch32.dtb
new file mode 100644
index 0000000..b044a76
--- /dev/null
+++ b/fdts/fvp-base-gicv2-psci-aarch32.dtb
Binary files differ
diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dts b/fdts/fvp-base-gicv2-psci-aarch32.dts
new file mode 100644
index 0000000..3a6007d
--- /dev/null
+++ b/fdts/fvp-base-gicv2-psci-aarch32.dts
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Base";
+	compatible = "arm,vfp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0x84000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0x84000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+				core1 {
+					cpu = <&CPU5>;
+				};
+				core2 {
+					cpu = <&CPU6>;
+				};
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU4:cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x100>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU5:cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x101>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU6:cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x102>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU7:cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x103>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		L2_0: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,
+		      <0x0 0x2c000000 0 0x2000>,
+		      <0x0 0x2c010000 0 0x2000>,
+		      <0x0 0x2c02F000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		/include/ "rtsm_ve-motherboard.dtsi"
+	};
+
+	panels {
+		panel@0 {
+			compatible	= "panel";
+			mode		= "XVGA";
+			refresh		= <60>;
+			xres		= <1024>;
+			yres		= <768>;
+			pixclock	= <15748>;
+			left_margin	= <152>;
+			right_margin	= <48>;
+			upper_margin	= <23>;
+			lower_margin	= <3>;
+			hsync_len	= <104>;
+			vsync_len	= <4>;
+			sync		= <0>;
+			vmode		= "FB_VMODE_NONINTERLACED";
+			tim2		= "TIM2_BCD", "TIM2_IPC";
+			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
+			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
+			bpp		= <16>;
+		};
+	};
+};
diff --git a/fdts/fvp-base-gicv3-psci-aarch32.dtb b/fdts/fvp-base-gicv3-psci-aarch32.dtb
new file mode 100644
index 0000000..474b188
--- /dev/null
+++ b/fdts/fvp-base-gicv3-psci-aarch32.dtb
Binary files differ
diff --git a/fdts/fvp-base-gicv3-psci-aarch32.dts b/fdts/fvp-base-gicv3-psci-aarch32.dts
new file mode 100644
index 0000000..ab69915
--- /dev/null
+++ b/fdts/fvp-base-gicv3-psci-aarch32.dts
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+};
+
+/ {
+	model = "FVP Base";
+	compatible = "arm,vfp-base", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
+		method = "smc";
+		cpu_suspend = <0x84000001>;
+		cpu_off = <0x84000002>;
+		cpu_on = <0x84000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+				core2 {
+					cpu = <&CPU2>;
+				};
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+				core1 {
+					cpu = <&CPU5>;
+				};
+				core2 {
+					cpu = <&CPU6>;
+				};
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <40>;
+				exit-latency-us = <100>;
+				min-residency-us = <150>;
+			};
+
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x1010000>;
+				entry-latency-us = <500>;
+				exit-latency-us = <1000>;
+				min-residency-us = <2500>;
+			};
+		};
+
+		CPU0:cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU1:cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x1>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU2:cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x2>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU3:cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x3>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU4:cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x100>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU5:cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x101>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU6:cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x102>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		CPU7:cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x103>;
+			enable-method = "psci";
+			cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>;
+			next-level-cache = <&L2_0>;
+		};
+
+		L2_0: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x7F000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2f000000 {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		interrupt-controller;
+		reg = <0x0 0x2f000000 0 0x10000>,	// GICD
+		      <0x0 0x2f100000 0 0x200000>,	// GICR
+		      <0x0 0x2c000000 0 0x2000>,	// GICC
+		      <0x0 0x2c010000 0 0x2000>,	// GICH
+		      <0x0 0x2c02f000 0 0x2000>;	// GICV
+		interrupts = <1 9 4>;
+
+		its: its@2f020000 {
+			compatible = "arm,gic-v3-its";
+			msi-controller;
+			reg = <0x0 0x2f020000 0x0 0x20000>; // GITS
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	timer@2a810000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x2a810000 0x0 0x10000>;
+			clock-frequency = <100000000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			frame@2a830000 {
+				frame-number = <1>;
+				interrupts = <0 26 4>;
+				reg = <0x0 0x2a830000 0x0 0x10000>;
+			};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0 0 0  0 4>,
+				<0 0  1 &gic 0 0 0  1 4>,
+				<0 0  2 &gic 0 0 0  2 4>,
+				<0 0  3 &gic 0 0 0  3 4>,
+				<0 0  4 &gic 0 0 0  4 4>,
+				<0 0  5 &gic 0 0 0  5 4>,
+				<0 0  6 &gic 0 0 0  6 4>,
+				<0 0  7 &gic 0 0 0  7 4>,
+				<0 0  8 &gic 0 0 0  8 4>,
+				<0 0  9 &gic 0 0 0  9 4>,
+				<0 0 10 &gic 0 0 0 10 4>,
+				<0 0 11 &gic 0 0 0 11 4>,
+				<0 0 12 &gic 0 0 0 12 4>,
+				<0 0 13 &gic 0 0 0 13 4>,
+				<0 0 14 &gic 0 0 0 14 4>,
+				<0 0 15 &gic 0 0 0 15 4>,
+				<0 0 16 &gic 0 0 0 16 4>,
+				<0 0 17 &gic 0 0 0 17 4>,
+				<0 0 18 &gic 0 0 0 18 4>,
+				<0 0 19 &gic 0 0 0 19 4>,
+				<0 0 20 &gic 0 0 0 20 4>,
+				<0 0 21 &gic 0 0 0 21 4>,
+				<0 0 22 &gic 0 0 0 22 4>,
+				<0 0 23 &gic 0 0 0 23 4>,
+				<0 0 24 &gic 0 0 0 24 4>,
+				<0 0 25 &gic 0 0 0 25 4>,
+				<0 0 26 &gic 0 0 0 26 4>,
+				<0 0 27 &gic 0 0 0 27 4>,
+				<0 0 28 &gic 0 0 0 28 4>,
+				<0 0 29 &gic 0 0 0 29 4>,
+				<0 0 30 &gic 0 0 0 30 4>,
+				<0 0 31 &gic 0 0 0 31 4>,
+				<0 0 32 &gic 0 0 0 32 4>,
+				<0 0 33 &gic 0 0 0 33 4>,
+				<0 0 34 &gic 0 0 0 34 4>,
+				<0 0 35 &gic 0 0 0 35 4>,
+				<0 0 36 &gic 0 0 0 36 4>,
+				<0 0 37 &gic 0 0 0 37 4>,
+				<0 0 38 &gic 0 0 0 38 4>,
+				<0 0 39 &gic 0 0 0 39 4>,
+				<0 0 40 &gic 0 0 0 40 4>,
+				<0 0 41 &gic 0 0 0 41 4>,
+				<0 0 42 &gic 0 0 0 42 4>;
+
+		/include/ "rtsm_ve-motherboard.dtsi"
+	};
+
+	panels {
+		panel@0 {
+			compatible	= "panel";
+			mode		= "XVGA";
+			refresh		= <60>;
+			xres		= <1024>;
+			yres		= <768>;
+			pixclock	= <15748>;
+			left_margin	= <152>;
+			right_margin	= <48>;
+			upper_margin	= <23>;
+			lower_margin	= <3>;
+			hsync_len	= <104>;
+			vsync_len	= <4>;
+			sync		= <0>;
+			vmode		= "FB_VMODE_NONINTERLACED";
+			tim2		= "TIM2_BCD", "TIM2_IPC";
+			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
+			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
+			bpp		= <16>;
+		};
+	};
+};
diff --git a/fdts/fvp-base-gicv3-psci.dtb b/fdts/fvp-base-gicv3-psci.dtb
index 0acbe17..e175bf0 100644
--- a/fdts/fvp-base-gicv3-psci.dtb
+++ b/fdts/fvp-base-gicv3-psci.dtb
Binary files differ
diff --git a/fdts/fvp-base-gicv3-psci.dts b/fdts/fvp-base-gicv3-psci.dts
index 5d54dbf..57f3516 100644
--- a/fdts/fvp-base-gicv3-psci.dts
+++ b/fdts/fvp-base-gicv3-psci.dts
@@ -57,6 +57,8 @@
 		cpu_suspend = <0xc4000001>;
 		cpu_off = <0x84000002>;
 		cpu_on = <0xc4000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
 	};
 
 	cpus {
@@ -310,7 +312,7 @@
 				<0 0 41 &gic 0 0 0 41 4>,
 				<0 0 42 &gic 0 0 0 42 4>;
 
-		/include/ "rtsm_ve-motherboard-no_psci.dtsi"
+		/include/ "rtsm_ve-motherboard.dtsi"
 	};
 
 	panels {
diff --git a/fdts/fvp-foundation-gicv3-psci.dtb b/fdts/fvp-foundation-gicv3-psci.dtb
index 4402436..34bf8db 100644
--- a/fdts/fvp-foundation-gicv3-psci.dtb
+++ b/fdts/fvp-foundation-gicv3-psci.dtb
Binary files differ
diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts
index 45c699a..2c84559 100644
--- a/fdts/fvp-foundation-gicv3-psci.dts
+++ b/fdts/fvp-foundation-gicv3-psci.dts
@@ -57,6 +57,8 @@
 		cpu_suspend = <0xc4000001>;
 		cpu_off = <0x84000002>;
 		cpu_on = <0xc4000003>;
+		sys_poweroff = <0x84000008>;
+		sys_reset = <0x84000009>;
 	};
 
 	cpus {
@@ -259,6 +261,6 @@
 				<0 0 41 &gic 0 0 0 41 4>,
 				<0 0 42 &gic 0 0 0 42 4>;
 
-		/include/ "fvp-foundation-motherboard-no_psci.dtsi"
+		/include/ "fvp-foundation-motherboard.dtsi"
 	};
 };
diff --git a/fdts/fvp-foundation-motherboard-no_psci.dtsi b/fdts/fvp-foundation-motherboard-no_psci.dtsi
deleted file mode 100644
index fd41c8a..0000000
--- a/fdts/fvp-foundation-motherboard-no_psci.dtsi
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the ARM nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-	motherboard {
-		arm,v2m-memory-map = "rs1";
-		compatible = "arm,vexpress,v2m-p1", "simple-bus";
-		#address-cells = <2>; /* SMB chipselect number and offset */
-		#size-cells = <1>;
-		#interrupt-cells = <1>;
-		ranges;
-
-		ethernet@2,02000000 {
-			compatible = "smsc,lan91c111";
-			reg = <2 0x02000000 0x10000>;
-			interrupts = <15>;
-		};
-
-		v2m_clk24mhz: clk24mhz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <24000000>;
-			clock-output-names = "v2m:clk24mhz";
-		};
-
-		v2m_refclk1mhz: refclk1mhz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <1000000>;
-			clock-output-names = "v2m:refclk1mhz";
-		};
-
-		v2m_refclk32khz: refclk32khz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <32768>;
-			clock-output-names = "v2m:refclk32khz";
-		};
-
-		iofpga@3,00000000 {
-			compatible = "arm,amba-bus", "simple-bus";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 3 0 0x200000>;
-
-			v2m_sysreg: sysreg@010000 {
-				compatible = "arm,vexpress-sysreg";
-				reg = <0x010000 0x1000>;
-				gpio-controller;
-				#gpio-cells = <2>;
-			};
-
-			v2m_sysctl: sysctl@020000 {
-				compatible = "arm,sp810", "arm,primecell";
-				reg = <0x020000 0x1000>;
-				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
-				clock-names = "refclk", "timclk", "apb_pclk";
-				#clock-cells = <1>;
-				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
-			};
-
-			v2m_serial0: uart@090000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x090000 0x1000>;
-				interrupts = <5>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial1: uart@0a0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0a0000 0x1000>;
-				interrupts = <6>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial2: uart@0b0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0b0000 0x1000>;
-				interrupts = <7>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial3: uart@0c0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0c0000 0x1000>;
-				interrupts = <8>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			wdt@0f0000 {
-				compatible = "arm,sp805", "arm,primecell";
-				reg = <0x0f0000 0x1000>;
-				interrupts = <0>;
-				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
-				clock-names = "wdogclk", "apb_pclk";
-			};
-
-			v2m_timer01: timer@110000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x110000 0x1000>;
-				interrupts = <2>;
-				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
-
-			v2m_timer23: timer@120000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x120000 0x1000>;
-				interrupts = <3>;
-				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
-
-			rtc@170000 {
-				compatible = "arm,pl031", "arm,primecell";
-				reg = <0x170000 0x1000>;
-				interrupts = <4>;
-				clocks = <&v2m_clk24mhz>;
-				clock-names = "apb_pclk";
-			};
-
-			virtio_block@0130000 {
-				compatible = "virtio,mmio";
-				reg = <0x130000 0x1000>;
-				interrupts = <0x2a>;
-			};
-		};
-
-		v2m_fixed_3v3: fixedregulator@0 {
-			compatible = "regulator-fixed";
-			regulator-name = "3V3";
-			regulator-min-microvolt = <3300000>;
-			regulator-max-microvolt = <3300000>;
-			regulator-always-on;
-		};
-
-
-		mcc {
-			compatible = "arm,vexpress,config-bus", "simple-bus";
-			arm,vexpress,config-bridge = <&v2m_sysreg>;
-
-			reset@0 {
-				compatible = "arm,vexpress-reset";
-				arm,vexpress-sysreg,func = <5 0>;
-			};
-
-			muxfpga@0 {
-				compatible = "arm,vexpress-muxfpga";
-				arm,vexpress-sysreg,func = <7 0>;
-			};
-
-			shutdown@0 {
-				compatible = "arm,vexpress-shutdown";
-				arm,vexpress-sysreg,func = <8 0>;
-			};
-
-			reboot@0 {
-				compatible = "arm,vexpress-reboot";
-				arm,vexpress-sysreg,func = <9 0>;
-			};
-
-			dvimode@0 {
-				compatible = "arm,vexpress-dvimode";
-				arm,vexpress-sysreg,func = <11 0>;
-			};
-		};
-	};
diff --git a/fdts/rtsm_ve-motherboard-no_psci.dtsi b/fdts/rtsm_ve-motherboard-no_psci.dtsi
deleted file mode 100644
index 7ba575e..0000000
--- a/fdts/rtsm_ve-motherboard-no_psci.dtsi
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of ARM nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-	motherboard {
-		arm,v2m-memory-map = "rs1";
-		compatible = "arm,vexpress,v2m-p1", "simple-bus";
-		#address-cells = <2>; /* SMB chipselect number and offset */
-		#size-cells = <1>;
-		#interrupt-cells = <1>;
-		ranges;
-
-		flash@0,00000000 {
-			compatible = "arm,vexpress-flash", "cfi-flash";
-			reg = <0 0x00000000 0x04000000>,
-			      <4 0x00000000 0x04000000>;
-			bank-width = <4>;
-		};
-
-		vram@2,00000000 {
-			compatible = "arm,vexpress-vram";
-			reg = <2 0x00000000 0x00800000>;
-		};
-
-		ethernet@2,02000000 {
-			compatible = "smsc,lan91c111";
-			reg = <2 0x02000000 0x10000>;
-			interrupts = <15>;
-		};
-
-		v2m_clk24mhz: clk24mhz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <24000000>;
-			clock-output-names = "v2m:clk24mhz";
-		};
-
-		v2m_refclk1mhz: refclk1mhz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <1000000>;
-			clock-output-names = "v2m:refclk1mhz";
-		};
-
-		v2m_refclk32khz: refclk32khz {
-			compatible = "fixed-clock";
-			#clock-cells = <0>;
-			clock-frequency = <32768>;
-			clock-output-names = "v2m:refclk32khz";
-		};
-
-		iofpga@3,00000000 {
-			compatible = "arm,amba-bus", "simple-bus";
-			#address-cells = <1>;
-			#size-cells = <1>;
-			ranges = <0 3 0 0x200000>;
-
-			v2m_sysreg: sysreg@010000 {
-				compatible = "arm,vexpress-sysreg";
-				reg = <0x010000 0x1000>;
-				gpio-controller;
-				#gpio-cells = <2>;
-			};
-
-			v2m_sysctl: sysctl@020000 {
-				compatible = "arm,sp810", "arm,primecell";
-				reg = <0x020000 0x1000>;
-				clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>;
-				clock-names = "refclk", "timclk", "apb_pclk";
-				#clock-cells = <1>;
-				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
-			};
-
-			aaci@040000 {
-				compatible = "arm,pl041", "arm,primecell";
-				reg = <0x040000 0x1000>;
-				interrupts = <11>;
-				clocks = <&v2m_clk24mhz>;
-				clock-names = "apb_pclk";
-			};
-
-			mmci@050000 {
-				compatible = "arm,pl180", "arm,primecell";
-				reg = <0x050000 0x1000>;
-				interrupts = <9 10>;
-				cd-gpios = <&v2m_sysreg 0 0>;
-				wp-gpios = <&v2m_sysreg 1 0>;
-				max-frequency = <12000000>;
-				vmmc-supply = <&v2m_fixed_3v3>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "mclk", "apb_pclk";
-			};
-
-			kmi@060000 {
-				compatible = "arm,pl050", "arm,primecell";
-				reg = <0x060000 0x1000>;
-				interrupts = <12>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "KMIREFCLK", "apb_pclk";
-			};
-
-			kmi@070000 {
-				compatible = "arm,pl050", "arm,primecell";
-				reg = <0x070000 0x1000>;
-				interrupts = <13>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "KMIREFCLK", "apb_pclk";
-			};
-
-			v2m_serial0: uart@090000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x090000 0x1000>;
-				interrupts = <5>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial1: uart@0a0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0a0000 0x1000>;
-				interrupts = <6>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial2: uart@0b0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0b0000 0x1000>;
-				interrupts = <7>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			v2m_serial3: uart@0c0000 {
-				compatible = "arm,pl011", "arm,primecell";
-				reg = <0x0c0000 0x1000>;
-				interrupts = <8>;
-				clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
-				clock-names = "uartclk", "apb_pclk";
-			};
-
-			wdt@0f0000 {
-				compatible = "arm,sp805", "arm,primecell";
-				reg = <0x0f0000 0x1000>;
-				interrupts = <0>;
-				clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>;
-				clock-names = "wdogclk", "apb_pclk";
-			};
-
-			v2m_timer01: timer@110000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x110000 0x1000>;
-				interrupts = <2>;
-				clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
-
-			v2m_timer23: timer@120000 {
-				compatible = "arm,sp804", "arm,primecell";
-				reg = <0x120000 0x1000>;
-				interrupts = <3>;
-				clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>;
-				clock-names = "timclken1", "timclken2", "apb_pclk";
-			};
-
-			rtc@170000 {
-				compatible = "arm,pl031", "arm,primecell";
-				reg = <0x170000 0x1000>;
-				interrupts = <4>;
-				clocks = <&v2m_clk24mhz>;
-				clock-names = "apb_pclk";
-			};
-
-			clcd@1f0000 {
-				compatible = "arm,pl111", "arm,primecell";
-				reg = <0x1f0000 0x1000>;
-				interrupts = <14>;
-				clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
-				clock-names = "clcdclk", "apb_pclk";
-				mode = "XVGA";
-				use_dma = <0>;
-				framebuffer = <0x18000000 0x00180000>;
-			};
-
-			virtio_block@0130000 {
-				compatible = "virtio,mmio";
-				reg = <0x130000 0x1000>;
-				interrupts = <0x2a>;
-			};
-		};
-
-		v2m_fixed_3v3: fixedregulator@0 {
-			compatible = "regulator-fixed";
-			regulator-name = "3V3";
-			regulator-min-microvolt = <3300000>;
-			regulator-max-microvolt = <3300000>;
-			regulator-always-on;
-		};
-
-		mcc {
-			compatible = "arm,vexpress,config-bus", "simple-bus";
-			arm,vexpress,config-bridge = <&v2m_sysreg>;
-
-			v2m_oscclk1: osc@1 {
-				/* CLCD clock */
-				compatible = "arm,vexpress-osc";
-				arm,vexpress-sysreg,func = <1 1>;
-				freq-range = <23750000 63500000>;
-				#clock-cells = <0>;
-				clock-output-names = "v2m:oscclk1";
-			};
-
-			reset@0 {
-				compatible = "arm,vexpress-reset";
-				arm,vexpress-sysreg,func = <5 0>;
-			};
-
-			muxfpga@0 {
-				compatible = "arm,vexpress-muxfpga";
-				arm,vexpress-sysreg,func = <7 0>;
-			};
-
-			shutdown@0 {
-				compatible = "arm,vexpress-shutdown";
-				arm,vexpress-sysreg,func = <8 0>;
-			};
-
-			reboot@0 {
-				compatible = "arm,vexpress-reboot";
-				arm,vexpress-sysreg,func = <9 0>;
-			};
-
-			dvimode@0 {
-				compatible = "arm,vexpress-dvimode";
-				arm,vexpress-sysreg,func = <11 0>;
-			};
-		};
-	};
diff --git a/include/drivers/partition/gpt.h b/include/drivers/partition/gpt.h
new file mode 100644
index 0000000..bd0a7f0
--- /dev/null
+++ b/include/drivers/partition/gpt.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __GPT_H__
+#define __GPT_H__
+
+#include <partition.h>
+
+#define PARTITION_TYPE_GPT		0xee
+#define GPT_HEADER_OFFSET		PARTITION_BLOCK_SIZE
+#define GPT_ENTRY_OFFSET		(GPT_HEADER_OFFSET +		\
+					 PARTITION_BLOCK_SIZE)
+#define GUID_LEN			16
+
+#define GPT_SIGNATURE			"EFI PART"
+
+typedef struct gpt_entry {
+	unsigned char		type_uuid[GUID_LEN];
+	unsigned char		unique_uuid[GUID_LEN];
+	unsigned long long	first_lba;
+	unsigned long long	last_lba;
+	unsigned long long	attr;
+	unsigned short		name[EFI_NAMELEN];
+} gpt_entry_t;
+
+typedef struct gpt_header {
+	unsigned char		signature[8];
+	unsigned int		revision;
+	unsigned int		size;
+	unsigned int		header_crc;
+	unsigned int		reserved;
+	unsigned long long	current_lba;
+	unsigned long long	backup_lba;
+	unsigned long long	first_lba;
+	unsigned long long	last_lba;
+	unsigned char		disk_uuid[16];
+	/* starting LBA of array of partition entries */
+	unsigned long long	part_lba;
+	/* number of partition entries in array */
+	unsigned int		list_num;
+	/* size of a single partition entry (usually 128) */
+	unsigned int		part_size;
+	unsigned int		part_crc;
+} gpt_header_t;
+
+int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry);
+
+#endif	/* __GPT_H__ */
diff --git a/include/drivers/partition/mbr.h b/include/drivers/partition/mbr.h
new file mode 100644
index 0000000..5287e28
--- /dev/null
+++ b/include/drivers/partition/mbr.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MBR_H__
+#define __MBR_H__
+
+#define MBR_OFFSET			0
+
+#define MBR_PRIMARY_ENTRY_OFFSET	0x1be
+#define MBR_PRIMARY_ENTRY_SIZE		0x10
+#define MBR_PRIMARY_ENTRY_NUMBER	4
+#define MBR_CHS_ADDRESS_LEN		3
+
+#define MBR_SIGNATURE_FIRST		0x55
+#define MBR_SIGNATURE_SECOND		0xAA
+
+typedef struct mbr_entry {
+	unsigned char		status;
+	unsigned char		first_sector[MBR_CHS_ADDRESS_LEN];
+	unsigned char		type;
+	unsigned char		last_sector[MBR_CHS_ADDRESS_LEN];
+	unsigned int		first_lba;
+	unsigned int		sector_nums;
+} mbr_entry_t;
+
+#endif	/* __MBR_H__ */
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
new file mode 100644
index 0000000..9d7221d
--- /dev/null
+++ b/include/drivers/partition/partition.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PARTITION_H__
+#define __PARTITION_H__
+
+#include <cassert.h>
+#include <types.h>
+
+#if !PLAT_PARTITION_MAX_ENTRIES
+# define PLAT_PARTITION_MAX_ENTRIES	128
+#endif	/* PLAT_PARTITION_MAX_ENTRIES */
+
+CASSERT(PLAT_PARTITION_MAX_ENTRIES <= 128, assert_plat_partition_max_entries);
+
+#define PARTITION_BLOCK_SIZE		512
+
+#define EFI_NAMELEN			36
+
+typedef struct partition_entry {
+	uint64_t		start;
+	uint64_t		length;
+	char			name[EFI_NAMELEN];
+} partition_entry_t;
+
+typedef struct partition_entry_list {
+	partition_entry_t	list[PLAT_PARTITION_MAX_ENTRIES];
+	int			entry_count;
+} partition_entry_list_t;
+
+int load_partition_table(unsigned int image_id);
+const partition_entry_t *get_partition_entry(const char *name);
+const partition_entry_list_t *get_partition_entry_list(void);
+void partition_init(unsigned int image_id);
+
+#endif	/* __PARTITION_H__ */
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index aba15df..4968e24 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -108,7 +108,7 @@
 
 /* SCTLR definitions */
 #define SCTLR_RES1	((1 << 23) | (1 << 22) | (1 << 11) | (1 << 4) | \
-			(1 << 3) | SCTLR_CP15BEN_BIT | SCTLR_NTWI_BIT | SCTLR_NTWE_BIT)
+			(1 << 3))
 #define SCTLR_M_BIT		(1 << 0)
 #define SCTLR_A_BIT		(1 << 1)
 #define SCTLR_C_BIT		(1 << 2)
@@ -128,7 +128,7 @@
 /* HSCTLR definitions */
 #define HSCTLR_RES1 	((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22)	\
 			| (1 << 18) | (1 << 16) | (1 << 11) | (1 << 4)	\
-			| (1 << 3) | HSCTLR_CP15BEN_BIT)
+			| (1 << 3))
 #define HSCTLR_M_BIT		(1 << 0)
 #define HSCTLR_A_BIT		(1 << 1)
 #define HSCTLR_C_BIT		(1 << 2)
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index fb8cbc0..bef6032 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -155,7 +155,10 @@
 #define SCTLR_A_BIT		(1 << 1)
 #define SCTLR_C_BIT		(1 << 2)
 #define SCTLR_SA_BIT		(1 << 3)
+#define SCTLR_CP15BEN_BIT	(1 << 5)
 #define SCTLR_I_BIT		(1 << 12)
+#define SCTLR_NTWI_BIT		(1 << 16)
+#define SCTLR_NTWE_BIT		(1 << 18)
 #define SCTLR_WXN_BIT		(1 << 19)
 #define SCTLR_EE_BIT		(1 << 25)
 
diff --git a/include/lib/el3_runtime/cpu_data.h b/include/lib/el3_runtime/cpu_data.h
index 910b153..3b00a5e 100644
--- a/include/lib/el3_runtime/cpu_data.h
+++ b/include/lib/el3_runtime/cpu_data.h
@@ -50,10 +50,20 @@
 
 #if CRASH_REPORTING
 #define CPU_DATA_LOG2SIZE		7
+#define CPU_DATA_CRASH_BUF_END		(CPU_DATA_CRASH_BUF_OFFSET + \
+						CPU_DATA_CRASH_BUF_SIZE)
 #else
 #define CPU_DATA_LOG2SIZE		6
+#define CPU_DATA_CRASH_BUF_END		CPU_DATA_CRASH_BUF_OFFSET
 #endif
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+/* Temporary space to store PMF timestamps from assembly code */
+#define CPU_DATA_PMF_TS_COUNT		1
+#define CPU_DATA_PMF_TS0_OFFSET		CPU_DATA_CRASH_BUF_END
+#define CPU_DATA_PMF_TS0_IDX		0
+#endif
+
 #ifndef __ASSEMBLY__
 
 #include <arch_helpers.h>
@@ -96,6 +106,9 @@
 #if CRASH_REPORTING
 	u_register_t crash_buf[CPU_DATA_CRASH_BUF_SIZE >> 3];
 #endif
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	uint64_t cpu_data_pmf_ts[CPU_DATA_PMF_TS_COUNT];
+#endif
 	struct psci_cpu_data psci_svc_cpu_data;
 #if PLAT_PCPU_DATA_SIZE
 	uint8_t platform_cpu_data[PLAT_PCPU_DATA_SIZE];
@@ -116,6 +129,12 @@
 		(cpu_data_t, cpu_ops_ptr),
 		assert_cpu_data_cpu_ops_ptr_offset_mismatch);
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+CASSERT(CPU_DATA_PMF_TS0_OFFSET == __builtin_offsetof
+		(cpu_data_t, cpu_data_pmf_ts[0]),
+		assert_cpu_data_pmf_ts0_offset_mismatch);
+#endif
+
 struct cpu_data *_cpu_data_by_index(uint32_t cpu_index);
 
 #ifndef AARCH32
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index 5f953b5..7c33387 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -75,6 +75,7 @@
 
 /* Following are the supported PMF service IDs */
 #define PMF_PSCI_STAT_SVC_ID	0
+#define PMF_RT_INSTR_SVC_ID	1
 
 #if ENABLE_PMF
 /*
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index bb4242c..e7fd275 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -33,6 +33,7 @@
 
 #include <arch_helpers.h>
 #include <assert.h>
+#include <bl_common.h>
 #include <platform.h>
 #include <pmf.h>
 #include <stdint.h>
diff --git a/include/lib/runtime_instr.h b/include/lib/runtime_instr.h
new file mode 100644
index 0000000..d409002
--- /dev/null
+++ b/include/lib/runtime_instr.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __RUNTIME_INSTR_H__
+#define __RUNTIME_INSTR_H__
+
+#define RT_INSTR_TOTAL_IDS		4
+#define RT_INSTR_ENTER_PSCI		0
+#define RT_INSTR_EXIT_PSCI		1
+#define RT_INSTR_ENTER_HW_LOW_PWR	2
+#define RT_INSTR_EXIT_HW_LOW_PWR	3
+
+#ifndef __ASSEMBLY__
+PMF_DECLARE_CAPTURE_TIMESTAMP(rt_instr_svc)
+PMF_DECLARE_GET_TIMESTAMP(rt_instr_svc)
+#endif /* __ASSEMBLY__ */
+
+#endif /* __RUNTIME_INSTR_H__ */
diff --git a/include/lib/stdlib/sys/uuid.h b/include/lib/stdlib/sys/uuid.h
index 5c4767b..d43b641 100644
--- a/include/lib/stdlib/sys/uuid.h
+++ b/include/lib/stdlib/sys/uuid.h
@@ -34,8 +34,6 @@
 #ifndef _SYS_UUID_H_
 #define _SYS_UUID_H_
 
-#include <sys/cdefs.h>
-
 /* Length of a node address (an IEEE 802 address). */
 #define	_UUID_NODE_LEN		6
 
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
new file mode 100644
index 0000000..640bbaf
--- /dev/null
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ARM_SIP_SVC_H__
+#define __ARM_SIP_SVC_H__
+
+/* SMC function IDs for SiP Service queries */
+
+#define ARM_SIP_SVC_CALL_COUNT		0x8200ff00
+#define ARM_SIP_SVC_UID			0x8200ff01
+/*					0x8200ff02 is reserved */
+#define ARM_SIP_SVC_VERSION		0x8200ff03
+
+/* ARM SiP Service Calls version numbers */
+#define ARM_SIP_SVC_VERSION_MAJOR		0x0
+#define ARM_SIP_SVC_VERSION_MINOR		0x1
+
+#endif /* __ARM_SIP_SVC_H__ */
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index bc5f9c4..02ae2a7 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -116,7 +116,12 @@
 	 */
 	if (security_state != SECURE) {
 		sctlr = EP_GET_EE(ep->h.attr) ? SCTLR_EE_BIT : 0;
-		sctlr |= SCTLR_RES1;
+		/*
+		 * In addition to SCTLR_RES1, set the CP15_BEN, nTWI & nTWE
+		 * bits that architecturally reset to 1.
+		 */
+		sctlr |= SCTLR_RES1 | SCTLR_CP15BEN_BIT |
+				SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
 		write_ctx_reg(reg_ctx, CTX_NS_SCTLR, sctlr);
 	}
 
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 4527aa3..4b5d0ee 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -143,8 +143,19 @@
 	sctlr_elx = EP_GET_EE(ep->h.attr) ? SCTLR_EE_BIT : 0;
 	if (GET_RW(ep->spsr) == MODE_RW_64)
 		sctlr_elx |= SCTLR_EL1_RES1;
-	else
+	else {
 		sctlr_elx |= SCTLR_AARCH32_EL1_RES1;
+		/*
+		 * If lower non-secure EL is AArch32, enable the CP15BEN, nTWI
+		 * & nTWI bits. This aligns with SCTLR initialization on
+		 * systems with an AArch32 EL3, where these bits
+		 * architecturally reset to 1.
+		 */
+		if (security_state != SECURE)
+			sctlr_elx |= SCTLR_CP15BEN_BIT | SCTLR_NTWI_BIT
+						| SCTLR_NTWE_BIT;
+	}
+
 	write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
 
 	if ((GET_RW(ep->spsr) == MODE_RW_64
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 23bd106..0a3a60a 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -33,6 +33,8 @@
 #include <assert.h>
 #include <debug.h>
 #include <platform.h>
+#include <pmf.h>
+#include <runtime_instr.h>
 #include <smcc.h>
 #include <string.h>
 #include "psci_private.h"
@@ -124,11 +126,23 @@
 			PMF_NO_CACHE_MAINT);
 #endif
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+		    RT_INSTR_ENTER_HW_LOW_PWR,
+		    PMF_NO_CACHE_MAINT);
+#endif
+
 		psci_plat_pm_ops->cpu_standby(cpu_pd_state);
 
 		/* Upon exit from standby, set the state back to RUN. */
 		psci_set_cpu_local_state(PSCI_LOCAL_STATE_RUN);
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+		    RT_INSTR_EXIT_HW_LOW_PWR,
+		    PMF_NO_CACHE_MAINT);
+#endif
+
 #if ENABLE_PSCI_STAT
 		/* Capture time-stamp after CPU standby */
 		PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR,
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 471141d..1cc6ede 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -33,6 +33,8 @@
 #include <assert.h>
 #include <debug.h>
 #include <platform.h>
+#include <pmf.h>
+#include <runtime_instr.h>
 #include <string.h>
 #include "psci_private.h"
 
@@ -153,6 +155,19 @@
 		dsbish();
 		inv_cpu_data(psci_svc_cpu_data.aff_info_state);
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+
+		/*
+		 * Update the timestamp with cache off.  We assume this
+		 * timestamp can only be read from the current CPU and the
+		 * timestamp cache line will be flushed before return to
+		 * normal world on wakeup.
+		 */
+		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+		    RT_INSTR_ENTER_HW_LOW_PWR,
+		    PMF_NO_CACHE_MAINT);
+#endif
+
 		if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi) {
 			/* This function must not return */
 			psci_plat_pm_ops->pwr_domain_pwr_down_wfi(&state_info);
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 0887e3b..10d2481 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -37,6 +37,8 @@
 #include <cpu_data.h>
 #include <debug.h>
 #include <platform.h>
+#include <pmf.h>
+#include <runtime_instr.h>
 #include <stddef.h>
 #include "psci_private.h"
 
@@ -212,6 +214,19 @@
 		return;
 
 	if (is_power_down_state) {
+#if ENABLE_RUNTIME_INSTRUMENTATION
+
+		/*
+		 * Update the timestamp with cache off.  We assume this
+		 * timestamp can only be read from the current CPU and the
+		 * timestamp cache line will be flushed before return to
+		 * normal world on wakeup.
+		 */
+		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+		    RT_INSTR_ENTER_HW_LOW_PWR,
+		    PMF_NO_CACHE_MAINT);
+#endif
+
 		/* The function calls below must not return */
 		if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi)
 			psci_plat_pm_ops->pwr_domain_pwr_down_wfi(state_info);
@@ -219,6 +234,12 @@
 			psci_power_down_wfi();
 	}
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+	    RT_INSTR_ENTER_HW_LOW_PWR,
+	    PMF_NO_CACHE_MAINT);
+#endif
+
 	/*
 	 * We will reach here if only retention/standby states have been
 	 * requested at multiple power levels. This means that the cpu
@@ -226,6 +247,12 @@
 	 */
 	wfi();
 
+#if ENABLE_RUNTIME_INSTRUMENTATION
+	PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+	    RT_INSTR_EXIT_HW_LOW_PWR,
+	    PMF_NO_CACHE_MAINT);
+#endif
+
 	/*
 	 * After we wake up from context retaining suspend, call the
 	 * context retaining suspend finisher.
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 98d7219..8f8d3fd 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -144,6 +144,11 @@
 				plat/common/aarch64/platform_mp_stack.S		\
 				plat/common/plat_psci_common.c
 
+ifeq (${ENABLE_PMF}, 1)
+BL31_SOURCES		+=	plat/arm/common/arm_sip_svc.c			\
+				lib/pmf/pmf_smc.c
+endif
+
 ifneq (${TRUSTED_BOARD_BOOT},0)
 
     # By default, ARM platforms use RSA keys
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
new file mode 100644
index 0000000..eb8ec9e
--- /dev/null
+++ b/plat/arm/common/arm_sip_svc.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arm_sip_svc.h>
+#include <debug.h>
+#include <pmf.h>
+#include <runtime_svc.h>
+#include <stdint.h>
+#include <uuid.h>
+
+
+/* ARM SiP Service UUID */
+DEFINE_SVC_UUID(arm_sip_svc_uid,
+		0xe2756d55, 0x3360, 0x4bb5, 0xbf, 0xf3,
+		0x62, 0x79, 0xfd, 0x11, 0x37, 0xff);
+
+static int arm_sip_setup(void)
+{
+	if (pmf_setup() != 0)
+		return 1;
+	return 0;
+}
+
+/*
+ * This function handles ARM defined SiP Calls
+ */
+static uintptr_t arm_sip_handler(unsigned int smc_fid,
+			u_register_t x1,
+			u_register_t x2,
+			u_register_t x3,
+			u_register_t x4,
+			void *cookie,
+			void *handle,
+			u_register_t flags)
+{
+	/*
+	 * Dispatch PMF calls to PMF SMC handler and return its return
+	 * value
+	 */
+	if (is_pmf_fid(smc_fid)) {
+		return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+				handle, flags);
+	}
+
+	switch (smc_fid) {
+	case ARM_SIP_SVC_CALL_COUNT:
+		/*
+		 * Return the number of SiP Service Calls. PMF is the only
+		 * SiP service implemented; so return number of PMF calls
+		 */
+		SMC_RET1(handle, PMF_NUM_SMC_CALLS);
+
+	case ARM_SIP_SVC_UID:
+		/* Return UID to the caller */
+		SMC_UUID_RET(handle, arm_sip_svc_uid);
+
+	case ARM_SIP_SVC_VERSION:
+		/* Return the version of current implementation */
+		SMC_RET2(handle, ARM_SIP_SVC_VERSION_MAJOR, ARM_SIP_SVC_VERSION_MINOR);
+
+	default:
+		WARN("Unimplemented ARM SiP Service Call: 0x%x \n", smc_fid);
+		SMC_RET1(handle, SMC_UNK);
+	}
+
+}
+
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+	arm_sip_svc,
+	OEN_SIP_START,
+	OEN_SIP_END,
+	SMC_TYPE_FAST,
+	arm_sip_setup,
+	arm_sip_handler
+);
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index d06d4cb..a93b526 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -67,7 +67,7 @@
 	 * Set the L2 Data RAM latency for Cortex-A72.
 	 * Set the L2 Tag RAM latency to for Cortex-A72.
 	 */
-	mov x0, #((2 << L2CTLR_DATA_RAM_LATENCY_SHIFT) |	\
+	mov x0, #((5 << L2CTLR_DATA_RAM_LATENCY_SHIFT) |	\
 			 (0x1 << 5))
 	msr	L2CTLR_EL1, x0
 	isb
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index 2dc70ec..e99db19 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -326,9 +326,16 @@
 {
 	int i;
 
-	for (i = 0; i < CRU_CLKSEL_COUNT; i++)
-		mmio_write_32((CRU_BASE + CRU_CLKSEL_CON(i)),
-			      REG_SOC_WMSK | slp_data.cru_clksel_con[i]);
+	for (i = 0; i < CRU_CLKSEL_COUNT; i++) {
+		/* CRU_CLKSEL_CON96~107 the high 16-bit isb't write_mask */
+		if (i > 95)
+			mmio_write_32((CRU_BASE + CRU_CLKSEL_CON(i)),
+				      slp_data.cru_clksel_con[i]);
+		else
+			mmio_write_32((CRU_BASE + CRU_CLKSEL_CON(i)),
+				      REG_SOC_WMSK |
+				      slp_data.cru_clksel_con[i]);
+	}
 	for (i = 0; i < PMUCRU_CLKSEL_CONUT; i++)
 		mmio_write_32((PMUCRU_BASE +
 			      PMUCRU_CLKSEL_OFFSET + i * REG_SIZE),
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h
index da4cb54..9693f57 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.h
+++ b/plat/rockchip/rk3399/drivers/soc/soc.h
@@ -64,8 +64,8 @@
 #define PLL_NO_BYPASS_MODE		WMSK_BIT(PLL_BYPASS_SHIFT)
 
 #define PLL_CON_COUNT			0x06
-#define CRU_CLKSEL_COUNT		0x108
-#define CRU_CLKSEL_CON(n)		(0x80 + (n) * 4)
+#define CRU_CLKSEL_COUNT		108
+#define CRU_CLKSEL_CON(n)		(0x100 + (n) * 4)
 
 #define PMUCRU_CLKSEL_CONUT		0x06
 #define PMUCRU_CLKSEL_OFFSET		0x080
diff --git a/readme.md b/readme.md
index cc2294b..d9a1714 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-ARM Trusted Firmware - version 1.2
+ARM Trusted Firmware - version 1.3
 ==================================
 
 ARM Trusted Firmware provides a reference implementation of secure world
@@ -17,17 +17,25 @@
 License
 -------
 
-The software is provided under a BSD 3-Clause [license]. Certain source files
-are derived from FreeBSD code: the original license is included in these
-source files.
+The software is provided under a BSD-3-Clause [license]. Contributions to this
+project are accepted under the same license with developer sign-off as
+described in the [Contributing Guidelines].
 
+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 libfdt source code is dual licensed. It is used by this project under
+    the terms of the BSD-2-Clause license.
+
 
 This Release
 ------------
 
 This release provides a suitable starting point for productization of secure
-world boot and runtime firmware. Future versions will contain new features,
-optimizations and quality improvements.
+world boot and runtime firmware, executing in either the AArch32 or AArch64
+execution state.
 
 Users are encouraged to do their own security validation, including penetration
 testing, on any secure world code derived from ARM Trusted Firmware.
@@ -42,7 +50,7 @@
 *   Library support for CPU specific reset and power down sequences. This
     includes support for errata workarounds.
 
-*   Drivers for both the version 2.0 and version 3.0 ARM Generic Interrupt
+*   Drivers for both versions 2.0 and 3.0 of the ARM Generic Interrupt
     Controller specifications (GICv2 and GICv3). The latter also enables GICv3
     hardware systems that do not contain legacy GICv2 support.
 
@@ -53,18 +61,26 @@
 *   SMC (Secure Monitor Call) handling, conforming to the [SMC Calling
     Convention][SMCCC] using an EL3 runtime services framework.
 
-*   SMC handling relating to [PSCI] for the Secondary CPU Boot, CPU Hotplug,
-    CPU Idle and System Shutdown/Reset/Suspend use-cases.
+*   [PSCI] library support for the Secondary CPU Boot, CPU Hotplug, CPU Idle
+    and System Shutdown/Reset/Suspend use-cases.
+    This library is pre-integrated with the provided AArch64 EL3 Runtime
+    Software, and is also suitable for integration into other EL3 Runtime
+    Software.
+
+*   A minimal AArch32 Secure Payload to demonstrate [PSCI] library integration
+    on platforms with AArch32 EL3 Runtime Software.
 
 *   Secure Monitor library code such as world switching, EL1 context management
-    and interrupt routing. This must be integrated with a Secure-EL1 Payload
-    Dispatcher (SPD) component to customize the interaction with a Secure-EL1
-    Payload (SP), for example a Secure OS.
+    and interrupt routing.
+    When using the provided AArch64 EL3 Runtime Software, this must be
+    integrated with a Secure-EL1 Payload Dispatcher (SPD) component to
+    customize the interaction with a Secure-EL1 Payload (SP), for example a
+    Secure OS.
 
-*   A Test Secure-EL1 Payload and Dispatcher to demonstrate Secure Monitor
-    functionality and Secure-EL1 interaction with PSCI.
+*   A Test Secure-EL1 Payload and Dispatcher to demonstrate AArch64 Secure
+    Monitor functionality and Secure-EL1 interaction with PSCI.
 
-*   SPDs for the [OP-TEE Secure OS] and [NVidia Trusted Little Kernel]
+*   AArch64 SPDs for the [OP-TEE Secure OS] and [NVidia Trusted Little Kernel]
     [NVidia TLK].
 
 *   A Trusted Board Boot implementation, conforming to all mandatory TBBR
@@ -72,11 +88,12 @@
     Firmware Update (or recovery mode) boot flow, and packaging of the various
     firmware images into a Firmware Image Package (FIP) to be loaded from
     non-volatile storage.
+    The TBBR implementation is currently only supported in the AArch64 build.
 
 *   Support for alternative boot flows. Some platforms have their own boot
-    firmware and only require the ARM Trusted Firmware Secure Monitor
-    functionality. Other platforms require minimal initialization before
-    booting into an arbitrary EL3 payload.
+    firmware and only require the AArch64 EL3 Runtime Software provided by this
+    project. Other platforms require minimal initialization before booting
+    into an arbitrary EL3 payload.
 
 For a full description of functionality and implementation details, please
 see the [Firmware Design] and supporting documentation. The [Change Log]
@@ -84,36 +101,46 @@
 
 ### Platforms
 
-This release of the Trusted Firmware has been tested on variants r0 and r1 of
-the [Juno ARM Development Platform] [Juno] with [Linaro Release 15.10]
-[Linaro Release Notes].
+The AArch64 build of this release has been tested on variants r0, r1 and r2
+of the [Juno ARM Development Platform] [Juno] with [Linaro Release 16.06].
 
-The Trusted Firmware has also been tested on the 64-bit Linux versions of the
-following ARM [FVP]s:
+The AArch64 build of this release has been tested on the following ARM
+[FVP]s (64-bit host machine only):
 
-*   `Foundation_Platform` (Version 9.4, Build 9.4.59)
-*   `FVP_Base_AEMv8A-AEMv8A` (Version 7.0, Build 0.8.7004)
-*   `FVP_Base_Cortex-A57x4-A53x4` (Version 7.0, Build 0.8.7004)
-*   `FVP_Base_Cortex-A57x1-A53x1` (Version 7.0, Build 0.8.7004)
-*   `FVP_Base_Cortex-A57x2-A53x4` (Version 7.0, Build 0.8.7004)
+*   `Foundation_Platform` (Version 10.1, Build 10.1.32)
+*   `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701)
+*   `FVP_Base_Cortex-A57x4-A53x4` (Version 7.7, Build 0.8.7701)
+*   `FVP_Base_Cortex-A57x1-A53x1` (Version 7.7, Build 0.8.7701)
+*   `FVP_Base_Cortex-A57x2-A53x4` (Version 7.7, Build 0.8.7701)
+
+The AArch32 build of this release has been tested on the following ARM
+[FVP]s (64-bit host machine only):
+
+*   `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701)
+*   `FVP_Base_Cortex-A32x4` (Version 10.1, Build 10.1.32)
 
 The Foundation FVP can be downloaded free of charge. The Base FVPs can be
 licensed from ARM: see [www.arm.com/fvp] [FVP].
 
 This release also contains the following platform support:
 
+*   MediaTek MT6795 and MT8173 SoCs
 *   NVidia T210 and T132 SoCs
-*   MediaTek MT8173 SoC
+*   QEMU emulator
+*   RockChip RK3368 and RK3399 SoCs
+*   Xilinx Zynq UltraScale + MPSoC
 
 ### Still to Come
 
-*   Complete implementation of the [PSCI] v1.0 specification.
-
-*   Support for new CPUs and System IP.
+*   AArch32 TBBR support and ongoing TBBR alignment.
 
 *   More platform support.
 
-*   Optimization and quality improvements.
+*   Ongoing support for new architectural features, CPUs and System IP.
+
+*   Ongoing [PSCI] alignment and feature support.
+
+*   Ongoing security hardening, optimization and quality improvements.
 
 For a full list of detailed issues in the current code, please see the [Change
 Log] and the [GitHub issue tracker].
@@ -147,7 +174,7 @@
 
 - - - - - - - - - - - - - - - - - - - - - - - - - -
 
-_Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved._
+_Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved._
 
 
 [License]:                  ./license.md "BSD license for ARM Trusted Firmware"
@@ -167,4 +194,4 @@
 [GitHub issue tracker]:  https://github.com/ARM-software/tf-issues/issues
 [OP-TEE Secure OS]:      https://github.com/OP-TEE/optee_os
 [NVidia TLK]:            http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
-[Linaro Release Notes]:  https://community.arm.com/docs/DOC-10952#jive_content_id_Linaro_Release_1510
+[Linaro Release 16.06]:  https://community.arm.com/docs/DOC-10952#jive_content_id_Linaro_Release_1606
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index e096601..97a9fbd 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -29,8 +29,11 @@
  */
 
 #include <assert.h>
+#include <cpu_data.h>
 #include <debug.h>
+#include <pmf.h>
 #include <psci.h>
+#include <runtime_instr.h>
 #include <runtime_svc.h>
 #include <smcc_helpers.h>
 #include <std_svc.h>
@@ -75,9 +78,25 @@
 	 * value
 	 */
 	if (is_psci_fid(smc_fid)) {
-		SMC_RET1(handle,
-			psci_smc_handler(smc_fid, x1, x2, x3, x4,
-					cookie, handle, flags));
+		uint64_t ret;
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+		PMF_WRITE_TIMESTAMP(rt_instr_svc,
+		    RT_INSTR_ENTER_PSCI,
+		    PMF_NO_CACHE_MAINT,
+		    get_cpu_data(cpu_data_pmf_ts[CPU_DATA_PMF_TS0_IDX]));
+#endif
+
+		ret = psci_smc_handler(smc_fid, x1, x2, x3, x4,
+		    cookie, handle, flags);
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+		PMF_CAPTURE_TIMESTAMP(rt_instr_svc,
+		    RT_INSTR_EXIT_PSCI,
+		    PMF_NO_CACHE_MAINT);
+#endif
+
+		SMC_RET1(handle, ret);
 	}
 
 	switch (smc_fid) {