Merge pull request #1136 from antonio-nino-diaz-arm/an/xlat-get-set-attr

Add APIs to get and modify attributes of memory regions
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index d868c53..cd9fe5c 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -162,6 +162,15 @@
 	stcopr	r0, SCR
 	isb
 
+	/*
+	 * Set PMCR.DP to 1 to prohibit cycle counting whilst in Secure Mode.
+	 * Also, the PMCR.LC field has an architecturally UNKNOWN value on reset
+	 * and so set to 1 as ARM has deprecated use of PMCR.LC=0.
+	 */
+	ldcopr	r0, PMCR
+	orr	r0, r0, #(PMCR_LC_BIT | PMCR_DP_BIT)
+	stcopr	r0, PMCR
+
 	ldr	r0, [r2, #SMC_CTX_GPREG_R0]	/* smc_fid */
 	/* Check whether an SMC64 is issued */
 	tst	r0, #(FUNCID_CC_MASK << FUNCID_CC_SHIFT)
@@ -210,6 +219,15 @@
 	stcopr	r0, SCR
 	isb
 
+	/*
+	 * Set PMCR.DP to 1 to prohibit cycle counting whilst in Secure Mode.
+	 * Also, the PMCR.LC field has an architecturally UNKNOWN value on reset
+	 * and so set to 1 as ARM has deprecated use of PMCR.LC=0.
+	 */
+	ldcopr	r0, PMCR
+	orr	r0, r0, #(PMCR_LC_BIT | PMCR_DP_BIT)
+	stcopr	r0, PMCR
+
 	push	{r2, r3}
 	bl	sp_min_fiq
 	pop	{r0, r3}
diff --git a/docs/firmware-design.rst b/docs/firmware-design.rst
index 997d29b..e16e9b8 100644
--- a/docs/firmware-design.rst
+++ b/docs/firmware-design.rst
@@ -886,10 +886,10 @@
 
 TODO: Provide design walkthrough of PSCI implementation.
 
-The PSCI v1.0 specification categorizes APIs as optional and mandatory. All the
-mandatory APIs in PSCI v1.0 and all the APIs in PSCI v0.2 draft specification
+The PSCI v1.1 specification categorizes APIs as optional and mandatory. All the
+mandatory APIs in PSCI v1.1, PSCI v1.0 and in PSCI v0.2 draft specification
 `Power State Coordination Interface PDD`_ are implemented. The table lists
-the PSCI v1.0 APIs and their support in generic code.
+the PSCI v1.1 APIs and their support in generic code.
 
 An API implementation might have a dependency on platform code e.g. CPU\_SUSPEND
 requires the platform to export a part of the implementation. Hence the level
@@ -898,9 +898,9 @@
 required support.
 
 +-----------------------------+-------------+-------------------------------+
-| PSCI v1.0 API               | Supported   | Comments                      |
+| PSCI v1.1 API               | Supported   | Comments                      |
 +=============================+=============+===============================+
-| ``PSCI_VERSION``            | Yes         | The version returned is 1.0   |
+| ``PSCI_VERSION``            | Yes         | The version returned is 1.1   |
 +-----------------------------+-------------+-------------------------------+
 | ``CPU_SUSPEND``             | Yes\*       |                               |
 +-----------------------------+-------------+-------------------------------+
@@ -936,6 +936,12 @@
 +-----------------------------+-------------+-------------------------------+
 | ``PSCI_STAT_COUNT``         | Yes\*       |                               |
 +-----------------------------+-------------+-------------------------------+
+| ``SYSTEM_RESET2``           | Yes\*       |                               |
++-----------------------------+-------------+-------------------------------+
+| ``MEM_PROTECT``             | Yes\*       |                               |
++-----------------------------+-------------+-------------------------------+
+| ``MEM_PROTECT_CHECK_RANGE`` | Yes\*       |                               |
++-----------------------------+-------------+-------------------------------+
 
 \*Note : These PSCI APIs require platform power management hooks to be
 registered with the generic PSCI code to be supported.
@@ -2425,7 +2431,7 @@
 References
 ----------
 
-.. [#] Trusted Board Boot Requirements CLIENT PDD (ARM DEN 0006B-5). Available
+.. [#] Trusted Board Boot Requirements CLIENT PDD (ARM DEN0006C-1). Available
        under NDA through your ARM account representative.
 .. [#] `Power State Coordination Interface PDD`_
 .. [#] `SMC Calling Convention PDD`_
diff --git a/docs/platform-migration-guide.rst b/docs/platform-migration-guide.rst
index 638033e..ca75546 100644
--- a/docs/platform-migration-guide.rst
+++ b/docs/platform-migration-guide.rst
@@ -158,6 +158,17 @@
         int (*validate_ns_entrypoint)(unsigned long ns_entrypoint);
         void (*get_sys_suspend_power_state)(
                         psci_power_state_t *req_state);
+        int (*get_pwr_lvl_state_idx)(plat_local_state_t pwr_domain_state,
+                                    int pwrlvl);
+        int (*translate_power_state_by_mpidr)(u_register_t mpidr,
+                                    unsigned int power_state,
+                                    psci_power_state_t *output_state);
+        int (*get_node_hw_state)(u_register_t mpidr, unsigned int power_level);
+        int (*mem_protect_chk)(uintptr_t base, u_register_t length);
+        int (*read_mem_protect)(int *val);
+        int (*write_mem_protect)(int val);
+        int (*system_reset2)(int is_vendor,
+                                int reset_type, u_register_t cookie);
     } plat_psci_ops_t;
 
 The description of these handlers can be found in the `Porting Guide <porting-guide.rst#user-content-function--plat_setup_psci_ops-mandatory>`__.
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 6c07b2e..cd3bcda 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -2271,6 +2271,44 @@
 Implementations are not expected to handle ``power_levels`` greater than
 ``PLAT_MAX_PWR_LVL``.
 
+plat\_psci\_ops.system\_reset2()
+................................
+
+This is an optional function. If implemented this function is
+called during the ``SYSTEM_RESET2`` call to perform a reset
+based on the first parameter ``reset_type`` as specified in
+`PSCI`_. The parameter ``cookie`` can be used to pass additional
+reset information. If the ``reset_type`` is not supported, the
+function must return ``PSCI_E_NOT_SUPPORTED``. For architectural
+resets, all failures must return ``PSCI_E_INVALID_PARAMETERS``
+and vendor reset can return other PSCI error codes as defined
+in `PSCI`_. On success this function will not return.
+
+plat\_psci\_ops.write\_mem\_protect()
+....................................
+
+This is an optional function. If implemented it enables or disables the
+``MEM_PROTECT`` functionality based on the value of ``val``.
+A non-zero value enables ``MEM_PROTECT`` and a value of zero
+disables it. Upon encountering failures it must return a negative value
+and on success it must return 0.
+
+plat\_psci\_ops.read\_mem\_protect()
+.....................................
+
+This is an optional function. If implemented it returns the current
+state of ``MEM_PROTECT`` via the ``val`` parameter.  Upon encountering
+failures it must return a negative value and on success it must
+return 0.
+
+plat\_psci\_ops.mem\_protect\_chk()
+...................................
+
+This is an optional function. If implemented it checks if a memory
+region defined by a base address ``base`` and with a size of ``length``
+bytes is protected by ``MEM_PROTECT``.  If the region is protected
+then it must return 0, otherwise it must return a negative number.
+
 Interrupt Management framework (in BL31)
 ----------------------------------------
 
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 67af425..7c0a980 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -1379,10 +1379,10 @@
 The latest version of the AArch64 build of ARM Trusted Firmware has been tested
 on the following ARM FVPs (64-bit host machine only).
 
-NOTE: Unless otherwise stated, the model version is Version 11.0 Build 11.0.34.
+NOTE: Unless otherwise stated, the model version is Version 11.1 Build 11.1.22.
 
 -  ``Foundation_Platform``
--  ``FVP_Base_AEMv8A-AEMv8A`` (Version 8.5, Build 0.8.8502)
+-  ``FVP_Base_AEMv8A-AEMv8A`` (Version 8.7, Build 0.8.8702)
 -  ``FVP_Base_Cortex-A35x4``
 -  ``FVP_Base_Cortex-A53x4``
 -  ``FVP_Base_Cortex-A57x4-A53x4``
@@ -1395,7 +1395,7 @@
 The latest version of the AArch32 build of ARM Trusted Firmware has been tested
 on the following ARM FVPs (64-bit host machine only).
 
--  ``FVP_Base_AEMv8A-AEMv8A`` (Version 8.5, Build 0.8.8502)
+-  ``FVP_Base_AEMv8A-AEMv8A`` (Version 8.7, Build 0.8.8702)
 -  ``FVP_Base_Cortex-A32x4``
 
 NOTE: The build numbers quoted above are those reported by launching the FVP
@@ -1414,7 +1414,7 @@
 CADI-compliant debugger (for example, ARM DS-5) can connect to and control its
 execution.
 
-NOTE: With FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
+NOTE: Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
 the internal synchronisation timings changed compared to older versions of the
 models. The models can be launched with ``-Q 100`` option if they are required
 to match the run time characteristics of the older versions.
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 5fbb83a..6c6d6a1 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -350,6 +350,8 @@
 #define PMCR_N_SHIFT		11
 #define PMCR_N_MASK		0x1f
 #define PMCR_N_BITS		(PMCR_N_MASK << PMCR_N_SHIFT)
+#define PMCR_LC_BIT		(1 << 6)
+#define PMCR_DP_BIT		(1 << 5)
 
 /*******************************************************************************
  * Definitions of register offsets, fields and macros for CPU system
diff --git a/include/lib/aarch32/smcc_helpers.h b/include/lib/aarch32/smcc_helpers.h
index 1bc8438..53f1aa4 100644
--- a/include/lib/aarch32/smcc_helpers.h
+++ b/include/lib/aarch32/smcc_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,7 +21,8 @@
 #define SMC_CTX_SP_MON		0x7C
 #define SMC_CTX_LR_MON		0x80
 #define SMC_CTX_SCR		0x84
-#define SMC_CTX_SIZE		0x88
+#define SMC_CTX_PMCR		0x88
+#define SMC_CTX_SIZE		0x8C
 
 #ifndef __ASSEMBLY__
 #include <cassert.h>
@@ -73,6 +74,7 @@
 	u_register_t sp_mon;
 	u_register_t lr_mon;
 	u_register_t scr;
+	u_register_t pmcr;
 } smc_ctx_t;
 
 /*
diff --git a/include/lib/aarch32/smcc_macros.S b/include/lib/aarch32/smcc_macros.S
index 7edf410..cf26175 100644
--- a/include/lib/aarch32/smcc_macros.S
+++ b/include/lib/aarch32/smcc_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,6 +13,8 @@
  * spsr, lr, sp registers and the `scr` register to the SMC context on entry
  * due a SMC call. The `lr` of the current mode (monitor) is expected to be
  * already saved. The `sp` must point to the `smc_ctx_t` to save to.
+ * Additionally, also save the 'pmcr' register as this is updated whilst
+ * executing in the secure world.
  */
 	.macro smcc_save_gp_mode_regs
 	/* Save r0 - r12 in the SMC context */
@@ -46,6 +48,8 @@
 	/* lr_mon is already saved by caller */
 	ldcopr	r4, SCR
 	str	r4, [sp, #SMC_CTX_SCR]
+	ldcopr	r4, PMCR
+	str	r4, [sp, #SMC_CTX_PMCR]
 	.endm
 
 /*
@@ -70,6 +74,12 @@
 	stcopr	r1, SCR
 	isb
 
+	/*
+	 * Restore the PMCR register.
+	 */
+	ldr	r1, [r0, #SMC_CTX_PMCR]
+	stcopr	r1, PMCR
+
 	/* Restore the banked registers including the current SPSR */
 	add	r1, r0, #SMC_CTX_SP_USR
 	ldm	r1!, {r4-r12}
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index f85e789..9cbe405 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -502,9 +502,14 @@
 #define CNTACR_RWPT_SHIFT	U(0x5)
 
 /* PMCR_EL0 definitions */
+#define PMCR_EL0_RESET_VAL	U(0x0)
 #define PMCR_EL0_N_SHIFT	U(11)
 #define PMCR_EL0_N_MASK		U(0x1f)
 #define PMCR_EL0_N_BITS		(PMCR_EL0_N_MASK << PMCR_EL0_N_SHIFT)
+#define PMCR_EL0_LC_BIT		(U(1) << 6)
+#define PMCR_EL0_DP_BIT		(U(1) << 5)
+#define PMCR_EL0_X_BIT		(U(1) << 4)
+#define PMCR_EL0_D_BIT		(U(1) << 3)
 
 /*******************************************************************************
  * Definitions of MAIR encodings for device and normal memory
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 5d20ce9..04b2e03 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -31,11 +31,8 @@
 	__asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v));	\
 }
 
-#define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name)		\
-static inline void write_ ## _name(const uint64_t v)			\
-{									\
-	__asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v));	\
-}
+#define SYSREG_WRITE_CONST(reg_name, v)				\
+	__asm__ volatile ("msr " #reg_name ", %0" : : "i" (v))
 
 /* Define read function for system register */
 #define DEFINE_SYSREG_READ_FUNC(_name) 			\
@@ -59,11 +56,6 @@
 #define DEFINE_RENAME_SYSREG_WRITE_FUNC(_name, _reg_name)	\
 	_DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name)
 
-/* Define write function for special system registers */
-#define DEFINE_SYSREG_WRITE_CONST_FUNC(_name)		\
-	_DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _name)
-
-
 /**********************************************************************
  * Macros to create inline functions for system instructions
  *********************************************************************/
@@ -180,8 +172,8 @@
  * Misc. accessor prototypes
  ******************************************************************************/
 
-DEFINE_SYSREG_WRITE_CONST_FUNC(daifset)
-DEFINE_SYSREG_WRITE_CONST_FUNC(daifclr)
+#define write_daifclr(val) SYSREG_WRITE_CONST(daifclr, val)
+#define write_daifset(val) SYSREG_WRITE_CONST(daifset, val)
 
 DEFINE_SYSREG_READ_FUNC(par_el1)
 DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
@@ -309,7 +301,7 @@
 DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
 DEFINE_SYSREG_RW_FUNCS(hstr_el2)
 DEFINE_SYSREG_RW_FUNCS(cnthp_ctl_el2)
-DEFINE_SYSREG_READ_FUNC(pmcr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index dcbf1c9..a89468d 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -87,22 +87,23 @@
 #define CTX_AFSR1_EL1		U(0x98)
 #define CTX_CONTEXTIDR_EL1	U(0xa0)
 #define CTX_VBAR_EL1		U(0xa8)
+#define CTX_PMCR_EL0		U(0xb0)
 
 /*
  * If the platform is AArch64-only, there is no need to save and restore these
  * AArch32 registers.
  */
 #if CTX_INCLUDE_AARCH32_REGS
-#define CTX_SPSR_ABT		U(0xb0)
-#define CTX_SPSR_UND		U(0xb8)
-#define CTX_SPSR_IRQ		U(0xc0)
-#define CTX_SPSR_FIQ		U(0xc8)
-#define CTX_DACR32_EL2		U(0xd0)
-#define CTX_IFSR32_EL2		U(0xd8)
-#define CTX_FP_FPEXC32_EL2	U(0xe0)
-#define CTX_TIMER_SYSREGS_OFF		U(0xf0) /* Align to the next 16 byte boundary */
+#define CTX_SPSR_ABT		U(0xc0)  /* Align to the next 16 byte boundary */
+#define CTX_SPSR_UND		U(0xc8)
+#define CTX_SPSR_IRQ		U(0xd0)
+#define CTX_SPSR_FIQ		U(0xd8)
+#define CTX_DACR32_EL2		U(0xe0)
+#define CTX_IFSR32_EL2		U(0xe8)
+#define CTX_FP_FPEXC32_EL2	U(0xf0)
+#define CTX_TIMER_SYSREGS_OFF	U(0x100) /* Align to the next 16 byte boundary */
 #else
-#define CTX_TIMER_SYSREGS_OFF		U(0xb0)
+#define CTX_TIMER_SYSREGS_OFF	U(0xc0)  /* Align to the next 16 byte boundary */
 #endif /* __CTX_INCLUDE_AARCH32_REGS__ */
 
 /*
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 0b44ab2..06434f9 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -65,6 +65,8 @@
 #define PSCI_STAT_RESIDENCY_AARCH64	U(0xc4000010)
 #define PSCI_STAT_COUNT_AARCH32		U(0x84000011)
 #define PSCI_STAT_COUNT_AARCH64		U(0xc4000011)
+#define PSCI_SYSTEM_RESET2_AARCH32	U(0x84000012)
+#define PSCI_SYSTEM_RESET2_AARCH64	U(0xc4000012)
 #define PSCI_MEM_PROTECT		U(0x84000013)
 #define PSCI_MEM_CHK_RANGE_AARCH32	U(0x84000014)
 #define PSCI_MEM_CHK_RANGE_AARCH64	U(0xc4000014)
@@ -149,7 +151,7 @@
  * PSCI version
  ******************************************************************************/
 #define PSCI_MAJOR_VER		(U(1) << 16)
-#define PSCI_MINOR_VER		U(0x0)
+#define PSCI_MINOR_VER		U(0x1)
 
 /*******************************************************************************
  * PSCI error codes
@@ -167,6 +169,14 @@
 
 #define PSCI_INVALID_MPIDR	~((u_register_t)0)
 
+/*
+ * SYSTEM_RESET2 macros
+ */
+#define PSCI_RESET2_TYPE_VENDOR_SHIFT	31
+#define PSCI_RESET2_TYPE_VENDOR		(1U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
+#define PSCI_RESET2_TYPE_ARCH		(0U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
+#define PSCI_RESET2_SYSTEM_WARM_RESET	(PSCI_RESET2_TYPE_ARCH | 0)
+
 #ifndef __ASSEMBLY__
 
 #include <stdint.h>
@@ -294,6 +304,8 @@
 	int (*mem_protect_chk)(uintptr_t base, u_register_t length);
 	int (*read_mem_protect)(int *val);
 	int (*write_mem_protect)(int val);
+	int (*system_reset2)(int is_vendor,
+				int reset_type, u_register_t cookie);
 } plat_psci_ops_t;
 
 /*******************************************************************************
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 8a6c11b..db16a9f 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -74,6 +74,9 @@
 	mrs	x9, vbar_el1
 	stp	x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
 
+	mrs	x10, pmcr_el0
+	str	x10, [x0, #CTX_PMCR_EL0]
+
 	/* Save AArch32 system registers if the build has instructed so */
 #if CTX_INCLUDE_AARCH32_REGS
 	mrs	x11, spsr_abt
@@ -193,6 +196,9 @@
 	msr	contextidr_el1, x17
 	msr	vbar_el1, x9
 
+	ldr	x10, [x0, #CTX_PMCR_EL0]
+	msr	pmcr_el0, x10
+
 	/* Restore AArch32 system registers if the build has instructed so */
 #if CTX_INCLUDE_AARCH32_REGS
 	ldp	x11, x12, [x0, #CTX_SPSR_ABT]
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 3d26056..21e86de 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -58,7 +58,7 @@
 static void cm_init_context_common(cpu_context_t *ctx, const entry_point_info_t *ep)
 {
 	unsigned int security_state;
-	uint32_t scr_el3;
+	uint32_t scr_el3, pmcr_el0;
 	el3_state_t *state;
 	gp_regs_t *gp_regs;
 	unsigned long sctlr_elx;
@@ -164,11 +164,35 @@
 
 	/*
 	 * Store the initialised SCTLR_EL1 value in the cpu_context - SCTLR_EL2
-	 * and other EL2 resgisters are set up by cm_preapre_ns_entry() as they
+	 * and other EL2 registers are set up by cm_preapre_ns_entry() as they
 	 * are not part of the stored cpu_context.
 	 */
 	write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
 
+	if (security_state == SECURE) {
+		/*
+		 * Initialise PMCR_EL0 for secure context only, setting all
+		 * fields rather than relying on hw. Some fields are
+		 * architecturally UNKNOWN on reset.
+		 *
+		 * PMCR_EL0.LC: Set to one so that cycle counter overflow, that
+		 *  is recorded in PMOVSCLR_EL0[31], occurs on the increment
+		 *  that changes PMCCNTR_EL0[63] from 1 to 0.
+		 *
+		 * PMCR_EL0.DP: Set to one so that the cycle counter,
+		 *  PMCCNTR_EL0 does not count when event counting is prohibited.
+		 *
+		 * PMCR_EL0.X: Set to zero to disable export of events.
+		 *
+		 * PMCR_EL0.D: Set to zero so that, when enabled, PMCCNTR_EL0
+		 *  counts on every clock cycle.
+		 */
+		pmcr_el0 = ((PMCR_EL0_RESET_VAL | PMCR_EL0_LC_BIT
+				| PMCR_EL0_DP_BIT)
+				& ~(PMCR_EL0_X_BIT | PMCR_EL0_D_BIT));
+		write_ctx_reg(get_sysregs_ctx(ctx), CTX_PMCR_EL0, pmcr_el0);
+	}
+
 	/* Populate EL3 state so that we've the right context before doing ERET */
 	state = get_el3state_ctx(ctx);
 	write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index a5d707e..4105e63 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -414,6 +414,10 @@
 		case PSCI_MEM_CHK_RANGE_AARCH32:
 			return psci_mem_chk_range(x1, x2);
 
+		case PSCI_SYSTEM_RESET2_AARCH32:
+			/* We should never return from psci_system_reset2() */
+			return psci_system_reset2(x1, x2);
+
 		default:
 			break;
 		}
@@ -453,6 +457,9 @@
 		case PSCI_MEM_CHK_RANGE_AARCH64:
 			return psci_mem_chk_range(x1, x2);
 
+		case PSCI_SYSTEM_RESET2_AARCH64:
+			/* We should never return from psci_system_reset2() */
+			return psci_system_reset2(x1, x2);
 
 		default:
 			break;
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index facfacb..504fb9e 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -89,7 +89,9 @@
 			define_psci_cap(PSCI_NODE_HW_STATE_AARCH64) |	\
 			define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64) |	\
 			define_psci_cap(PSCI_STAT_RESIDENCY_AARCH64) |	\
-			define_psci_cap(PSCI_STAT_COUNT_AARCH64))
+			define_psci_cap(PSCI_STAT_COUNT_AARCH64) |	\
+			define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64) |	\
+			define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64))
 
 /*
  * Helper macros to get/set the fields of PSCI per-cpu data.
@@ -258,6 +260,7 @@
 /* Private exported functions from psci_system_off.c */
 void __dead2 psci_system_off(void);
 void __dead2 psci_system_reset(void);
+int psci_system_reset2(uint32_t reset_type, u_register_t cookie);
 
 /* Private exported functions from psci_stat.c */
 void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 5ef49ac..a841dda 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -248,6 +248,8 @@
 		psci_caps |= define_psci_cap(PSCI_MEM_PROTECT);
 	if (psci_plat_pm_ops->mem_protect_chk)
 		psci_caps |= define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64);
+	if (psci_plat_pm_ops->system_reset2)
+		psci_caps |= define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64);
 
 #if ENABLE_PSCI_STAT
 	psci_caps |=  define_psci_cap(PSCI_STAT_RESIDENCY_AARCH64);
