All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU
@ 2020-02-11 17:37 Peter Maydell
  2020-02-11 17:37 ` [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers Peter Maydell
                   ` (12 more replies)
  0 siblings, 13 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

This patchset implements the ARMv8.1-PMU and ARMv8.4-PMU architecture
extensions. These are fairly small changes on top of the basic
PMUv3 we already implement, and in fact we already had most of
the v8.1-PMU functionality implemented but unadvertised.

In the course of doing this, I found that our naming and use of
isar_feature ID register test functions was slightly inconsistent,
so the first few patches straighten this out and align on:

 * functions which test AArch32 ID registers always have an
   _aa32_ infix in their name, and can only be used if we
   know the CPU has AArch32 (eg in codegen in translate.c)
   or if "false" is the right answer for a no-AArch32 CPU
   (eg registering AArch32-only system registers, or
   determining whether to allow guest writes to sysreg bits
   that are writeable only on the AArch32 version of the reg)
 * functions which test AArch64 ID registers always have an
   _aa64_ infix in their name, and can only be used if
   we know the CPU has AArch64 or if "false" is the right
   answer for a no-AArch64 CPU
 * functions with an _any_ infix always return the logical
   OR of the _aa32_ and _aa64_ tests, and should be used
   when we want to know "does this feature exist" in code
   that might be called for AArch32 or AArch64

I have audited all the callsites of isar_feature tests and they
almost all followed this naming convention and usage already.  We
were missing the _aa32_ infix in the arm_div, thumb_div and jazelle
tests, and we needed an _any_ version of the function for fp16
(specifically whether FP(S)CR.FZ16 is writeable) and for predinv
(whether to register the sysregs).

Having got those preliminaries out of the way, we can define _aa32_,
_aa64_ and _any_ versions of "do I have a PMUv3 with the v8.1
extensions?", and use them when implementing the extended
functionality.

The ARMv8.1-PMU extension requires:
 * the evtCount field in PMETYPER<n>_EL0 is 16 bits, not 10
 * MDCR_EL2.HPMD allows event counting to be disabled at EL2
 * two new required events, STALL_FRONTEND and STALL_BACKEND
 * ID register bits in ID_AA64DFR0_EL1 and ID_DFR0
We already implement all of that except the new events;
for QEMU our CPU never "stalls" in that sense, so we can
just implement them as always-reads-zero.

The ARMv8.4-PMU extension adds:
 * one new required event, STALL (again, reads-as-zero)
 * one new system register PMMIR_EL1, which provides information
   about the PMU implementation. Since the only currently defined
   field in it relates to an event we don't provide, we can
   validly implement the register as RAZ.

The final two patches fix some bugs I discovered while
running this through Eric's recent kvm-unit-tests PMU tests:
 * we had the wrong definition of the PMCR.DP bit position
 * we incorrectly implemented PMCR.LC as RAZ/WI

I've tested this with Eric's unit tests, and by running 'perf test'
in a VM (which had some failures but none which seemed to be related
to these changes).  I don't generally use the perf emulation, so
testing would be welcome from people who do.

Based-on: 20200210120146.17631-1-peter.maydell@linaro.org
("target/arm: Implement ARMv8.1-VMID16 extension")
purely to avoid possible textual conflicts.

thanks
-- PMM


Peter Maydell (13):
  target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID
    registers
  target/arm: Add isar_feature_any_fp16 and document naming/usage
    conventions
  target/arm: Define and use any_predinv isar_feature test
  target/arm: Factor out PMU register definitions
  target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
  target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
  target/arm: Define an aa32_pmu_8_1 isar feature test function
  target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
  target/arm: Implement ARMv8.1-PMU extension
  target/arm: Implement ARMv8.4-PMU extension
  target/arm: Provide ARMv8.4-PMU in '-cpu max'
  target/arm: Correct definition of PMCRDP
  target/arm: Correct handling of PMCR_EL0.LC bit

 target/arm/cpu.h        |  87 +++++++++++++-
 hw/intc/armv7m_nvic.c   |   2 +-
 linux-user/elfload.c    |   4 +-
 target/arm/cpu.c        |  37 +++---
 target/arm/cpu64.c      |  20 +++-
 target/arm/helper.c     | 248 ++++++++++++++++++++++++----------------
 target/arm/translate.c  |   6 +-
 target/arm/vfp_helper.c |   2 +-
 8 files changed, 273 insertions(+), 133 deletions(-)

-- 
2.20.1



^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:25   ` Richard Henderson
  2020-02-12  6:23   ` Philippe Mathieu-Daudé
  2020-02-11 17:37 ` [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions Peter Maydell
                   ` (11 subsequent siblings)
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Enforce a convention that an isar_feature function that tests a
32-bit ID register always has _aa32_ in its name, and one that
tests a 64-bit ID register always has _aa64_ in its name.
We already follow this except for three cases: thumb_div,
arm_div and jazelle, which all need _aa32_ adding.

(As noted in the comment, isar_feature_aa32_fp16_arith()
is an exception in that it currently tests ID_AA64PFR0_EL1,
but will switch to MVFR1 once we've properly implemented
FP16 for AArch32.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h       | 13 ++++++++++---
 linux-user/elfload.c   |  4 ++--
 target/arm/cpu.c       |  6 ++++--
 target/arm/helper.c    |  2 +-
 target/arm/translate.c |  6 +++---
 5 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 608fcbd0b75..ad2f0e172a7 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3396,20 +3396,27 @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
 /* Shared between translate-sve.c and sve_helper.c.  */
 extern const uint64_t pred_esz_masks[4];
 
+/*
+ * Naming convention for isar_feature functions:
+ * Functions which test 32-bit ID registers should have _aa32_ in
+ * their name. Functions which test 64-bit ID registers should have
+ * _aa64_ in their name.
+ */
+
 /*
  * 32-bit feature tests via id registers.
  */
-static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
+static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
 {
     return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
 }
 
-static inline bool isar_feature_arm_div(const ARMISARegisters *id)
+static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
 {
     return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
 }
 
-static inline bool isar_feature_jazelle(const ARMISARegisters *id)
+static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
 {
     return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
 }
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f3080a16358..b1a895f24ce 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -475,8 +475,8 @@ static uint32_t get_elf_hwcap(void)
     GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
     GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
     GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
-    GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
-    GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
+    GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
+    GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
     /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
      * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
      * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f86e71a260d..5712082c0b9 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1470,7 +1470,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
          * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
          * Security Extensions is ARM_FEATURE_EL3.
          */
-        assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(arm_div, cpu));
+        assert(!tcg_enabled() || no_aa32 ||
+               cpu_isar_feature(aa32_arm_div, cpu));
         set_feature(env, ARM_FEATURE_LPAE);
         set_feature(env, ARM_FEATURE_V7);
     }
@@ -1496,7 +1497,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
     if (arm_feature(env, ARM_FEATURE_V6)) {
         set_feature(env, ARM_FEATURE_V5);
         if (!arm_feature(env, ARM_FEATURE_M)) {
-            assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(jazelle, cpu));
+            assert(!tcg_enabled() || no_aa32 ||
+                   cpu_isar_feature(aa32_jazelle, cpu));
             set_feature(env, ARM_FEATURE_AUXCR);
         }
     }
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 19a57a17da5..ddfd0183d98 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6781,7 +6781,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
         define_arm_cp_regs(cpu, lpae_cp_reginfo);
     }
