3 void cpu_mips_irqctrl_init (void)
7 /* XXX: do not use a global */
8 uint32_t cpu_mips_get_random (CPUState
*env
)
10 static uint32_t seed
= 0;
12 seed
= seed
* 314159 + 1;
13 idx
= (seed
>> 16) % (env
->tlb
->nb_tlb
- env
->CP0_Wired
) + env
->CP0_Wired
;
18 uint32_t cpu_mips_get_count (CPUState
*env
)
20 if (env
->CP0_Cause
& (1 << CP0Ca_DC
))
21 return env
->CP0_Count
;
23 return env
->CP0_Count
+
24 (uint32_t)muldiv64(qemu_get_clock(vm_clock
),
25 100 * 1000 * 1000, ticks_per_sec
);
28 void cpu_mips_store_count (CPUState
*env
, uint32_t count
)
32 uint32_t compare
= env
->CP0_Compare
;
37 now
= qemu_get_clock(vm_clock
);
38 next
= now
+ muldiv64(compare
- tmp
, ticks_per_sec
, 100 * 1000 * 1000);
43 fprintf(logfile
, "%s: 0x%08" PRIx64
" %08x %08x => 0x%08" PRIx64
"\n",
44 __func__
, now
, count
, compare
, next
- now
);
47 /* Store new count and compare registers */
48 env
->CP0_Compare
= compare
;
50 count
- (uint32_t)muldiv64(now
, 100 * 1000 * 1000, ticks_per_sec
);
52 qemu_mod_timer(env
->timer
, next
);
55 static void cpu_mips_update_count (CPUState
*env
, uint32_t count
)
57 if (env
->CP0_Cause
& (1 << CP0Ca_DC
))
60 cpu_mips_store_count(env
, count
);
63 void cpu_mips_store_compare (CPUState
*env
, uint32_t value
)
65 env
->CP0_Compare
= value
;
66 cpu_mips_update_count(env
, cpu_mips_get_count(env
));
67 if ((env
->CP0_Config0
& (0x7 << CP0C0_AR
)) == (1 << CP0C0_AR
))
68 env
->CP0_Cause
&= ~(1 << CP0Ca_TI
);
69 qemu_irq_lower(env
->irq
[(env
->CP0_IntCtl
>> CP0IntCtl_IPTI
) & 0x7]);
72 void cpu_mips_start_count(CPUState
*env
)
74 cpu_mips_store_count(env
, env
->CP0_Count
);
77 void cpu_mips_stop_count(CPUState
*env
)
79 /* Store the current value */
80 env
->CP0_Count
+= (uint32_t)muldiv64(qemu_get_clock(vm_clock
),
81 100 * 1000 * 1000, ticks_per_sec
);
84 static void mips_timer_cb (void *opaque
)
91 fprintf(logfile
, "%s\n", __func__
);
95 if (env
->CP0_Cause
& (1 << CP0Ca_DC
))
98 cpu_mips_update_count(env
, cpu_mips_get_count(env
));
99 if ((env
->CP0_Config0
& (0x7 << CP0C0_AR
)) == (1 << CP0C0_AR
))
100 env
->CP0_Cause
|= 1 << CP0Ca_TI
;
101 qemu_irq_raise(env
->irq
[(env
->CP0_IntCtl
>> CP0IntCtl_IPTI
) & 0x7]);
104 void cpu_mips_clock_init (CPUState
*env
)
106 env
->timer
= qemu_new_timer(vm_clock
, &mips_timer_cb
, env
);
107 env
->CP0_Compare
= 0;
108 cpu_mips_update_count(env
, 1);