3 #include "qemu-timer.h"
5 void cpu_mips_irqctrl_init (void)
9 /* XXX: do not use a global */
10 uint32_t cpu_mips_get_random (CPUState
*env
)
12 static uint32_t seed
= 0;
14 seed
= seed
* 314159 + 1;
15 idx
= (seed
>> 16) % (env
->tlb
->nb_tlb
- env
->CP0_Wired
) + env
->CP0_Wired
;
20 uint32_t cpu_mips_get_count (CPUState
*env
)
22 if (env
->CP0_Cause
& (1 << CP0Ca_DC
))
23 return env
->CP0_Count
;
25 return env
->CP0_Count
+
26 (uint32_t)muldiv64(qemu_get_clock(vm_clock
),
27 100 * 1000 * 1000, ticks_per_sec
);
30 void cpu_mips_store_count (CPUState
*env
, uint32_t count
)
34 uint32_t compare
= env
->CP0_Compare
;
39 now
= qemu_get_clock(vm_clock
);
40 next
= now
+ muldiv64(compare
- tmp
, ticks_per_sec
, 100 * 1000 * 1000);
45 fprintf(logfile
, "%s: 0x%08" PRIx64
" %08x %08x => 0x%08" PRIx64
"\n",
46 __func__
, now
, count
, compare
, next
- now
);
49 /* Store new count and compare registers */
50 env
->CP0_Compare
= compare
;
52 count
- (uint32_t)muldiv64(now
, 100 * 1000 * 1000, ticks_per_sec
);
54 qemu_mod_timer(env
->timer
, next
);
57 static void cpu_mips_update_count (CPUState
*env
, uint32_t count
)
59 if (env
->CP0_Cause
& (1 << CP0Ca_DC
))
62 cpu_mips_store_count(env
, count
);
65 void cpu_mips_store_compare (CPUState
*env
, uint32_t value
)
67 env
->CP0_Compare
= value
;
68 cpu_mips_update_count(env
, cpu_mips_get_count(env
));
69 if ((env
->CP0_Config0
& (0x7 << CP0C0_AR
)) == (1 << CP0C0_AR
))
70 env
->CP0_Cause
&= ~(1 << CP0Ca_TI
);
71 qemu_irq_lower(env
->irq
[(env
->CP0_IntCtl
>> CP0IntCtl_IPTI
) & 0x7]);
74 void cpu_mips_start_count(CPUState
*env
)
76 cpu_mips_store_count(env
, env
->CP0_Count
);
79 void cpu_mips_stop_count(CPUState
*env
)
81 /* Store the current value */
82 env
->CP0_Count
+= (uint32_t)muldiv64(qemu_get_clock(vm_clock
),
83 100 * 1000 * 1000, ticks_per_sec
);
86 static void mips_timer_cb (void *opaque
)
93 fprintf(logfile
, "%s\n", __func__
);
97 if (env
->CP0_Cause
& (1 << CP0Ca_DC
))
100 cpu_mips_update_count(env
, cpu_mips_get_count(env
));
101 if ((env
->CP0_Config0
& (0x7 << CP0C0_AR
)) == (1 << CP0C0_AR
))
102 env
->CP0_Cause
|= 1 << CP0Ca_TI
;
103 qemu_irq_raise(env
->irq
[(env
->CP0_IntCtl
>> CP0IntCtl_IPTI
) & 0x7]);
106 void cpu_mips_clock_init (CPUState
*env
)
108 env
->timer
= qemu_new_timer(vm_clock
, &mips_timer_cb
, env
);
109 env
->CP0_Compare
= 0;
110 cpu_mips_update_count(env
, 1);