|
|
1.1 ! root 1: #include "vl.h" ! 2: ! 3: void cpu_mips_irqctrl_init (void) ! 4: { ! 5: } ! 6: ! 7: /* XXX: do not use a global */ ! 8: uint32_t cpu_mips_get_random (CPUState *env) ! 9: { ! 10: static uint32_t seed = 0; ! 11: uint32_t idx; ! 12: seed = seed * 314159 + 1; ! 13: idx = (seed >> 16) % (MIPS_TLB_NB - env->CP0_Wired) + env->CP0_Wired; ! 14: return idx; ! 15: } ! 16: ! 17: /* MIPS R4K timer */ ! 18: uint32_t cpu_mips_get_count (CPUState *env) ! 19: { ! 20: return env->CP0_Count + ! 21: (uint32_t)muldiv64(qemu_get_clock(vm_clock), ! 22: 100 * 1000 * 1000, ticks_per_sec); ! 23: } ! 24: ! 25: static void cpu_mips_update_count (CPUState *env, uint32_t count, ! 26: uint32_t compare) ! 27: { ! 28: uint64_t now, next; ! 29: uint32_t tmp; ! 30: ! 31: tmp = count; ! 32: if (count == compare) ! 33: tmp++; ! 34: now = qemu_get_clock(vm_clock); ! 35: next = now + muldiv64(compare - tmp, ticks_per_sec, 100 * 1000 * 1000); ! 36: if (next == now) ! 37: next++; ! 38: #if 0 ! 39: if (logfile) { ! 40: fprintf(logfile, "%s: 0x%08" PRIx64 " %08x %08x => 0x%08" PRIx64 "\n", ! 41: __func__, now, count, compare, next - now); ! 42: } ! 43: #endif ! 44: /* Store new count and compare registers */ ! 45: env->CP0_Compare = compare; ! 46: env->CP0_Count = ! 47: count - (uint32_t)muldiv64(now, 100 * 1000 * 1000, ticks_per_sec); ! 48: /* Adjust timer */ ! 49: qemu_mod_timer(env->timer, next); ! 50: } ! 51: ! 52: void cpu_mips_store_count (CPUState *env, uint32_t value) ! 53: { ! 54: cpu_mips_update_count(env, value, env->CP0_Compare); ! 55: } ! 56: ! 57: void cpu_mips_store_compare (CPUState *env, uint32_t value) ! 58: { ! 59: cpu_mips_update_count(env, cpu_mips_get_count(env), value); ! 60: cpu_mips_irq_request(env, 7, 0); ! 61: } ! 62: ! 63: static void mips_timer_cb (void *opaque) ! 64: { ! 65: CPUState *env; ! 66: ! 67: env = opaque; ! 68: #if 0 ! 69: if (logfile) { ! 70: fprintf(logfile, "%s\n", __func__); ! 71: } ! 72: #endif ! 73: cpu_mips_update_count(env, cpu_mips_get_count(env), env->CP0_Compare); ! 74: cpu_mips_irq_request(env, 7, 1); ! 75: } ! 76: ! 77: void cpu_mips_clock_init (CPUState *env) ! 78: { ! 79: env->timer = qemu_new_timer(vm_clock, &mips_timer_cb, env); ! 80: env->CP0_Compare = 0; ! 81: cpu_mips_update_count(env, 1, 0); ! 82: } ! 83:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.