-    if (cpu_isar_feature(jazelle, cpu)) {
+    if (cpu_isar_feature(aa32_jazelle, cpu)) {
         define_arm_cp_regs(cpu, jazelle_regs);
     }
     /* Slightly awkwardly, the OMAP and StrongARM cores need all of
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 2f4aea927f1..052992037cc 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -42,7 +42,7 @@
 #define ENABLE_ARCH_5     arm_dc_feature(s, ARM_FEATURE_V5)
 /* currently all emulated v5 cores are also v5TE, so don't bother */
 #define ENABLE_ARCH_5TE   arm_dc_feature(s, ARM_FEATURE_V5)
-#define ENABLE_ARCH_5J    dc_isar_feature(jazelle, s)
+#define ENABLE_ARCH_5J    dc_isar_feature(aa32_jazelle, s)
 #define ENABLE_ARCH_6     arm_dc_feature(s, ARM_FEATURE_V6)
 #define ENABLE_ARCH_6K    arm_dc_feature(s, ARM_FEATURE_V6K)
 #define ENABLE_ARCH_6T2   arm_dc_feature(s, ARM_FEATURE_THUMB2)
@@ -9850,8 +9850,8 @@ static bool op_div(DisasContext *s, arg_rrr *a, bool u)
     TCGv_i32 t1, t2;
 
     if (s->thumb
-        ? !dc_isar_feature(thumb_div, s)
-        : !dc_isar_feature(arm_div, s)) {
+        ? !dc_isar_feature(aa32_thumb_div, s)
+        : !dc_isar_feature(aa32_arm_div, s)) {
         return false;
     }
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
  2020-02-11 17:37 ` [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:28   ` Richard Henderson
  2020-02-12  6:24   ` Philippe Mathieu-Daudé
  2020-02-11 17:37 ` [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test Peter Maydell
                   ` (10 subsequent siblings)
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Our current usage of the isar_feature feature tests almost always
uses an _aa32_ test when the code path is known to be AArch32
specific and an _aa64_ test when the code path is known to be
AArch64 specific. There is just one exception: in the vfp_set_fpscr
helper we check aa64_fp16 to determine whether the FZ16 bit in
the FP(S)CR exists, but this code is also used for AArch32.
There are other places in future where we're likely to want
a general "does this feature exist for either AArch32 or
AArch64" check (typically where architecturally the feature exists
for both CPU states if it exists at all, but the CPU might be
AArch32-only or AArch64-only, and so only have one set of ID
registers).

Introduce a new category of isar_feature_* functions:
isar_feature_any_foo() should be tested when what we want to
know is "does this feature exist for either AArch32 or AArch64",
and always returns the logical OR of isar_feature_aa32_foo()
and isar_feature_aa64_foo().

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h        | 19 ++++++++++++++++++-
 target/arm/vfp_helper.c |  2 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ad2f0e172a7..ac4b7950166 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3400,7 +3400,16 @@ extern const uint64_t pred_esz_masks[4];
  * Naming convention for isar_feature functions:
  * Functions which test 32-bit ID registers should have _aa32_ in
  * their name. Functions which test 64-bit ID registers should have
- * _aa64_ in their name.
+ * _aa64_ in their name. These must only be used in code where we
+ * know for certain that the CPU has AArch32 or AArch64 respectively
+ * or where the correct answer for a CPU which doesn't implement that
+ * CPU state is "false" (eg when generating A32 or A64 code, if adding
+ * system registers that are specific to that CPU state, for "should
+ * we let this system register bit be set" tests where the 32-bit
+ * flavour of the register doesn't have the bit, and so on).
+ * Functions which simply ask "does this feature exist at all" have
+ * _any_ in their name, and always return the logical OR of the _aa64_
+ * and the _aa32_ function.
  */
 
 /*
@@ -3702,6 +3711,14 @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
 }
 
+/*
+ * Feature tests for "does this exist in either 32-bit or 64-bit?"
+ */
+static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
+{
+    return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
+}
+
 /*
  * Forward to the above feature tests given an ARMCPU pointer.
  */
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index 0ae7d4f34a9..930d6e747f6 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -185,7 +185,7 @@ uint32_t vfp_get_fpscr(CPUARMState *env)
 void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
 {
     /* When ARMv8.2-FP16 is not supported, FZ16 is RES0.  */
-    if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
+    if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
         val &= ~FPCR_FZ16;
     }
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
  2020-02-11 17:37 ` [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers Peter Maydell
  2020-02-11 17:37 ` [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:29   ` Richard Henderson
  2020-02-12  6:24   ` Philippe Mathieu-Daudé
  2020-02-11 17:37 ` [PATCH 04/13] target/arm: Factor out PMU register definitions Peter Maydell
                   ` (9 subsequent siblings)
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Instead of open-coding "ARM_FEATURE_AARCH64 ? aa64_predinv: aa32_predinv",
define and use an any_predinv isar_feature test function.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h    | 5 +++++
 target/arm/helper.c | 9 +--------
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ac4b7950166..b1f3ecfd942 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3719,6 +3719,11 @@ static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
     return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
 }
 
+static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
+{
+    return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
+}
+
 /*
  * Forward to the above feature tests given an ARMCPU pointer.
  */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index ddfd0183d98..bf083c369fc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7116,14 +7116,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 #endif /*CONFIG_USER_ONLY*/
 #endif
 
-    /*
-     * While all v8.0 cpus support aarch64, QEMU does have configurations
-     * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
-     * which will set ID_ISAR6.
-     */
-    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
-        ? cpu_isar_feature(aa64_predinv, cpu)
-        : cpu_isar_feature(aa32_predinv, cpu)) {
+    if (cpu_isar_feature(any_predinv, cpu)) {
         define_arm_cp_regs(cpu, predinv_reginfo);
     }
 }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 04/13] target/arm: Factor out PMU register definitions
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (2 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:30   ` Richard Henderson
  2020-02-12  6:40   ` Philippe Mathieu-Daudé
  2020-02-11 17:37 ` [PATCH 05/13] target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1 Peter Maydell
                   ` (8 subsequent siblings)
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Pull the code that defines the various PMU registers out
into its own function, matching the pattern we have
already for the debug registers.

Apart from one style fix to a multi-line comment, this
is purely movement of code with no changes to it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/helper.c | 158 +++++++++++++++++++++++---------------------
 1 file changed, 82 insertions(+), 76 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index bf083c369fc..0011a22f42d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5822,6 +5822,87 @@ static void define_debug_regs(ARMCPU *cpu)
     }
 }
 
+static void define_pmu_regs(ARMCPU *cpu)
+{
+    /*
+     * v7 performance monitor control register: same implementor
+     * field as main ID register, and we implement four counters in
+     * addition to the cycle count register.
+     */
+    unsigned int i, pmcrn = 4;
+    ARMCPRegInfo pmcr = {
+        .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
+        .access = PL0_RW,
+        .type = ARM_CP_IO | ARM_CP_ALIAS,
+        .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
+        .accessfn = pmreg_access, .writefn = pmcr_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) | (pmcrn << PMCRN_SHIFT),
+        .writefn = pmcr_write, .raw_writefn = raw_write,
+    };
+    define_one_arm_cp_reg(cpu, &pmcr);
+    define_one_arm_cp_reg(cpu, &pmcr64);
+    for (i = 0; i < pmcrn; i++) {
+        char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
+        char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
+        char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
+        char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
+        ARMCPRegInfo pmev_regs[] = {
+            { .name = pmevcntr_name, .cp = 15, .crn = 14,
+              .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
+              .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
+              .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
+              .accessfn = pmreg_access },
+            { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
+              .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
+              .type = ARM_CP_IO,
+              .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
+              .raw_readfn = pmevcntr_rawread,
+              .raw_writefn = pmevcntr_rawwrite },
+            { .name = pmevtyper_name, .cp = 15, .crn = 14,
+              .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
+              .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
+              .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
+              .accessfn = pmreg_access },
+            { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
+              .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
+              .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
+              .type = ARM_CP_IO,
+              .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
+              .raw_writefn = pmevtyper_rawwrite },
+            REGINFO_SENTINEL
+        };
+        define_arm_cp_regs(cpu, pmev_regs);
+        g_free(pmevcntr_name);
+        g_free(pmevcntr_el0_name);
+        g_free(pmevtyper_name);
+        g_free(pmevtyper_el0_name);
+    }
+    if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
+            FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
+        ARMCPRegInfo v81_pmu_regs[] = {
+            { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
+              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
+              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
+              .resetvalue = extract64(cpu->pmceid0, 32, 32) },
+            { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
+              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
+              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
+              .resetvalue = extract64(cpu->pmceid1, 32, 32) },
+            REGINFO_SENTINEL
+        };
+        define_arm_cp_regs(cpu, v81_pmu_regs);
+    }
+}
+
 /* We don't know until after realize whether there's a GICv3
  * attached, and that is what registers the gicv3 sysregs.
  * So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
@@ -6244,67 +6325,6 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
     }
     if (arm_feature(env, ARM_FEATURE_V7)) {
-        /* v7 performance monitor control register: same implementor
-         * field as main ID register, and we implement four counters in
-         * addition to the cycle count register.
-         */
-        unsigned int i, pmcrn = 4;
-        ARMCPRegInfo pmcr = {
-            .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
-            .access = PL0_RW,
-            .type = ARM_CP_IO | ARM_CP_ALIAS,
-            .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
-            .accessfn = pmreg_access, .writefn = pmcr_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) | (pmcrn << PMCRN_SHIFT),
-            .writefn = pmcr_write, .raw_writefn = raw_write,
-        };
-        define_one_arm_cp_reg(cpu, &pmcr);
-        define_one_arm_cp_reg(cpu, &pmcr64);
-        for (i = 0; i < pmcrn; i++) {
-            char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
-            char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
-            char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
-            char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
-            ARMCPRegInfo pmev_regs[] = {
-                { .name = pmevcntr_name, .cp = 15, .crn = 14,
-                  .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
-                  .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
-                  .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
-                  .accessfn = pmreg_access },
-                { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
-                  .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
-                  .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
-                  .type = ARM_CP_IO,
-                  .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
-                  .raw_readfn = pmevcntr_rawread,
-                  .raw_writefn = pmevcntr_rawwrite },
-                { .name = pmevtyper_name, .cp = 15, .crn = 14,
-                  .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
-                  .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
-                  .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
-                  .accessfn = pmreg_access },
-                { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
-                  .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
-                  .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
-                  .type = ARM_CP_IO,
-                  .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
-                  .raw_writefn = pmevtyper_rawwrite },
-                REGINFO_SENTINEL
-            };
-            define_arm_cp_regs(cpu, pmev_regs);
-            g_free(pmevcntr_name);
-            g_free(pmevcntr_el0_name);
-            g_free(pmevtyper_name);
-            g_free(pmevtyper_el0_name);
-        }
         ARMCPRegInfo clidr = {
             .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
             .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
@@ -6315,24 +6335,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         define_one_arm_cp_reg(cpu, &clidr);
         define_arm_cp_regs(cpu, v7_cp_reginfo);
         define_debug_regs(cpu);
+        define_pmu_regs(cpu);
     } else {
         define_arm_cp_regs(cpu, not_v7_cp_reginfo);
     }
-    if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
-            FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
-        ARMCPRegInfo v81_pmu_regs[] = {
-            { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
-              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
-              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
-              .resetvalue = extract64(cpu->pmceid0, 32, 32) },
-            { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
-              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
-              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
-              .resetvalue = extract64(cpu->pmceid1, 32, 32) },
-            REGINFO_SENTINEL
-        };
-        define_arm_cp_regs(cpu, v81_pmu_regs);
-    }
     if (arm_feature(env, ARM_FEATURE_V8)) {
         /* AArch64 ID registers, which all have impdef reset values.
          * Note that within the ID register ranges the unused slots
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 05/13] target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (3 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 04/13] target/arm: Factor out PMU register definitions Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:34   ` Richard Henderson
  2020-02-11 17:37 ` [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field Peter Maydell
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Add FIELD() definitions for the ID_AA64DFR0_EL1 and use them
where we currently have hard-coded bit values.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h    | 10 ++++++++++
 target/arm/cpu.c    |  2 +-
 target/arm/helper.c |  6 +++---
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index b1f3ecfd942..f2194b27ba3 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1806,6 +1806,16 @@ FIELD(ID_AA64MMFR1, PAN, 20, 4)
 FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
 FIELD(ID_AA64MMFR1, XNX, 28, 4)
 
+FIELD(ID_AA64DFR0, DEBUGVER, 0, 4)
+FIELD(ID_AA64DFR0, TRACEVER, 4, 4)
+FIELD(ID_AA64DFR0, PMUVER, 8, 4)
+FIELD(ID_AA64DFR0, BRPS, 12, 4)
+FIELD(ID_AA64DFR0, WRPS, 20, 4)
+FIELD(ID_AA64DFR0, CTX_CMPS, 28, 4)
+FIELD(ID_AA64DFR0, PMSVER, 32, 4)
+FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
+FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
+
 FIELD(ID_DFR0, COPDBG, 0, 4)
 FIELD(ID_DFR0, COPSDBG, 4, 4)
 FIELD(ID_DFR0, MMAPDBG, 8, 4)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5712082c0b9..dc582da8fa4 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1602,7 +1602,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
                 cpu);
 #endif
     } else {
-        cpu->id_aa64dfr0 &= ~0xf00;
+        cpu->id_aa64dfr0 = FIELD_DP32(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
         cpu->id_dfr0 &= ~(0xf << 24);
         cpu->pmceid0 = 0;
         cpu->pmceid1 = 0;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0011a22f42d..2a57bfd9e86 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5771,9 +5771,9 @@ static void define_debug_regs(ARMCPU *cpu)
      * check that if they both exist then they agree.
      */
     if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
-        assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
-        assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
-        assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
+        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
+        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
+        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
     }
 
     define_one_arm_cp_reg(cpu, &dbgdidr);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (4 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 05/13] target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1 Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:34   ` Richard Henderson
  2020-02-12  6:48   ` Philippe Mathieu-Daudé
  2020-02-11 17:37 ` [PATCH 07/13] target/arm: Define an aa32_pmu_8_1 isar feature test function Peter Maydell
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

We already define FIELD macros for ID_DFR0, so use them in the
one place where we're doing direct bit value manipulation.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
We have lots of this non-FIELD style in the code, of course;
I change this one purely because it otherwise looks a bit odd
sat next to the ID_AA64DFR0 line that was changed in the previous
patch...
---
 target/arm/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index dc582da8fa4..e7858b073b5 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1603,7 +1603,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
 #endif
     } else {
         cpu->id_aa64dfr0 = FIELD_DP32(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
-        cpu->id_dfr0 &= ~(0xf << 24);
+        cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
         cpu->pmceid0 = 0;
         cpu->pmceid1 = 0;
     }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 07/13] target/arm: Define an aa32_pmu_8_1 isar feature test function
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (5 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:38   ` Richard Henderson
  2020-02-11 17:37 ` [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks Peter Maydell
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Instead of open-coding a check on the ID_DFR0 PerfMon ID register
field, create a standardly-named isar_feature for "does AArch32 have
a v8.1 PMUv3" and use it.

This entails moving the id_dfr0 field into the ARMISARegisters struct.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h      |  9 ++++++++-
 hw/intc/armv7m_nvic.c |  2 +-
 target/arm/cpu.c      | 28 ++++++++++++++--------------
 target/arm/cpu64.c    |  6 +++---
 target/arm/helper.c   |  5 ++---
 5 files changed, 28 insertions(+), 22 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f2194b27ba3..b55f6c8b7d3 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -864,6 +864,7 @@ struct ARMCPU {
         uint32_t mvfr0;
         uint32_t mvfr1;
         uint32_t mvfr2;
+        uint32_t id_dfr0;
         uint64_t id_aa64isar0;
         uint64_t id_aa64isar1;
         uint64_t id_aa64pfr0;
@@ -878,7 +879,6 @@ struct ARMCPU {
     uint32_t reset_sctlr;
     uint32_t id_pfr0;
     uint32_t id_pfr1;
-    uint32_t id_dfr0;
     uint64_t pmceid0;
     uint64_t pmceid1;
     uint32_t id_afr0;
@@ -3562,6 +3562,13 @@ static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
     return FIELD_EX64(id->mvfr2, MVFR2, FPMISC) >= 4;
 }
 
+static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
+{
+    /* 0xf means "non-standard IMPDEF PMU" */
+    return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
+        FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+}
+
 /*
  * 64-bit feature tests via id registers.
  */
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index f9e0eeaace6..5a403fc9704 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1227,7 +1227,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
     case 0xd44: /* PFR1.  */
         return cpu->id_pfr1;
     case 0xd48: /* DFR0.  */
-        return cpu->id_dfr0;
+        return cpu->isar.id_dfr0;
     case 0xd4c: /* AFR0.  */
         return cpu->id_afr0;
     case 0xd50: /* MMFR0.  */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index e7858b073b5..ac0c96322d1 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1603,7 +1603,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
 #endif
     } else {
         cpu->id_aa64dfr0 = FIELD_DP32(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
-        cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);
+        cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
         cpu->pmceid0 = 0;
         cpu->pmceid1 = 0;
     }
@@ -1841,7 +1841,7 @@ static void arm1136_r2_initfn(Object *obj)
     cpu->reset_sctlr = 0x00050078;
     cpu->id_pfr0 = 0x111;
     cpu->id_pfr1 = 0x1;
-    cpu->id_dfr0 = 0x2;
+    cpu->isar.id_dfr0 = 0x2;
     cpu->id_afr0 = 0x3;
     cpu->id_mmfr0 = 0x01130003;
     cpu->id_mmfr1 = 0x10030302;
@@ -1873,7 +1873,7 @@ static void arm1136_initfn(Object *obj)
     cpu->reset_sctlr = 0x00050078;
     cpu->id_pfr0 = 0x111;
     cpu->id_pfr1 = 0x1;
-    cpu->id_dfr0 = 0x2;
+    cpu->isar.id_dfr0 = 0x2;
     cpu->id_afr0 = 0x3;
     cpu->id_mmfr0 = 0x01130003;
     cpu->id_mmfr1 = 0x10030302;
@@ -1906,7 +1906,7 @@ static void arm1176_initfn(Object *obj)
     cpu->reset_sctlr = 0x00050078;
     cpu->id_pfr0 = 0x111;
     cpu->id_pfr1 = 0x11;
-    cpu->id_dfr0 = 0x33;
+    cpu->isar.id_dfr0 = 0x33;
     cpu->id_afr0 = 0;
     cpu->id_mmfr0 = 0x01130003;
     cpu->id_mmfr1 = 0x10030302;
@@ -1936,7 +1936,7 @@ static void arm11mpcore_initfn(Object *obj)
     cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
     cpu->id_pfr0 = 0x111;
     cpu->id_pfr1 = 0x1;
-    cpu->id_dfr0 = 0;
+    cpu->isar.id_dfr0 = 0;
     cpu->id_afr0 = 0x2;
     cpu->id_mmfr0 = 0x01100103;
     cpu->id_mmfr1 = 0x10020302;
@@ -1968,7 +1968,7 @@ static void cortex_m3_initfn(Object *obj)
     cpu->pmsav7_dregion = 8;
     cpu->id_pfr0 = 0x00000030;
     cpu->id_pfr1 = 0x00000200;
-    cpu->id_dfr0 = 0x00100000;
+    cpu->isar.id_dfr0 = 0x00100000;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x00000030;
     cpu->id_mmfr1 = 0x00000000;
@@ -1999,7 +1999,7 @@ static void cortex_m4_initfn(Object *obj)
     cpu->isar.mvfr2 = 0x00000000;
     cpu->id_pfr0 = 0x00000030;
     cpu->id_pfr1 = 0x00000200;
-    cpu->id_dfr0 = 0x00100000;
+    cpu->isar.id_dfr0 = 0x00100000;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x00000030;
     cpu->id_mmfr1 = 0x00000000;
@@ -2030,7 +2030,7 @@ static void cortex_m7_initfn(Object *obj)
     cpu->isar.mvfr2 = 0x00000040;
     cpu->id_pfr0 = 0x00000030;
     cpu->id_pfr1 = 0x00000200;
-    cpu->id_dfr0 = 0x00100000;
+    cpu->isar.id_dfr0 = 0x00100000;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x00100030;
     cpu->id_mmfr1 = 0x00000000;
@@ -2063,7 +2063,7 @@ static void cortex_m33_initfn(Object *obj)
     cpu->isar.mvfr2 = 0x00000040;
     cpu->id_pfr0 = 0x00000030;
     cpu->id_pfr1 = 0x00000210;
-    cpu->id_dfr0 = 0x00200000;
+    cpu->isar.id_dfr0 = 0x00200000;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x00101F40;
     cpu->id_mmfr1 = 0x00000000;
@@ -2115,7 +2115,7 @@ static void cortex_r5_initfn(Object *obj)
     cpu->midr = 0x411fc153; /* r1p3 */
     cpu->id_pfr0 = 0x0131;
     cpu->id_pfr1 = 0x001;
-    cpu->id_dfr0 = 0x010400;
+    cpu->isar.id_dfr0 = 0x010400;
     cpu->id_afr0 = 0x0;
     cpu->id_mmfr0 = 0x0210030;
     cpu->id_mmfr1 = 0x00000000;
@@ -2170,7 +2170,7 @@ static void cortex_a8_initfn(Object *obj)
     cpu->reset_sctlr = 0x00c50078;
     cpu->id_pfr0 = 0x1031;
     cpu->id_pfr1 = 0x11;
-    cpu->id_dfr0 = 0x400;
+    cpu->isar.id_dfr0 = 0x400;
     cpu->id_afr0 = 0;
     cpu->id_mmfr0 = 0x31100003;
     cpu->id_mmfr1 = 0x20000000;
@@ -2243,7 +2243,7 @@ static void cortex_a9_initfn(Object *obj)
     cpu->reset_sctlr = 0x00c50078;
     cpu->id_pfr0 = 0x1031;
     cpu->id_pfr1 = 0x11;
-    cpu->id_dfr0 = 0x000;
+    cpu->isar.id_dfr0 = 0x000;
     cpu->id_afr0 = 0;
     cpu->id_mmfr0 = 0x00100103;
     cpu->id_mmfr1 = 0x20000000;
@@ -2308,7 +2308,7 @@ static void cortex_a7_initfn(Object *obj)
     cpu->reset_sctlr = 0x00c50078;
     cpu->id_pfr0 = 0x00001131;
     cpu->id_pfr1 = 0x00011011;
-    cpu->id_dfr0 = 0x02010555;
+    cpu->isar.id_dfr0 = 0x02010555;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x10101105;
     cpu->id_mmfr1 = 0x40000000;
@@ -2354,7 +2354,7 @@ static void cortex_a15_initfn(Object *obj)
     cpu->reset_sctlr = 0x00c50078;
     cpu->id_pfr0 = 0x00001131;
     cpu->id_pfr1 = 0x00011011;
-    cpu->id_dfr0 = 0x02010555;
+    cpu->isar.id_dfr0 = 0x02010555;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x10201105;
     cpu->id_mmfr1 = 0x20000000;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index bf2cf278c03..f8fda7e0988 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -121,7 +121,7 @@ static void aarch64_a57_initfn(Object *obj)
     cpu->reset_sctlr = 0x00c50838;
     cpu->id_pfr0 = 0x00000131;
     cpu->id_pfr1 = 0x00011011;
-    cpu->id_dfr0 = 0x03010066;
+    cpu->isar.id_dfr0 = 0x03010066;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x10101105;
     cpu->id_mmfr1 = 0x40000000;
@@ -175,7 +175,7 @@ static void aarch64_a53_initfn(Object *obj)
     cpu->reset_sctlr = 0x00c50838;
     cpu->id_pfr0 = 0x00000131;
     cpu->id_pfr1 = 0x00011011;
-    cpu->id_dfr0 = 0x03010066;
+    cpu->isar.id_dfr0 = 0x03010066;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x10101105;
     cpu->id_mmfr1 = 0x40000000;
@@ -228,7 +228,7 @@ static void aarch64_a72_initfn(Object *obj)
     cpu->reset_sctlr = 0x00c50838;
     cpu->id_pfr0 = 0x00000131;
     cpu->id_pfr1 = 0x00011011;
-    cpu->id_dfr0 = 0x03010066;
+    cpu->isar.id_dfr0 = 0x03010066;
     cpu->id_afr0 = 0x00000000;
     cpu->id_mmfr0 = 0x10201105;
     cpu->id_mmfr1 = 0x40000000;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2a57bfd9e86..ca0bf3402ca 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5886,8 +5886,7 @@ static void define_pmu_regs(ARMCPU *cpu)
         g_free(pmevtyper_name);
         g_free(pmevtyper_el0_name);
     }
-    if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
-            FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
+    if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
         ARMCPRegInfo v81_pmu_regs[] = {
             { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
               .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
@@ -6241,7 +6240,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
               .access = PL1_R, .type = ARM_CP_CONST,
               .accessfn = access_aa32_tid3,
-              .resetvalue = cpu->id_dfr0 },
+              .resetvalue = cpu->isar.id_dfr0 },
             { .name = "ID_AFR0", .state = ARM_CP_STATE_BOTH,
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 3,
               .access = PL1_R, .type = ARM_CP_CONST,
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (6 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 07/13] target/arm: Define an aa32_pmu_8_1 isar feature test function Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:40   ` Richard Henderson
  2020-02-12  6:56   ` Philippe Mathieu-Daudé
  2020-02-11 17:37 ` [PATCH 09/13] target/arm: Implement ARMv8.1-PMU extension Peter Maydell
                   ` (4 subsequent siblings)
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Add the 64-bit version of the "is this a v8.1 PMUv3?"
ID register check function, and the _any_ version that
checks for either AArch32 or AArch64 support. We'll use
this in a later commit.

We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
but we move id_aa64dfr1 into the ARMISARegisters struct with
id_aa64dfr0, for consistency.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h    | 15 +++++++++++++--
 target/arm/cpu.c    |  3 ++-
 target/arm/cpu64.c  |  6 +++---
 target/arm/helper.c | 12 +++++++-----
 4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index b55f6c8b7d3..2b3124fd76b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -871,6 +871,8 @@ struct ARMCPU {
         uint64_t id_aa64pfr1;
         uint64_t id_aa64mmfr0;
         uint64_t id_aa64mmfr1;
+        uint64_t id_aa64dfr0;
+        uint64_t id_aa64dfr1;
     } isar;
     uint32_t midr;
     uint32_t revidr;
@@ -887,8 +889,6 @@ struct ARMCPU {
     uint32_t id_mmfr2;
     uint32_t id_mmfr3;
     uint32_t id_mmfr4;
-    uint64_t id_aa64dfr0;
-    uint64_t id_aa64dfr1;
     uint64_t id_aa64afr0;
     uint64_t id_aa64afr1;
     uint32_t dbgdidr;
@@ -3728,6 +3728,12 @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
     return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
 }
 
+static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
+{
+    return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
+        FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+}
+
 /*
  * Feature tests for "does this exist in either 32-bit or 64-bit?"
  */
@@ -3741,6 +3747,11 @@ static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
     return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
 }
 
+static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
+{
+    return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
+}
+
 /*
  * Forward to the above feature tests given an ARMCPU pointer.
  */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ac0c96322d1..df44df1a43a 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1602,7 +1602,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
                 cpu);
 #endif
     } else {
-        cpu->id_aa64dfr0 = FIELD_DP32(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
+        cpu->isar.id_aa64dfr0 =
+            FIELD_DP32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
         cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
         cpu->pmceid0 = 0;
         cpu->pmceid1 = 0;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index f8fda7e0988..4b4b134ef84 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -135,7 +135,7 @@ static void aarch64_a57_initfn(Object *obj)
     cpu->isar.id_isar5 = 0x00011121;
     cpu->isar.id_isar6 = 0;
     cpu->isar.id_aa64pfr0 = 0x00002222;
-    cpu->id_aa64dfr0 = 0x10305106;
+    cpu->isar.id_aa64dfr0 = 0x10305106;
     cpu->isar.id_aa64isar0 = 0x00011120;
     cpu->isar.id_aa64mmfr0 = 0x00001124;
     cpu->dbgdidr = 0x3516d000;
@@ -189,7 +189,7 @@ static void aarch64_a53_initfn(Object *obj)
     cpu->isar.id_isar5 = 0x00011121;
     cpu->isar.id_isar6 = 0;
     cpu->isar.id_aa64pfr0 = 0x00002222;
-    cpu->id_aa64dfr0 = 0x10305106;
+    cpu->isar.id_aa64dfr0 = 0x10305106;
     cpu->isar.id_aa64isar0 = 0x00011120;
     cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
     cpu->dbgdidr = 0x3516d000;
@@ -241,7 +241,7 @@ static void aarch64_a72_initfn(Object *obj)
     cpu->isar.id_isar4 = 0x00011142;
     cpu->isar.id_isar5 = 0x00011121;
     cpu->isar.id_aa64pfr0 = 0x00002222;
-    cpu->id_aa64dfr0 = 0x10305106;
+    cpu->isar.id_aa64dfr0 = 0x10305106;
     cpu->isar.id_aa64isar0 = 0x00011120;
     cpu->isar.id_aa64mmfr0 = 0x00001124;
     cpu->dbgdidr = 0x3516d000;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index ca0bf3402ca..9537785104e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -25,6 +25,7 @@
 #include "hw/semihosting/semihost.h"
 #include "sysemu/cpus.h"
 #include "sysemu/kvm.h"
+#include "sysemu/tcg.h"
 #include "qemu/range.h"
 #include "qapi/qapi-commands-machine-target.h"
 #include "qapi/error.h"
@@ -5771,9 +5772,10 @@ static void define_debug_regs(ARMCPU *cpu)
      * check that if they both exist then they agree.
      */
     if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
-        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
-        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
-        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
+        assert(FIELD_EX32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
+        assert(FIELD_EX32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
+        assert(FIELD_EX32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
+               == ctx_cmps);
     }
 
     define_one_arm_cp_reg(cpu, &dbgdidr);
@@ -6395,12 +6397,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
               .access = PL1_R, .type = ARM_CP_CONST,
               .accessfn = access_aa64_tid3,
-              .resetvalue = cpu->id_aa64dfr0 },
+              .resetvalue = cpu->isar.id_aa64dfr0 },
             { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
               .access = PL1_R, .type = ARM_CP_CONST,
               .accessfn = access_aa64_tid3,
-              .resetvalue = cpu->id_aa64dfr1 },
+              .resetvalue = cpu->isar.id_aa64dfr1 },
             { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
               .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
               .access = PL1_R, .type = ARM_CP_CONST,
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 09/13] target/arm: Implement ARMv8.1-PMU extension
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (7 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:45   ` Richard Henderson
  2020-02-11 17:37 ` [PATCH 10/13] target/arm: Implement ARMv8.4-PMU extension Peter Maydell
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

The ARMv8.1-PMU extension requires:
 * the evtCount field in PMETYPER<n>_EL0 is 16 bits, not 10
 * MDCR_EL2.HPMD allows event counting to be disabled at EL2
 * two new required events, STALL_FRONTEND and STALL_BACKEND
 * ID register bits in ID_AA64DFR0_EL1 and ID_DFR0

We already implement the 16-bit evtCount field and the
HPMD bit, so all that is missing is the two new events:
  STALL_FRONTEND
   "counts every cycle counted by the CPU_CYCLES event on which no
    operation was issued because there are no operations available
    to issue to this PE from the frontend"
  STALL_BACKEND
   "counts every cycle counted by the CPU_CYCLES event on which no
    operation was issued because the backend is unable to accept
    any available operations from the frontend"

QEMU never stalls in this sense, so our implementation is trivial:
always return a zero count.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/helper.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 9537785104e..c896ad0b7ee 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1124,6 +1124,24 @@ static int64_t instructions_ns_per(uint64_t icount)
 }
 #endif
 
+static bool pmu_8_1_events_supported(CPUARMState *env)
+{
+    /* For events which are supported in any v8.1 PMU */
+    return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
+}
+
+static uint64_t zero_event_get_count(CPUARMState *env)
+{
+    /* For events which on QEMU never fire, so their count is always zero */
+    return 0;
+}
+
+static int64_t zero_event_ns_per(uint64_t cycles)
+{
+    /* An event which never fires can never overflow */
+    return -1;
+}
+
 static const pm_event pm_events[] = {
     { .number = 0x000, /* SW_INCR */
       .supported = event_always_supported,
@@ -1140,8 +1158,18 @@ static const pm_event pm_events[] = {
       .supported = event_always_supported,
       .get_count = cycles_get_count,
       .ns_per_count = cycles_ns_per,
-    }
+    },
 #endif
+    { .number = 0x023, /* STALL_FRONTEND */
+      .supported = pmu_8_1_events_supported,
+      .get_count = zero_event_get_count,
+      .ns_per_count = zero_event_ns_per,
+    },
+    { .number = 0x024, /* STALL_BACKEND */
+      .supported = pmu_8_1_events_supported,
+      .get_count = zero_event_get_count,
+      .ns_per_count = zero_event_ns_per,
+    },
 };
 
 /*
@@ -1150,7 +1178,7 @@ static const pm_event pm_events[] = {
  * should first be updated to something sparse instead of the current
  * supported_event_map[] array.
  */
-#define MAX_EVENT_ID 0x11
+#define MAX_EVENT_ID 0x24
 #define UNSUPPORTED_EVENT UINT16_MAX
 static uint16_t supported_event_map[MAX_EVENT_ID + 1];
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 10/13] target/arm: Implement ARMv8.4-PMU extension
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (8 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 09/13] target/arm: Implement ARMv8.1-PMU extension Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:49   ` Richard Henderson
  2020-02-11 17:37 ` [PATCH 11/13] target/arm: Provide ARMv8.4-PMU in '-cpu max' Peter Maydell
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

