All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Henrique Barboza <danielhb413@gmail.com>
To: qemu-devel@nongnu.org
Cc: Daniel Henrique Barboza <danielhb413@gmail.com>,
	richard.henderson@linaro.org, groug@kaod.org,
	qemu-ppc@nongnu.org, clg@kaod.org, matheus.ferst@eldorado.org.br,
	david@gibson.dropbear.id.au
Subject: [PATCH v3 12/15] target/ppc/power8_pmu.c: cycles overflow with all PMCs
Date: Fri,  3 Sep 2021 17:31:13 -0300	[thread overview]
Message-ID: <20210903203116.80628-13-danielhb413@gmail.com> (raw)
In-Reply-To: <20210903203116.80628-1-danielhb413@gmail.com>

All performance monitor counters can trigger a counter negative
condition if the proper MMCR0 bits are set. This patch does that
for all PMCs that can count cycles by doing the following:

- pmc_counter_negative_enabled() will check whether a given PMC is
eligible to trigger the counter negative alert;

- get_counter_neg_timeout() will return the timeout for the counter
negative condition for a given PMC, or -1 if the PMC is not able to
trigger this alert;

- the existing counter_negative_cond_enabled() now must consider the
counter negative bit for PMCs 2-6, MMCR0_PMCjCE;

- start_cycle_count_session() will start overflow timers for all eligible
PMCs.

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

diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index ba93b30ae2..02177e584e 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -355,6 +355,7 @@ typedef struct ppc_v3_pate_t {
 #define MMCR0_FC14 PPC_BIT(58) /* MMCR0 Freeze Counters 1-4 bit */
 #define MMCR0_FC56 PPC_BIT(59) /* MMCR0 Freeze Counters 5-6 bit */
 #define MMCR0_PMC1CE PPC_BIT(48) /* MMCR0 PMC1 Condition Enabled */
+#define MMCR0_PMCjCE PPC_BIT(49) /* MMCR0 PMCj Condition Enabled */
 
 #define MMCR1_EVT_SIZE 8
 /* extract64() does a right shift before extracting */
diff --git a/target/ppc/power8_pmu.c b/target/ppc/power8_pmu.c
index b2224d363a..9125ba29ae 100644
--- a/target/ppc/power8_pmu.c
+++ b/target/ppc/power8_pmu.c
@@ -131,9 +131,81 @@ static int64_t get_CYC_timeout(CPUPPCState *env, int sprn)
     return remaining_cyc;
 }
 
+static bool pmc_counter_negative_enabled(CPUPPCState *env, int sprn)
+{
+    if (!pmc_is_running(env, sprn)) {
+        return false;
+    }
+
+    switch (sprn) {
+    case SPR_POWER_PMC1:
+        return env->spr[SPR_POWER_MMCR0] & MMCR0_PMC1CE;
+
+    case SPR_POWER_PMC2:
+    case SPR_POWER_PMC3:
+    case SPR_POWER_PMC4:
+    case SPR_POWER_PMC5:
+    case SPR_POWER_PMC6:
+        return env->spr[SPR_POWER_MMCR0] & MMCR0_PMCjCE;
+
+    default:
+        break;
+    }
+
+    return false;
+}
+
+static int64_t get_counter_neg_timeout(CPUPPCState *env, int sprn)
+{
+    int64_t timeout = -1;
+
+    if (!pmc_counter_negative_enabled(env, sprn)) {
+        return -1;
+    }
+
+    if (env->spr[sprn] >= COUNTER_NEGATIVE_VAL) {
+        return 0;
+    }
+
+    switch (sprn) {
+    case SPR_POWER_PMC1:
+    case SPR_POWER_PMC2:
+    case SPR_POWER_PMC3:
+    case SPR_POWER_PMC4:
+        switch (get_PMC_event(env, sprn)) {
+        case 0xF0:
+            if (sprn == SPR_POWER_PMC1) {
+                timeout = get_CYC_timeout(env, sprn);
+            }
+            break;
+        case 0x1E:
+            timeout = get_CYC_timeout(env, sprn);
+            break;
+        }
+
+        break;
+    case SPR_POWER_PMC6:
+        timeout = get_CYC_timeout(env, sprn);
+        break;
+    default:
+        break;
+    }
+
+    return timeout;
+}
+
 static bool counter_negative_cond_enabled(uint64_t mmcr0)
 {
-    return mmcr0 & MMCR0_PMC1CE;
+    return mmcr0 & (MMCR0_PMC1CE | MMCR0_PMCjCE);
+}
+
+static void pmu_delete_timers(CPUPPCState *env)
+{
+    int i;
+
+    for (i = 0; i < PMU_TIMERS_LEN; i++) {
+        timer_del(env->pmu_intr_timers[i]);
+    }
 }
 
 /*
@@ -144,7 +216,8 @@ static bool counter_negative_cond_enabled(uint64_t mmcr0)
 static void start_cycle_count_session(CPUPPCState *env)
 {
     uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-    uint64_t timeout;
+    int64_t timeout;
+    int i;
 
     env->pmu_base_time = now;
 
@@ -152,30 +225,32 @@ static void start_cycle_count_session(CPUPPCState *env)
      * Always delete existing overflow timers when starting a
      * new cycle counting session.
      */
