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:
parent
421c7ebd93
commit
8521466b39
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user