mirror of https://gitee.com/openkylin/qemu.git
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;
|
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
|
* Return the underlying cycle count for the PMU cycle counters. If we're in
|
||||||
* usermode, simply return 0.
|
* usermode, simply return 0.
|
||||||
|
@ -1054,6 +1063,10 @@ static uint64_t instructions_get_count(CPUARMState *env)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const pm_event pm_events[] = {
|
static const pm_event pm_events[] = {
|
||||||
|
{ .number = 0x000, /* SW_INCR */
|
||||||
|
.supported = event_always_supported,
|
||||||
|
.get_count = swinc_get_count,
|
||||||
|
},
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
|
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
|
||||||
.supported = instructions_supported,
|
.supported = instructions_supported,
|
||||||
|
@ -1393,6 +1406,24 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
|
||||||
pmu_op_finish(env);
|
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)
|
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
|
||||||
{
|
{
|
||||||
uint64_t ret;
|
uint64_t ret;
|
||||||
|
@ -1822,9 +1853,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
|
||||||
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
|
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
|
||||||
.writefn = pmovsr_write,
|
.writefn = pmovsr_write,
|
||||||
.raw_writefn = raw_write },
|
.raw_writefn = raw_write },
|
||||||
/* Unimplemented so WI. */
|
|
||||||
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
|
{ .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,
|
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
|
||||||
.access = PL0_RW, .type = ARM_CP_ALIAS,
|
.access = PL0_RW, .type = ARM_CP_ALIAS,
|
||||||
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
|
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
|
||||||
|
|
Loading…
Reference in New Issue