-    timer_del(env->pmu_intr_timers[0]);
+    pmu_delete_timers(env);
 
     if (!counter_negative_cond_enabled(env->spr[SPR_POWER_MMCR0])) {
         return;
     }
 
-    if (!pmc_is_running(env, SPR_POWER_PMC1)) {
-        return;
-    }
+    /*
+     * Scroll through all programmable PMCs start counter overflow
+     * timers for PM_CYC events, if needed.
+     */
+    for (i = SPR_POWER_PMC1; i < SPR_POWER_PMC5; i++) {
+        timeout = get_counter_neg_timeout(env, i);
 
-    if (!(env->spr[SPR_POWER_MMCR0] & MMCR0_PMC1CE)) {
-        return;
-    }
+        if (timeout == -1) {
+            continue;
+        }
 
-    switch (get_PMC_event(env, SPR_POWER_PMC1)) {
-    case 0xF0:
-    case 0x1E:
-        timeout = get_CYC_timeout(env, SPR_POWER_PMC1);
-        break;
-    default:
-        return;
+        timer_mod(env->pmu_intr_timers[i - SPR_POWER_PMC1],
+                                       now + timeout);
     }
 
-    timer_mod(env->pmu_intr_timers[0], now + timeout);
+    /* Check for counter neg timeout in PMC6 */
+    timeout = get_counter_neg_timeout(env, SPR_POWER_PMC6);
+    if (timeout != -1) {
+        timer_mod(env->pmu_intr_timers[PMU_TIMERS_LEN - 1], now + timeout);
+    }
 }
 
 static void cpu_ppc_pmu_timer_cb(void *opaque)
@@ -193,6 +268,13 @@ static void cpu_ppc_pmu_timer_cb(void *opaque)
 
         /* Changing MMCR0_FC demands a new hflags compute */
         hreg_compute_hflags(env);
+
+        /*
+         * Delete all pending timers if we need to freeze
+         * the PMC. We'll restart them when the PMC starts
+         * running again.
+         */
+        pmu_delete_timers(env);
     }
 
     update_cycles_PMCs(env);
-- 
2.31.1



  parent reply	other threads:[~2021-09-03 20:52 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-03 20:31 [PATCH v3 00/15] PMU-EBB support for PPC64 TCG Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 01/15] target/ppc: add user read functions for MMCR0 and MMCR2 Daniel Henrique Barboza
2021-09-07  1:27   ` David Gibson
2021-09-22 11:23   ` Matheus K. Ferst
2021-09-22 21:10     ` Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 02/15] target/ppc: add user write access control for PMU SPRs Daniel Henrique Barboza
2021-09-07  1:38   ` David Gibson
2021-09-23 14:39     ` Daniel Henrique Barboza
2021-09-27  5:08       ` David Gibson
2021-09-27 23:05         ` Daniel Henrique Barboza
2021-10-07  1:17           ` David Gibson
2021-09-03 20:31 ` [PATCH v3 03/15] target/ppc: PMU basic cycle count for pseries TCG Daniel Henrique Barboza
2021-09-07  1:48   ` David Gibson
2021-09-22 11:24   ` Matheus K. Ferst
2021-09-24 14:41     ` Daniel Henrique Barboza
2021-09-24 18:34       ` Matheus K. Ferst
2021-09-24 19:05         ` Daniel Henrique Barboza
2021-09-27  5:04           ` David Gibson
2021-09-03 20:31 ` [PATCH v3 04/15] target/ppc/power8_pmu.c: enable PMC1-PMC4 events Daniel Henrique Barboza
2021-09-07  1:50   ` David Gibson
2021-09-03 20:31 ` [PATCH v3 05/15] target/ppc: PMU: add instruction counting Daniel Henrique Barboza
2021-09-07  1:57   ` David Gibson
2021-09-21 21:11     ` Daniel Henrique Barboza
2021-09-27  4:59       ` David Gibson
2021-09-03 20:31 ` [PATCH v3 06/15] target/ppc/power8_pmu.c: add PM_RUN_INST_CMPL (0xFA) event Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 07/15] target/ppc/power8_pmu.c: add PMC14/PMC56 counter freeze bits Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 08/15] PPC64/TCG: Implement 'rfebb' instruction Daniel Henrique Barboza
2021-09-09 11:47   ` Matheus K. Ferst
2021-09-22 19:41     ` Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 09/15] target/ppc: PMU Event-Based exception support Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 10/15] target/ppc/excp_helper.c: EBB handling adjustments Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 11/15] target/ppc/power8_pmu.c: enable PMC1 counter negative overflow Daniel Henrique Barboza
2021-09-03 20:31 ` Daniel Henrique Barboza [this message]
2021-09-03 20:31 ` [PATCH v3 13/15] target/ppc: PMU: insns counter negative overflow support Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 14/15] target/ppc/translate: PMU: handle setting of PMCs while running Daniel Henrique Barboza
2021-09-03 20:31 ` [PATCH v3 15/15] target/ppc/power8_pmu.c: handle overflow bits when PMU is running Daniel Henrique Barboza

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210903203116.80628-13-danielhb413@gmail.com \
    --to=danielhb413@gmail.com \
    --cc=clg@kaod.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=groug@kaod.org \
    --cc=matheus.ferst@eldorado.org.br \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.