Extend the performance monitoring registers
cover Extend the performance monitoring registers
This patch set is based on the patch sent by Christopher Covington and written by Aaron Lindsay which was sent as an RFC (Implement remaining PMU functionality).
It adds a few performance monitoring related registers.
Alistair Francis (3):
target-arm: Add the pmceid0 and pmceid1 registers
target-arm: Add Some of the performance monitor registers
target-arm: Add the pmovsclr_el0 and pmintenclr_el1 registers
target-arm/cpu-qom.h | 2 + target-arm/cpu.c | 2 + target-arm/cpu.h | 6 +++ target-arm/cpu64.c | 2 + target-arm/helper.c | 109 +++++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 110 insertions(+), 11 deletions(-)
Signature · 1 line
2.5.0
PATCH 1/3 target-arm: Add the pmceid0 and pmceid1 registers
---
target-arm/cpu-qom.h | 2 ++ target-arm/cpu.c | 2 ++ target-arm/cpu64.c | 2 ++ target-arm/helper.c | 8 ++++++++ 4 files changed, 14 insertions(+)
target-arm/cpu-qom.h +2 -0
@@ -148,6 +148,8 @@ typedef struct ARMCPU {uint32_t id_pfr0;uint32_t id_pfr1;uint32_t id_dfr0; +uint32_t pmceid0; +uint32_t pmceid1;uint32_t id_afr0;uint32_t id_mmfr0;uint32_t id_mmfr1;
target-arm/cpu.c +2 -0
@@ -1147,6 +1147,8 @@ static void cortex_a15_initfn(Object *obj) cpu->id_pfr0 =0x00001131 ; cpu->id_pfr1 =0x00011011 ; cpu->id_dfr0 =0x02010555 ; + cpu->pmceid0 =0x00000481 ;/* PMUv3 events 0x0, 0x8, and 0x11 */ + cpu->pmceid1 =0x00000000 ; cpu->id_afr0 =0x00000000 ; cpu->id_mmfr0 =0x10201105 ; cpu->id_mmfr1 =0x20000000 ;
target-arm/cpu64.c +2 -0
@@ -134,6 +134,8 @@ static void aarch64_a57_initfn(Object *obj) cpu->id_isar5 =0x00011121 ; cpu->id_aa64pfr0 =0x00002222 ; cpu->id_aa64dfr0 =0x10305106 ; + cpu->pmceid0 =0x00000481 ;/* PMUv3 events 0x0, 0x8, and 0x11 */ + cpu->pmceid1 =0x00000000 ; cpu->id_aa64isar0 =0x00011120 ; cpu->id_aa64mmfr0 =0x00001124 ; cpu->dbgdidr =0x3516d000 ;
target-arm/helper.c +8 -0
@@ -4192,6 +4192,14 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->id_aa64dfr1 }, + { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmceid0}, + { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmceid1}, { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST,
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v1 1/3] target-arm: Add the pmceid0 and pmceid1 registers
Quoted 1 line · Alistair Francis
Signed-off-by Alistair Francis <[email protected]>
Quoted 69 lines
---
target-arm/cpu-qom.h | 2 ++ target-arm/cpu.c | 2 ++ target-arm/cpu64.c | 2 ++ target-arm/helper.c | 8 ++++++++ 4 files changed, 14 insertions(+)target-arm/cpu-qom.h +2
-0@@ -148,6 +148,8 @@ typedef struct ARMCPU {uint32_t id_pfr0;uint32_t id_pfr1;uint32_t id_dfr0; +uint32_t pmceid0; +uint32_t pmceid1;uint32_t id_afr0;uint32_t id_mmfr0;uint32_t id_mmfr1;target-arm/cpu.c +2
-0@@ -1147,6 +1147,8 @@ static void cortex_a15_initfn(Object *obj) cpu->id_pfr0 =0x00001131 ; cpu->id_pfr1 =0x00011011 ; cpu->id_dfr0 =0x02010555 ; + cpu->pmceid0 =0x00000481 ;/* PMUv3 events 0x0, 0x8, and 0x11 */ + cpu->pmceid1 =0x00000000 ; cpu->id_afr0 =0x00000000 ; cpu->id_mmfr0 =0x10201105 ; cpu->id_mmfr1 =0x20000000 ;target-arm/cpu64.c +2
-0@@ -134,6 +134,8 @@ static void aarch64_a57_initfn(Object *obj) cpu->id_isar5 =0x00011121 ; cpu->id_aa64pfr0 =0x00002222 ; cpu->id_aa64dfr0 =0x10305106 ; + cpu->pmceid0 =0x00000481 ;/* PMUv3 events 0x0, 0x8, and 0x11 */ + cpu->pmceid1 =0x00000000 ; cpu->id_aa64isar0 =0x00011120 ; cpu->id_aa64mmfr0 =0x00001124 ; cpu->dbgdidr =0x3516d000 ;target-arm/helper.c +8
-1@@ -4192,6 +4192,14 @@ void register_cp_regs_for_features(ARMCPU *cpu) .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->id_aa64dfr1 }, + { .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmceid0}, + { .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7, + .access = PL1_R, .type = ARM_CP_CONST, + .resetvalue = cpu->pmceid1}, { .name = "ID_AA64AFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 4, .access = PL1_R, .type = ARM_CP_CONST, --2.5.0
PATCH 2/3 target-arm: Add Some of the performance monitor registers
In reply to Alistair FrancisThis patch adds the following registers including read and write functions:
PMSELR, PMSELR_EL0, PMXEVCNTR, PMXEVCNTR_EL0, PMXEVTYPER and PMXEVTYPER_EL0.
---
target-arm/cpu.h | 6 ++++ target-arm/helper.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 11 deletions(-)
target-arm/cpu.h +6 -0
@@ -117,6 +117,8 @@ typedef struct ARMGenericTimer {#define GTIMER_SEC 3#define NUM_GTIMERS 4 +#define NUM_PMU_COUNTERS 4 + typedef struct { uint64_t raw_tcr; uint32_t mask;
@@ -300,6 +302,7 @@ typedef struct CPUARMState {uint32_t c9_pmxevtyper;/* perf monitor event type */ uint32_t c9_pmuserenr;/* perf monitor user enable */ uint32_t c9_pminten;/* perf monitor interrupt enables */ +uint32_t c9_pmselr;/* perf monitor event counter selection */ union { /* Memory attribute redirection */ struct { #ifdef HOST_WORDS_BIGENDIAN
@@ -361,6 +364,9 @@ typedef struct CPUARMState {uint64_t tpidruro_ns;uint64_t tpidrro_el[1 ]; }; +uint32_t c14_pmccfiltr;/* Performance Monitor Filter Register */ +uint32_t c14_pmevcntr[NUM_PMU_COUNTERS ]; +uint32_t c14_pmevtyper[NUM_PMU_COUNTERS ];uint64_t c14_cntfrq;/* Counter Frequency register */ uint64_t c14_cntkctl;/* Timer Control register */ uint32_t cnthctl_el2;/* Counter/Timer Hyp Control register */
target-arm/helper.c +78 -11
107 lines not on this page · raw message
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v1 2/3] target-arm: Add Some of the performance monitor registers
Quoted 4 lines · Alistair Francis
This patch adds the following registers including read and write functions:
PMSELR,PMSELR_EL0, PMXEVCNTR,PMXEVCNTR_EL0, PMXEVTYPER andPMXEVTYPER_EL0.Signed-off-by Alistair Francis <[email protected]>
Quoted 154 lines
---
target-arm/cpu.h | 6 ++++ target-arm/helper.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 84 insertions(+), 11 deletions(-)target-arm/cpu.h +6
-0@@ -117,6 +117,8 @@ typedef struct ARMGenericTimer {#define GTIMER_SEC 3#define NUM_GTIMERS 4 +#define NUM_PMU_COUNTERS 4 + typedef struct { uint64_t raw_tcr; uint32_t mask;@@ -300,6 +302,7 @@ typedef struct CPUARMState {uint32_t c9_pmxevtyper;/* perf monitor event type */ uint32_t c9_pmuserenr;/* perf monitor user enable */ uint32_t c9_pminten;/* perf monitor interrupt enables */ +uint32_t c9_pmselr;/* perf monitor event counter selection */ union { /* Memory attribute redirection */ struct { #ifdef HOST_WORDS_BIGENDIAN@@ -361,6 +364,9 @@ typedef struct CPUARMState {uint64_t tpidruro_ns;uint64_t tpidrro_el[1 ]; }; +uint32_t c14_pmccfiltr;/* Performance Monitor Filter Register */ +uint32_t c14_pmevcntr[NUM_PMU_COUNTERS ]; +uint32_t c14_pmevtyper[NUM_PMU_COUNTERS ];uint64_t c14_cntfrq;/* Counter Frequency register */ uint64_t c14_cntkctl;/* Timer Control register */ uint32_t cnthctl_el2;/* Counter/Timer Hyp Control register */ target-arm/helper.c +78
-12@@ -807,6 +807,58 @@ void pmccntr_sync(CPUARMState *env)#endif +static void pmselr_write (CPUARMState *env,const ARMCPRegInfo *ri, +uint64_t value) +{ + env->cp15.c9_pmselr = value &31 ; +} + +static uint64_t pmevcntr_read (CPUARMState *env,const ARMCPRegInfo *ri, +const uint8_t idx) +{ +if (idx >=NUM_PMU_COUNTERS ) { +return arm_cp_read_zero (env, ri); + } +return env->cp15.c14_pmevcntr[idx]; +} + +static uint64_t pmxevcntr_read (CPUARMState *env,const ARMCPRegInfo *ri) +{ +return pmevcntr_read (env, ri, env->cp15.c9_pmselr &31 ); +} + +static void pmevcntr_write (CPUARMState *env,const ARMCPRegInfo *ri, +uint64_t value,const uint8_t idx) +{ +if (idx >=NUM_PMU_COUNTERS ) { +return arm_cp_write_ignore (env, ri, value); + } + env->cp15.c14_pmevcntr[idx] = value; +} + +static void pmxevcntr_write (CPUARMState *env,const ARMCPRegInfo *ri, +uint64_t value) +{ +pmevcntr_write (env, ri, value, env->cp15.c9_pmselr &31 ); +} + +static uint64_t pmevtyper_read (CPUARMState *env,const ARMCPRegInfo *ri, +const uint8_t idx) +{ +if (idx >=NUM_PMU_COUNTERS ) { +return arm_cp_read_zero (env, ri); + } +return env->cp15.c14_pmevtyper[idx]; +} + +static uint64_t pmxevtyper_read (CPUARMState *env,const ARMCPRegInfo *ri) +{ +if (!!(env->cp15.c9_pmselr &31 )) { +return env->cp15.c14_pmccfiltr; + } +return pmevtyper_read (env, ri, env->cp15.c9_pmselr &31 ); +} +static void pmccfiltr_write (CPUARMState *env,const ARMCPRegInfo *ri,uint64_t value) {@@ -986,8 +1038,32 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {* We choose to RAZ/WI. */ { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, - .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, - .accessfn = pmreg_access }, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .accessfn = pmreg_access, .writefn = pmselr_write, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr) }, + { .name = "PMSELR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 5, + .access = PL0_RW, .accessfn = pmreg_access, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr), + .writefn = pmselr_write, .resetvalue = 0 }, + { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .accessfn = pmreg_access, .writefn = pmxevcntr_write, + .readfn = pmxevcntr_read }, + { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .accessfn = pmreg_access, .writefn = pmxevcntr_write, + .readfn = pmxevcntr_read }, + { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .accessfn = pmreg_access, .writefn = pmxevtyper_write, + .readfn = pmxevtyper_read }, + { .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1, + .access = PL0_RW, .type = ARM_CP_ALIAS, + .accessfn = pmreg_access, .writefn = pmxevtyper_write, + .readfn = pmxevtyper_read }, #ifndef CONFIG_USER_ONLY { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0, .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,@@ -1006,15 +1082,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .type = ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), .resetvalue = 0, }, - { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, - .access = PL0_RW, - .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper), - .accessfn = pmreg_access, .writefn = pmxevtyper_write, - .raw_writefn = raw_write }, - /* Unimplemented, RAZ/WI. */ - { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2, - .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, - .accessfn = pmreg_access }, { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0, .access = PL0_R | PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr), --2.5.0
PATCH 3/3 target-arm: Add the pmovsclr_el0 and pmintenclr_el1 registers
In reply to Alistair Francis---
target-arm/helper.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
target-arm/helper.c +12 -0
@@ -1031,6 +1031,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .accessfn = pmreg_access, .writefn = pmovsr_write, .raw_writefn = raw_write }, + { .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS, + .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, .type = ARM_CP_NOP },
@@ -1096,6 +1103,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .access = PL1_RW, .type = ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .writefn = pmintenclr_write, }, + { .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .writefn = pmintenclr_write }, { .name = "VBAR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .writefn = vbar_write,
Signature · 1 line
2.5.0
Re: [Qemu-devel] [PATCH v1 3/3] target-arm: Add the pmovsclr_el0 and pmintenclr_el1 registers
Quoted 1 line · Alistair Francis
Signed-off-by Alistair Francis <[email protected]>
Quoted 38 lines
---
target-arm/helper.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)target-arm/helper.c +12
-1@@ -1031,6 +1031,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .accessfn = pmreg_access, .writefn = pmovsr_write, .raw_writefn = raw_write }, + { .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS, + .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, .type = ARM_CP_NOP },@@ -1096,6 +1103,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .access = PL1_RW, .type = ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .writefn = pmintenclr_write, }, + { .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), + .writefn = pmintenclr_write }, { .name = "VBAR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, .access = PL1_RW, .writefn = vbar_write, --2.5.0
Alistair,
Quoted 3 lines · Alistair Francis
This patch set is based on the patch sent by Christopher Covington and written by Aaron Lindsay which was sent as an RFC (Implement remaining PMU functionality).
These patches look like a good start to improving the PMU support, thanks for splitting them out for review.
Please add my
to all three.
If you're so inclined, you can also add me as Author (Chris originally omitted it for reasons that no longer apply), but that's up to you.
-Aaron
Quoted 7 lines · Aaron Lindsay
Alistair,
Quoted 3 lines · Alistair Francis
This patch set is based on the patch sent by Christopher Covington and written by Aaron Lindsay which was sent as an RFC (Implement remaining PMU functionality).
Quoted 6 lines
These patches look like a good start to improving the PMU support, thanks for splitting them out for review.
Please add my
Signed-off-by Aaron Lindsay <[email protected]>to all three.
Ok, I wasn't sure what you wanted to do there. I'll add them all and they will be there in the next version. I won't re-send this one until I have some comments. Is that ok with you?
Thanks,
Alistair
Quoted 6 lines
If you're so inclined, you can also add me as Author (Chris originally omitted it for reasons that no longer apply), but that's up to you.
-Aaron
Quoted 8 lines · Alistair Francis
Quoted 3 lines · Aaron Lindsay
Please add my
Signed-off-by Aaron Lindsay <[email protected]>to all three.
Ok, I wasn't sure what you wanted to do there. I'll add them all and they will be there in the next version. I won't re-send this one until I have some comments. Is that ok with you?
Absolutely.
-Aaron