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 11/15] target/ppc/power8_pmu.c: enable PMC1 counter negative overflow
Date: Fri, 3 Sep 2021 17:31:12 -0300 [thread overview]
Message-ID: <20210903203116.80628-12-danielhb413@gmail.com> (raw)
In-Reply-To: <20210903203116.80628-1-danielhb413@gmail.com>
This patch starts the counter negative EBB support by enabling PMC1
counter negative overflow when PMC1 is counting cycles.
A counter negative overflow happens when a performance monitor counter
reaches the value 0x80000000. When that happens, if counter negative
condition events are enabled in that counter, a performance monitor
alert is triggered. For PMC1, this condition is enabled by MMCR0_PMC1CE.
Cycle counting is done by calculating elapsed time between the time
the PMU started to run and when the PMU is shut down. Our clock is
fixed in 1Ghz, so 1 cycle equals 1 nanoseconds. The same idea is used to
predict a counter negative overflow: calculate the amount of nanoseconds
for the timer to reach 0x80000000, start a timer with it and trigger the
performance monitor alert. If event-based exceptions are enabled (bit
MMCR0_EBE), we'll go ahead and fire a PPC_INTERRUPT_PMC.
A new function 'start_cycle_count_session' was added to encapsulate the
most common steps of cycle calculation: redefine base time and start
overflow timers. This will avoid code repetition in the next patches.
Counter overflow for the remaining counters will be added shortly.
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
---
target/ppc/cpu.h | 1 +
target/ppc/power8_pmu.c | 99 +++++++++++++++++++++++++++++++++--------
2 files changed, 82 insertions(+), 18 deletions(-)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 780eab6f92..ba93b30ae2 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -354,6 +354,7 @@ typedef struct ppc_v3_pate_t {
#define MMCR0_UREG_MASK (MMCR0_FC | MMCR0_PMAO | MMCR0_PMAE)
#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 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 aa5df6f51f..b2224d363a 100644
--- a/target/ppc/power8_pmu.c
+++ b/target/ppc/power8_pmu.c
@@ -33,6 +33,8 @@ static void update_PMC_PM_CYC(CPUPPCState *env, int sprn,
env->spr[sprn] += time_delta;
}
+#define COUNTER_NEGATIVE_VAL 0x80000000
+
static uint8_t get_PMC_event(CPUPPCState *env, int sprn)
{
uint8_t evt_extr = 0;
@@ -117,30 +119,91 @@ static void update_cycles_PMCs(CPUPPCState *env)
}
}
+static int64_t get_CYC_timeout(CPUPPCState *env, int sprn)
+{
+ int64_t remaining_cyc;
+
+ if (env->spr[sprn] >= COUNTER_NEGATIVE_VAL) {
+ return 0;
+ }
+
+ remaining_cyc = COUNTER_NEGATIVE_VAL - env->spr[sprn];
+ return remaining_cyc;
+}
+
+static bool counter_negative_cond_enabled(uint64_t mmcr0)
+{
+ return mmcr0 & MMCR0_PMC1CE;
+}
+
+/*
+ * A cycle count session consists of the basic operations we
+ * need to do to support PM_CYC events: redefine a new base_time
+ * to be used to calculate PMC values and start overflow timers.
+ */
+static void start_cycle_count_session(CPUPPCState *env)
+{
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ uint64_t timeout;
+
+ env->pmu_base_time = now;
+
+ /*
+ * Always delete existing overflow timers when starting a
+ * new cycle counting session.
+ */
+ timer_del(env->pmu_intr_timers[0]);
+
+ if (!counter_negative_cond_enabled(env->spr[SPR_POWER_MMCR0])) {
+ return;
+ }
+
+ if (!pmc_is_running(env, SPR_POWER_PMC1)) {
+ return;
+ }
+
+ if (!(env->spr[SPR_POWER_MMCR0] & MMCR0_PMC1CE)) {
+ return;
+ }
+
+ 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[0], now + timeout);
+}
+
static void cpu_ppc_pmu_timer_cb(void *opaque)
{
PowerPCCPU *cpu = opaque;
CPUPPCState *env = &cpu->env;
- uint64_t mmcr0;
-
- mmcr0 = env->spr[SPR_POWER_MMCR0];
- if (env->spr[SPR_POWER_MMCR0] & MMCR0_EBE) {
- /* freeeze counters if needed */
- if (mmcr0 & MMCR0_FCECE) {
- mmcr0 &= ~MMCR0_FCECE;
- mmcr0 |= MMCR0_FC;
- }
- /* Clear PMAE and set PMAO */
- if (mmcr0 & MMCR0_PMAE) {
- mmcr0 &= ~MMCR0_PMAE;
- mmcr0 |= MMCR0_PMAO;
- }
- env->spr[SPR_POWER_MMCR0] = mmcr0;
+ if (!(env->spr[SPR_POWER_MMCR0] & MMCR0_EBE)) {
+ return;
+ }
- /* Fire the PMC hardware exception */
- ppc_set_irq(cpu, PPC_INTERRUPT_PMC, 1);
+ if (env->spr[SPR_POWER_MMCR0] & MMCR0_FCECE) {
+ env->spr[SPR_POWER_MMCR0] &= ~MMCR0_FCECE;
+ env->spr[SPR_POWER_MMCR0] |= MMCR0_FC;
+
+ /* Changing MMCR0_FC demands a new hflags compute */
+ hreg_compute_hflags(env);
+ }
+
+ update_cycles_PMCs(env);
+
+ if (env->spr[SPR_POWER_MMCR0] & MMCR0_PMAE) {
+ env->spr[SPR_POWER_MMCR0] &= ~MMCR0_PMAE;
+ env->spr[SPR_POWER_MMCR0] |= MMCR0_PMAO;
}
+
+ /* Fire the PMC hardware exception */
+ ppc_set_irq(cpu, PPC_INTERRUPT_PMC, 1);
}
void cpu_ppc_pmu_timer_init(CPUPPCState *env)
@@ -184,7 +247,7 @@ void helper_store_mmcr0(CPUPPCState *env, target_ulong value)
if (!curr_FC) {
update_cycles_PMCs(env);
} else {
- env->pmu_base_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ start_cycle_count_session(env);
}
}
}
--
2.31.1
next prev parent reply other threads:[~2021-09-03 20:54 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 ` Daniel Henrique Barboza [this message]
2021-09-03 20:31 ` [PATCH v3 12/15] target/ppc/power8_pmu.c: cycles overflow with all PMCs Daniel Henrique Barboza
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-12-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.