summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Cunado <david.cunado@arm.com>2017-04-13 22:38:29 +0100
committerDavid Cunado <david.cunado@arm.com>2017-06-21 17:57:54 +0100
commit18f2efd67d881fe0a9a535ce9e801e60d746e024 (patch)
tree5c02488f3d5e7c29035e51f65fbe8b83fad74026 /lib
parentb1187232fdf819586ba8c8ece4a27a7515cbdc6d (diff)
Fully initialise essential control registers
This patch updates the el3_arch_init_common macro so that it fully initialises essential control registers rather then relying on hardware to set the reset values. The context management functions are also updated to fully initialise the appropriate control registers when initialising the non-secure and secure context structures and when preparing to leave EL3 for a lower EL. This gives better alignement with the ARM ARM which states that software must initialise RES0 and RES1 fields with 0 / 1. This patch also corrects the following typos: "NASCR definitions" -> "NSACR definitions" Change-Id: Ia8940b8351dc27bc09e2138b011e249655041cfc Signed-off-by: David Cunado <david.cunado@arm.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/el3_runtime/aarch32/context_mgmt.c154
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c253
2 files changed, 285 insertions, 122 deletions
diff --git a/lib/el3_runtime/aarch32/context_mgmt.c b/lib/el3_runtime/aarch32/context_mgmt.c
index 020f3a36..3e7a5b73 100644
--- a/lib/el3_runtime/aarch32/context_mgmt.c
+++ b/lib/el3_runtime/aarch32/context_mgmt.c
@@ -75,36 +75,44 @@ static void cm_init_context_common(cpu_context_t *ctx, const entry_point_info_t
if (security_state != SECURE)
scr |= SCR_NS_BIT;
- /*
- * Set up SCTLR for the Non Secure context.
- * EE bit is taken from the entrypoint attributes
- * M, C and I bits must be zero (as required by PSCI specification)
- *
- * The target exception level is based on the spsr mode requested.
- * If execution is requested to hyp mode, HVC is enabled
- * via SCR.HCE.
- *
- * Always compute the SCTLR_EL1 value and save in the cpu_context
- * - the HYP registers are set up by cm_preapre_ns_entry() as they
- * are not part of the stored cpu_context
- *
- * TODO: In debug builds the spsr should be validated and checked
- * against the CPU support, security state, endianness and pc
- */
if (security_state != SECURE) {
- sctlr = EP_GET_EE(ep->h.attr) ? SCTLR_EE_BIT : 0;
/*
- * In addition to SCTLR_RES1, set the CP15_BEN, nTWI & nTWE
- * bits that architecturally reset to 1.
+ * Set up SCTLR for the Non-secure context.
+ *
+ * SCTLR.EE: Endianness is taken from the entrypoint attributes.
+ *
+ * SCTLR.M, SCTLR.C and SCTLR.I: These fields must be zero (as
+ * required by PSCI specification)
+ *
+ * Set remaining SCTLR fields to their architecturally defined
+ * values. Some fields reset to an IMPLEMENTATION DEFINED value:
+ *
+ * SCTLR.TE: Set to zero so that exceptions to an Exception
+ * Level executing at PL1 are taken to A32 state.
+ *
+ * SCTLR.V: Set to zero to select the normal exception vectors
+ * with base address held in VBAR.
*/
- sctlr |= SCTLR_RES1 | SCTLR_CP15BEN_BIT |
- SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
+ assert(((ep->spsr >> SPSR_E_SHIFT) & SPSR_E_MASK) ==
+ (EP_GET_EE(ep->h.attr) >> EP_EE_SHIFT));
+
+ sctlr = EP_GET_EE(ep->h.attr) ? SCTLR_EE_BIT : 0;
+ sctlr |= (SCTLR_RESET_VAL & ~(SCTLR_TE_BIT | SCTLR_V_BIT));
write_ctx_reg(reg_ctx, CTX_NS_SCTLR, sctlr);
}
+ /*
+ * The target exception level is based on the spsr mode requested. If
+ * execution is requested to hyp mode, HVC is enabled via SCR.HCE.
+ */
if (GET_M32(ep->spsr) == MODE32_hyp)
scr |= SCR_HCE_BIT;
+ /*
+ * Store the initialised values for SCTLR and SCR in the cpu_context.
+ * The Hyp mode registers are not part of the saved context and are
+ * set-up in cm_prepare_el3_exit().
+ */
write_ctx_reg(reg_ctx, CTX_SCR, scr);
write_ctx_reg(reg_ctx, CTX_LR, ep->pc);
write_ctx_reg(reg_ctx, CTX_SPSR, ep->spsr);
@@ -151,7 +159,7 @@ void cm_init_my_context(const entry_point_info_t *ep)
******************************************************************************/
void cm_prepare_el3_exit(uint32_t security_state)
{
- uint32_t sctlr, scr, hcptr;
+ uint32_t hsctlr, scr;
cpu_context_t *ctx = cm_get_context(security_state);
assert(ctx);
@@ -160,9 +168,9 @@ void cm_prepare_el3_exit(uint32_t security_state)
scr = read_ctx_reg(get_regs_ctx(ctx), CTX_SCR);
if (scr & SCR_HCE_BIT) {
/* Use SCTLR value to initialize HSCTLR */
- sctlr = read_ctx_reg(get_regs_ctx(ctx),
+ hsctlr = read_ctx_reg(get_regs_ctx(ctx),
CTX_NS_SCTLR);
- sctlr |= HSCTLR_RES1;
+ hsctlr |= HSCTLR_RES1;
/* Temporarily set the NS bit to access HSCTLR */
write_scr(read_scr() | SCR_NS_BIT);
/*
@@ -170,7 +178,7 @@ void cm_prepare_el3_exit(uint32_t security_state)
* we can access HSCTLR
*/
isb();
- write_hsctlr(sctlr);
+ write_hsctlr(hsctlr);
isb();
write_scr(read_scr() & ~SCR_NS_BIT);
@@ -184,48 +192,92 @@ void cm_prepare_el3_exit(uint32_t security_state)
write_scr(read_scr() | SCR_NS_BIT);
isb();
- /* PL2 present but unused, need to disable safely */
- write_hcr(0);
-
- /* HSCTLR : can be ignored when bypassing */
+ /*
+ * Hyp / PL2 present but unused, need to disable safely.
+ * HSCTLR can be ignored in this case.
+ *
+ * Set HCR to its architectural reset value so that
+ * Non-secure operations do not trap to Hyp mode.
+ */
+ write_hcr(HCR_RESET_VAL);
- /* HCPTR : disable all traps TCPAC, TTA, TCP */
- hcptr = read_hcptr();
- hcptr &= ~(TCPAC_BIT | TTA_BIT | TCP11_BIT | TCP10_BIT);
- write_hcptr(hcptr);
+ /*
+ * Set HCPTR to its architectural reset value so that
+ * Non-secure access from EL1 or EL0 to trace and to
+ * Advanced SIMD and floating point functionality does
+ * not trap to Hyp mode.
+ */
+ write_hcptr(HCPTR_RESET_VAL);
- /* Enable EL1 access to timer */
- write_cnthctl(PL1PCEN_BIT | PL1PCTEN_BIT);
+ /*
+ * Initialise CNTHCTL. All fields are architecturally
+ * UNKNOWN on reset and are set to zero except for
+ * field(s) listed below.
+ *
+ * CNTHCTL.PL1PCEN: Disable traps to Hyp mode of
+ * Non-secure EL0 and EL1 accessed to the physical
+ * timer registers.
+ *
+ * CNTHCTL.PL1PCTEN: Disable traps to Hyp mode of
+ * Non-secure EL0 and EL1 accessed to the physical
+ * counter registers.
+ */
+ write_cnthctl(CNTHCTL_RESET_VAL |
+ PL1PCEN_BIT | PL1PCTEN_BIT);
- /* Reset CNTVOFF_EL2 */
+ /*
+ * Initialise CNTVOFF to zero as it resets to an
+ * IMPLEMENTATION DEFINED value.
+ */
write64_cntvoff(0);
- /* Set VPIDR, VMPIDR to match MIDR, MPIDR */
+ /*
+ * Set VPIDR and VMPIDR to match MIDR_EL1 and MPIDR
+ * respectively.
+ */
write_vpidr(read_midr());
write_vmpidr(read_mpidr());
/*
- * Reset VTTBR.
- * Needed because cache maintenance operations depend on
- * the VMID even when non-secure EL1&0 stage 2 address
- * translation are disabled.
+ * Initialise VTTBR, setting all fields rather than
+ * relying on the hw. Some fields are architecturally
+ * UNKNOWN at reset.
+ *
+ * VTTBR.VMID: Set to zero which is the architecturally
+ * defined reset value. Even though EL1&0 stage 2
+ * address translation is disabled, cache maintenance
+ * operations depend on the VMID.
+ *
+ * VTTBR.BADDR: Set to zero as EL1&0 stage 2 address
+ * translation is disabled.
*/
- write64_vttbr(0);
+ write64_vttbr(VTTBR_RESET_VAL &
+ ~((VTTBR_VMID_MASK << VTTBR_VMID_SHIFT)
+ | (VTTBR_BADDR_MASK << VTTBR_BADDR_SHIFT)));
/*
- * 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.
+ * Initialise HDCR, setting all the fields rather than
+ * relying on hw.
+ *
+ * HDCR.HPMN: Set to value of PMCR.N which is the
+ * architecturally-defined reset value.
*/
- write_hdcr((read_pmcr() & PMCR_N_BITS) >> PMCR_N_SHIFT);
+ write_hdcr(HDCR_RESET_VAL |
+ ((read_pmcr() & PMCR_N_BITS) >> PMCR_N_SHIFT));
/*
- * Reset CNTHP_CTL to disable the EL2 physical timer and
- * therefore prevent timer interrupts.
+ * Set HSTR to its architectural reset value so that
+ * access to system registers in the cproc=1111
+ * encoding space do not trap to Hyp mode.
+ */
+ write_hstr(HSTR_RESET_VAL);
+ /*
+ * Set CNTHP_CTL to its architectural reset value to
+ * disable the EL2 physical timer and prevent timer
+ * interrupts. Some fields are architecturally UNKNOWN
+ * on reset and are set to zero.
*/
- write_cnthp_ctl(0);
+ write_cnthp_ctl(CNTHP_CTL_RESET_VAL);
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 0104c4ed..11ff1632 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -71,77 +71,104 @@ static void cm_init_context_common(cpu_context_t *ctx, const entry_point_info_t
zeromem(ctx, sizeof(*ctx));
/*
- * Base the context SCR on the current value, adjust for entry point
- * specific requirements and set trap bits from the IMF
- * TODO: provide the base/global SCR bits using another mechanism?
+ * SCR_EL3 was initialised during reset sequence in macro
+ * el3_arch_init_common. This code modifies the SCR_EL3 fields that
+ * affect the next EL.
+ *
+ * The following fields are initially set to zero and then updated to
+ * the required value depending on the state of the SPSR_EL3 and the
+ * Security state and entrypoint attributes of the next EL.
*/
scr_el3 = read_scr();
scr_el3 &= ~(SCR_NS_BIT | SCR_RW_BIT | SCR_FIQ_BIT | SCR_IRQ_BIT |
SCR_ST_BIT | SCR_HCE_BIT);
-
+ /*
+ * SCR_NS: Set the security state of the next EL.
+ */
if (security_state != SECURE)
scr_el3 |= SCR_NS_BIT;
-
+ /*
+ * SCR_EL3.RW: Set the execution state, AArch32 or AArch64, for next
+ * Exception level as specified by SPSR.
+ */
if (GET_RW(ep->spsr) == MODE_RW_64)
scr_el3 |= SCR_RW_BIT;
-
+ /*
+ * SCR_EL3.ST: Traps Secure EL1 accesses to the Counter-timer Physical
+ * Secure timer registers to EL3, from AArch64 state only, if specified
+ * by the entrypoint attributes.
+ */
if (EP_GET_ST(ep->h.attr))
scr_el3 |= SCR_ST_BIT;
#ifndef HANDLE_EA_EL3_FIRST
- /* Explicitly stop to trap aborts from lower exception levels. */
+ /*
+ * SCR_EL3.EA: Do not route External Abort and SError Interrupt External
+ * to EL3 when executing at a lower EL. When executing at EL3, External
+ * Aborts are taken to EL3.
+ */
scr_el3 &= ~SCR_EA_BIT;
#endif
#ifdef IMAGE_BL31
/*
- * IRQ/FIQ bits only need setting if interrupt routing
- * model has been set up for BL31.
+ * SCR_EL3.IRQ, SCR_EL3.FIQ: Enable the physical FIQ and IRQ rounting as
+ * indicated by the interrupt routing model for BL31.
*/
scr_el3 |= get_scr_el3_from_routing_model(security_state);
#endif
/*
- * Set up SCTLR_ELx for the target exception level:
- * EE bit is taken from the entrypoint attributes
- * M, C and I bits must be zero (as required by PSCI specification)
- *
- * The target exception level is based on the spsr mode requested.
- * If execution is requested to EL2 or hyp mode, HVC is enabled
- * via SCR_EL3.HCE.
+ * SCR_EL3.HCE: Enable HVC instructions if next execution state is
+ * AArch64 and next EL is EL2, or if next execution state is AArch32 and
+ * next mode is Hyp.
+ */
+ if ((GET_RW(ep->spsr) == MODE_RW_64
+ && GET_EL(ep->spsr) == MODE_EL2)
+ || (GET_RW(ep->spsr) != MODE_RW_64
+ && GET_M32(ep->spsr) == MODE32_hyp)) {
+ scr_el3 |= SCR_HCE_BIT;
+ }
+
+ /*
+ * Initialise SCTLR_EL1 to the reset value corresponding to the target
+ * execution state setting all fields rather than relying of the hw.
+ * Some fields have architecturally UNKNOWN reset values and these are
+ * set to zero.
*
- * Always compute the SCTLR_EL1 value and save in the cpu_context
- * - the EL2 registers are set up by cm_preapre_ns_entry() as they
- * are not part of the stored cpu_context
+ * SCTLR.EE: Endianness is taken from the entrypoint attributes.
*
- * TODO: In debug builds the spsr should be validated and checked
- * against the CPU support, security state, endianess and pc
+ * SCTLR.M, SCTLR.C and SCTLR.I: These fields must be zero (as
+ * required by PSCI specification)
*/
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 {
- 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 the target execution state is AArch32 then the following
+ * fields need to be set.
+ *
+ * SCTRL_EL1.nTWE: Set to one so that EL0 execution of WFE
+ * instructions are not trapped to EL1.
+ *
+ * SCTLR_EL1.nTWI: Set to one so that EL0 execution of WFI
+ * instructions are not trapped to EL1.
+ *
+ * SCTLR_EL1.CP15BEN: Set to one to enable EL0 execution of the
+ * CP15DMB, CP15DSB, and CP15ISB instructions.
*/
- if (security_state != SECURE)
- sctlr_elx |= SCTLR_CP15BEN_BIT | SCTLR_NTWI_BIT
- | SCTLR_NTWE_BIT;
+ sctlr_elx |= SCTLR_AARCH32_EL1_RES1 | SCTLR_CP15BEN_BIT
+ | SCTLR_NTWI_BIT | SCTLR_NTWE_BIT;
}
+ /*
+ * 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
+ * are not part of the stored cpu_context.
+ */
write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_elx);
- if ((GET_RW(ep->spsr) == MODE_RW_64
- && GET_EL(ep->spsr) == MODE_EL2)
- || (GET_RW(ep->spsr) != MODE_RW_64
- && GET_M32(ep->spsr) == MODE32_hyp)) {
- scr_el3 |= SCR_HCE_BIT;
- }
-
/* 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);
@@ -191,7 +218,7 @@ void cm_init_my_context(const entry_point_info_t *ep)
******************************************************************************/
void cm_prepare_el3_exit(uint32_t security_state)
{
- uint32_t sctlr_elx, scr_el3, cptr_el2;
+ uint32_t sctlr_elx, scr_el3;
cpu_context_t *ctx = cm_get_context(security_state);
assert(ctx);
@@ -206,57 +233,141 @@ void cm_prepare_el3_exit(uint32_t security_state)
sctlr_elx |= SCTLR_EL2_RES1;
write_sctlr_el2(sctlr_elx);
} else if (EL_IMPLEMENTED(2)) {
- /* EL2 present but unused, need to disable safely */
-
- /* HCR_EL2 = 0, except RW bit set to match SCR_EL3 */
+ /*
+ * EL2 present but unused, need to disable safely.
+ * SCTLR_EL2 can be ignored in this case.
+ *
+ * Initialise all fields in HCR_EL2, except HCR_EL2.RW,
+ * to zero so that Non-secure operations do not trap to
+ * EL2.
+ *
+ * HCR_EL2.RW: Set this field to match SCR_EL3.RW
+ */
write_hcr_el2((scr_el3 & SCR_RW_BIT) ? HCR_RW_BIT : 0);
- /* SCTLR_EL2 : can be ignored when bypassing */
-
- /* CPTR_EL2 : disable all traps TCPAC, TTA, TFP */
- cptr_el2 = read_cptr_el2();
- cptr_el2 &= ~(TCPAC_BIT | TTA_BIT | TFP_BIT);
- write_cptr_el2(cptr_el2);
+ /*
+ * Initialise CPTR_EL2 setting all fields rather than
+ * relying on the hw. All fields have architecturally
+ * UNKNOWN reset values.
+ *
+ * CPTR_EL2.TCPAC: Set to zero so that Non-secure EL1
+ * accesses to the CPACR_EL1 or CPACR from both
+ * Execution states do not trap to EL2.
+ *
+ * CPTR_EL2.TTA: Set to zero so that Non-secure System
+ * register accesses to the trace registers from both
+ * Execution states do not trap to EL2.
+ *
+ * CPTR_EL2.TFP: Set to zero so that Non-secure accesses
+ * to SIMD and floating-point functionality from both
+ * Execution states do not trap to EL2.
+ */
+ write_cptr_el2(CPTR_EL2_RESET_VAL &
+ ~(CPTR_EL2_TCPAC_BIT | CPTR_EL2_TTA_BIT
+ | CPTR_EL2_TFP_BIT));
- /* Enable EL1 access to timer */
- write_cnthctl_el2(EL1PCEN_BIT | EL1PCTEN_BIT);
+ /*
+ * Initiliase CNTHCTL_EL2. All fields are
+ * architecturally UNKNOWN on reset and are set to zero
+ * except for field(s) listed below.
+ *
+ * CNTHCTL_EL2.EL1PCEN: Set to one to disable traps to
+ * Hyp mode of Non-secure EL0 and EL1 accesses to the
+ * physical timer registers.
+ *
+ * CNTHCTL_EL2.EL1PCTEN: Set to one to disable traps to
+ * Hyp mode of Non-secure EL0 and EL1 accesses to the
+ * physical counter registers.
+ */
+ write_cnthctl_el2(CNTHCTL_RESET_VAL |
+ EL1PCEN_BIT | EL1PCTEN_BIT);
- /* Reset CNTVOFF_EL2 */
+ /*
+ * Initialise CNTVOFF_EL2 to zero as it resets to an
+ * architecturally UNKNOWN value.
+ */
write_cntvoff_el2(0);
- /* Set VPIDR, VMPIDR to match MIDR, MPIDR */
+ /*
+ * Set VPIDR_EL2 and VMPIDR_EL2 to match MIDR_EL1 and
+ * MPIDR_EL1 respectively.
+ */
write_vpidr_el2(read_midr_el1());
write_vmpidr_el2(read_mpidr_el1());
/*
- * Reset VTTBR_EL2.
- * Needed because cache maintenance operations depend on
- * the VMID even when non-secure EL1&0 stage 2 address
- * translation are disabled.
+ * Initialise VTTBR_EL2. All fields are architecturally
+ * UNKNOWN on reset.
+ *
+ * VTTBR_EL2.VMID: Set to zero. Even though EL1&0 stage
+ * 2 address translation is disabled, cache maintenance
+ * operations depend on the VMID.
+ *
+ * VTTBR_EL2.BADDR: Set to zero as EL1&0 stage 2 address
+ * translation is disabled.
*/
- write_vttbr_el2(0);
+ write_vttbr_el2(VTTBR_RESET_VAL &
+ ~((VTTBR_VMID_MASK << VTTBR_VMID_SHIFT)
+ | (VTTBR_BADDR_MASK << VTTBR_BADDR_SHIFT)));
+
/*
- * 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.
+ * Initialise MDCR_EL2, setting all fields rather than
+ * relying on hw. Some fields are architecturally
+ * UNKNOWN on reset.
+ *
+ * MDCR_EL2.TDRA: Set to zero so that Non-secure EL0 and
+ * EL1 System register accesses to the Debug ROM
+ * registers are not trapped to EL2.
+ *
+ * MDCR_EL2.TDOSA: Set to zero so that Non-secure EL1
+ * System register accesses to the powerdown debug
+ * registers are not trapped to EL2.
+ *
+ * MDCR_EL2.TDA: Set to zero so that System register
+ * accesses to the debug registers do not trap to EL2.
+ *
+ * MDCR_EL2.TDE: Set to zero so that debug exceptions
+ * are not routed to EL2.
+ *
+ * MDCR_EL2.HPME: Set to zero to disable EL2 Performance
+ * Monitors.
+ *
+ * MDCR_EL2.TPM: Set to zero so that Non-secure EL0 and
+ * EL1 accesses to all Performance Monitors registers
+ * are not trapped to EL2.
+ *
+ * MDCR_EL2.TPMCR: Set to zero so that Non-secure EL0
+ * and EL1 accesses to the PMCR_EL0 or PMCR are not
+ * trapped to EL2.
+ *
+ * MDCR_EL2.HPMN: Set to value of PMCR_EL0.N which is the
+ * architecturally-defined reset value.
*/
- write_mdcr_el2((read_pmcr_el0() & PMCR_EL0_N_BITS)
- >> PMCR_EL0_N_SHIFT);
+ write_mdcr_el2((MDCR_EL2_RESET_VAL |
+ ((read_pmcr_el0() & PMCR_EL0_N_BITS)
+ >> PMCR_EL0_N_SHIFT)) &
+ ~(MDCR_EL2_TDRA_BIT | MDCR_EL2_TDOSA_BIT
+ | MDCR_EL2_TDA_BIT | MDCR_EL2_TDE_BIT
+ | MDCR_EL2_HPME_BIT | MDCR_EL2_TPM_BIT
+ | MDCR_EL2_TPMCR_BIT));
/*
- * Avoid unexpected traps of non-secure access to
- * certain system registers at EL1 or lower where
- * HSTR_EL2 is not completely reset to zero by the
- * hardware - zero the entire register.
+ * Initialise HSTR_EL2. All fields are architecturally
+ * UNKNOWN on reset.
+ *
+ * HSTR_EL2.T<n>: Set all these fields to zero so that
+ * Non-secure EL0 or EL1 accesses to System registers
+ * do not trap to EL2.
*/
- write_hstr_el2(0);
+ write_hstr_el2(HSTR_EL2_RESET_VAL & ~(HSTR_EL2_T_MASK));
/*
- * Reset CNTHP_CTL_EL2 to disable the EL2 physical timer
- * and therefore prevent timer interrupts.
+ * Initialise CNTHP_CTL_EL2. All fields are
+ * architecturally UNKNOWN on reset.
+ *
+ * CNTHP_CTL_EL2:ENABLE: Set to zero to disable the EL2
+ * physical timer and prevent timer interrupts.
*/
- write_cnthp_ctl_el2(0);
+ write_cnthp_ctl_el2(CNTHP_CTL_RESET_VAL &
+ ~(CNTHP_CTL_ENABLE_BIT));
}
}