diff options
Diffstat (limited to 'target/mips/cp0_timer.c')
-rw-r--r-- | target/mips/cp0_timer.c | 51 |
1 files changed, 13 insertions, 38 deletions
diff --git a/target/mips/cp0_timer.c b/target/mips/cp0_timer.c index bd7efb152d..5ec0d6249e 100644 --- a/target/mips/cp0_timer.c +++ b/target/mips/cp0_timer.c @@ -27,43 +27,17 @@ #include "sysemu/kvm.h" #include "internal.h" -#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */ - -/* XXX: do not use a global */ -uint32_t cpu_mips_get_random(CPUMIPSState *env) -{ - static uint32_t seed = 1; - static uint32_t prev_idx = 0; - uint32_t idx; - uint32_t nb_rand_tlb = env->tlb->nb_tlb - env->CP0_Wired; - - if (nb_rand_tlb == 1) { - return env->tlb->nb_tlb - 1; - } - - /* Don't return same value twice, so get another value */ - do { - /* - * Use a simple algorithm of Linear Congruential Generator - * from ISO/IEC 9899 standard. - */ - seed = 1103515245 * seed + 12345; - idx = (seed >> 16) % nb_rand_tlb + env->CP0_Wired; - } while (idx == prev_idx); - prev_idx = idx; - return idx; -} - /* MIPS R4K timer */ static void cpu_mips_timer_update(CPUMIPSState *env) { - uint64_t now, next; + uint64_t now_ns, next_ns; uint32_t wait; - now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - wait = env->CP0_Compare - env->CP0_Count - (uint32_t)(now / TIMER_PERIOD); - next = now + (uint64_t)wait * TIMER_PERIOD; - timer_mod(env->timer, next); + now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + wait = env->CP0_Compare - env->CP0_Count - + (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); } /* Expire the timer. */ @@ -81,16 +55,16 @@ uint32_t cpu_mips_get_count(CPUMIPSState *env) if (env->CP0_Cause & (1 << CP0Ca_DC)) { return env->CP0_Count; } else { - uint64_t now; + uint64_t now_ns; - now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); if (timer_pending(env->timer) - && timer_expired(env->timer, now)) { + && timer_expired(env->timer, now_ns)) { /* The timer has already expired. */ cpu_mips_timer_expire(env); } - return env->CP0_Count + (uint32_t)(now / TIMER_PERIOD); + return env->CP0_Count + (uint32_t)(now_ns / env->cp0_count_ns); } } @@ -106,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); } @@ -133,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) |