Commit 7ece99b1 authored by Aaron Lindsay's avatar Aaron Lindsay Committed by Peter Maydell
Browse files

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



This is in preparation for enabling counters other than PMCCNTR

Signed-off-by: default avatarAaron Lindsay <alindsay@codeaurora.org>
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Message-id: 1523997485-1905-5-git-send-email-alindsay@codeaurora.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 169c8938
Loading
Loading
Loading
Loading
+22 −9
Original line number Diff line number Diff line
@@ -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;
}