The ARMv8.4-PMU extension adds:
 * one new required event, STALL
 * one new system register PMMIR_EL1

(There are also some more L1-cache related events, but since
we don't implement any cache we don't provide these, in the
same way we don't provide the base-PMUv3 cache events.)

The STALL event "counts every attributable cycle on which no
attributable instruction or operation was sent for execution on this
PE".  QEMU doesn't stall in this sense, so this is another
always-reads-zero event.

The PMMIR_EL1 register is a read-only register providing
implementation-specific information about the PMU; currently it has
only one field, SLOTS, which defines behaviour of the STALL_SLOT PMU
event.  Since QEMU doesn't implement the STALL_SLOT event, we can
validly make the register read zero.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.h    | 18 ++++++++++++++++++
 target/arm/helper.c | 22 +++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 2b3124fd76b..cfe7cfd1a4d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3569,6 +3569,13 @@ static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
         FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
 }
 
+static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
+{
+    /* 0xf means "non-standard IMPDEF PMU" */
+    return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
+        FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+}
+
 /*
  * 64-bit feature tests via id registers.
  */
@@ -3734,6 +3741,12 @@ static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
         FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
 }
 
+static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
+{
+    return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
+        FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+}
+
 /*
  * Feature tests for "does this exist in either 32-bit or 64-bit?"
  */
