diff --git a/include/lib/extensions/spe.h b/include/lib/extensions/spe.h index bbfbd1983..4801a2206 100644 --- a/include/lib/extensions/spe.h +++ b/include/lib/extensions/spe.h @@ -12,12 +12,16 @@ #if ENABLE_SPE_FOR_NS void spe_enable(cpu_context_t *ctx); +void spe_disable(cpu_context_t *ctx); void spe_init_el2_unused(void); void spe_stop(void); #else static inline void spe_enable(cpu_context_t *ctx) { } +static inline void spe_disable(cpu_context_t *ctx) +{ +} static inline void spe_init_el2_unused(void) { } diff --git a/lib/extensions/spe/spe.c b/lib/extensions/spe/spe.c index 750a8cb93..d6532224a 100644 --- a/lib/extensions/spe/spe.c +++ b/lib/extensions/spe/spe.c @@ -52,6 +52,27 @@ void spe_enable(cpu_context_t *ctx) write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val); } +void spe_disable(cpu_context_t *ctx) +{ + el3_state_t *state = get_el3state_ctx(ctx); + u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3); + + /* + * MDCR_EL3.NSPB: Clear these bits to disable SPE feature, as it was enabled + * for Non-secure state only. After clearing these bits Secure state owns + * the Profiling Buffer and accesses to Statistical Profiling and Profiling + * Buffer control registers at EL2 and EL1 generate Trap exceptions to EL3 + * + * MDCR_EL3.NSPBE: Don't care as it was cleared during spe_enable and setting + * this to 1 does not make sense as NSPBE{1} and NSPB{0b0x} is RESERVED. + * + * MDCR_EL3.EnPMSN (ARM v8.7): Clear the bit to trap access of PMSNEVFR_EL1 + * from EL2/EL1 to EL3. + */ + mdcr_el3_val &= ~(MDCR_NSPB(MDCR_NSPB_EL1) | MDCR_EnPMSN_BIT); + write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val); +} + void spe_init_el2_unused(void) { uint64_t v;