Statistics
| Branch: | Revision:

root / qemu-timer.h @ 19bf7c87

History | View | Annotate | Download (8.6 kB)

1 87ecb68b pbrook
#ifndef QEMU_TIMER_H
2 87ecb68b pbrook
#define QEMU_TIMER_H
3 87ecb68b pbrook
4 29e922b6 Blue Swirl
#include "qemu-common.h"
5 44a9b356 Paolo Bonzini
#include "main-loop.h"
6 691a0c9c Jan Kiszka
#include "notify.h"
7 c57c846a Blue Swirl
#include <time.h>
8 c57c846a Blue Swirl
#include <sys/time.h>
9 c57c846a Blue Swirl
10 c57c846a Blue Swirl
#ifdef _WIN32
11 c57c846a Blue Swirl
#include <windows.h>
12 c57c846a Blue Swirl
#endif
13 29e922b6 Blue Swirl
14 87ecb68b pbrook
/* timers */
15 87ecb68b pbrook
16 0ce1b948 Paolo Bonzini
#define SCALE_MS 1000000
17 0ce1b948 Paolo Bonzini
#define SCALE_US 1000
18 0ce1b948 Paolo Bonzini
#define SCALE_NS 1
19 0ce1b948 Paolo Bonzini
20 87ecb68b pbrook
typedef struct QEMUClock QEMUClock;
21 87ecb68b pbrook
typedef void QEMUTimerCB(void *opaque);
22 87ecb68b pbrook
23 87ecb68b pbrook
/* The real time clock should be used only for stuff which does not
24 87ecb68b pbrook
   change the virtual machine state, as it is run even if the virtual
25 87ecb68b pbrook
   machine is stopped. The real time clock has a frequency of 1000
26 87ecb68b pbrook
   Hz. */
27 87ecb68b pbrook
extern QEMUClock *rt_clock;
28 87ecb68b pbrook
29 87ecb68b pbrook
/* The virtual clock is only run during the emulation. It is stopped
30 87ecb68b pbrook
   when the virtual machine is stopped. Virtual timers use a high
31 87ecb68b pbrook
   precision clock, usually cpu cycles (use ticks_per_sec). */
32 87ecb68b pbrook
extern QEMUClock *vm_clock;
33 87ecb68b pbrook
34 21d5d12b Jan Kiszka
/* The host clock should be use for device models that emulate accurate
35 21d5d12b Jan Kiszka
   real time sources. It will continue to run when the virtual machine
36 21d5d12b Jan Kiszka
   is suspended, and it will reflect system time changes the host may
37 21d5d12b Jan Kiszka
   undergo (e.g. due to NTP). The host clock has the same precision as
38 21d5d12b Jan Kiszka
   the virtual clock. */
39 21d5d12b Jan Kiszka
extern QEMUClock *host_clock;
40 21d5d12b Jan Kiszka
41 41c872b6 Paolo Bonzini
int64_t qemu_get_clock_ns(QEMUClock *clock);
42 dc2dfcf0 Paolo Bonzini
int64_t qemu_clock_has_timers(QEMUClock *clock);
43 dc2dfcf0 Paolo Bonzini
int64_t qemu_clock_expired(QEMUClock *clock);
44 dc2dfcf0 Paolo Bonzini
int64_t qemu_clock_deadline(QEMUClock *clock);
45 db1a4972 Paolo Bonzini
void qemu_clock_enable(QEMUClock *clock, int enabled);
46 ab33fcda Paolo Bonzini
void qemu_clock_warp(QEMUClock *clock);
47 87ecb68b pbrook
48 691a0c9c Jan Kiszka
void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier);
49 691a0c9c Jan Kiszka
void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
50 691a0c9c Jan Kiszka
                                          Notifier *notifier);
51 691a0c9c Jan Kiszka
52 4a998740 Paolo Bonzini
QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
53 4a998740 Paolo Bonzini
                          QEMUTimerCB *cb, void *opaque);
