VirtualBox

source: vbox/trunk/src/recompiler/qemu-timer.h@ 76553

Last change on this file since 76553 was 37689, checked in by vboxsync, 13 years ago

recompiler: Merged in changes from 0.13.0.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1#ifndef QEMU_TIMER_H
2#define QEMU_TIMER_H
3
4#include "qemu-common.h"
5
6/* timers */
7#ifndef VBOX
8
9typedef struct QEMUClock QEMUClock;
10typedef void QEMUTimerCB(void *opaque);
11
12/* The real time clock should be used only for stuff which does not
13 change the virtual machine state, as it is run even if the virtual
14 machine is stopped. The real time clock has a frequency of 1000
15 Hz. */
16extern QEMUClock *rt_clock;
17
18/* The virtual clock is only run during the emulation. It is stopped
19 when the virtual machine is stopped. Virtual timers use a high
20 precision clock, usually cpu cycles (use ticks_per_sec). */
21extern QEMUClock *vm_clock;
22
23/* The host clock should be use for device models that emulate accurate
24 real time sources. It will continue to run when the virtual machine
25 is suspended, and it will reflect system time changes the host may
26 undergo (e.g. due to NTP). The host clock has the same precision as
27 the virtual clock. */
28extern QEMUClock *host_clock;
29
30int64_t qemu_get_clock(QEMUClock *clock);
31int64_t qemu_get_clock_ns(QEMUClock *clock);
32void qemu_clock_enable(QEMUClock *clock, int enabled);
33
34QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
35void qemu_free_timer(QEMUTimer *ts);
36void qemu_del_timer(QEMUTimer *ts);
37void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
38int qemu_timer_pending(QEMUTimer *ts);
39int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
40
41void 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
51static inline int64_t get_ticks_per_sec(void)
52{
53 return 1000000000LL;
54}
55
56
57void 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
75/* icount */
76int64_t qemu_icount_round(int64_t count);
77extern int64_t qemu_icount;
78#endif /* !VBOX */
79extern int use_icount;
80#ifndef VBOX
81extern int icount_time_shift;
82extern int64_t qemu_icount_bias;
83int64_t cpu_get_icount(void);
84
85/*******************************************/
86/* host CPU ticks (if available) */
87
88#if defined(_ARCH_PPC)
89
90static inline int64_t cpu_get_real_ticks(void)
91{
92 int64_t retval;
93#ifdef _ARCH_PPC64
94 /* This reads timebase in one 64bit go and includes Cell workaround from:
95 http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
96 */
97 __asm__ __volatile__ ("mftb %0\n\t"
98 "cmpwi %0,0\n\t"
99 "beq- $-8"
100 : "=r" (retval));
101#else
102 /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
103 unsigned long junk;
104 __asm__ __volatile__ ("mfspr %1,269\n\t" /* mftbu */
105 "mfspr %L0,268\n\t" /* mftb */
106 "mfspr %0,269\n\t" /* mftbu */
107 "cmpw %0,%1\n\t"
108 "bne $-16"
109 : "=r" (retval), "=r" (junk));
110#endif
111 return retval;
112}
113
114#elif defined(__i386__)
115
116static inline int64_t cpu_get_real_ticks(void)
117{
118 int64_t val;
119 asm volatile ("rdtsc" : "=A" (val));
120 return val;
121}
122
123#elif defined(__x86_64__)
124
125static inline int64_t cpu_get_real_ticks(void)
126{
127 uint32_t low,high;
128 int64_t val;
129 asm volatile("rdtsc" : "=a" (low), "=d" (high));
130 val = high;
131 val <<= 32;
132 val |= low;
133 return val;
134}
135
136#elif defined(__hppa__)
137
138static inline int64_t cpu_get_real_ticks(void)
139{
140 int val;
141 asm volatile ("mfctl %%cr16, %0" : "=r"(val));
142 return val;
143}
144
145#elif defined(__ia64)
146
147static inline int64_t cpu_get_real_ticks(void)
148{
149 int64_t val;
150 asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
151 return val;
152}
153
154#elif defined(__s390__)
155
156static inline int64_t cpu_get_real_ticks(void)
157{
158 int64_t val;
159 asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
160 return val;
161}
162
163#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
164
165static inline int64_t cpu_get_real_ticks (void)
166{
167#if defined(_LP64)
168 uint64_t rval;
169 asm volatile("rd %%tick,%0" : "=r"(rval));
170 return rval;
171#else
172 union {
173 uint64_t i64;
174 struct {
175 uint32_t high;
176 uint32_t low;
177 } i32;
178 } rval;
179 asm volatile("rd %%tick,%1; srlx %1,32,%0"
180 : "=r"(rval.i32.high), "=r"(rval.i32.low));
181 return rval.i64;
182#endif
183}
184
185#elif defined(__mips__) && \
186 ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
187/*
188 * binutils wants to use rdhwr only on mips32r2
189 * but as linux kernel emulate it, it's fine
190 * to use it.
191 *
192 */
193#define MIPS_RDHWR(rd, value) { \
194 __asm__ __volatile__ (".set push\n\t" \
195 ".set mips32r2\n\t" \
196 "rdhwr %0, "rd"\n\t" \
197 ".set pop" \
198 : "=r" (value)); \
199 }
200
201static inline int64_t cpu_get_real_ticks(void)
202{
203 /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
204 uint32_t count;
205 static uint32_t cyc_per_count = 0;
206
207 if (!cyc_per_count) {
208 MIPS_RDHWR("$3", cyc_per_count);
209 }
210
211 MIPS_RDHWR("$2", count);
212 return (int64_t)(count * cyc_per_count);
213}
214
215#elif defined(__alpha__)
216
217static inline int64_t cpu_get_real_ticks(void)
218{
219 uint64_t cc;
220 uint32_t cur, ofs;
221
222 asm volatile("rpcc %0" : "=r"(cc));
223 cur = cc;
224 ofs = cc >> 32;
225 return cur - ofs;
226}
227
228#else
229/* The host CPU doesn't have an easily accessible cycle counter.
230 Just return a monotonically increasing value. This will be
231 totally wrong, but hopefully better than nothing. */
232static inline int64_t cpu_get_real_ticks (void)
233{
234 static int64_t ticks = 0;
235 return ticks++;
236}
237#endif
238
239#endif /* !VBOX */
240
241#ifdef NEED_CPU_H
242/* Deterministic execution requires that IO only be performed on the last
243 instruction of a TB so that interrupts take effect immediately. */
244static inline int can_do_io(CPUState *env)
245{
246 if (!use_icount)
247 return 1;
248
249 /* If not executing code then assume we are ok. */
250 if (!env->current_tb)
251 return 1;
252
253 return env->can_do_io != 0;
254}
255#endif
256
257#ifndef VBOX
258
259#ifdef CONFIG_PROFILER
260static inline int64_t profile_getclock(void)
261{
262 return cpu_get_real_ticks();
263}
264
265extern int64_t qemu_time, qemu_time_start;
266extern int64_t tlb_flush_time;
267extern int64_t dev_time;
268#endif
269
270#endif /* !VBOX */
271
272#endif
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use