diff mbox series

[v2,07/16] target/ppc/power8_pmu.c: add PM_RUN_INST_CMPL (0xFA) event

Message ID 20210824163032.394099-8-danielhb413@gmail.com
State New
Headers show
Series PMU-EBB support for PPC64 TCG | expand

Commit Message

Daniel Henrique Barboza Aug. 24, 2021, 4:30 p.m. UTC
PM_RUN_INST_CMPL, instructions completed with the run latch set, is
the architected PowerISA v3.1 event defined with PMC4SEL = 0xFA.

Implement it by checking for the CTRL RUN bit before incrementing the
counter.

Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
 target/ppc/cpu.h        |  3 +++
 target/ppc/power8_pmu.c | 25 ++++++++++++++++++++-----
 2 files changed, 23 insertions(+), 5 deletions(-)

Comments

David Gibson Aug. 25, 2021, 5:32 a.m. UTC | #1
On Tue, Aug 24, 2021 at 01:30:23PM -0300, Daniel Henrique Barboza wrote:
> PM_RUN_INST_CMPL, instructions completed with the run latch set, is
> the architected PowerISA v3.1 event defined with PMC4SEL = 0xFA.
> 
> Implement it by checking for the CTRL RUN bit before incrementing the
> counter.
> 
> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> ---
>  target/ppc/cpu.h        |  3 +++
>  target/ppc/power8_pmu.c | 25 ++++++++++++++++++++-----
>  2 files changed, 23 insertions(+), 5 deletions(-)
> 
> diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> index e5df644a3c..60e5e1159a 100644
> --- a/target/ppc/cpu.h
> +++ b/target/ppc/cpu.h
> @@ -358,6 +358,9 @@ typedef struct ppc_v3_pate_t {
>  #define MMCR1_PMC3SEL PPC_BITMASK(48, 55)
>  #define MMCR1_PMC4SEL PPC_BITMASK(56, 63)
>  
> +/* PMU uses CTRL_RUN to sample PM_RUN_INST_CMPL */
> +#define CTRL_RUN PPC_BIT(63)
> +
>  /* LPCR bits */
>  #define LPCR_VPM0         PPC_BIT(0)
>  #define LPCR_VPM1         PPC_BIT(1)
> diff --git a/target/ppc/power8_pmu.c b/target/ppc/power8_pmu.c
> index 311eaa358f..9154fca5fd 100644
> --- a/target/ppc/power8_pmu.c
> +++ b/target/ppc/power8_pmu.c
> @@ -131,10 +131,10 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
>      }
>  }
>  
> -static bool pmc_counting_insns(CPUPPCState *env, int sprn)
> +static bool pmc_counting_insns(CPUPPCState *env, int sprn,
> +                               uint8_t event)
>  {
>      bool ret = false;
> -    uint8_t event;
>  
>      if (sprn == SPR_POWER_PMC5) {
>          return true;
> @@ -156,8 +156,15 @@ static bool pmc_counting_insns(CPUPPCState *env, int sprn)
>          return event == 0x2 || event == 0xFE;
>      case SPR_POWER_PMC2:
>      case SPR_POWER_PMC3:
> -    case SPR_POWER_PMC4:
>          return event == 0x2;
> +    case SPR_POWER_PMC4:
> +        /*
> +         * Event 0xFA is the "instructions completed with run latch
> +         * set" event. Consider it as instruction counting event.
> +         * The caller is responsible for handling it separately
> +         * from PM_INST_CMPL.
> +         */
> +        return event == 0x2 || event == 0xFA;
>      default:
>          break;
>      }
> @@ -171,8 +178,16 @@ void helper_insns_inc(CPUPPCState *env, uint32_t num_insns)
>      int sprn;
>  
>      for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC5; sprn++) {
> -        if (pmc_counting_insns(env, sprn)) {
> -            env->spr[sprn] += num_insns;
> +        uint8_t event = get_PMC_event(env, sprn);
> +
> +        if (pmc_counting_insns(env, sprn, event)) {
> +            if (sprn == SPR_POWER_PMC4 && event == 0xFA) {
> +                if (env->spr[SPR_CTRL] & CTRL_RUN) {
> +                    env->spr[SPR_POWER_PMC4] += num_insns;

This is only correct if changes to CTRL force a new translation
block.  Is that true at the moment?

> +                }
> +            } else {
> +                env->spr[sprn] += num_insns;
> +            }
>          }
>      }
>  }
diff mbox series

Patch

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index e5df644a3c..60e5e1159a 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -358,6 +358,9 @@  typedef struct ppc_v3_pate_t {
 #define MMCR1_PMC3SEL PPC_BITMASK(48, 55)
 #define MMCR1_PMC4SEL PPC_BITMASK(56, 63)
 
+/* PMU uses CTRL_RUN to sample PM_RUN_INST_CMPL */
+#define CTRL_RUN PPC_BIT(63)
+
 /* LPCR bits */
 #define LPCR_VPM0         PPC_BIT(0)
 #define LPCR_VPM1         PPC_BIT(1)
diff --git a/target/ppc/power8_pmu.c b/target/ppc/power8_pmu.c
index 311eaa358f..9154fca5fd 100644
--- a/target/ppc/power8_pmu.c
+++ b/target/ppc/power8_pmu.c
@@ -131,10 +131,10 @@  void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
     }
 }
 
-static bool pmc_counting_insns(CPUPPCState *env, int sprn)
+static bool pmc_counting_insns(CPUPPCState *env, int sprn,
+                               uint8_t event)
 {
     bool ret = false;
-    uint8_t event;
 
     if (sprn == SPR_POWER_PMC5) {
         return true;
@@ -156,8 +156,15 @@  static bool pmc_counting_insns(CPUPPCState *env, int sprn)
         return event == 0x2 || event == 0xFE;
     case SPR_POWER_PMC2:
     case SPR_POWER_PMC3:
-    case SPR_POWER_PMC4:
         return event == 0x2;
+    case SPR_POWER_PMC4:
+        /*
+         * Event 0xFA is the "instructions completed with run latch
+         * set" event. Consider it as instruction counting event.
+         * The caller is responsible for handling it separately
+         * from PM_INST_CMPL.
+         */
+        return event == 0x2 || event == 0xFA;
     default:
         break;
     }
@@ -171,8 +178,16 @@  void helper_insns_inc(CPUPPCState *env, uint32_t num_insns)
     int sprn;
 
     for (sprn = SPR_POWER_PMC1; sprn <= SPR_POWER_PMC5; sprn++) {
-        if (pmc_counting_insns(env, sprn)) {
-            env->spr[sprn] += num_insns;
+        uint8_t event = get_PMC_event(env, sprn);
+
+        if (pmc_counting_insns(env, sprn, event)) {
+            if (sprn == SPR_POWER_PMC4 && event == 0xFA) {
+                if (env->spr[SPR_CTRL] & CTRL_RUN) {
+                    env->spr[SPR_POWER_PMC4] += num_insns;
+                }
+            } else {
+                env->spr[sprn] += num_insns;
+            }
         }
     }
 }