diff --git a/lib/psci/psci_system_off.c b/lib/psci/psci_system_off.c
index ef5d3d1..13e9f4a 100644
--- a/lib/psci/psci_system_off.c
+++ b/lib/psci/psci_system_off.c
@@ -49,3 +49,33 @@
 
 	/* This function does not return. We should never get here */
 }
+
+int psci_system_reset2(uint32_t reset_type, u_register_t cookie)
+{
+	int is_vendor;
+
+	psci_print_power_domain_map();
+
+	assert(psci_plat_pm_ops->system_reset2);
+
+	is_vendor = (reset_type >> PSCI_RESET2_TYPE_VENDOR_SHIFT) & 1;
+	if (!is_vendor) {
+		/*
+		 * Only WARM_RESET is allowed for architectural type resets.
+		 */
+		if (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET)
+			return PSCI_E_INVALID_PARAMS;
+		if (psci_plat_pm_ops->write_mem_protect &&
+		    psci_plat_pm_ops->write_mem_protect(0) < 0) {
+			return PSCI_E_NOT_SUPPORTED;
+		}
+	}
+
+	/* Notify the Secure Payload Dispatcher */
+	if (psci_spd_pm && psci_spd_pm->svc_system_reset) {
+		psci_spd_pm->svc_system_reset();
+	}
+	console_flush();
+
+	return psci_plat_pm_ops->system_reset2(is_vendor, reset_type, cookie);
+}
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index 93d51fe..39c02af 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -300,4 +300,7 @@
 	.read_mem_protect	= arm_psci_read_mem_protect,
 	.write_mem_protect	= arm_nor_psci_write_mem_protect,
 #endif
