target/mips: Move cp0_count_ns to CPUMIPSState
Currently the CP0 timer period is fixed at 10 ns, corresponding to a fixed CPU frequency of 200 MHz (using half the speed of the CPU). In few commits we will be able to use a different CPU frequency. In preparation, move the cp0_count_ns variable to CPUMIPSState so we can modify it. Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Message-Id: <20201012095804.3335117-9-f4bug@amsat.org>
This commit is contained in:
parent
8dadffc017
commit
d225b51220
@ -27,18 +27,6 @@
|
||||
#include "sysemu/kvm.h"
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#define CPU_FREQ_HZ_DEFAULT 200000000
|
||||
#define CP0_COUNT_RATE_DEFAULT 2
|
||||
#define TIMER_PERIOD 10 /* 1 / (CPU_FREQ_HZ / CP0_COUNT_RATE) */
|
||||
|
||||
/* MIPS R4K timer */
|
||||
static void cpu_mips_timer_update(CPUMIPSState *env)
|
||||
{
|
||||
@ -47,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);
|
||||
}
|
||||
|
||||
@ -76,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,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);
|
||||
}
|
||||
@ -119,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)
|
||||
|
@ -134,6 +134,25 @@ 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
|
||||
*/
|
||||
#define CPU_FREQ_HZ_DEFAULT 200000000
|
||||
#define CP0_COUNT_RATE_DEFAULT 2
|
||||
#define TIMER_PERIOD_DEFAULT 10 /* 1 / (CPU_FREQ_HZ / CP0_COUNT_RATE) */
|
||||
|
||||
static void mips_cp0_period_set(MIPSCPU *cpu)
|
||||
{
|
||||
CPUMIPSState *env = &cpu->env;
|
||||
|
||||
env->cp0_count_ns = TIMER_PERIOD_DEFAULT;
|
||||
}
|
||||
|
||||
static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
@ -141,6 +160,8 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev);
|
||||
Error *local_err = NULL;
|
||||
|
||||
mips_cp0_period_set(cpu);
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(errp, local_err);
|
||||
|
@ -1145,6 +1145,7 @@ struct CPUMIPSState {
|
||||
struct MIPSITUState *itu;
|
||||
MemoryRegion *itc_tag; /* ITC Configuration Tags */
|
||||
target_ulong exception_base; /* ExceptionBase input to the core */
|
||||
uint64_t cp0_count_ns; /* CP0_Count clock period (in nanoseconds) */
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user