54 87ecb68b pbrook
void qemu_free_timer(QEMUTimer *ts);
55 87ecb68b pbrook
void qemu_del_timer(QEMUTimer *ts);
56 2ff68d07 Paolo Bonzini
void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
57 87ecb68b pbrook
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
58 87ecb68b pbrook
int qemu_timer_pending(QEMUTimer *ts);
59 2430ffe4 Stefano Stabellini
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
60 2ff68d07 Paolo Bonzini
uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts);
61 87ecb68b pbrook
62 db1a4972 Paolo Bonzini
void qemu_run_all_timers(void);
63 db1a4972 Paolo Bonzini
int qemu_alarm_pending(void);
64 db1a4972 Paolo Bonzini
void configure_alarms(char const *opt);
65 db1a4972 Paolo Bonzini
int qemu_calculate_timeout(void);
66 db1a4972 Paolo Bonzini
void init_clocks(void);
67 db1a4972 Paolo Bonzini
int init_timer_alarm(void);
68 db1a4972 Paolo Bonzini
69 70c3b557 Blue Swirl
int64_t cpu_get_ticks(void);
70 70c3b557 Blue Swirl
void cpu_enable_ticks(void);
71 70c3b557 Blue Swirl
void cpu_disable_ticks(void);
72 70c3b557 Blue Swirl
73 0ce1b948 Paolo Bonzini
static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
74 0ce1b948 Paolo Bonzini
                                           void *opaque)
75 0ce1b948 Paolo Bonzini
{
76 4a998740 Paolo Bonzini
    return qemu_new_timer(clock, SCALE_NS, cb, opaque);
77 0ce1b948 Paolo Bonzini
}
78 0ce1b948 Paolo Bonzini
79 0ce1b948 Paolo Bonzini
static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock, QEMUTimerCB *cb,
80 0ce1b948 Paolo Bonzini
                                           void *opaque)
81 0ce1b948 Paolo Bonzini
{
82 4a998740 Paolo Bonzini
    return qemu_new_timer(clock, SCALE_MS, cb, opaque);
83 0ce1b948 Paolo Bonzini
}
84 0ce1b948 Paolo Bonzini
85 0ce1b948 Paolo Bonzini
static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
86 0ce1b948 Paolo Bonzini
{
87 0ce1b948 Paolo Bonzini
    return qemu_get_clock_ns(clock) / SCALE_MS;
88 0ce1b948 Paolo Bonzini
}
89 0ce1b948 Paolo Bonzini
90 274dfed8 Anthony Liguori
static inline int64_t get_ticks_per_sec(void)
91 274dfed8 Anthony Liguori
{
92 274dfed8 Anthony Liguori
    return 1000000000LL;
93 274dfed8 Anthony Liguori
}
94 87ecb68b pbrook
95 c57c846a Blue Swirl
/* real time host monotonic timer */
96 c57c846a Blue Swirl
static inline int64_t get_clock_realtime(void)
97 c57c846a Blue Swirl
{
98 c57c846a Blue Swirl
    struct timeval tv;
99 c57c846a Blue Swirl
100 c57c846a Blue Swirl
    gettimeofday(&tv, NULL);
101 c57c846a Blue Swirl
    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
102 c57c846a Blue Swirl
}
103 c57c846a Blue Swirl
104 c57c846a Blue Swirl
/* Warning: don't insert tracepoints into these functions, they are
105 c57c846a Blue Swirl
   also used by simpletrace backend and tracepoints would cause
106 c57c846a Blue Swirl
   an infinite recursion! */
