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()) { if (is_feat_trf_supported()) {
trf_enable(ctx); trf_enable(ctx);
} }
pmuv3_enable(ctx);
#endif /* IMAGE_BL31 */ #endif /* IMAGE_BL31 */
/* /*
@ -822,8 +824,6 @@ static void manage_extensions_nonsecure(cpu_context_t *ctx)
if (is_feat_brbe_supported()) { if (is_feat_brbe_supported()) {
brbe_enable(ctx); brbe_enable(ctx);
} }
pmuv3_enable(ctx);
#endif /* IMAGE_BL31 */ #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; 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) static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
{ {
if (!is_feat_mtpmu_supported()) { if (!is_feat_mtpmu_supported()) {
@ -48,14 +37,20 @@ static u_register_t mtpmu_disable_el3(u_register_t mdcr_el3)
return 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 * MDCR_EL3.MPMX: Set to zero to not affect event counters (when
* SPME = 0). * 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 * 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. * 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_MPMX_BIT | MDCR_SPME_BIT | MDCR_TPM_BIT);
mdcr_el3 = mtpmu_disable_el3(mdcr_el3); mdcr_el3_val = mtpmu_disable_el3(mdcr_el3_val);
write_mdcr_el3(mdcr_el3);
write_ctx_reg(state, CTX_MDCR_EL3, mdcr_el3_val);
}
void pmuv3_init_el3(void)
{
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
* Initialise PMCR_EL0 setting all fields rather than relying * Initialise PMCR_EL0 setting all fields rather than relying
* on hw. Some fields are architecturally UNKNOWN on reset. * 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) 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. * Enable access to TPIDR2_EL0 if SME/SME2 is enabled for Non Secure world.
*/ */