target-arm: Implement PMCCNTR_EL0 and related registers

This patch adds support for the ARMv8 version of the PMCCNTR and
related registers. It also starts to implement the PMCCFILTR_EL0
register.

Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Message-id: b5d1094764a5416363ee95216799b394ecd011e8.1409025949.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Alistair Francis 2014-08-29 15:00:29 +01:00 committed by Peter Maydell
parent 421c7ebd93
commit 8521466b39
2 changed files with 42 additions and 8 deletions

View File

@ -191,8 +191,8 @@ typedef struct CPUARMState {
uint64_t par_el1; /* Translation result. */ uint64_t par_el1; /* Translation result. */
uint32_t c9_insn; /* Cache lockdown registers. */ uint32_t c9_insn; /* Cache lockdown registers. */
uint32_t c9_data; uint32_t c9_data;
uint32_t c9_pmcr; /* performance monitor control register */ uint64_t c9_pmcr; /* performance monitor control register */
uint32_t c9_pmcnten; /* perf monitor counter enables */ uint64_t c9_pmcnten; /* perf monitor counter enables */
uint32_t c9_pmovsr; /* perf monitor overflow status */ uint32_t c9_pmovsr; /* perf monitor overflow status */
uint32_t c9_pmxevtyper; /* perf monitor event type */ uint32_t c9_pmxevtyper; /* perf monitor event type */
uint32_t c9_pmuserenr; /* perf monitor user enable */ uint32_t c9_pmuserenr; /* perf monitor user enable */
@ -225,6 +225,7 @@ typedef struct CPUARMState {
* was reset. Otherwise it stores the counter value * was reset. Otherwise it stores the counter value
*/ */
uint64_t c15_ccnt; uint64_t c15_ccnt;
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
} cp15; } cp15;
struct { struct {

View File

@ -736,16 +736,28 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
* or PL0_RO as appropriate and then check PMUSERENR in the helper fn. * or PL0_RO as appropriate and then check PMUSERENR in the helper fn.
*/ */
{ .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1, { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
.access = PL0_RW, .resetvalue = 0, .access = PL0_RW, .type = ARM_CP_NO_MIGRATE,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
.writefn = pmcntenset_write, .writefn = pmcntenset_write,
.accessfn = pmreg_access, .accessfn = pmreg_access,
.raw_writefn = raw_write }, .raw_writefn = raw_write },
{ .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1,
.access = PL0_RW, .accessfn = pmreg_access,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0,
.writefn = pmcntenset_write, .raw_writefn = raw_write },
{ .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2, { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .access = PL0_RW,
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
.accessfn = pmreg_access, .accessfn = pmreg_access,
.writefn = pmcntenclr_write, .writefn = pmcntenclr_write,
.type = ARM_CP_NO_MIGRATE }, .type = ARM_CP_NO_MIGRATE },
{ .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2,
.access = PL0_RW, .accessfn = pmreg_access,
.type = ARM_CP_NO_MIGRATE,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
.writefn = pmcntenclr_write },
{ .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3, { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
.access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
.accessfn = pmreg_access, .accessfn = pmreg_access,
@ -765,7 +777,18 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
.access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO, .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
.readfn = pmccntr_read, .writefn = pmccntr_write32, .readfn = pmccntr_read, .writefn = pmccntr_write32,
.accessfn = pmreg_access }, .accessfn = pmreg_access },
{ .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
.access = PL0_RW, .accessfn = pmreg_access,
.type = ARM_CP_IO,
.readfn = pmccntr_read, .writefn = pmccntr_write, },
#endif #endif
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
.access = PL0_RW, .accessfn = pmreg_access,
.type = ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
.resetvalue = 0, },
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
.access = PL0_RW, .access = PL0_RW,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper), .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
@ -2394,13 +2417,23 @@ void register_cp_regs_for_features(ARMCPU *cpu)
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
ARMCPRegInfo pmcr = { ARMCPRegInfo pmcr = {
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
.access = PL0_RW, .resetvalue = cpu->midr & 0xff000000, .access = PL0_RW,
.type = ARM_CP_IO, .type = ARM_CP_IO | ARM_CP_NO_MIGRATE,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr), .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
.accessfn = pmreg_access, .writefn = pmcr_write, .accessfn = pmreg_access, .writefn = pmcr_write,
.raw_writefn = raw_write, .raw_writefn = raw_write,
}; };
ARMCPRegInfo pmcr64 = {
.name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
.access = PL0_RW, .accessfn = pmreg_access,
.type = ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
.resetvalue = cpu->midr & 0xff000000,
.writefn = pmcr_write, .raw_writefn = raw_write,
};
define_one_arm_cp_reg(cpu, &pmcr); define_one_arm_cp_reg(cpu, &pmcr);
define_one_arm_cp_reg(cpu, &pmcr64);
#endif #endif
ARMCPRegInfo clidr = { ARMCPRegInfo clidr = {
.name = "CLIDR", .state = ARM_CP_STATE_BOTH, .name = "CLIDR", .state = ARM_CP_STATE_BOTH,