107 c57c846a Blue Swirl
#ifdef _WIN32
108 c57c846a Blue Swirl
extern int64_t clock_freq;
109 c57c846a Blue Swirl
110 c57c846a Blue Swirl
static inline int64_t get_clock(void)
111 c57c846a Blue Swirl
{
112 c57c846a Blue Swirl
    LARGE_INTEGER ti;
113 c57c846a Blue Swirl
    QueryPerformanceCounter(&ti);
114 c57c846a Blue Swirl
    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
115 c57c846a Blue Swirl
}
116 c57c846a Blue Swirl
117 c57c846a Blue Swirl
#else
118 c57c846a Blue Swirl
119 c57c846a Blue Swirl
extern int use_rt_clock;
120 c57c846a Blue Swirl
121 c57c846a Blue Swirl
static inline int64_t get_clock(void)
122 c57c846a Blue Swirl
{
123 c57c846a Blue Swirl
#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
124 c57c846a Blue Swirl
    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
125 c57c846a Blue Swirl
    if (use_rt_clock) {
126 c57c846a Blue Swirl
        struct timespec ts;
127 c57c846a Blue Swirl
        clock_gettime(CLOCK_MONOTONIC, &ts);
128 c57c846a Blue Swirl
        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
129 c57c846a Blue Swirl
    } else
130 c57c846a Blue Swirl
#endif
131 c57c846a Blue Swirl
    {
132 c57c846a Blue Swirl
        /* XXX: using gettimeofday leads to problems if the date
133 c57c846a Blue Swirl
           changes, so it should be avoided. */
134 c57c846a Blue Swirl
        return get_clock_realtime();
135 c57c846a Blue Swirl
    }
136 c57c846a Blue Swirl
}
137 c57c846a Blue Swirl
#endif
138 db1a4972 Paolo Bonzini
139 87ecb68b pbrook
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
140 87ecb68b pbrook
void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
141 87ecb68b pbrook
142 87ecb68b pbrook
/* ptimer.c */
143 87ecb68b pbrook
typedef struct ptimer_state ptimer_state;
144 87ecb68b pbrook
typedef void (*ptimer_cb)(void *opaque);
145 87ecb68b pbrook
146 87ecb68b pbrook
ptimer_state *ptimer_init(QEMUBH *bh);
147 87ecb68b pbrook
void ptimer_set_period(ptimer_state *s, int64_t period);
148 87ecb68b pbrook
void ptimer_set_freq(ptimer_state *s, uint32_t freq);
149 87ecb68b pbrook
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
150 87ecb68b pbrook
uint64_t ptimer_get_count(ptimer_state *s);
151 87ecb68b pbrook
void ptimer_set_count(ptimer_state *s, uint64_t count);
152 87ecb68b pbrook
void ptimer_run(ptimer_state *s, int oneshot);
153 87ecb68b pbrook
void ptimer_stop(ptimer_state *s);
154 87ecb68b pbrook
155 29e922b6 Blue Swirl
/* icount */
156 29e922b6 Blue Swirl
int64_t cpu_get_icount(void);
157 946fb27c Paolo Bonzini
int64_t cpu_get_clock(void);
158 29e922b6 Blue Swirl
159 29e922b6 Blue Swirl
/*******************************************/
160 29e922b6 Blue Swirl
/* host CPU ticks (if available) */
161 29e922b6 Blue Swirl
162 29e922b6 Blue Swirl
#if defined(_ARCH_PPC)
163 29e922b6 Blue Swirl
164 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks(void)
165 29e922b6 Blue Swirl
{
166 29e922b6 Blue Swirl
    int64_t retval;
167 29e922b6 Blue Swirl
#ifdef _ARCH_PPC64
168 29e922b6 Blue Swirl
    /* This reads timebase in one 64bit go and includes Cell workaround from:
169 29e922b6 Blue Swirl
       http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
170 29e922b6 Blue Swirl
    */
171 29e922b6 Blue Swirl
    __asm__ __volatile__ ("mftb    %0\n\t"
172 29e922b6 Blue Swirl
                          "cmpwi   %0,0\n\t"
173 29e922b6 Blue Swirl
                          "beq-    $-8"
174 29e922b6 Blue Swirl
                          : "=r" (retval));
175 29e922b6 Blue Swirl
#else
176 29e922b6 Blue Swirl
    /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
177 29e922b6 Blue Swirl
    unsigned long junk;
178 4a9590f3 Alexander Graf
    __asm__ __volatile__ ("mfspr   %1,269\n\t"  /* mftbu */
179 4a9590f3 Alexander Graf
                          "mfspr   %L0,268\n\t" /* mftb */
180 4a9590f3 Alexander Graf
                          "mfspr   %0,269\n\t"  /* mftbu */
181 29e922b6 Blue Swirl
                          "cmpw    %0,%1\n\t"
182 29e922b6 Blue Swirl
                          "bne     $-16"
183 29e922b6 Blue Swirl
                          : "=r" (retval), "=r" (junk));
184 29e922b6 Blue Swirl
#endif
185 29e922b6 Blue Swirl
    return retval;
186 29e922b6 Blue Swirl
}
187 29e922b6 Blue Swirl
188 29e922b6 Blue Swirl
#elif defined(__i386__)
189 29e922b6 Blue Swirl
190 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks(void)
191 29e922b6 Blue Swirl
{
192 29e922b6 Blue Swirl
    int64_t val;
193 29e922b6 Blue Swirl
    asm volatile ("rdtsc" : "=A" (val));
194 29e922b6 Blue Swirl
    return val;
195 29e922b6 Blue Swirl
}
196 29e922b6 Blue Swirl
197 29e922b6 Blue Swirl
#elif defined(__x86_64__)
198 29e922b6 Blue Swirl
199 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks(void)
200 29e922b6 Blue Swirl
{
201 29e922b6 Blue Swirl
    uint32_t low,high;
202 29e922b6 Blue Swirl
    int64_t val;
203 29e922b6 Blue Swirl
    asm volatile("rdtsc" : "=a" (low), "=d" (high));
204 29e922b6 Blue Swirl
    val = high;
205 29e922b6 Blue Swirl
    val <<= 32;
206 29e922b6 Blue Swirl
    val |= low;
207 29e922b6 Blue Swirl
    return val;
208 29e922b6 Blue Swirl
}
209 29e922b6 Blue Swirl
210 29e922b6 Blue Swirl
#elif defined(__hppa__)
211 29e922b6 Blue Swirl
212 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks(void)
213 29e922b6 Blue Swirl
{
214 29e922b6 Blue Swirl
    int val;
215 29e922b6 Blue Swirl
    asm volatile ("mfctl %%cr16, %0" : "=r"(val));
216 29e922b6 Blue Swirl
    return val;
217 29e922b6 Blue Swirl
}
218 29e922b6 Blue Swirl
219 29e922b6 Blue Swirl
#elif defined(__ia64)
220 29e922b6 Blue Swirl
221 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks(void)
222 29e922b6 Blue Swirl
{
223 29e922b6 Blue Swirl
    int64_t val;
224 29e922b6 Blue Swirl
    asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
225 29e922b6 Blue Swirl
    return val;
226 29e922b6 Blue Swirl
}
227 29e922b6 Blue Swirl
228 29e922b6 Blue Swirl
#elif defined(__s390__)
229 29e922b6 Blue Swirl
230 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks(void)
231 29e922b6 Blue Swirl
{
232 29e922b6 Blue Swirl
    int64_t val;
233 29e922b6 Blue Swirl
    asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
234 29e922b6 Blue Swirl
    return val;
235 29e922b6 Blue Swirl
}
236 29e922b6 Blue Swirl
237 29e922b6 Blue Swirl
#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
238 29e922b6 Blue Swirl
239 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks (void)
240 29e922b6 Blue Swirl
{
241 29e922b6 Blue Swirl
#if defined(_LP64)
242 29e922b6 Blue Swirl
    uint64_t        rval;
243 29e922b6 Blue Swirl
    asm volatile("rd %%tick,%0" : "=r"(rval));
244 29e922b6 Blue Swirl
    return rval;
245 29e922b6 Blue Swirl
#else
246 29e922b6 Blue Swirl
    union {
247 29e922b6 Blue Swirl
        uint64_t i64;
248 29e922b6 Blue Swirl
        struct {
249 29e922b6 Blue Swirl
            uint32_t high;
250 29e922b6 Blue Swirl
            uint32_t low;
251 29e922b6 Blue Swirl
        }       i32;
252 29e922b6 Blue Swirl
    } rval;
253 29e922b6 Blue Swirl
    asm volatile("rd %%tick,%1; srlx %1,32,%0"
254 29e922b6 Blue Swirl
                 : "=r"(rval.i32.high), "=r"(rval.i32.low));
255 29e922b6 Blue Swirl
    return rval.i64;
256 29e922b6 Blue Swirl
#endif
257 29e922b6 Blue Swirl
}
258 29e922b6 Blue Swirl
259 29e922b6 Blue Swirl
#elif defined(__mips__) && \
260 29e922b6 Blue Swirl
    ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
