Skip to contentSkip to conversation

Extend the performance monitoring registers

PATCH Superseded Alistair Francis 3 participants 10 messages Feb 4, 2016 – Feb 5, 2016

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 07c0a71..1cc4502 100644
@@ -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
index 0e582c4..d3d789c 100644
@@ -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
index c847513..8c4b6fd 100644
@@ -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
index ae02486..100b6ad 100644
@@ -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
Tested-by on v1 1/3
#2 lore raw

Re: [Qemu-devel] [PATCH v1 1/3] target-arm: Add the pmceid0 and pmceid1 registers

Quoted 1 line · Alistair Francis
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
index 07c0a71..1cc4502 100644
@@ -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
index 0e582c4..d3d789c 100644
@@ -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
index c847513..8c4b6fd 100644
@@ -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
index ae02486..100b6ad 100644
@@ -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

#3 lore raw

PATCH 2/3 target-arm: Add Some of the performance monitor registers

In reply to Alistair Francis

This 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
index b8b3364..5c31c56 100644
@@ -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
Tested-by on v1 2/3
#4 lore raw

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 and PMXEVTYPER_EL0.

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
index b8b3364..5c31c56 100644
@@ -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
index 100b6ad..2e0018c 100644
@@ -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

#5 lore raw

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
index 2e0018c..c3fa57d 100644
@@ -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
Tested-by on v1 3/3
#6 lore raw

Re: [Qemu-devel] [PATCH v1 3/3] target-arm: Add the pmovsclr_el0 and pmintenclr_el1 registers

Quoted 1 line · Alistair Francis
Quoted 38 lines

---

 target-arm/helper.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
target-arm/helper.c +12 -1
index 2e0018c..c3fa57d 100644
@@ -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

#7 lore raw
In reply to Alistair Francis

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

#8 lore raw
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

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

#9 lore raw
Quoted 8 lines · Alistair Francis
Quoted 3 lines · Aaron Lindsay

Please add my

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