+#if CSS_USE_SCMI_SDS_DRIVER
+	.system_reset2		= css_system_reset2,
+#endif
 };
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index c39bc4b..e29cd86 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -259,10 +259,7 @@
 	return HW_OFF;
 }
 
-/*
- * Helper function to shutdown the system via SCMI.
- */
-void __dead2 css_scp_sys_shutdown(void)
+void __dead2 css_scp_system_off(int state)
 {
 	int ret;
 
@@ -273,52 +270,37 @@
 	plat_arm_gic_cpuif_disable();
 
 	/*
-	 * Issue SCMI command for SYSTEM_SHUTDOWN. First issue a graceful
+	 * Issue SCMI command. First issue a graceful
 	 * request and if that fails force the request.
 	 */
 	ret = scmi_sys_pwr_state_set(scmi_handle,
 			SCMI_SYS_PWR_FORCEFUL_REQ,
-			SCMI_SYS_PWR_SHUTDOWN);
+			state);
+
 	if (ret != SCMI_E_SUCCESS) {
-		ERROR("SCMI system power domain shutdown return 0x%x unexpected\n",
-				ret);
+		ERROR("SCMI system power state set 0x%x returns unexpected 0x%x\n",
+			state, ret);
 		panic();
 	}
-
 	wfi();