@@ -3752,6 +3765,11 @@ static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
     return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
 }
 
+static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
+{
+    return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
+}
+
 /*
  * Forward to the above feature tests given an ARMCPU pointer.
  */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c896ad0b7ee..cb3c30f1725 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1130,6 +1130,12 @@ static bool pmu_8_1_events_supported(CPUARMState *env)
     return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
 }
 
+static bool pmu_8_4_events_supported(CPUARMState *env)
+{
+    /* For events which are supported in any v8.1 PMU */
+    return cpu_isar_feature(any_pmu_8_4, env_archcpu(env));
+}
+
 static uint64_t zero_event_get_count(CPUARMState *env)
 {
     /* For events which on QEMU never fire, so their count is always zero */
@@ -1170,6 +1176,11 @@ static const pm_event pm_events[] = {
       .get_count = zero_event_get_count,
       .ns_per_count = zero_event_ns_per,
     },
+    { .number = 0x03c, /* STALL */
+      .supported = pmu_8_4_events_supported,
+      .get_count = zero_event_get_count,
+      .ns_per_count = zero_event_ns_per,
+    },
 };
 
 /*
@@ -1178,7 +1189,7 @@ static const pm_event pm_events[] = {
  * should first be updated to something sparse instead of the current
  * supported_event_map[] array.
  */
-#define MAX_EVENT_ID 0x24
+#define MAX_EVENT_ID 0x3c
 #define UNSUPPORTED_EVENT UINT16_MAX
 static uint16_t supported_event_map[MAX_EVENT_ID + 1];
 
@@ -5930,6 +5941,15 @@ static void define_pmu_regs(ARMCPU *cpu)
         };
         define_arm_cp_regs(cpu, v81_pmu_regs);
     }
