feat(pmuv3): setup per world MDCR_EL3

MDCR_EL3 register will context switch across all worlds. Thus the pmuv3
init has to be part of context management initialization.

Change-Id: I10ef7a3071c0fc5c11a93d3c9c2a95ec8c6493bf
Signed-off-by: Mateusz Sulimowicz <matsul@google.com>
This commit is contained in:
Mateusz Sulimowicz 2025-01-14 11:24:59 +00:00
parent 9ac82c4979
commit c95aa2eb0d
3 changed files with 20 additions and 23 deletions

View file

@ -573,6 +573,8 @@ static void setup_context_common(cpu_context_t *ctx, const entry_point_info_t *e
if (is_feat_trf_supported()) {
trf_enable(ctx);
}
pmuv3_enable(ctx);
#endif /* IMAGE_BL31 */
/*
@ -822,8 +824,6 @@ static void manage_extensions_nonsecure(cpu_context_t *ctx)
if (is_feat_brbe_supported()) {
brbe_enable(ctx);
}
pmuv3_enable(ctx);
#endif /* IMAGE_BL31 */
}

View file

@ -21,17 +21,6 @@ static u_register_t init_mdcr_el2_hpmn(u_register_t mdcr_el2)
return mdcr_el2;
}
void pmuv3_enable(cpu_context_t *ctx)
{
#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
u_register_t mdcr_el2_val;
mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
}
static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
{
if (!is_feat_mtpmu_supported()) {
@ -48,14 +37,20 @@ static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
return mdcr_el3;
}
void pmuv3_init_el3(void)
void pmuv3_enable(cpu_context_t *ctx)
{
u_register_t mdcr_el3 = read_mdcr_el3();
#if (CTX_INCLUDE_EL2_REGS && IMAGE_BL31)
u_register_t mdcr_el2_val;
mdcr_el2_val = read_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2);
mdcr_el2_val = init_mdcr_el2_hpmn(mdcr_el2_val);
write_el2_ctx_common(get_el2_sysregs_ctx(ctx), mdcr_el2, mdcr_el2_val);
#endif /* (CTX_INCLUDE_EL2_REGS && IMAGE_BL31) */
el3_state_t *state = get_el3state_ctx(ctx);
u_register_t mdcr_el3_val = read_ctx_reg(state, CTX_MDCR_EL3);
/* ---------------------------------------------------------------------
* Initialise MDCR_EL3, setting all fields rather than relying on hw.
* Some fields are architecturally UNKNOWN on reset.
*
* MDCR_EL3.MPMX: Set to zero to not affect event counters (when
* SPME = 0).
*
@ -86,11 +81,15 @@ void pmuv3_init_el3(void)
* MDCR_EL3.TPM: Set to zero so that EL0, EL1, and EL2 System register
* accesses to all Performance Monitors registers do not trap to EL3.
*/
mdcr_el3 = (mdcr_el3 | MDCR_SCCD_BIT | MDCR_MCCD_BIT) &
mdcr_el3_val = (mdcr_el3_val | MDCR_SCCD_BIT | MDCR_MCCD_BIT) &
~(MDCR_MPMX_BIT | MDCR_SPME_BIT | MDCR_TPM_BIT);
mdcr_el3 = mtpmu_disable_el3(mdcr_el3);
write_mdcr_el3(mdcr_el3);
mdcr_el3_val = mtpmu_disable_el3(mdcr_el3_val);
write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
}
void pmuv3_init_el3(void)
{
/* ---------------------------------------------------------------------
* Initialise PMCR_EL0 setting all fields rather than relying
* on hw. Some fields are architecturally UNKNOWN on reset.

View file

@ -121,8 +121,6 @@ static void rmm_el2_context_init(el2_sysregs_t *regs)
static void manage_extensions_realm(cpu_context_t *ctx)
{
pmuv3_enable(ctx);
/*
* Enable access to TPIDR2_EL0 if SME/SME2 is enabled for Non Secure world.
*/