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

This is in preparation for enabling counters other than PMCCNTR

Backports commit 7ece99b17e832065236c07a158dfac62619ef99b from qemu
This commit is contained in:
Aaron Lindsay 2018-04-26 09:09:10 -04:00 committed by Lioncash
parent e1d021ad74
commit 1228bcf45d
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -43,11 +43,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 uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
@ -801,6 +796,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)
{
@ -1008,14 +1021,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;
}
@ -1063,14 +1076,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;
}