+    if (cpu_isar_feature(any_pmu_8_4, cpu)) {
+        static const ARMCPRegInfo v84_pmmir = {
+            .name = "PMMIR_EL1", .state = ARM_CP_STATE_BOTH,
+            .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 6,
+            .access = PL1_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
+            .resetvalue = 0
+        };
+        define_one_arm_cp_reg(cpu, &v84_pmmir);
+    }
 }
 
 /* We don't know until after realize whether there's a GICv3
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 11/13] target/arm: Provide ARMv8.4-PMU in '-cpu max'
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (9 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 10/13] target/arm: Implement ARMv8.4-PMU extension Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:50   ` Richard Henderson
  2020-02-11 17:37 ` [PATCH 12/13] target/arm: Correct definition of PMCRDP Peter Maydell
  2020-02-11 17:37 ` [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit Peter Maydell
  12 siblings, 1 reply; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

Set the ID register bits to provide ARMv8.4-PMU (and implicitly
also ARMv8.1-PMU) in the 'max' CPU.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu64.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 4b4b134ef84..5b8b7a9d4b8 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -693,6 +693,14 @@ static void aarch64_max_initfn(Object *obj)
         u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
         cpu->isar.id_isar6 = u;
 
+        u = cpu->isar.id_aa64dfr0;
+        u = FIELD_DP32(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
+        cpu->isar.id_aa64dfr0 = u;
+
+        u = cpu->isar.id_dfr0;
+        u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
+        cpu->isar.id_dfr0 = u;
+
         /*
          * FIXME: We do not yet support ARMv8.2-fp16 for AArch32 yet,
          * so do not set MVFR1.FPHP.  Strictly speaking this is not legal,
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 12/13] target/arm: Correct definition of PMCRDP
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (10 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 11/13] target/arm: Provide ARMv8.4-PMU in '-cpu max' Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:52   ` Richard Henderson
  2020-02-12  7:00   ` Philippe Mathieu-Daudé
  2020-02-11 17:37 ` [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit Peter Maydell
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

The PMCR_EL0.DP bit is bit 5, which is 0x20, not 0x10.  0x10 is 'X'.
Correct our #define of PMCRDP and add the missing PMCRX.

We do have the correct behaviour for handling the DP bit being
set, so this fixes a guest-visible bug.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index cb3c30f1725..c6758bfbeb5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1017,7 +1017,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 #define PMCRN_MASK  0xf800
 #define PMCRN_SHIFT 11
 #define PMCRLC  0x40
-#define PMCRDP  0x10
+#define PMCRDP  0x20
+#define PMCRX   0x10
 #define PMCRD   0x8
 #define PMCRC   0x4
 #define PMCRP   0x2
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit
  2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
                   ` (11 preceding siblings ...)
  2020-02-11 17:37 ` [PATCH 12/13] target/arm: Correct definition of PMCRDP Peter Maydell
@ 2020-02-11 17:37 ` Peter Maydell
  2020-02-11 18:55   ` Richard Henderson
  2020-02-12  7:14   ` Philippe Mathieu-Daudé
  12 siblings, 2 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-11 17:37 UTC (permalink / raw)
  To: qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay, Richard Henderson

The LC bit in the PMCR_EL0 register is supposed to be:
 * read/write
 * RES1 on an AArch64-only implementation
 * an architecturally UNKNOWN value on reset
(and use of LC==0 by software is deprecated).

We were implementing it incorrectly as read-only always zero,
though we do have all the code needed to test it and behave
accordingly.

Instead make it a read-write bit which resets to 1 always, which
satisfies all the architectural requirements above.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/helper.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index c6758bfbeb5..1d8eafceda8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1023,6 +1023,11 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 #define PMCRC   0x4
 #define PMCRP   0x2
 #define PMCRE   0x1
+/*
+ * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
+ * which can be written as 1 to trigger behaviour but which stay RAZ).
+ */
+#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
 
 #define PMXEVTYPER_P          0x80000000
 #define PMXEVTYPER_U          0x40000000
@@ -1577,9 +1582,8 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
         }
     }
 
-    /* only the DP, X, D and E bits are writable */
-    env->cp15.c9_pmcr &= ~0x39;
-    env->cp15.c9_pmcr |= (value & 0x39);
+    env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
+    env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
 
     pmu_op_finish(env);
 }
@@ -5886,7 +5890,8 @@ static void define_pmu_regs(ARMCPU *cpu)
         .access = PL0_RW, .accessfn = pmreg_access,
         .type = ARM_CP_IO,
         .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
-        .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
+        .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
+                      PMCRLC,
         .writefn = pmcr_write, .raw_writefn = raw_write,
     };
     define_one_arm_cp_reg(cpu, &pmcr);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers
  2020-02-11 17:37 ` [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers Peter Maydell
@ 2020-02-11 18:25   ` Richard Henderson
  2020-02-12  6:23   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:25 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> Enforce a convention that an isar_feature function that tests a
> 32-bit ID register always has _aa32_ in its name, and one that
> tests a 64-bit ID register always has _aa64_ in its name.
> We already follow this except for three cases: thumb_div,
> arm_div and jazelle, which all need _aa32_ adding.
> 
> (As noted in the comment, isar_feature_aa32_fp16_arith()
> is an exception in that it currently tests ID_AA64PFR0_EL1,
> but will switch to MVFR1 once we've properly implemented
> FP16 for AArch32.)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h       | 13 ++++++++++---
>  linux-user/elfload.c   |  4 ++--
>  target/arm/cpu.c       |  6 ++++--
>  target/arm/helper.c    |  2 +-
>  target/arm/translate.c |  6 +++---
>  5 files changed, 20 insertions(+), 11 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
  2020-02-11 17:37 ` [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions Peter Maydell
@ 2020-02-11 18:28   ` Richard Henderson
  2020-02-12  6:24   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:28 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> Our current usage of the isar_feature feature tests almost always
> uses an _aa32_ test when the code path is known to be AArch32
> specific and an _aa64_ test when the code path is known to be
> AArch64 specific. There is just one exception: in the vfp_set_fpscr
> helper we check aa64_fp16 to determine whether the FZ16 bit in
> the FP(S)CR exists, but this code is also used for AArch32.
> There are other places in future where we're likely to want
> a general "does this feature exist for either AArch32 or
> AArch64" check (typically where architecturally the feature exists
> for both CPU states if it exists at all, but the CPU might be
> AArch32-only or AArch64-only, and so only have one set of ID
> registers).
> 
> Introduce a new category of isar_feature_* functions:
> isar_feature_any_foo() should be tested when what we want to
> know is "does this feature exist for either AArch32 or AArch64",
> and always returns the logical OR of isar_feature_aa32_foo()
> and isar_feature_aa64_foo().
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h        | 19 ++++++++++++++++++-
>  target/arm/vfp_helper.c |  2 +-
>  2 files changed, 19 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test
  2020-02-11 17:37 ` [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test Peter Maydell
@ 2020-02-11 18:29   ` Richard Henderson
  2020-02-12  6:24   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:29 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> Instead of open-coding "ARM_FEATURE_AARCH64 ? aa64_predinv: aa32_predinv",
> define and use an any_predinv isar_feature test function.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h    | 5 +++++
>  target/arm/helper.c | 9 +--------
>  2 files changed, 6 insertions(+), 8 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 04/13] target/arm: Factor out PMU register definitions
  2020-02-11 17:37 ` [PATCH 04/13] target/arm: Factor out PMU register definitions Peter Maydell
@ 2020-02-11 18:30   ` Richard Henderson
  2020-02-12  6:40   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:30 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> Pull the code that defines the various PMU registers out
> into its own function, matching the pattern we have
> already for the debug registers.
> 
> Apart from one style fix to a multi-line comment, this
> is purely movement of code with no changes to it.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/helper.c | 158 +++++++++++++++++++++++---------------------
>  1 file changed, 82 insertions(+), 76 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 05/13] target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
  2020-02-11 17:37 ` [PATCH 05/13] target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1 Peter Maydell
@ 2020-02-11 18:34   ` Richard Henderson
  2020-02-12  6:44     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
>      if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
> -        assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
> -        assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
> -        assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
> +        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
> +        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
> +        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);

Should really be FIELD_EX64.  Otherwise,

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~




^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
  2020-02-11 17:37 ` [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field Peter Maydell
@ 2020-02-11 18:34   ` Richard Henderson
  2020-02-12  6:48   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:34 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> We already define FIELD macros for ID_DFR0, so use them in the
> one place where we're doing direct bit value manipulation.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> We have lots of this non-FIELD style in the code, of course;
> I change this one purely because it otherwise looks a bit odd
> sat next to the ID_AA64DFR0 line that was changed in the previous
> patch...
> ---
>  target/arm/cpu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 07/13] target/arm: Define an aa32_pmu_8_1 isar feature test function
  2020-02-11 17:37 ` [PATCH 07/13] target/arm: Define an aa32_pmu_8_1 isar feature test function Peter Maydell
@ 2020-02-11 18:38   ` Richard Henderson
  0 siblings, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:38 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> Instead of open-coding a check on the ID_DFR0 PerfMon ID register
> field, create a standardly-named isar_feature for "does AArch32 have
> a v8.1 PMUv3" and use it.
> 
> This entails moving the id_dfr0 field into the ARMISARegisters struct.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h      |  9 ++++++++-
>  hw/intc/armv7m_nvic.c |  2 +-
>  target/arm/cpu.c      | 28 ++++++++++++++--------------
>  target/arm/cpu64.c    |  6 +++---
>  target/arm/helper.c   |  5 ++---
>  5 files changed, 28 insertions(+), 22 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
  2020-02-11 17:37 ` [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks Peter Maydell
@ 2020-02-11 18:40   ` Richard Henderson
  2020-02-12  6:56   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:40 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> Add the 64-bit version of the "is this a v8.1 PMUv3?"
> ID register check function, and the _any_ version that
> checks for either AArch32 or AArch64 support. We'll use
> this in a later commit.
> 
> We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
> but we move id_aa64dfr1 into the ARMISARegisters struct with
> id_aa64dfr0, for consistency.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h    | 15 +++++++++++++--
>  target/arm/cpu.c    |  3 ++-
>  target/arm/cpu64.c  |  6 +++---
>  target/arm/helper.c | 12 +++++++-----
>  4 files changed, 25 insertions(+), 11 deletions(-)

Normally we also read the value of the ISAR registers for KVM.  I know these
tests don't apply along these paths, but for consistency...

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 09/13] target/arm: Implement ARMv8.1-PMU extension
  2020-02-11 17:37 ` [PATCH 09/13] target/arm: Implement ARMv8.1-PMU extension Peter Maydell
@ 2020-02-11 18:45   ` Richard Henderson
  0 siblings, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:45 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> The ARMv8.1-PMU extension requires:
>  * the evtCount field in PMETYPER<n>_EL0 is 16 bits, not 10
>  * MDCR_EL2.HPMD allows event counting to be disabled at EL2
>  * two new required events, STALL_FRONTEND and STALL_BACKEND
>  * ID register bits in ID_AA64DFR0_EL1 and ID_DFR0
> 
> We already implement the 16-bit evtCount field and the
> HPMD bit, so all that is missing is the two new events:
>   STALL_FRONTEND
>    "counts every cycle counted by the CPU_CYCLES event on which no
>     operation was issued because there are no operations available
>     to issue to this PE from the frontend"
>   STALL_BACKEND
>    "counts every cycle counted by the CPU_CYCLES event on which no
>     operation was issued because the backend is unable to accept
>     any available operations from the frontend"
> 
> QEMU never stalls in this sense, so our implementation is trivial:
> always return a zero count.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/helper.c | 32 ++++++++++++++++++++++++++++++--
>  1 file changed, 30 insertions(+), 2 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 10/13] target/arm: Implement ARMv8.4-PMU extension
  2020-02-11 17:37 ` [PATCH 10/13] target/arm: Implement ARMv8.4-PMU extension Peter Maydell
@ 2020-02-11 18:49   ` Richard Henderson
  0 siblings, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:49 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> The ARMv8.4-PMU extension adds:
>  * one new required event, STALL
>  * one new system register PMMIR_EL1
> 
> (There are also some more L1-cache related events, but since
> we don't implement any cache we don't provide these, in the
> same way we don't provide the base-PMUv3 cache events.)
> 
> The STALL event "counts every attributable cycle on which no
> attributable instruction or operation was sent for execution on this
> PE".  QEMU doesn't stall in this sense, so this is another
> always-reads-zero event.
> 
> The PMMIR_EL1 register is a read-only register providing
> implementation-specific information about the PMU; currently it has
> only one field, SLOTS, which defines behaviour of the STALL_SLOT PMU
> event.  Since QEMU doesn't implement the STALL_SLOT event, we can
> validly make the register read zero.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu.h    | 18 ++++++++++++++++++
>  target/arm/helper.c | 22 +++++++++++++++++++++-
>  2 files changed, 39 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 11/13] target/arm: Provide ARMv8.4-PMU in '-cpu max'
  2020-02-11 17:37 ` [PATCH 11/13] target/arm: Provide ARMv8.4-PMU in '-cpu max' Peter Maydell
@ 2020-02-11 18:50   ` Richard Henderson
  0 siblings, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:50 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> Set the ID register bits to provide ARMv8.4-PMU (and implicitly
> also ARMv8.1-PMU) in the 'max' CPU.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/cpu64.c | 8 ++++++++
>  1 file changed, 8 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 12/13] target/arm: Correct definition of PMCRDP
  2020-02-11 17:37 ` [PATCH 12/13] target/arm: Correct definition of PMCRDP Peter Maydell
@ 2020-02-11 18:52   ` Richard Henderson
  2020-02-12  7:00   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:52 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> The PMCR_EL0.DP bit is bit 5, which is 0x20, not 0x10.  0x10 is 'X'.
