blob: e1758094a2be174ee315051247d0220ac70c9473 [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001#ifndef QEMU_TIMER_H
2#define QEMU_TIMER_H
3
David Turner6a9ef172010-09-09 22:54:36 +02004#include "qemu-common.h"
5
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08006/* timers */
7
8typedef struct QEMUClock QEMUClock;
9typedef void QEMUTimerCB(void *opaque);
10
11/* The real time clock should be used only for stuff which does not
12 change the virtual machine state, as it is run even if the virtual
13 machine is stopped. The real time clock has a frequency of 1000
14 Hz. */
15extern QEMUClock *rt_clock;
16
17/* The virtual clock is only run during the emulation. It is stopped
18 when the virtual machine is stopped. Virtual timers use a high
19 precision clock, usually cpu cycles (use ticks_per_sec). */
20extern QEMUClock *vm_clock;
21
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -070022/* The host clock should be use for device models that emulate accurate
23 real time sources. It will continue to run when the virtual machine
24 is suspended, and it will reflect system time changes the host may
25 undergo (e.g. due to NTP). The host clock has the same precision as
26 the virtual clock. */
27extern QEMUClock *host_clock;
28
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080029int64_t qemu_get_clock(QEMUClock *clock);
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -070030int64_t qemu_get_clock_ns(QEMUClock *clock);
David Turner6a9ef172010-09-09 22:54:36 +020031void qemu_clock_enable(QEMUClock *clock, int enabled);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080032
33QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
34void qemu_free_timer(QEMUTimer *ts);
35void qemu_del_timer(QEMUTimer *ts);
36void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
37int qemu_timer_pending(QEMUTimer *ts);
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -070038int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
David 'Digit' Turner6b512812010-10-15 15:05:04 +020039int qemu_timer_alarm_pending(void);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080040
David Turner6a9ef172010-09-09 22:54:36 +020041void qemu_run_all_timers(void);
42int qemu_alarm_pending(void);
43int64_t qemu_next_deadline(void);
44void configure_alarms(char const *opt);
45void configure_icount(const char *option);
46int qemu_calculate_timeout(void);
47void init_clocks(void);
48int init_timer_alarm(void);
49void quit_timers(void);
50
David 'Digit' Turnera7fb77d2010-05-10 23:50:54 -070051static inline int64_t get_ticks_per_sec(void)
52{
53 return 1000000000LL;
54}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080055
David Turner6a9ef172010-09-09 22:54:36 +020056
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080057void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
58void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
59
60/* ptimer.c */
61typedef struct ptimer_state ptimer_state;
62typedef void (*ptimer_cb)(void *opaque);
63
64ptimer_state *ptimer_init(QEMUBH *bh);
65void ptimer_set_period(ptimer_state *s, int64_t period);
66void ptimer_set_freq(ptimer_state *s, uint32_t freq);
67void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
68uint64_t ptimer_get_count(ptimer_state *s);
69void ptimer_set_count(ptimer_state *s, uint64_t count);
70void ptimer_run(ptimer_state *s, int oneshot);
71void ptimer_stop(ptimer_state *s);
72void qemu_put_ptimer(QEMUFile *f, ptimer_state *s);
73void qemu_get_ptimer(QEMUFile *f, ptimer_state *s);
74
David Turner6a9ef172010-09-09 22:54:36 +020075/* icount */
76int64_t qemu_icount_round(int64_t count);
77extern int64_t qemu_icount;
78extern int use_icount;
79extern int icount_time_shift;
80extern int64_t qemu_icount_bias;
81int64_t cpu_get_icount(void);
82
83/*******************************************/
84/* host CPU ticks (if available) */
85
86#if defined(_ARCH_PPC)
87
88static inline int64_t cpu_get_real_ticks(void)
89{
90 int64_t retval;
91#ifdef _ARCH_PPC64
92 /* This reads timebase in one 64bit go and includes Cell workaround from:
93 http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
94 */
95 __asm__ __volatile__ ("mftb %0\n\t"
96 "cmpwi %0,0\n\t"
97 "beq- $-8"
98 : "=r" (retval));
99#else
100 /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
101 unsigned long junk;
102 __asm__ __volatile__ ("mfspr %1,269\n\t" /* mftbu */
103 "mfspr %L0,268\n\t" /* mftb */
104 "mfspr %0,269\n\t" /* mftbu */
105 "cmpw %0,%1\n\t"
106 "bne $-16"
107 : "=r" (retval), "=r" (junk));
108#endif
109 return retval;
110}
111
112#elif defined(__i386__)
113
114static inline int64_t cpu_get_real_ticks(void)
115{
116 int64_t val;
117 asm volatile ("rdtsc" : "=A" (val));
118 return val;
119}
120
121#elif defined(__x86_64__)
122
123static inline int64_t cpu_get_real_ticks(void)
124{
125 uint32_t low,high;
126 int64_t val;
127 asm volatile("rdtsc" : "=a" (low), "=d" (high));
128 val = high;
129 val <<= 32;
130 val |= low;
131 return val;
132}
133
134#elif defined(__hppa__)
135
136static inline int64_t cpu_get_real_ticks(void)
137{
138 int val;
139 asm volatile ("mfctl %%cr16, %0" : "=r"(val));
140 return val;
141}
142
143#elif defined(__ia64)
144
145static inline int64_t cpu_get_real_ticks(void)
146{
147 int64_t val;
148 asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
149 return val;
150}
151
152#elif defined(__s390__)
153
154static inline int64_t cpu_get_real_ticks(void)
155{
156 int64_t val;
157 asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
158 return val;
159}
160
161#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
162
163static inline int64_t cpu_get_real_ticks (void)
164{
165#if defined(_LP64)
166 uint64_t rval;
167 asm volatile("rd %%tick,%0" : "=r"(rval));
168 return rval;
169#else
170 union {
171 uint64_t i64;
172 struct {
173 uint32_t high;
174 uint32_t low;
175 } i32;
176 } rval;
177 asm volatile("rd %%tick,%1; srlx %1,32,%0"
178 : "=r"(rval.i32.high), "=r"(rval.i32.low));
179 return rval.i64;
180#endif
181}
182
183#elif defined(__mips__) && \
184 ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
185/*
186 * binutils wants to use rdhwr only on mips32r2
187 * but as linux kernel emulate it, it's fine
188 * to use it.
189 *
190 */
191#define MIPS_RDHWR(rd, value) { \
192 __asm__ __volatile__ (".set push\n\t" \
193 ".set mips32r2\n\t" \
194 "rdhwr %0, "rd"\n\t" \
195 ".set pop" \
196 : "=r" (value)); \
197 }
198
199static inline int64_t cpu_get_real_ticks(void)
200{
201 /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
202 uint32_t count;
203 static uint32_t cyc_per_count = 0;
204
205 if (!cyc_per_count) {
206 MIPS_RDHWR("$3", cyc_per_count);
207 }
208
209 MIPS_RDHWR("$2", count);
210 return (int64_t)(count * cyc_per_count);
211}
212
213#elif defined(__alpha__)
214
215static inline int64_t cpu_get_real_ticks(void)
216{
217 uint64_t cc;
218 uint32_t cur, ofs;
219
220 asm volatile("rpcc %0" : "=r"(cc));
221 cur = cc;
222 ofs = cc >> 32;
223 return cur - ofs;
224}
225
226#else
227/* The host CPU doesn't have an easily accessible cycle counter.
228 Just return a monotonically increasing value. This will be
229 totally wrong, but hopefully better than nothing. */
230static inline int64_t cpu_get_real_ticks (void)
231{
232 static int64_t ticks = 0;
233 return ticks++;
234}
235#endif
236
237#ifdef NEED_CPU_H
238/* Deterministic execution requires that IO only be performed on the last
239 instruction of a TB so that interrupts take effect immediately. */
240static inline int can_do_io(CPUState *env)
241{
242 if (!use_icount)
243 return 1;
244
245 /* If not executing code then assume we are ok. */
246 if (!env->current_tb)
247 return 1;
248
249 return env->can_do_io != 0;
250}
251#endif
252
253#ifdef CONFIG_PROFILER
254static inline int64_t profile_getclock(void)
255{
256 return cpu_get_real_ticks();
257}
258
259extern int64_t qemu_time, qemu_time_start;
260extern int64_t tlb_flush_time;
261extern int64_t dev_time;
262#endif
263
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800264#endif