diff mbox series

[for-8.2,2/2] target/riscv/cpu.c: add zihpm extension flag

Message ID 20230717215419.124258-3-dbarboza@ventanamicro.com
State New
Headers show
Series target/riscv: add zicntr and zihpm flags | expand

Commit Message

Daniel Henrique Barboza July 17, 2023, 9:54 p.m. UTC
zihpm is the Hardware Performance Counters extension described in
chapter 12 of the unprivileged spec. It describes support for 29
unprivileged performance counters, hpmcounter3-hpmcounter21.

As with zicntr, QEMU already implements zihpm before it was even an
extension. zihpm is also part of the RVA22 profile, so add it to QEMU
to complement the future future profile implementation.

Default it to 'true' since it was always present in the code. Change the
realize() time validation to disable it in case 'icsr' isn't present and
if there's no hardware counters (cpu->cfg.pmu_num is zero).

There's a small tweak needed in riscv_cpu_realize_tcg() made:
riscv_cpu_validate_set_extensions() must be executed after the block
that executes riscv_pmu_init(). The reason is that riscv_pmu_init() will
do "cpu->cfg.pmu_num = 0" if PMU support cannot be enabled. We want to
get the latest, definite value of cfg.pmu_num during the validation() to
ensure we do the right thing.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.c     | 20 +++++++++++++-------
 target/riscv/cpu_cfg.h |  1 +
 2 files changed, 14 insertions(+), 7 deletions(-)

Comments

Alistair Francis July 24, 2023, 2 a.m. UTC | #1
On Tue, Jul 18, 2023 at 7:55 AM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> zihpm is the Hardware Performance Counters extension described in
> chapter 12 of the unprivileged spec. It describes support for 29
> unprivileged performance counters, hpmcounter3-hpmcounter21.
>
> As with zicntr, QEMU already implements zihpm before it was even an
> extension. zihpm is also part of the RVA22 profile, so add it to QEMU
> to complement the future future profile implementation.
>
> Default it to 'true' since it was always present in the code. Change the
> realize() time validation to disable it in case 'icsr' isn't present and
> if there's no hardware counters (cpu->cfg.pmu_num is zero).
>
> There's a small tweak needed in riscv_cpu_realize_tcg() made:
> riscv_cpu_validate_set_extensions() must be executed after the block
> that executes riscv_pmu_init(). The reason is that riscv_pmu_init() will
> do "cpu->cfg.pmu_num = 0" if PMU support cannot be enabled. We want to
> get the latest, definite value of cfg.pmu_num during the validation() to
> ensure we do the right thing.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.c     | 20 +++++++++++++-------
>  target/riscv/cpu_cfg.h |  1 +
>  2 files changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 7ec88659be..5836640d5c 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -89,6 +89,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
>      ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
>      ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
>      ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
> +    ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_ihpm),
>      ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
>      ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
>      ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
> @@ -1296,6 +1297,10 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
>          cpu->cfg.ext_icntr = false;
>      }
>
> +    if (cpu->cfg.ext_ihpm && (!cpu->cfg.ext_icsr || cpu->cfg.pmu_num == 0)) {
> +        cpu->cfg.ext_ihpm = false;
> +    }
> +
>      /*
>       * Disable isa extensions based on priv spec after we
>       * validated and set everything we need.
> @@ -1426,12 +1431,6 @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
>          return;
>      }
>
> -    riscv_cpu_validate_set_extensions(cpu, &local_err);
> -    if (local_err != NULL) {
> -        error_propagate(errp, local_err);
> -        return;
> -    }
> -
>  #ifndef CONFIG_USER_ONLY
>      CPU(dev)->tcg_cflags |= CF_PCREL;
>
> @@ -1446,6 +1445,12 @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
>          }
>       }
>  #endif
> +
> +    riscv_cpu_validate_set_extensions(cpu, &local_err);
> +    if (local_err != NULL) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
>  }
>
>  static void riscv_cpu_realize(DeviceState *dev, Error **errp)
> @@ -1784,10 +1789,11 @@ static Property riscv_cpu_extensions[] = {
>      DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false),
>
>      /*
> -     * Always default true - we'll disable it during
> +     * Always default true - we'll disable them during
>       * realize() if needed.
>       */
>      DEFINE_PROP_BOOL("zicntr", RISCVCPU, cfg.ext_icntr, true),
> +    DEFINE_PROP_BOOL("zihpm", RISCVCPU, cfg.ext_ihpm, true),
>
>      DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
>      DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index d36dc12b92..85c7a71853 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -66,6 +66,7 @@ struct RISCVCPUConfig {
>      bool ext_icsr;
>      bool ext_icbom;
>      bool ext_icboz;
> +    bool ext_ihpm;
>      bool ext_zicond;
>      bool ext_zihintpause;
>      bool ext_smstateen;
> --
> 2.41.0
>
>
diff mbox series

Patch

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7ec88659be..5836640d5c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -89,6 +89,7 @@  static const struct isa_ext_data isa_edata_arr[] = {
     ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
     ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
     ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
+    ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_ihpm),
     ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
     ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
     ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
@@ -1296,6 +1297,10 @@  void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
         cpu->cfg.ext_icntr = false;
     }
 
+    if (cpu->cfg.ext_ihpm && (!cpu->cfg.ext_icsr || cpu->cfg.pmu_num == 0)) {
+        cpu->cfg.ext_ihpm = false;
+    }
+
     /*
      * Disable isa extensions based on priv spec after we
      * validated and set everything we need.
@@ -1426,12 +1431,6 @@  static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
         return;
     }
 
-    riscv_cpu_validate_set_extensions(cpu, &local_err);
-    if (local_err != NULL) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
 #ifndef CONFIG_USER_ONLY
     CPU(dev)->tcg_cflags |= CF_PCREL;
 
@@ -1446,6 +1445,12 @@  static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
         }
      }
 #endif
+
+    riscv_cpu_validate_set_extensions(cpu, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
+    }
 }
 
 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
@@ -1784,10 +1789,11 @@  static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false),
 
     /*
-     * Always default true - we'll disable it during
+     * Always default true - we'll disable them during
      * realize() if needed.
      */
     DEFINE_PROP_BOOL("zicntr", RISCVCPU, cfg.ext_icntr, true),
+    DEFINE_PROP_BOOL("zihpm", RISCVCPU, cfg.ext_ihpm, true),
 
     DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true),
     DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index d36dc12b92..85c7a71853 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -66,6 +66,7 @@  struct RISCVCPUConfig {
     bool ext_icsr;
     bool ext_icbom;
     bool ext_icboz;
+    bool ext_ihpm;
     bool ext_zicond;
     bool ext_zihintpause;
     bool ext_smstateen;