Merge pull request #757 from douglas-raillard-arm/dr/doc_plat_psci_ops

Document plat_psci_ops.(system_off|system_reset)
diff --git a/docs/firmware-design.md b/docs/firmware-design.md
index abe7dc5..c37f9c5 100644
--- a/docs/firmware-design.md
+++ b/docs/firmware-design.md
@@ -1077,7 +1077,7 @@
 
 Details for implementing a CPU specific reset handler can be found in
 Section 8. Details for implementing a platform specific reset handler can be
-found in the [Porting Guide](see the `plat_reset_handler()` function).
+found in the [Porting Guide] (see the `plat_reset_handler()` function).
 
 When adding functionality to a reset handler, keep in mind that if a different
 reset handling behavior is required between the first and the subsequent
diff --git a/include/common/aarch32/el3_common_macros.S b/include/common/aarch32/el3_common_macros.S
index 50ce952..0018ea4 100644
--- a/include/common/aarch32/el3_common_macros.S
+++ b/include/common/aarch32/el3_common_macros.S
@@ -67,6 +67,14 @@
 	orr	r0, r0, #SCR_SIF_BIT
 	stcopr	r0, SCR
 
+	/* -----------------------------------------------------------------
+	 * Reset those registers that may have architecturally unknown reset
+	 * values
+	 * -----------------------------------------------------------------
+	 */
+	mov	r0, #0
+	stcopr	r0, SDCR
+
 	/* -----------------------------------------------------
 	 * Enable the Asynchronous data abort now that the
 	 * exception vectors have been setup.
diff --git a/include/common/aarch64/el3_common_macros.S b/include/common/aarch64/el3_common_macros.S
index 9b22a73..a418911 100644
--- a/include/common/aarch64/el3_common_macros.S
+++ b/include/common/aarch64/el3_common_macros.S
@@ -77,6 +77,13 @@
 	 */
 	mov	x0, #(SCR_RES1_BITS | SCR_EA_BIT | SCR_SIF_BIT)
 	msr	scr_el3, x0
+
+	/* ---------------------------------------------------------------------
+	 * Reset registers that may have architecturally unknown reset values
+	 * ---------------------------------------------------------------------
+	 */
+	msr	mdcr_el3, xzr
+
 	/* ---------------------------------------------------------------------
 	 * Enable External Aborts and SError Interrupts now that the exception
 	 * vectors have been setup.
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 4968e24..3c5ab26 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -318,6 +318,11 @@
 
 #define MAX_CACHE_LINE_SIZE	0x800 /* 2KB */
 
+/* PMCR definitions */
+#define PMCR_N_SHIFT		11
+#define PMCR_N_MASK		0x1f
+#define PMCR_N_BITS		(PMCR_N_MASK << PMCR_N_SHIFT)
+
 /*******************************************************************************
  * Definitions of register offsets and fields in the CNTCTLBase Frame of the
  * system level implementation of the Generic Timer.
@@ -375,6 +380,11 @@
 #define CSSELR		p15, 2, c0, c0, 0
 #define CCSIDR		p15, 1, c0, c0, 0
 
+/* Debug register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
+#define HDCR		p15, 4, c1, c1, 1
+#define SDCR		p15, 0, c1, c3, 1
+#define PMCR		p15, 0, c9, c12, 0
+
 /* GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
 #define ICC_IAR1	p15, 0, c12, c12, 0
 #define ICC_IAR0	p15, 0, c12, c8, 0
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index 3b4349c..0633bca 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -249,6 +249,9 @@
 DEFINE_COPROCR_RW_FUNCS(icc_eoir0_el1, ICC_EOIR0)
 DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
 
+DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
+DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
+
 /*
  * TLBI operation prototypes
  */
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index bef6032..a034ae2 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -411,4 +411,9 @@
 #define CNTACR_RWVT_SHIFT	0x4
 #define CNTACR_RWPT_SHIFT	0x5
 
+/* PMCR_EL0 definitions */
+#define PMCR_EL0_N_SHIFT	11
+#define PMCR_EL0_N_MASK		0x1f
+#define PMCR_EL0_N_BITS		(PMCR_EL0_N_MASK << PMCR_EL0_N_SHIFT)
+
 #endif /* __ARCH_H__ */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 4d936ad..37db031 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -279,6 +279,9 @@
 
 DEFINE_SYSREG_READ_FUNC(ctr_el0)
 
+DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
+DEFINE_SYSREG_READ_FUNC(pmcr_el0)
+
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3)
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 02ae2a7..29532e8 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -200,7 +200,10 @@
 			isb();
 		} else if (read_id_pfr1() &
 			(ID_PFR1_VIRTEXT_MASK << ID_PFR1_VIRTEXT_SHIFT)) {
-			/* Set the NS bit to access HCR, HCPTR, CNTHCTL, VPIDR, VMPIDR */
+			/*
+			 * Set the NS bit to access NS copies of certain banked
+			 * registers
+			 */
 			write_scr(read_scr() | SCR_NS_BIT);
 			isb();
 
@@ -231,6 +234,15 @@
 			 * translation are disabled.
 			 */
 			write64_vttbr(0);
+
+			/*
+			 * Avoid unexpected debug traps in case where HDCR
+			 * is not completely reset by the hardware - set
+			 * HDCR.HPMN to PMCR.N and zero the remaining bits.
+			 * The HDCR.HPMN and PMCR.N fields are the same size
+			 * (5 bits) and HPMN is at offset zero within HDCR.
+			 */
+			write_hdcr((read_pmcr() & PMCR_N_BITS) >> PMCR_N_SHIFT);
 			isb();
 
 			write_scr(read_scr() & ~SCR_NS_BIT);
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index 4b5d0ee..fadc1db 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -259,6 +259,16 @@
 			 * translation are disabled.
 			 */
 			write_vttbr_el2(0);
+			/*
+			 * Avoid unexpected debug traps in case where MDCR_EL2
+			 * is not completely reset by the hardware - set
+			 * MDCR_EL2.HPMN to PMCR_EL0.N and zero the remaining
+			 * bits.
+			 * MDCR_EL2.HPMN and PMCR_EL0.N fields are the same size
+			 * (5 bits) and HPMN is at offset zero within MDCR_EL2.
+			 */
+			write_mdcr_el2((read_pmcr_el0() & PMCR_EL0_N_BITS)
+					>> PMCR_EL0_N_SHIFT);
 		}
 	}
 
diff --git a/readme.md b/readme.md
index d9a1714..ef5f6ee 100644
--- a/readme.md
+++ b/readme.md
@@ -105,7 +105,7 @@
 of the [Juno ARM Development Platform] [Juno] with [Linaro Release 16.06].
 
 The AArch64 build of this release has been tested on the following ARM
-[FVP]s (64-bit host machine only):
+[FVP]s (64-bit host machine only, with [Linaro Release 16.06]):
 
 *   `Foundation_Platform` (Version 10.1, Build 10.1.32)
 *   `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701)
@@ -114,7 +114,7 @@
 *   `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]s (64-bit host machine only, with [Linaro Release 16.06]):
 
 *   `FVP_Base_AEMv8A-AEMv8A` (Version 7.7, Build 0.8.7701)
 *   `FVP_Base_Cortex-A32x4` (Version 10.1, Build 10.1.32)