From 3e61b2b54336510475fbab83b7d97538f3ac5460 Mon Sep 17 00:00:00 2001 From: David Cunado Date: Mon, 2 Oct 2017 17:41:39 +0100 Subject: Init and save / restore of PMCR_EL0 / PMCR Currently TF does not initialise the PMCR_EL0 register in the secure context or save/restore the register. In particular, the DP field may not be set to one to prohibit cycle counting in the secure state, even though event counting generally is prohibited via the default setting of MDCR_EL3.SMPE to 0. This patch initialises PMCR_EL0.DP to one in the secure state to prohibit cycle counting and also initialises other fields that have an architectually UNKNOWN reset value. Additionally, PMCR_EL0 is added to the list of registers that are saved and restored during a world switch. Similar changes are made for PMCR for the AArch32 execution state. NOTE: secure world code at lower ELs that assume other values in PMCR_EL0 will be impacted. Change-Id: Iae40e8c0a196d74053accf97063ebc257b4d2f3a Signed-off-by: David Cunado --- lib/el3_runtime/aarch64/context.S | 6 ++++++ lib/el3_runtime/aarch64/context_mgmt.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S index 8a6c11b7..db16a9f0 100644 --- a/lib/el3_runtime/aarch64/context.S +++ b/lib/el3_runtime/aarch64/context.S @@ -74,6 +74,9 @@ func el1_sysregs_context_save 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 @@ func el1_sysregs_context_restore 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 3d26056a..21e86de0 100644 --- a/lib/el3_runtime/aarch64/context_mgmt.c +++ b/lib/el3_runtime/aarch64/context_mgmt.c @@ -58,7 +58,7 @@ void cm_init(void) 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 @@ static void cm_init_context_common(cpu_context_t *ctx, const entry_point_info_t /* * 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); -- cgit v1.2.3