qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
To: qemu-devel@nongnu.org
Cc: "Damien Hedde" <damien.hedde@greensocs.com>,
	"Huacai Chen" <zltjiangshi@gmail.com>,
	"Aleksandar Rikalo" <aleksandar.rikalo@syrmia.com>,
	"Eduardo Habkost" <ehabkost@redhat.com>,
	"Paul Burton" <paulburton@kernel.org>,
	"Edgar E . Iglesias" <edgar.iglesias@gmail.com>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
	"Aleksandar Markovic" <aleksandar.qemu.devel@gmail.com>,
	"Hervé Poussineau" <hpoussin@reactos.org>,
	"Cleber Rosa" <crosa@redhat.com>,
	"Huacai Chen" <chenhc@lemote.com>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>,
	"Aurelien Jarno" <aurelien@aurel32.net>,
	"Richard Henderson" <rth@twiddle.net>
Subject: [PATCH 06/16] target/mips: Keep CP0 counter in sync with the CPU frequency
Date: Mon, 28 Sep 2020 19:15:29 +0200	[thread overview]
Message-ID: <20200928171539.788309-7-f4bug@amsat.org> (raw)
In-Reply-To: <20200928171539.788309-1-f4bug@amsat.org>

Since commit 6af0bf9c7c3 the CP0 counter is running at half the
frequency of a 200 MHz CPU: a static 100 MHz value is used.

By using the Clock API we can change the CPU frequency at runtime,
so the CP0 counter might run out of sync with the CPU clock.
Avoid that by using the recently introduced CPUClass::clock_update()
callback. If the CPU clock is dynamically changed, our CP0 counter
will be updated correspondingly.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 target/mips/cpu.h       |  9 +++++++++
 target/mips/cp0_timer.c | 13 ++++++-------
 target/mips/cpu.c       | 20 ++++++++++++++++++++
 3 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 7cf7f5239f7..66d6124ae02 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1145,6 +1145,7 @@ struct CPUMIPSState {
     struct MIPSITUState *itu;
     MemoryRegion *itc_tag; /* ITC Configuration Tags */
     target_ulong exception_base; /* ExceptionBase input to the core */
+    unsigned cp0_count_ns; /* CP0_Count clock period (in nanoseconds) */
 };
 
 /**
@@ -1160,6 +1161,14 @@ struct MIPSCPU {
 
     CPUNegativeOffsetState neg;
     CPUMIPSState env;
+    /*
+     * The Count register acts as a timer, incrementing at a constant rate,
+     * whether or not an instruction is executed, retired, or any forward
+     * progress is made through the pipeline. The rate at which the counter
+     * increments is implementation dependent, and is a function of the
+     * pipeline clock of the processor, not the issue width of the processor.
+     */
+    unsigned cp0_count_rate;
 };
 
 
diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c
index 5194c967ae3..5ec0d6249e9 100644
--- a/target/mips/cp0_timer.c
+++ b/target/mips/cp0_timer.c
@@ -27,8 +27,6 @@
 #include "sysemu/kvm.h"
 #include "internal.h"
 
-#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */
-
 /* MIPS R4K timer */
 static void cpu_mips_timer_update(CPUMIPSState *env)
 {
@@ -37,8 +35,8 @@ static void cpu_mips_timer_update(CPUMIPSState *env)
 
     now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     wait = env->CP0_Compare - env->CP0_Count -
-           (uint32_t)(now_ns / TIMER_PERIOD);
-    next_ns = now_ns + (uint64_t)wait * TIMER_PERIOD;
+           (uint32_t)(now_ns / env->cp0_count_ns);
+    next_ns = now_ns + (uint64_t)wait * env->cp0_count_ns;
     timer_mod(env->timer, next_ns);
 }
 
@@ -66,7 +64,7 @@ uint32_t cpu_mips_get_count(CPUMIPSState *env)
             cpu_mips_timer_expire(env);
         }
 
-        return env->CP0_Count + (uint32_t)(now_ns / TIMER_PERIOD);
+        return env->CP0_Count + (uint32_t)(now_ns / env->cp0_count_ns);
     }
 }
 
@@ -82,7 +80,8 @@ void cpu_mips_store_count(CPUMIPSState *env, uint32_t count)
     } else {
         /* Store new count register */
         env->CP0_Count = count -
-               (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD);
+               (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
+                          env->cp0_count_ns);
         /* Update timer timer */
         cpu_mips_timer_update(env);
     }
@@ -109,7 +108,7 @@ void cpu_mips_stop_count(CPUMIPSState *env)
 {
     /* Store the current value */
     env->CP0_Count += (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
-                                 TIMER_PERIOD);
+                                 env->cp0_count_ns);
 }
 
 static void mips_timer_cb(void *opaque)
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 8d07a293a2e..2f75216c324 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -26,6 +26,7 @@
 #include "qemu/module.h"
 #include "sysemu/kvm.h"
 #include "exec/exec-all.h"
+#include "hw/qdev-clock.h"
 #include "hw/qdev-properties.h"
 
 static void mips_cpu_set_pc(CPUState *cs, vaddr value)
@@ -134,6 +135,22 @@ static void mips_cpu_disas_set_info(CPUState *s, disassemble_info *info)
     }
 }
 
+static void mips_cp0_period_set(MIPSCPU *cpu)
+{
+    CPUMIPSState *env = &cpu->env;
+
+    /* Recompute CP0's period on clock change */
+    env->cp0_count_ns = cpu->cp0_count_rate * clock_get_ns(CPU(cpu)->clock);
+}
+
+static void mips_cpu_clk_update(CPUState *cs)
+{
+    MIPSCPU *cpu = MIPS_CPU(cs);
+
+    /* Recompute CP0's period on clock change */
+    mips_cp0_period_set(cpu);
+}
+
 static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