> Correct our #define of PMCRDP and add the missing PMCRX.
> 
> We do have the correct behaviour for handling the DP bit being
> set, so this fixes a guest-visible bug.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/helper.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit
  2020-02-11 17:37 ` [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit Peter Maydell
@ 2020-02-11 18:55   ` Richard Henderson
  2020-02-12  7:14   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Richard Henderson @ 2020-02-11 18:55 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel; +Cc: Eric Auger, Aaron Lindsay

On 2/11/20 9:37 AM, Peter Maydell wrote:
> The LC bit in the PMCR_EL0 register is supposed to be:
>  * read/write
>  * RES1 on an AArch64-only implementation
>  * an architecturally UNKNOWN value on reset
> (and use of LC==0 by software is deprecated).
> 
> We were implementing it incorrectly as read-only always zero,
> though we do have all the code needed to test it and behave
> accordingly.
> 
> Instead make it a read-write bit which resets to 1 always, which
> satisfies all the architectural requirements above.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target/arm/helper.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~




^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers
  2020-02-11 17:37 ` [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers Peter Maydell
  2020-02-11 18:25   ` Richard Henderson
@ 2020-02-12  6:23   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  6:23 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> Enforce a convention that an isar_feature function that tests a
> 32-bit ID register always has _aa32_ in its name, and one that
> tests a 64-bit ID register always has _aa64_ in its name.
> We already follow this except for three cases: thumb_div,
> arm_div and jazelle, which all need _aa32_ adding.
> 
> (As noted in the comment, isar_feature_aa32_fp16_arith()
> is an exception in that it currently tests ID_AA64PFR0_EL1,
> but will switch to MVFR1 once we've properly implemented
> FP16 for AArch32.)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> ---
>   target/arm/cpu.h       | 13 ++++++++++---
>   linux-user/elfload.c   |  4 ++--
>   target/arm/cpu.c       |  6 ++++--
>   target/arm/helper.c    |  2 +-
>   target/arm/translate.c |  6 +++---
>   5 files changed, 20 insertions(+), 11 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 608fcbd0b75..ad2f0e172a7 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -3396,20 +3396,27 @@ static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
>   /* Shared between translate-sve.c and sve_helper.c.  */
>   extern const uint64_t pred_esz_masks[4];
>   
> +/*
> + * Naming convention for isar_feature functions:
> + * Functions which test 32-bit ID registers should have _aa32_ in
> + * their name. Functions which test 64-bit ID registers should have
> + * _aa64_ in their name.
> + */
> +
>   /*
>    * 32-bit feature tests via id registers.
>    */
> -static inline bool isar_feature_thumb_div(const ARMISARegisters *id)
> +static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
>   {
>       return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
>   }
>   
> -static inline bool isar_feature_arm_div(const ARMISARegisters *id)
> +static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
>   {
>       return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
>   }
>   
> -static inline bool isar_feature_jazelle(const ARMISARegisters *id)
> +static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
>   {
>       return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
>   }
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index f3080a16358..b1a895f24ce 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -475,8 +475,8 @@ static uint32_t get_elf_hwcap(void)
>       GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
>       GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
>       GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
> -    GET_FEATURE_ID(arm_div, ARM_HWCAP_ARM_IDIVA);
> -    GET_FEATURE_ID(thumb_div, ARM_HWCAP_ARM_IDIVT);
> +    GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
> +    GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
>       /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
>        * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
>        * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index f86e71a260d..5712082c0b9 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1470,7 +1470,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
>            * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
>            * Security Extensions is ARM_FEATURE_EL3.
>            */
> -        assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(arm_div, cpu));
> +        assert(!tcg_enabled() || no_aa32 ||
> +               cpu_isar_feature(aa32_arm_div, cpu));
>           set_feature(env, ARM_FEATURE_LPAE);
>           set_feature(env, ARM_FEATURE_V7);
>       }
> @@ -1496,7 +1497,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
>       if (arm_feature(env, ARM_FEATURE_V6)) {
>           set_feature(env, ARM_FEATURE_V5);
>           if (!arm_feature(env, ARM_FEATURE_M)) {
> -            assert(!tcg_enabled() || no_aa32 || cpu_isar_feature(jazelle, cpu));
> +            assert(!tcg_enabled() || no_aa32 ||
> +                   cpu_isar_feature(aa32_jazelle, cpu));
>               set_feature(env, ARM_FEATURE_AUXCR);
>           }
>       }
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 19a57a17da5..ddfd0183d98 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -6781,7 +6781,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>       if (arm_feature(env, ARM_FEATURE_LPAE)) {
>           define_arm_cp_regs(cpu, lpae_cp_reginfo);
>       }
> -    if (cpu_isar_feature(jazelle, cpu)) {
> +    if (cpu_isar_feature(aa32_jazelle, cpu)) {
>           define_arm_cp_regs(cpu, jazelle_regs);
>       }
>       /* Slightly awkwardly, the OMAP and StrongARM cores need all of
> diff --git a/target/arm/translate.c b/target/arm/translate.c
> index 2f4aea927f1..052992037cc 100644
> --- a/target/arm/translate.c
> +++ b/target/arm/translate.c
> @@ -42,7 +42,7 @@
>   #define ENABLE_ARCH_5     arm_dc_feature(s, ARM_FEATURE_V5)
>   /* currently all emulated v5 cores are also v5TE, so don't bother */
>   #define ENABLE_ARCH_5TE   arm_dc_feature(s, ARM_FEATURE_V5)
> -#define ENABLE_ARCH_5J    dc_isar_feature(jazelle, s)
> +#define ENABLE_ARCH_5J    dc_isar_feature(aa32_jazelle, s)
>   #define ENABLE_ARCH_6     arm_dc_feature(s, ARM_FEATURE_V6)
>   #define ENABLE_ARCH_6K    arm_dc_feature(s, ARM_FEATURE_V6K)
>   #define ENABLE_ARCH_6T2   arm_dc_feature(s, ARM_FEATURE_THUMB2)
> @@ -9850,8 +9850,8 @@ static bool op_div(DisasContext *s, arg_rrr *a, bool u)
>       TCGv_i32 t1, t2;
>   
>       if (s->thumb
> -        ? !dc_isar_feature(thumb_div, s)
> -        : !dc_isar_feature(arm_div, s)) {
> +        ? !dc_isar_feature(aa32_thumb_div, s)
> +        : !dc_isar_feature(aa32_arm_div, s)) {
>           return false;
>       }
>   
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
  2020-02-11 17:37 ` [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions Peter Maydell
  2020-02-11 18:28   ` Richard Henderson
@ 2020-02-12  6:24   ` Philippe Mathieu-Daudé
  2020-02-12 11:32     ` Peter Maydell
  1 sibling, 1 reply; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  6:24 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> Our current usage of the isar_feature feature tests almost always
> uses an _aa32_ test when the code path is known to be AArch32
> specific and an _aa64_ test when the code path is known to be
> AArch64 specific. There is just one exception: in the vfp_set_fpscr
> helper we check aa64_fp16 to determine whether the FZ16 bit in
> the FP(S)CR exists, but this code is also used for AArch32.
> There are other places in future where we're likely to want
> a general "does this feature exist for either AArch32 or
> AArch64" check (typically where architecturally the feature exists
> for both CPU states if it exists at all, but the CPU might be
> AArch32-only or AArch64-only, and so only have one set of ID
> registers).
> 
> Introduce a new category of isar_feature_* functions:
> isar_feature_any_foo() should be tested when what we want to
> know is "does this feature exist for either AArch32 or AArch64",
> and always returns the logical OR of isar_feature_aa32_foo()
> and isar_feature_aa64_foo().

Good idea.

> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/cpu.h        | 19 ++++++++++++++++++-
>   target/arm/vfp_helper.c |  2 +-
>   2 files changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index ad2f0e172a7..ac4b7950166 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -3400,7 +3400,16 @@ extern const uint64_t pred_esz_masks[4];
>    * Naming convention for isar_feature functions:
>    * Functions which test 32-bit ID registers should have _aa32_ in
>    * their name. Functions which test 64-bit ID registers should have
> - * _aa64_ in their name.
> + * _aa64_ in their name. These must only be used in code where we
> + * know for certain that the CPU has AArch32 or AArch64 respectively
> + * or where the correct answer for a CPU which doesn't implement that
> + * CPU state is "false" (eg when generating A32 or A64 code, if adding
> + * system registers that are specific to that CPU state, for "should
> + * we let this system register bit be set" tests where the 32-bit
> + * flavour of the register doesn't have the bit, and so on).
> + * Functions which simply ask "does this feature exist at all" have
> + * _any_ in their name, and always return the logical OR of the _aa64_
> + * and the _aa32_ function.
>    */
>   
>   /*
> @@ -3702,6 +3711,14 @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
>       return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
>   }
>   
> +/*
> + * Feature tests for "does this exist in either 32-bit or 64-bit?"
> + */
> +static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
> +{
> +    return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
> +}
> +
>   /*
>    * Forward to the above feature tests given an ARMCPU pointer.
>    */
> diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
> index 0ae7d4f34a9..930d6e747f6 100644
> --- a/target/arm/vfp_helper.c
> +++ b/target/arm/vfp_helper.c
> @@ -185,7 +185,7 @@ uint32_t vfp_get_fpscr(CPUARMState *env)
>   void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
>   {
>       /* When ARMv8.2-FP16 is not supported, FZ16 is RES0.  */
> -    if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
> +    if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {

So we had a potential bug on aa32?

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

>           val &= ~FPCR_FZ16;
>       }
>   
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test
  2020-02-11 17:37 ` [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test Peter Maydell
  2020-02-11 18:29   ` Richard Henderson
@ 2020-02-12  6:24   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  6:24 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> Instead of open-coding "ARM_FEATURE_AARCH64 ? aa64_predinv: aa32_predinv",
> define and use an any_predinv isar_feature test function.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/cpu.h    | 5 +++++
>   target/arm/helper.c | 9 +--------
>   2 files changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index ac4b7950166..b1f3ecfd942 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -3719,6 +3719,11 @@ static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
>       return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
>   }
>   
> +static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
> +{
> +    return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
> +}
> +
>   /*
>    * Forward to the above feature tests given an ARMCPU pointer.
>    */
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index ddfd0183d98..bf083c369fc 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -7116,14 +7116,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>   #endif /*CONFIG_USER_ONLY*/
>   #endif
>   
> -    /*
> -     * While all v8.0 cpus support aarch64, QEMU does have configurations
> -     * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
> -     * which will set ID_ISAR6.
> -     */
> -    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
> -        ? cpu_isar_feature(aa64_predinv, cpu)
> -        : cpu_isar_feature(aa32_predinv, cpu)) {
> +    if (cpu_isar_feature(any_predinv, cpu)) {

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

>           define_arm_cp_regs(cpu, predinv_reginfo);
>       }
>   }
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 04/13] target/arm: Factor out PMU register definitions
  2020-02-11 17:37 ` [PATCH 04/13] target/arm: Factor out PMU register definitions Peter Maydell
  2020-02-11 18:30   ` Richard Henderson