-	ERROR("CSS System Shutdown: operation not handled.\n");
+	ERROR("CSS set power state: operation not handled.\n");
 	panic();
 }
 
 /*
+ * Helper function to shutdown the system via SCMI.
+ */
+void __dead2 css_scp_sys_shutdown(void)
+{
+	css_scp_system_off(SCMI_SYS_PWR_SHUTDOWN);
+}
+
+/*
  * Helper function to reset the system via SCMI.
  */
 void __dead2 css_scp_sys_reboot(void)
 {
-	int ret;
-
-	/*
-	 * Disable GIC CPU interface to prevent pending interrupt from waking
-	 * up the AP from WFI.
-	 */
-	plat_arm_gic_cpuif_disable();
-
-	/*
-	 * Issue SCMI command for SYSTEM_REBOOT. First issue a graceful
-	 * request and if that fails force the request.
-	 */
-	ret = scmi_sys_pwr_state_set(scmi_handle,
-			SCMI_SYS_PWR_FORCEFUL_REQ,
-			SCMI_SYS_PWR_COLD_RESET);
-	if (ret != SCMI_E_SUCCESS) {
-		ERROR("SCMI system power domain reset return 0x%x unexpected\n",
-				ret);
-		panic();
-	}
-
-	wfi();
-	ERROR("CSS System Reset: operation not handled.\n");
-	panic();
+	css_scp_system_off(SCMI_SYS_PWR_COLD_RESET);
 }
 
 scmi_channel_plat_info_t plat_css_scmi_plat_info = {
@@ -376,13 +358,35 @@
 		ops->system_off = NULL;
 		ops->system_reset = NULL;
 		ops->get_sys_suspend_power_state = NULL;
-	} else if (!(msg_attr & SCMI_SYS_PWR_SUSPEND_SUPPORTED)) {
-		/*
-		 * System power management protocol is available, but it does
-		 * not support SYSTEM SUSPEND.
-		 */
-		ops->get_sys_suspend_power_state = NULL;
+	} else {
+		if (!(msg_attr & SCMI_SYS_PWR_SUSPEND_SUPPORTED)) {
+			/*
+			 * System power management protocol is available, but
+			 * it does not support SYSTEM SUSPEND.
+			 */
+			ops->get_sys_suspend_power_state = NULL;
+		}
+		if (!(msg_attr & SCMI_SYS_PWR_WARM_RESET_SUPPORTED)) {
+			/*
+			 * WARM reset is not available.
+			 */
+			ops->system_reset2 = NULL;
+		}
 	}
 
 	return ops;
 }
