From d0bec217ee0f6c948ba4579ca0f43a1a3f346cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 12 Oct 2020 11:57:53 +0200 Subject: [PATCH] target/mips/cpu: Make cp0_count_rate a property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since not all CPU implementations use a cores use a CP0 timer at half the frequency of the CPU, make this variable a property. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20201012095804.3335117-11-f4bug@amsat.org> --- target/mips/cpu.c | 19 +++++++++++-------- target/mips/cpu.h | 9 +++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 46188139b7..461edfe22b 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -26,7 +26,7 @@ #include "qemu/module.h" #include "sysemu/kvm.h" #include "exec/exec-all.h" - +#include "hw/qdev-properties.h" static void mips_cpu_set_pc(CPUState *cs, vaddr value) { @@ -135,12 +135,7 @@ static void mips_cpu_disas_set_info(CPUState *s, disassemble_info *info) } /* - * Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz - * and a CP0 timer running at half the clock of the CPU (cp0_count_rate = 2). - * - * TIMER_FREQ_HZ = CPU_FREQ_HZ / CP0_COUNT_RATE = 200 MHz / 2 = 100 MHz - * - * TIMER_PERIOD_NS = 1 / TIMER_FREQ_HZ = 10 ns + * Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz. */ #define CPU_FREQ_HZ_DEFAULT 200000000 #define CP0_COUNT_RATE_DEFAULT 2 @@ -149,7 +144,7 @@ static void mips_cp0_period_set(MIPSCPU *cpu) { CPUMIPSState *env = &cpu->env; - env->cp0_count_ns = muldiv64(NANOSECONDS_PER_SECOND, CP0_COUNT_RATE_DEFAULT, + env->cp0_count_ns = muldiv64(NANOSECONDS_PER_SECOND, cpu->cp0_count_rate, CPU_FREQ_HZ_DEFAULT); } @@ -202,6 +197,13 @@ static ObjectClass *mips_cpu_class_by_name(const char *cpu_model) return oc; } +static Property mips_cpu_properties[] = { + /* CP0 timer running at half the clock of the CPU */ + DEFINE_PROP_UINT32("cp0-count-rate", MIPSCPU, cp0_count_rate, + CP0_COUNT_RATE_DEFAULT), + DEFINE_PROP_END_OF_LIST() +}; + static void mips_cpu_class_init(ObjectClass *c, void *data) { MIPSCPUClass *mcc = MIPS_CPU_CLASS(c); @@ -211,6 +213,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data) device_class_set_parent_realize(dc, mips_cpu_realizefn, &mcc->parent_realize); device_class_set_parent_reset(dc, mips_cpu_reset, &mcc->parent_reset); + device_class_set_props(dc, mips_cpu_properties); cc->class_by_name = mips_cpu_class_by_name; cc->has_work = mips_cpu_has_work; diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 085a88e955..baeceb892e 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1151,6 +1151,7 @@ struct CPUMIPSState { /** * MIPSCPU: * @env: #CPUMIPSState + * @cp0_count_rate: rate at which the coprocessor 0 counter increments * * A MIPS CPU. */ @@ -1161,6 +1162,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; };