target/arm: Mask PMU register writes based on PMCR_EL0.N

This is in preparation for enabling counters other than PMCCNTR

Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1523997485-1905-5-git-send-email-alindsay@codeaurora.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Aaron Lindsay 2018-04-26 11:04:39 +01:00 committed by Peter Maydell
parent 169c893874
commit 7ece99b17e
1 changed files with 22 additions and 9 deletions

View File

@ -52,11 +52,6 @@ typedef struct V8M_SAttributes {
static void v8m_security_lookup(CPUARMState *env, uint32_t address,
MMUAccessType access_type, ARMMMUIdx mmu_idx,
V8M_SAttributes *sattrs);
/* Definitions for the PMCCNTR and PMCR registers */
#define PMCRD 0x8
#define PMCRC 0x4
#define PMCRE 0x1
#endif
static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
@ -906,6 +901,24 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
REGINFO_SENTINEL
};
/* Definitions for the PMU registers */
#define PMCRN_MASK 0xf800
#define PMCRN_SHIFT 11
#define PMCRD 0x8
#define PMCRC 0x4
#define PMCRE 0x1
static inline uint32_t pmu_num_counters(CPUARMState *env)
{
return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
}
/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
static inline uint64_t pmu_counter_mask(CPUARMState *env)
{
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
}
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
@ -1113,14 +1126,14 @@ static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
value &= (1 << 31);
value &= pmu_counter_mask(env);
env->cp15.c9_pmcnten |= value;
}
static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
value &= (1 << 31);
value &= pmu_counter_mask(env);
env->cp15.c9_pmcnten &= ~value;
}
@ -1168,14 +1181,14 @@ static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
/* We have no event counters so only the C bit can be changed */
value &= (1 << 31);
value &= pmu_counter_mask(env);
env->cp15.c9_pminten |= value;
}
static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
{
value &= (1 << 31);
value &= pmu_counter_mask(env);
env->cp15.c9_pminten &= ~value;
}