target/arm: Implement PMSWINC
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20181211151945.29137-14-aaron@os.amperecomputing.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
ac689a2e51
commit
0d4bfd7df8
|
@ -1027,6 +1027,15 @@ static bool event_always_supported(CPUARMState *env)
|
|||
return true;
|
||||
}
|
||||
|
||||
static uint64_t swinc_get_count(CPUARMState *env)
|
||||
{
|
||||
/*
|
||||
* SW_INCR events are written directly to the pmevcntr's by writes to
|
||||
* PMSWINC, so there is no underlying count maintained by the PMU itself
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the underlying cycle count for the PMU cycle counters. If we're in
|
||||
* usermode, simply return 0.
|
||||
|
@ -1054,6 +1063,10 @@ static uint64_t instructions_get_count(CPUARMState *env)
|
|||
#endif
|
||||
|
||||
static const pm_event pm_events[] = {
|
||||
{ .number = 0x000, /* SW_INCR */
|
||||
.supported = event_always_supported,
|
||||
.get_count = swinc_get_count,
|
||||
},
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
|
||||
.supported = instructions_supported,
|
||||
|
@ -1393,6 +1406,24 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
|||
pmu_op_finish(env);
|
||||
}
|
||||
|
||||
static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||
uint64_t value)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < pmu_num_counters(env); i++) {
|
||||
/* Increment a counter's count iff: */
|
||||
if ((value & (1 << i)) && /* counter's bit is set */
|
||||
/* counter is enabled and not filtered */
|
||||
pmu_counter_enabled(env, i) &&
|
||||
/* counter is SW_INCR */
|
||||
(env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
|
||||
pmevcntr_op_start(env, i);
|
||||
env->cp15.c14_pmevcntr[i]++;
|
||||
pmevcntr_op_finish(env, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||
{
|
||||
uint64_t ret;
|
||||
|
@ -1822,9 +1853,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
|
|||
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
|
||||
.writefn = pmovsr_write,
|
||||
.raw_writefn = raw_write },
|
||||
/* Unimplemented so WI. */
|
||||
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
|
||||
.access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
|
||||
.access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
|
||||
.writefn = pmswinc_write },
|
||||
{ .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
|
||||
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
|
||||
.access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
|
||||
.writefn = pmswinc_write },
|
||||
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
|
||||
.access = PL0_RW, .type = ARM_CP_ALIAS,
|
||||
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
|
||||
|
|
Loading…
Reference in a new issue