+
+int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie)
+{
+	if (is_vendor || (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET))
+		return PSCI_E_INVALID_PARAMS;
+
+	css_scp_system_off(SCMI_SYS_PWR_WARM_RESET);
+	/*
+	 * css_scp_system_off cannot return (it is a __dead function),
+	 * but css_system_reset2 has to return some value, even in
+	 * this case.
+	 */
+	return 0;
+}
diff --git a/plat/arm/css/drivers/scp/css_scp.h b/plat/arm/css/drivers/scp/css_scp.h
index 223e372..1f0cf8e 100644
--- a/plat/arm/css/drivers/scp/css_scp.h
+++ b/plat/arm/css/drivers/scp/css_scp.h
@@ -15,12 +15,14 @@
 struct psci_power_state;
 
 /* API for power management by SCP */
+int css_system_reset2(int is_vendor, int reset_type, u_register_t cookie);
 void css_scp_suspend(const struct psci_power_state *target_state);
 void css_scp_off(const struct psci_power_state *target_state);
 void css_scp_on(u_register_t mpidr);
 int css_scp_get_power_state(u_register_t mpidr, unsigned int power_level);
 void __dead2 css_scp_sys_shutdown(void);
 void __dead2 css_scp_sys_reboot(void);
+void __dead2 css_scp_system_off(int state);
 
 /* API for SCP Boot Image transfer. Return 0 on success, -1 on error */
 int css_scp_boot_image_xfer(void *image, unsigned int image_size);
diff --git a/plat/socionext/uniphier/uniphier_rotpk.S b/plat/socionext/uniphier/uniphier_rotpk.S
index 0045a34..21c44b6 100644
--- a/plat/socionext/uniphier/uniphier_rotpk.S
+++ b/plat/socionext/uniphier/uniphier_rotpk.S
@@ -6,6 +6,7 @@
 
 	.global uniphier_rotpk_hash
 	.global uniphier_rotpk_hash_end
+	.section .rodata.uniphier_rotpk_hash, "a"
 uniphier_rotpk_hash:
 	/* DER header */
 	.byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48