Statistics
| Branch: | Revision:

root / qemu-timer.h @ 338b922e

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