@@ -148,6 +165,7 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
          */
         clock_set_hz(cs->clock, 200000000);
     }
+    mips_cpu_clk_update(cs);
 
     cpu_exec_realizefn(cs, &local_err);
     if (local_err != NULL) {
@@ -190,6 +208,7 @@ static ObjectClass *mips_cpu_class_by_name(const char *cpu_model)
 }
 
 static Property mips_cpu_properties[] = {
+    DEFINE_PROP_UINT32("CP0_Count-rate", MIPSCPU, cp0_count_rate, 2),
     DEFINE_PROP_END_OF_LIST()
 };
 
@@ -224,6 +243,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->tcg_initialize = mips_tcg_init;
     cc->tlb_fill = mips_cpu_tlb_fill;
 #endif
+    cc->clock_update = mips_cpu_clk_update;
 
     cc->gdb_num_core_regs = 73;
     cc->gdb_stop_before_watchpoint = true;
-- 
2.26.2



  parent reply	other threads:[~2020-09-28 17:22 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-28 17:15 [PATCH 00/16] hw/mips: Set CPU frequency Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 01/16] hw/core/cpu: Let CPU object have a clock source Philippe Mathieu-Daudé
2020-09-30  7:43   ` Igor Mammedov
2020-09-30 10:16     ` Philippe Mathieu-Daudé
2020-10-05 16:40       ` Igor Mammedov
2020-10-05 17:19         ` Philippe Mathieu-Daudé
2020-10-05 17:44         ` Eduardo Habkost
2020-10-05 18:09           ` Philippe Mathieu-Daudé
2020-10-05 18:29             ` Philippe Mathieu-Daudé
2020-10-05 19:22               ` Eduardo Habkost
2020-10-06 18:11                 ` Philippe Mathieu-Daudé
2020-10-06 19:53                   ` Philippe Mathieu-Daudé
2020-10-05 18:43             ` Eduardo Habkost
2020-09-28 17:15 ` [PATCH 02/16] target/mips: Move cpu_mips_get_random() with CP0 helpers Philippe Mathieu-Daudé
2020-09-30 18:04   ` Aleksandar Markovic
2020-09-28 17:15 ` [PATCH 03/16] target/mips/cp0_timer: Explicit unit in variable name Philippe Mathieu-Daudé
2020-09-30 18:10   ` Aleksandar Markovic
2020-09-28 17:15 ` [PATCH 04/16] target/mips/cpu: Introduce mips_cpu_properties[] Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 05/16] target/mips/cpu: Set default CPU frequency to 200 MHz Philippe Mathieu-Daudé
2020-09-28 17:15 ` Philippe Mathieu-Daudé [this message]
2020-09-28 17:15 ` [PATCH 07/16] hw/mips/r4k: Explicit CPU frequency is " Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 08/16] hw/mips/fuloong2e: Set CPU frequency to 533 MHz Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 09/16] hw/mips/mipssim: Correct CPU frequency Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 10/16] hw/mips/jazz: Correct CPU frequencies Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 11/16] hw/mips/cps: Expose input clock and connect it to CPU cores Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 12/16] hw/mips/boston: Set CPU frequency to 1 GHz Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 13/16] hw/mips/malta: Set CPU frequency to 320 MHz Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 14/16] hw/mips/cps: Do not allow use without input clock Philippe Mathieu-Daudé
2020-09-28 17:15 ` [PATCH 15/16] target/mips/cpu: Do not allow system-mode " Philippe Mathieu-Daudé
2020-09-29 13:01   ` Igor Mammedov
2020-09-29 14:40     ` Philippe Mathieu-Daudé
2020-10-05  7:39       ` Philippe Mathieu-Daudé
2020-10-05 16:25       ` Igor Mammedov
2020-09-28 17:15 ` [PATCH 16/16] tests/acceptance: Test the MIPSsim machine Philippe Mathieu-Daudé
2020-09-28 20:33   ` Willian Rampazzo
2020-09-29  9:09     ` Philippe Mathieu-Daudé
2020-09-29  9:38       ` Alex Bennée
2020-09-29  9:50         ` Philippe Mathieu-Daudé
2020-09-30  8:43         ` Daniel P. Berrangé
2020-09-30  9:49           ` Alex Bennée
2020-09-30 10:08             ` Philippe Mathieu-Daudé
2020-09-29  2:46 ` [PATCH 00/16] hw/mips: Set CPU frequency no-reply
2020-09-29  8:58   ` Philippe Mathieu-Daudé
2020-09-30  7:40 ` Igor Mammedov
2020-09-30 10:13   ` Philippe Mathieu-Daudé
2020-10-09 15:40 ` Philippe Mathieu-Daudé

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=20200928171539.788309-7-f4bug@amsat.org \
    --to=f4bug@amsat.org \
    --cc=aleksandar.qemu.devel@gmail.com \
    --cc=aleksandar.rikalo@syrmia.com \
    --cc=aurelien@aurel32.net \
    --cc=chenhc@lemote.com \
    --cc=crosa@redhat.com \
    --cc=damien.hedde@greensocs.com \
    --cc=edgar.iglesias@gmail.com \
    --cc=ehabkost@redhat.com \
    --cc=hpoussin@reactos.org \
    --cc=paulburton@kernel.org \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=wainersm@redhat.com \
    --cc=zltjiangshi@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).