summaryrefslogtreecommitdiff
path: root/lib/el3_runtime
diff options
context:
space:
mode:
authorDavid Cunado <david.cunado@arm.com>2016-10-31 17:37:34 +0000
committerDavid Cunado <david.cunado@arm.com>2016-11-09 15:45:06 +0000
commit495f3d3c51096de3559cc7fb77494a16fc158e26 (patch)
tree0f63e1ee431d91bfa7c5bacbe2e0c7630f7cc119 /lib/el3_runtime
parent90d2956aeaa9f0838400eb40d6c48935ec4c988b (diff)
Reset debug registers MDCR-EL3/SDCR and MDCR_EL2/HDCR
In order to avoid unexpected traps into EL3/MON mode, this patch resets the debug registers, MDCR_EL3 and MDCR_EL2 for AArch64, and SDCR and HDCR for AArch32. MDCR_EL3/SDCR is zero'ed when EL3/MON mode is entered, at the start of BL1 and BL31/SMP_MIN. For MDCR_EL2/HDCR, this patch zero's the bits that are architecturally UNKNOWN values on reset. This is done when exiting from EL3/MON mode but only on platforms that support EL2/HYP mode but choose to exit to EL1/SVC mode. Fixes ARM-software/tf-issues#430 Change-Id: Idb992232163c072faa08892251b5626ae4c3a5b6 Signed-off-by: David Cunado <david.cunado@arm.com>
Diffstat (limited to 'lib/el3_runtime')
-rw-r--r--lib/el3_runtime/aarch32/context_mgmt.c14
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c10
2 files changed, 23 insertions, 1 deletions
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 02ae2a7e..29532e8c 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -200,7 +200,10 @@ void cm_prepare_el3_exit(uint32_t security_state)
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 @@ void cm_prepare_el3_exit(uint32_t security_state)
* 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 4b5d0ee5..fadc1dbf 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -259,6 +259,16 @@ void cm_prepare_el3_exit(uint32_t security_state)
* 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);
}
}