@ 2020-02-12  6:40   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  6:40 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> Pull the code that defines the various PMU registers out
> into its own function, matching the pattern we have
> already for the debug registers.
> 
> Apart from one style fix to a multi-line comment, this
> is purely movement of code with no changes to it.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/helper.c | 158 +++++++++++++++++++++++---------------------
>   1 file changed, 82 insertions(+), 76 deletions(-)
> 
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index bf083c369fc..0011a22f42d 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -5822,6 +5822,87 @@ static void define_debug_regs(ARMCPU *cpu)
>       }
>   }
>   
> +static void define_pmu_regs(ARMCPU *cpu)
> +{
> +    /*
> +     * v7 performance monitor control register: same implementor
> +     * field as main ID register, and we implement four counters in
> +     * addition to the cycle count register.
> +     */
> +    unsigned int i, pmcrn = 4;
> +    ARMCPRegInfo pmcr = {
> +        .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
> +        .access = PL0_RW,
> +        .type = ARM_CP_IO | ARM_CP_ALIAS,
> +        .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
> +        .accessfn = pmreg_access, .writefn = pmcr_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) | (pmcrn << PMCRN_SHIFT),
> +        .writefn = pmcr_write, .raw_writefn = raw_write,
> +    };
> +    define_one_arm_cp_reg(cpu, &pmcr);
> +    define_one_arm_cp_reg(cpu, &pmcr64);
> +    for (i = 0; i < pmcrn; i++) {
> +        char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
> +        char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
> +        char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
> +        char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
> +        ARMCPRegInfo pmev_regs[] = {
> +            { .name = pmevcntr_name, .cp = 15, .crn = 14,
> +              .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
> +              .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
> +              .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
> +              .accessfn = pmreg_access },
> +            { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
> +              .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
> +              .type = ARM_CP_IO,
> +              .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
> +              .raw_readfn = pmevcntr_rawread,
> +              .raw_writefn = pmevcntr_rawwrite },
> +            { .name = pmevtyper_name, .cp = 15, .crn = 14,
> +              .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
> +              .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
> +              .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
> +              .accessfn = pmreg_access },
> +            { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
> +              .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
> +              .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
> +              .type = ARM_CP_IO,
> +              .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
> +              .raw_writefn = pmevtyper_rawwrite },
> +            REGINFO_SENTINEL
> +        };
> +        define_arm_cp_regs(cpu, pmev_regs);
> +        g_free(pmevcntr_name);
> +        g_free(pmevcntr_el0_name);
> +        g_free(pmevtyper_name);
> +        g_free(pmevtyper_el0_name);
> +    }
> +    if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
> +            FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
> +        ARMCPRegInfo v81_pmu_regs[] = {
> +            { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
> +              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
> +              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
> +              .resetvalue = extract64(cpu->pmceid0, 32, 32) },
> +            { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
> +              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
> +              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
> +              .resetvalue = extract64(cpu->pmceid1, 32, 32) },
> +            REGINFO_SENTINEL
> +        };
> +        define_arm_cp_regs(cpu, v81_pmu_regs);
> +    }
> +}
> +
>   /* We don't know until after realize whether there's a GICv3
>    * attached, and that is what registers the gicv3 sysregs.
>    * So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
> @@ -6244,67 +6325,6 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>           define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
>       }
>       if (arm_feature(env, ARM_FEATURE_V7)) {
> -        /* v7 performance monitor control register: same implementor
> -         * field as main ID register, and we implement four counters in
> -         * addition to the cycle count register.
> -         */
> -        unsigned int i, pmcrn = 4;
> -        ARMCPRegInfo pmcr = {
> -            .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
> -            .access = PL0_RW,
> -            .type = ARM_CP_IO | ARM_CP_ALIAS,
> -            .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
> -            .accessfn = pmreg_access, .writefn = pmcr_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) | (pmcrn << PMCRN_SHIFT),
> -            .writefn = pmcr_write, .raw_writefn = raw_write,
> -        };
> -        define_one_arm_cp_reg(cpu, &pmcr);
> -        define_one_arm_cp_reg(cpu, &pmcr64);
> -        for (i = 0; i < pmcrn; i++) {
> -            char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
> -            char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
> -            char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
> -            char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
> -            ARMCPRegInfo pmev_regs[] = {
> -                { .name = pmevcntr_name, .cp = 15, .crn = 14,
> -                  .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
> -                  .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
> -                  .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
> -                  .accessfn = pmreg_access },
> -                { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
> -                  .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 8 | (3 & (i >> 3)),
> -                  .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
> -                  .type = ARM_CP_IO,
> -                  .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
> -                  .raw_readfn = pmevcntr_rawread,
> -                  .raw_writefn = pmevcntr_rawwrite },
> -                { .name = pmevtyper_name, .cp = 15, .crn = 14,
> -                  .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
> -                  .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
> -                  .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
> -                  .accessfn = pmreg_access },
> -                { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
> -                  .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 12 | (3 & (i >> 3)),
> -                  .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
> -                  .type = ARM_CP_IO,
> -                  .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
> -                  .raw_writefn = pmevtyper_rawwrite },
> -                REGINFO_SENTINEL
> -            };
> -            define_arm_cp_regs(cpu, pmev_regs);
> -            g_free(pmevcntr_name);
> -            g_free(pmevcntr_el0_name);
> -            g_free(pmevtyper_name);
> -            g_free(pmevtyper_el0_name);

TIL git-diff --color-moved

Maybe move PERFMON block first, then extract define_pmu_regs()?

In any case,
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> -        }
>           ARMCPRegInfo clidr = {
>               .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
>               .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
> @@ -6315,24 +6335,10 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>           define_one_arm_cp_reg(cpu, &clidr);
>           define_arm_cp_regs(cpu, v7_cp_reginfo);
>           define_debug_regs(cpu);
> +        define_pmu_regs(cpu);
>       } else {
>           define_arm_cp_regs(cpu, not_v7_cp_reginfo);
>       }
> -    if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
> -            FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
> -        ARMCPRegInfo v81_pmu_regs[] = {
> -            { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
> -              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
> -              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
> -              .resetvalue = extract64(cpu->pmceid0, 32, 32) },
> -            { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
> -              .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
> -              .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
> -              .resetvalue = extract64(cpu->pmceid1, 32, 32) },
> -            REGINFO_SENTINEL
> -        };
> -        define_arm_cp_regs(cpu, v81_pmu_regs);
> -    }
>       if (arm_feature(env, ARM_FEATURE_V8)) {
>           /* AArch64 ID registers, which all have impdef reset values.
>            * Note that within the ID register ranges the unused slots
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 05/13] target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
  2020-02-11 18:34   ` Richard Henderson
@ 2020-02-12  6:44     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  6:44 UTC (permalink / raw)
  To: Richard Henderson, Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay

On 2/11/20 7:34 PM, Richard Henderson wrote:
> On 2/11/20 9:37 AM, Peter Maydell wrote:
>>       if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
>> -        assert(extract32(cpu->id_aa64dfr0, 12, 4) == brps);
>> -        assert(extract32(cpu->id_aa64dfr0, 20, 4) == wrps);
>> -        assert(extract32(cpu->id_aa64dfr0, 28, 4) == ctx_cmps);
>> +        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
>> +        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
>> +        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
> 
> Should really be FIELD_EX64.  Otherwise,

Similarly to the other previous call, FIELD_DP64:

        cpu->id_aa64dfr0 = FIELD_DP32(cpu->id_aa64dfr0, ID_AA64DFR0, 
PMUVER, 0);

So far the code is safe because the >31 bits macros aren't used:

   FIELD(ID_AA64DFR0, PMSVER, 32, 4)
   FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
   FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)

But you are right, let's fix it now to avoid copy/pasting 32bit macros 
and unpleasant debugging sessions.

> 
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

Using 64bit macros:
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
  2020-02-11 17:37 ` [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field Peter Maydell
  2020-02-11 18:34   ` Richard Henderson
@ 2020-02-12  6:48   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  6:48 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> We already define FIELD macros for ID_DFR0, so use them in the
> one place where we're doing direct bit value manipulation.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> We have lots of this non-FIELD style in the code, of course;
> I change this one purely because it otherwise looks a bit odd
> sat next to the ID_AA64DFR0 line that was changed in the previous
> patch...
> ---
>   target/arm/cpu.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index dc582da8fa4..e7858b073b5 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1603,7 +1603,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
>   #endif
>       } else {
>           cpu->id_aa64dfr0 = FIELD_DP32(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);

While this one should be FIELD_DP64(),

> -        cpu->id_dfr0 &= ~(0xf << 24);
> +        cpu->id_dfr0 = FIELD_DP32(cpu->id_dfr0, ID_DFR0, PERFMON, 0);

this one is correct.

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

>           cpu->pmceid0 = 0;
>           cpu->pmceid1 = 0;
>       }
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
  2020-02-11 17:37 ` [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks Peter Maydell
  2020-02-11 18:40   ` Richard Henderson
@ 2020-02-12  6:56   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  6:56 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> Add the 64-bit version of the "is this a v8.1 PMUv3?"
> ID register check function, and the _any_ version that
> checks for either AArch32 or AArch64 support. We'll use
> this in a later commit.
> 
> We don't (yet) do any isar_feature checks on ID_AA64DFR1_EL1,
> but we move id_aa64dfr1 into the ARMISARegisters struct with
> id_aa64dfr0, for consistency.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/cpu.h    | 15 +++++++++++++--
>   target/arm/cpu.c    |  3 ++-
>   target/arm/cpu64.c  |  6 +++---
>   target/arm/helper.c | 12 +++++++-----
>   4 files changed, 25 insertions(+), 11 deletions(-)
> 
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index b55f6c8b7d3..2b3124fd76b 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -871,6 +871,8 @@ struct ARMCPU {
>           uint64_t id_aa64pfr1;
>           uint64_t id_aa64mmfr0;
>           uint64_t id_aa64mmfr1;
> +        uint64_t id_aa64dfr0;
> +        uint64_t id_aa64dfr1;
>       } isar;
>       uint32_t midr;
>       uint32_t revidr;
> @@ -887,8 +889,6 @@ struct ARMCPU {
>       uint32_t id_mmfr2;
>       uint32_t id_mmfr3;
>       uint32_t id_mmfr4;
> -    uint64_t id_aa64dfr0;
> -    uint64_t id_aa64dfr1;
>       uint64_t id_aa64afr0;
>       uint64_t id_aa64afr1;
>       uint32_t dbgdidr;
> @@ -3728,6 +3728,12 @@ static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
>       return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
>   }
>   
> +static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
> +{
> +    return FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
> +        FIELD_EX32(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;

FIELD_EX64()

> +}
> +
>   /*
>    * Feature tests for "does this exist in either 32-bit or 64-bit?"
>    */
> @@ -3741,6 +3747,11 @@ static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
>       return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
>   }
>   
> +static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
> +{
> +    return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
> +}
> +
>   /*
>    * Forward to the above feature tests given an ARMCPU pointer.
>    */

I'm not sure why, I can't apply this patch locally, but this might be a 
problem with my smtp setup (I am having some mails oddly re-encoded).

Applying: target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
error: patch failed: target/arm/cpu.h:3741
error: target/arm/cpu.h: patch does not apply
Patch failed at 0008 target/arm: Add _aa64_ and _any_ versions of 
pmu_8_1 isar checks

> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index ac0c96322d1..df44df1a43a 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -1602,7 +1602,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
>                   cpu);
>   #endif
>       } else {
> -        cpu->id_aa64dfr0 = FIELD_DP32(cpu->id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
> +        cpu->isar.id_aa64dfr0 =
> +            FIELD_DP32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);

FIELD_EX64()

>           cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
>           cpu->pmceid0 = 0;
>           cpu->pmceid1 = 0;
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index f8fda7e0988..4b4b134ef84 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -135,7 +135,7 @@ static void aarch64_a57_initfn(Object *obj)
>       cpu->isar.id_isar5 = 0x00011121;
>       cpu->isar.id_isar6 = 0;
>       cpu->isar.id_aa64pfr0 = 0x00002222;
> -    cpu->id_aa64dfr0 = 0x10305106;
> +    cpu->isar.id_aa64dfr0 = 0x10305106;
>       cpu->isar.id_aa64isar0 = 0x00011120;
>       cpu->isar.id_aa64mmfr0 = 0x00001124;
>       cpu->dbgdidr = 0x3516d000;
> @@ -189,7 +189,7 @@ static void aarch64_a53_initfn(Object *obj)
>       cpu->isar.id_isar5 = 0x00011121;
>       cpu->isar.id_isar6 = 0;
>       cpu->isar.id_aa64pfr0 = 0x00002222;
> -    cpu->id_aa64dfr0 = 0x10305106;
> +    cpu->isar.id_aa64dfr0 = 0x10305106;
>       cpu->isar.id_aa64isar0 = 0x00011120;
>       cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
>       cpu->dbgdidr = 0x3516d000;
> @@ -241,7 +241,7 @@ static void aarch64_a72_initfn(Object *obj)
>       cpu->isar.id_isar4 = 0x00011142;
>       cpu->isar.id_isar5 = 0x00011121;
>       cpu->isar.id_aa64pfr0 = 0x00002222;
> -    cpu->id_aa64dfr0 = 0x10305106;
> +    cpu->isar.id_aa64dfr0 = 0x10305106;
>       cpu->isar.id_aa64isar0 = 0x00011120;
>       cpu->isar.id_aa64mmfr0 = 0x00001124;
>       cpu->dbgdidr = 0x3516d000;
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index ca0bf3402ca..9537785104e 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -25,6 +25,7 @@
>   #include "hw/semihosting/semihost.h"
>   #include "sysemu/cpus.h"
>   #include "sysemu/kvm.h"
> +#include "sysemu/tcg.h"
>   #include "qemu/range.h"
>   #include "qapi/qapi-commands-machine-target.h"
>   #include "qapi/error.h"
> @@ -5771,9 +5772,10 @@ static void define_debug_regs(ARMCPU *cpu)
>        * check that if they both exist then they agree.
>        */
>       if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
> -        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
> -        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
> -        assert(FIELD_EX32(cpu->id_aa64dfr0, ID_AA64DFR0, CTX_CMPS) == ctx_cmps);
> +        assert(FIELD_EX32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) == brps);
> +        assert(FIELD_EX32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) == wrps);
> +        assert(FIELD_EX32(cpu->isar.id_aa64dfr0, ID_AA64DFR0, CTX_CMPS)
> +               == ctx_cmps);

FIELD_EX64()

>       }
>   
>       define_one_arm_cp_reg(cpu, &dbgdidr);
> @@ -6395,12 +6397,12 @@ void register_cp_regs_for_features(ARMCPU *cpu)
>                 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 0,
>                 .access = PL1_R, .type = ARM_CP_CONST,
>                 .accessfn = access_aa64_tid3,
> -              .resetvalue = cpu->id_aa64dfr0 },
> +              .resetvalue = cpu->isar.id_aa64dfr0 },
>               { .name = "ID_AA64DFR1_EL1", .state = ARM_CP_STATE_AA64,
>                 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 1,
>                 .access = PL1_R, .type = ARM_CP_CONST,
>                 .accessfn = access_aa64_tid3,
> -              .resetvalue = cpu->id_aa64dfr1 },
> +              .resetvalue = cpu->isar.id_aa64dfr1 },
>               { .name = "ID_AA64DFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
>                 .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 5, .opc2 = 2,
>                 .access = PL1_R, .type = ARM_CP_CONST,
> 

Using 64bit macros:
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 12/13] target/arm: Correct definition of PMCRDP
  2020-02-11 17:37 ` [PATCH 12/13] target/arm: Correct definition of PMCRDP Peter Maydell
  2020-02-11 18:52   ` Richard Henderson
@ 2020-02-12  7:00   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  7:00 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel, Aaron Lindsay
  Cc: Eric Auger, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> The PMCR_EL0.DP bit is bit 5, which is 0x20, not 0x10.  0x10 is 'X'.
> Correct our #define of PMCRDP and add the missing PMCRX.
> 
> We do have the correct behaviour for handling the DP bit being
> set, so this fixes a guest-visible bug.
> 

Fixes: 033614c47de
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/helper.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index cb3c30f1725..c6758bfbeb5 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -1017,7 +1017,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
>   #define PMCRN_MASK  0xf800
>   #define PMCRN_SHIFT 11
>   #define PMCRLC  0x40
> -#define PMCRDP  0x10
> +#define PMCRDP  0x20
> +#define PMCRX   0x10
>   #define PMCRD   0x8
>   #define PMCRC   0x4
>   #define PMCRP   0x2
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit
  2020-02-11 17:37 ` [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit Peter Maydell
  2020-02-11 18:55   ` Richard Henderson
@ 2020-02-12  7:14   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 37+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-02-12  7:14 UTC (permalink / raw)
  To: Peter Maydell, qemu-arm, qemu-devel
  Cc: Eric Auger, Aaron Lindsay, Richard Henderson

On 2/11/20 6:37 PM, Peter Maydell wrote:
> The LC bit in the PMCR_EL0 register is supposed to be:
>   * read/write
>   * RES1 on an AArch64-only implementation
>   * an architecturally UNKNOWN value on reset
> (and use of LC==0 by software is deprecated).
> 
> We were implementing it incorrectly as read-only always zero,
> though we do have all the code needed to test it and behave
> accordingly.
> 
> Instead make it a read-write bit which resets to 1 always, which
> satisfies all the architectural requirements above.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   target/arm/helper.c | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index c6758bfbeb5..1d8eafceda8 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -1023,6 +1023,11 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
>   #define PMCRC   0x4
>   #define PMCRP   0x2
>   #define PMCRE   0x1
> +/*
> + * Mask of PMCR bits writeable by guest (not including WO bits like C, P,
> + * which can be written as 1 to trigger behaviour but which stay RAZ).
> + */
> +#define PMCR_WRITEABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
>   
>   #define PMXEVTYPER_P          0x80000000
>   #define PMXEVTYPER_U          0x40000000
> @@ -1577,9 +1582,8 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
>           }
>       }
>   
> -    /* only the DP, X, D and E bits are writable */
> -    env->cp15.c9_pmcr &= ~0x39;
> -    env->cp15.c9_pmcr |= (value & 0x39);

Ah this was missing PMCRLC indeed.

I was tempted to use 'Fixes: 74594c9d813' but the PMCRLC is "Reserved, 
UNK/SBZP" in the ARMv7 reference manual.
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> +    env->cp15.c9_pmcr &= ~PMCR_WRITEABLE_MASK;
> +    env->cp15.c9_pmcr |= (value & PMCR_WRITEABLE_MASK);
>   
>       pmu_op_finish(env);
>   }
> @@ -5886,7 +5890,8 @@ static void define_pmu_regs(ARMCPU *cpu)
>           .access = PL0_RW, .accessfn = pmreg_access,
>           .type = ARM_CP_IO,
>           .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
> -        .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
> +        .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT) |
> +                      PMCRLC,
>           .writefn = pmcr_write, .raw_writefn = raw_write,
>       };
>       define_one_arm_cp_reg(cpu, &pmcr);
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
  2020-02-12  6:24   ` Philippe Mathieu-Daudé
@ 2020-02-12 11:32     ` Peter Maydell
  0 siblings, 0 replies; 37+ messages in thread
From: Peter Maydell @ 2020-02-12 11:32 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Eric Auger, Aaron Lindsay, qemu-arm, Richard Henderson, QEMU Developers

On Wed, 12 Feb 2020 at 06:24, Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
>
> On 2/11/20 6:37 PM, Peter Maydell wrote:
> > @@ -185,7 +185,7 @@ uint32_t vfp_get_fpscr(CPUARMState *env)
> >   void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
> >   {
> >       /* When ARMv8.2-FP16 is not supported, FZ16 is RES0.  */
> > -    if (!cpu_isar_feature(aa64_fp16, env_archcpu(env))) {
> > +    if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
>
> So we had a potential bug on aa32?

No, because right now we don't support AA32 FP16 yet (so
the aa32_fp16_arith check is temporarily testing an AA64
ID reg, as noted in a TODO comment in that function), and
anyway all our CPUs which have ARMv8 features also mandatorily
have AArch64 currently. This is mainly tidyup so we are in
a position to add a new v8-32-bit-only CPU if we want to.

thanks
--- PMM


^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2020-02-12 11:33 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-11 17:37 [PATCH 00/13] arm: Implement ARMv8.1-PMU and ARMv8.4-PMU Peter Maydell
2020-02-11 17:37 ` [PATCH 01/13] target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers Peter Maydell
2020-02-11 18:25   ` Richard Henderson
2020-02-12  6:23   ` Philippe Mathieu-Daudé
2020-02-11 17:37 ` [PATCH 02/13] target/arm: Add isar_feature_any_fp16 and document naming/usage conventions Peter Maydell
2020-02-11 18:28   ` Richard Henderson
2020-02-12  6:24   ` Philippe Mathieu-Daudé
2020-02-12 11:32     ` Peter Maydell
2020-02-11 17:37 ` [PATCH 03/13] target/arm: Define and use any_predinv isar_feature test Peter Maydell
2020-02-11 18:29   ` Richard Henderson
2020-02-12  6:24   ` Philippe Mathieu-Daudé
2020-02-11 17:37 ` [PATCH 04/13] target/arm: Factor out PMU register definitions Peter Maydell
2020-02-11 18:30   ` Richard Henderson
2020-02-12  6:40   ` Philippe Mathieu-Daudé
2020-02-11 17:37 ` [PATCH 05/13] target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1 Peter Maydell
2020-02-11 18:34   ` Richard Henderson
2020-02-12  6:44     ` Philippe Mathieu-Daudé
2020-02-11 17:37 ` [PATCH 06/13] target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field Peter Maydell
2020-02-11 18:34   ` Richard Henderson
2020-02-12  6:48   ` Philippe Mathieu-Daudé
2020-02-11 17:37 ` [PATCH 07/13] target/arm: Define an aa32_pmu_8_1 isar feature test function Peter Maydell
2020-02-11 18:38   ` Richard Henderson
2020-02-11 17:37 ` [PATCH 08/13] target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks Peter Maydell
2020-02-11 18:40   ` Richard Henderson
2020-02-12  6:56   ` Philippe Mathieu-Daudé
2020-02-11 17:37 ` [PATCH 09/13] target/arm: Implement ARMv8.1-PMU extension Peter Maydell
2020-02-11 18:45   ` Richard Henderson
2020-02-11 17:37 ` [PATCH 10/13] target/arm: Implement ARMv8.4-PMU extension Peter Maydell
2020-02-11 18:49   ` Richard Henderson
2020-02-11 17:37 ` [PATCH 11/13] target/arm: Provide ARMv8.4-PMU in '-cpu max' Peter Maydell
2020-02-11 18:50   ` Richard Henderson
2020-02-11 17:37 ` [PATCH 12/13] target/arm: Correct definition of PMCRDP Peter Maydell
2020-02-11 18:52   ` Richard Henderson
2020-02-12  7:00   ` Philippe Mathieu-Daudé
2020-02-11 17:37 ` [PATCH 13/13] target/arm: Correct handling of PMCR_EL0.LC bit Peter Maydell
2020-02-11 18:55   ` Richard Henderson
2020-02-12  7:14   ` Philippe Mathieu-Daudé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.