261 29e922b6 Blue Swirl
/*
262 29e922b6 Blue Swirl
 * binutils wants to use rdhwr only on mips32r2
263 29e922b6 Blue Swirl
 * but as linux kernel emulate it, it's fine
264 29e922b6 Blue Swirl
 * to use it.
265 29e922b6 Blue Swirl
 *
266 29e922b6 Blue Swirl
 */
267 29e922b6 Blue Swirl
#define MIPS_RDHWR(rd, value) {                         \
268 29e922b6 Blue Swirl
        __asm__ __volatile__ (".set   push\n\t"         \
269 29e922b6 Blue Swirl
                              ".set mips32r2\n\t"       \
270 29e922b6 Blue Swirl
                              "rdhwr  %0, "rd"\n\t"     \
271 29e922b6 Blue Swirl
                              ".set   pop"              \
272 29e922b6 Blue Swirl
                              : "=r" (value));          \
273 29e922b6 Blue Swirl
    }
274 29e922b6 Blue Swirl
275 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks(void)
276 29e922b6 Blue Swirl
{
277 29e922b6 Blue Swirl
    /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
278 29e922b6 Blue Swirl
    uint32_t count;
279 29e922b6 Blue Swirl
    static uint32_t cyc_per_count = 0;
280 29e922b6 Blue Swirl
281 29e922b6 Blue Swirl
    if (!cyc_per_count) {
282 29e922b6 Blue Swirl
        MIPS_RDHWR("$3", cyc_per_count);
283 29e922b6 Blue Swirl
    }
284 29e922b6 Blue Swirl
285 29e922b6 Blue Swirl
    MIPS_RDHWR("$2", count);
286 29e922b6 Blue Swirl
    return (int64_t)(count * cyc_per_count);
287 29e922b6 Blue Swirl
}
288 29e922b6 Blue Swirl
289 14a6063a Richard Henderson
#elif defined(__alpha__)
290 14a6063a Richard Henderson
291 14a6063a Richard Henderson
static inline int64_t cpu_get_real_ticks(void)
292 14a6063a Richard Henderson
{
293 14a6063a Richard Henderson
    uint64_t cc;
294 14a6063a Richard Henderson
    uint32_t cur, ofs;
295 14a6063a Richard Henderson
296 14a6063a Richard Henderson
    asm volatile("rpcc %0" : "=r"(cc));
297 14a6063a Richard Henderson
    cur = cc;
298 14a6063a Richard Henderson
    ofs = cc >> 32;
299 14a6063a Richard Henderson
    return cur - ofs;
300 14a6063a Richard Henderson
}
301 14a6063a Richard Henderson
302 29e922b6 Blue Swirl
#else
303 29e922b6 Blue Swirl
/* The host CPU doesn't have an easily accessible cycle counter.
304 29e922b6 Blue Swirl
   Just return a monotonically increasing value.  This will be
305 29e922b6 Blue Swirl
   totally wrong, but hopefully better than nothing.  */
306 29e922b6 Blue Swirl
static inline int64_t cpu_get_real_ticks (void)
307 29e922b6 Blue Swirl
{
308 29e922b6 Blue Swirl
    static int64_t ticks = 0;
309 29e922b6 Blue Swirl
    return ticks++;
310 29e922b6 Blue Swirl
}
311 29e922b6 Blue Swirl
#endif
312 29e922b6 Blue Swirl
313 2d8ebcf9 Richard Henderson
#ifdef CONFIG_PROFILER
314 2d8ebcf9 Richard Henderson
static inline int64_t profile_getclock(void)
315 2d8ebcf9 Richard Henderson
{
316 2d8ebcf9 Richard Henderson
    return cpu_get_real_ticks();
317 2d8ebcf9 Richard Henderson
}
318 2d8ebcf9 Richard Henderson
319 2d8ebcf9 Richard Henderson
extern int64_t qemu_time, qemu_time_start;
320 2d8ebcf9 Richard Henderson
extern int64_t tlb_flush_time;
321 2d8ebcf9 Richard Henderson
extern int64_t dev_time;
322 2d8ebcf9 Richard Henderson
#endif
323 2d8ebcf9 Richard Henderson
324 87ecb68b pbrook
#endif