]> git.proxmox.com Git - mirror_qemu.git/blame - include/qemu/timer.h
Merge remote-tracking branch 'mst/tags/for_anthony' into stable-1.5
[mirror_qemu.git] / include / qemu / timer.h
CommitLineData
87ecb68b
PB
1#ifndef QEMU_TIMER_H
2#define QEMU_TIMER_H
3
ff83c66e 4#include "qemu/typedefs.h"
29e922b6 5#include "qemu-common.h"
1de7afc9 6#include "qemu/notify.h"
29e922b6 7
87ecb68b
PB
8/* timers */
9
0ce1b948
PB
10#define SCALE_MS 1000000
11#define SCALE_US 1000
12#define SCALE_NS 1
13
ff83c66e
AB
14/**
15 * QEMUClockType:
16 *
17 * The following clock types are available:
18 *
19 * @QEMU_CLOCK_REALTIME: Real time clock
20 *
21 * The real time clock should be used only for stuff which does not
22 * change the virtual machine state, as it is run even if the virtual
23 * machine is stopped. The real time clock has a frequency of 1000
24 * Hz.
25 *
ff83c66e
AB
26 * @QEMU_CLOCK_VIRTUAL: virtual clock
27 *
28 * The virtual clock is only run during the emulation. It is stopped
29 * when the virtual machine is stopped. Virtual timers use a high
30 * precision clock, usually cpu cycles (use ticks_per_sec).
31 *
ff83c66e
AB
32 * @QEMU_CLOCK_HOST: host clock
33 *
34 * The host clock should be use for device models that emulate accurate
35 * real time sources. It will continue to run when the virtual machine
36 * is suspended, and it will reflect system time changes the host may
37 * undergo (e.g. due to NTP). The host clock has the same precision as
38 * the virtual clock.
ff83c66e
AB
39 */
40
41typedef enum {
42 QEMU_CLOCK_REALTIME = 0,
43 QEMU_CLOCK_VIRTUAL = 1,
44 QEMU_CLOCK_HOST = 2,
45 QEMU_CLOCK_MAX
46} QEMUClockType;
58ac56b9 47
ff83c66e 48typedef struct QEMUTimerList QEMUTimerList;
754d6a54
AB
49
50struct QEMUTimerListGroup {
51 QEMUTimerList *tl[QEMU_CLOCK_MAX];
52};
53
87ecb68b 54typedef void QEMUTimerCB(void *opaque);
d5541d86 55typedef void QEMUTimerListNotifyCB(void *opaque);
87ecb68b 56
ff83c66e
AB
57struct QEMUTimer {
58 int64_t expire_time; /* in nanoseconds */
59 QEMUTimerList *timer_list;
60 QEMUTimerCB *cb;
61 void *opaque;
62 QEMUTimer *next;
63 int scale;
64};
65
754d6a54 66extern QEMUTimerListGroup main_loop_tlg;
87ecb68b 67
40daca54 68/*
b4049b74 69 * QEMUClockType
40daca54
AB
70 */
71
b4049b74 72/*
54904d2a
AB
73 * qemu_clock_get_ns;
74 * @type: the clock type
75 *
76 * Get the nanosecond value of a clock with
77 * type @type
78 *
79 * Returns: the clock value in nanoseconds
80 */
40daca54 81int64_t qemu_clock_get_ns(QEMUClockType type);
54904d2a 82
55a197da
AB
83/**
84 * qemu_clock_get_ms;
85 * @type: the clock type
86 *
87 * Get the millisecond value of a clock with
88 * type @type
89 *
90 * Returns: the clock value in milliseconds
91 */
92static inline int64_t qemu_clock_get_ms(QEMUClockType type)
93{
94 return qemu_clock_get_ns(type) / SCALE_MS;
95}
96
97/**
98 * qemu_clock_get_us;
99 * @type: the clock type
100 *
101 * Get the microsecond value of a clock with
102 * type @type
103 *
104 * Returns: the clock value in microseconds
105 */
106static inline int64_t qemu_clock_get_us(QEMUClockType type)
107{
108 return qemu_clock_get_ns(type) / SCALE_US;
109}
110
54904d2a
AB
111/**
112 * qemu_clock_has_timers:
40daca54 113 * @type: the clock type
54904d2a
AB
114 *
115 * Determines whether a clock's default timer list
116 * has timers attached
117 *
118 * Returns: true if the clock's default timer list
119 * has timers attached
120 */
40daca54 121bool qemu_clock_has_timers(QEMUClockType type);
54904d2a
AB
122
123/**
124 * qemu_clock_expired:
40daca54 125 * @type: the clock type
54904d2a
AB
126 *
127 * Determines whether a clock's default timer list
128 * has an expired clock.
129 *
130 * Returns: true if the clock's default timer list has
131 * an expired timer
132 */
40daca54 133bool qemu_clock_expired(QEMUClockType type);
02a03a9f 134
ff83c66e
AB
135/**
136 * qemu_clock_use_for_deadline:
40daca54 137 * @type: the clock type
ff83c66e
AB
138 *
139 * Determine whether a clock should be used for deadline
140 * calculations. Some clocks, for instance vm_clock with
141 * use_icount set, do not count in nanoseconds. Such clocks
142 * are not used for deadline calculations, and are presumed
143 * to interrupt any poll using qemu_notify/aio_notify
144 * etc.
145 *
146 * Returns: true if the clock runs in nanoseconds and
147 * should be used for a deadline.
148 */
40daca54 149bool qemu_clock_use_for_deadline(QEMUClockType type);
ff83c66e 150
ac70aafc 151/**
40daca54
AB
152 * qemu_clock_deadline_ns_all:
153 * @type: the clock type
ac70aafc
AB
154 *
155 * Calculate the deadline across all timer lists associated
156 * with a clock (as opposed to just the default one)
157 * in nanoseconds, or -1 if no timer is set to expire.
158 *
159 * Returns: time until expiry in nanoseconds or -1
160 */
40daca54 161int64_t qemu_clock_deadline_ns_all(QEMUClockType type);
ac70aafc 162
ff83c66e
AB
163/**
164 * qemu_clock_get_main_loop_timerlist:
40daca54 165 * @type: the clock type
ff83c66e
AB
166 *
167 * Return the default timer list assocatiated with a clock.
168 *
169 * Returns: the default timer list
170 */
40daca54 171QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type);
ff83c66e 172
b1bbfe72
AB
173/**
174 * qemu_clock_nofify:
40daca54 175 * @type: the clock type
b1bbfe72
AB
176 *
177 * Call the notifier callback connected with the default timer
178 * list linked to the clock, or qemu_notify() if none.
179 */
40daca54
AB
180void qemu_clock_notify(QEMUClockType type);
181
182/**
183 * qemu_clock_enable:
184 * @type: the clock type
185 * @enabled: true to enable, false to disable
186 *
187 * Enable or disable a clock
188 */
189void qemu_clock_enable(QEMUClockType type, bool enabled);
190
191/**
192 * qemu_clock_warp:
193 * @type: the clock type
194 *
195 * Warp a clock to a new value
196 */
197void qemu_clock_warp(QEMUClockType type);
198
199/**
200 * qemu_clock_register_reset_notifier:
201 * @type: the clock type
202 * @notifier: the notifier function
203 *
204 * Register a notifier function to call when the clock
205 * concerned is reset.
206 */
207void qemu_clock_register_reset_notifier(QEMUClockType type,
208 Notifier *notifier);
209
210/**
211 * qemu_clock_unregister_reset_notifier:
212 * @type: the clock type
213 * @notifier: the notifier function
214 *
215 * Unregister a notifier function to call when the clock
216 * concerned is reset.
217 */
218void qemu_clock_unregister_reset_notifier(QEMUClockType type,
219 Notifier *notifier);
220
221/**
222 * qemu_clock_run_timers:
223 * @type: clock on which to operate
224 *
225 * Run all the timers associated with the default timer list
226 * of a clock.
227 *
228 * Returns: true if any timer ran.
229 */
230bool qemu_clock_run_timers(QEMUClockType type);
231
232/**
233 * qemu_clock_run_all_timers:
234 *
235 * Run all the timers associated with the default timer list
236 * of every clock.
237 *
238 * Returns: true if any timer ran.
239 */
240bool qemu_clock_run_all_timers(void);
241
242/*
243 * QEMUTimerList
244 */
b1bbfe72 245
ff83c66e
AB
246/**
247 * timerlist_new:
248 * @type: the clock type to associate with the timerlist
d5541d86
AB
249 * @cb: the callback to call on notification
250 * @opaque: the opaque pointer to pass to the callback
ff83c66e
AB
251 *
252 * Create a new timerlist associated with the clock of
253 * type @type.
254 *
255 * Returns: a pointer to the QEMUTimerList created
256 */
d5541d86
AB
257QEMUTimerList *timerlist_new(QEMUClockType type,
258 QEMUTimerListNotifyCB *cb, void *opaque);
ff83c66e
AB
259
260/**
261 * timerlist_free:
262 * @timer_list: the timer list to free
263 *
264 * Frees a timer_list. It must have no active timers.
265 */
266void timerlist_free(QEMUTimerList *timer_list);
267
268/**
269 * timerlist_has_timers:
270 * @timer_list: the timer list to operate on
271 *
272 * Determine whether a timer list has active timers
273 *
274 * Returns: true if the timer list has timers.
275 */
276bool timerlist_has_timers(QEMUTimerList *timer_list);
277
278/**
279 * timerlist_expired:
280 * @timer_list: the timer list to operate on
281 *
282 * Determine whether a timer list has any timers which
283 * are expired.
284 *
285 * Returns: true if the timer list has timers which
286 * have expired.
287 */
288bool timerlist_expired(QEMUTimerList *timer_list);
ff83c66e
AB
289
290/**
291 * timerlist_deadline_ns:
292 * @timer_list: the timer list to operate on
293 *
294 * Determine the deadline for a timer_list, i.e.
295 * the number of nanoseconds until the first timer
296 * expires. Return -1 if there are no timers.
297 *
298 * Returns: the number of nanoseconds until the earliest
299 * timer expires -1 if none
300 */
301int64_t timerlist_deadline_ns(QEMUTimerList *timer_list);
302
303/**
40daca54 304 * timerlist_get_clock:
ff83c66e
AB
305 * @timer_list: the timer list to operate on
306 *
40daca54 307 * Determine the clock type associated with a timer list.
ff83c66e 308 *
40daca54
AB
309 * Returns: the clock type associated with the
310 * timer list.
ff83c66e 311 */
40daca54 312QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list);
ff83c66e
AB
313
314/**
315 * timerlist_run_timers:
316 * @timer_list: the timer list to use
317 *
318 * Call all expired timers associated with the timer list.
319 *
320 * Returns: true if any timer expired
321 */
322bool timerlist_run_timers(QEMUTimerList *timer_list);
323
d5541d86
AB
324/**
325 * timerlist_notify:
326 * @timer_list: the timer list to use
327 *
328 * call the notifier callback associated with the timer list.
329 */
330void timerlist_notify(QEMUTimerList *timer_list);
331
40daca54
AB
332/*
333 * QEMUTimerListGroup
334 */
335
754d6a54
AB
336/**
337 * timerlistgroup_init:
338 * @tlg: the timer list group
d5541d86
AB
339 * @cb: the callback to call when a notify is required
340 * @opaque: the opaque pointer to be passed to the callback.
754d6a54
AB
341 *
342 * Initialise a timer list group. This must already be
d5541d86
AB
343 * allocated in memory and zeroed. The notifier callback is
344 * called whenever a clock in the timer list group is
345 * reenabled or whenever a timer associated with any timer
346 * list is modified. If @cb is specified as null, qemu_notify()
347 * is used instead.
754d6a54 348 */
d5541d86
AB
349void timerlistgroup_init(QEMUTimerListGroup *tlg,
350 QEMUTimerListNotifyCB *cb, void *opaque);
754d6a54
AB
351
352/**
353 * timerlistgroup_deinit:
354 * @tlg: the timer list group
355 *
356 * Deinitialise a timer list group. This must already be
357 * initialised. Note the memory is not freed.
358 */
359void timerlistgroup_deinit(QEMUTimerListGroup *tlg);
360
361/**
362 * timerlistgroup_run_timers:
363 * @tlg: the timer list group
364 *
365 * Run the timers associated with a timer list group.
366 * This will run timers on multiple clocks.
367 *
368 * Returns: true if any timer callback ran
369 */
370bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg);
371
372/**
54904d2a 373 * timerlistgroup_deadline_ns:
754d6a54
AB
374 * @tlg: the timer list group
375 *
376 * Determine the deadline of the soonest timer to
377 * expire associated with any timer list linked to
378 * the timer list group. Only clocks suitable for
379 * deadline calculation are included.
380 *
381 * Returns: the deadline in nanoseconds or -1 if no
382 * timers are to expire.
383 */
384int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg);
385
40daca54
AB
386/*
387 * QEMUTimer
54904d2a 388 */
ff83c66e
AB
389
390/**
391 * timer_init:
392 * @ts: the timer to be initialised
393 * @timer_list: the timer list to attach the timer to
394 * @scale: the scale value for the tiemr
395 * @cb: the callback to be called when the timer expires
396 * @opaque: the opaque pointer to be passed to the callback
397 *
398 * Initialise a new timer and associate it with @timer_list.
399 * The caller is responsible for allocating the memory.
400 *
401 * You need not call an explicit deinit call. Simply make
402 * sure it is not on a list with timer_del.
403 */
404void timer_init(QEMUTimer *ts,
405 QEMUTimerList *timer_list, int scale,
406 QEMUTimerCB *cb, void *opaque);
407
408/**
409 * timer_new_tl:
410 * @timer_list: the timer list to attach the timer to
411 * @scale: the scale value for the tiemr
412 * @cb: the callback to be called when the timer expires
413 * @opaque: the opaque pointer to be passed to the callback
414 *
415 * Creeate a new timer and associate it with @timer_list.
416 * The memory is allocated by the function.
417 *
418 * This is not the preferred interface unless you know you
419 * are going to call timer_free. Use timer_init instead.
420 *
421 * Returns: a pointer to the timer
422 */
423static inline QEMUTimer *timer_new_tl(QEMUTimerList *timer_list,
424 int scale,
425 QEMUTimerCB *cb,
426 void *opaque)
427{
428 QEMUTimer *ts = g_malloc0(sizeof(QEMUTimer));
429 timer_init(ts, timer_list, scale, cb, opaque);
430 return ts;
431}
432
a3a726ae
AB
433/**
434 * timer_new:
435 * @type: the clock type to use
436 * @scale: the scale value for the tiemr
437 * @cb: the callback to be called when the timer expires
438 * @opaque: the opaque pointer to be passed to the callback
439 *
440 * Creeate a new timer and associate it with the default
441 * timer list for the clock type @type.
442 *
443 * Returns: a pointer to the timer
444 */
445static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
446 QEMUTimerCB *cb, void *opaque)
447{
448 return timer_new_tl(main_loop_tlg.tl[type], scale, cb, opaque);
449}
450
54904d2a 451/**
40daca54
AB
452 * timer_new_ns:
453 * @clock: the clock to associate with the timer
454 * @callback: the callback to call when the timer expires
455 * @opaque: the opaque pointer to pass to the callback
54904d2a 456 *
40daca54
AB
457 * Create a new timer with nanosecond scale on the default timer list
458 * associated with the clock.
ff83c66e 459 *
40daca54 460 * Returns: a pointer to the newly created timer
ff83c66e 461 */
40daca54
AB
462static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
463 void *opaque)
ff83c66e 464{
40daca54 465 return timer_new(type, SCALE_NS, cb, opaque);
ff83c66e
AB
466}
467
54904d2a 468/**
40daca54
AB
469 * timer_new_us:
470 * @clock: the clock to associate with the timer
471 * @callback: the callback to call when the timer expires
472 * @opaque: the opaque pointer to pass to the callback
54904d2a 473 *
40daca54
AB
474 * Create a new timer with microsecond scale on the default timer list
475 * associated with the clock.
54904d2a 476 *
40daca54 477 * Returns: a pointer to the newly created timer
54904d2a 478 */
40daca54
AB
479static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
480 void *opaque)
481{
482 return timer_new(type, SCALE_US, cb, opaque);
483}
54904d2a 484
ff83c66e 485/**
40daca54
AB
486 * timer_new_ms:
487 * @clock: the clock to associate with the timer
488 * @callback: the callback to call when the timer expires
489 * @opaque: the opaque pointer to pass to the callback
ff83c66e 490 *
40daca54
AB
491 * Create a new timer with millisecond scale on the default timer list
492 * associated with the clock.
493 *
494 * Returns: a pointer to the newly created timer
ff83c66e 495 */
40daca54
AB
496static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
497 void *opaque)
ff83c66e 498{
40daca54 499 return timer_new(type, SCALE_MS, cb, opaque);
ff83c66e
AB
500}
501
54904d2a 502/**
40daca54
AB
503 * timer_free:
504 * @ts: the timer
54904d2a 505 *
40daca54 506 * Free a timer (it must not be on the active list)
54904d2a 507 */
40daca54 508void timer_free(QEMUTimer *ts);
54904d2a 509
ff83c66e 510/**
40daca54
AB
511 * timer_del:
512 * @ts: the timer
ff83c66e 513 *
40daca54 514 * Delete a timer from the active list.
ff83c66e 515 */
40daca54 516void timer_del(QEMUTimer *ts);
ff83c66e 517
54904d2a 518/**
40daca54
AB
519 * timer_mod_ns:
520 * @ts: the timer
521 * @expire_time: the expiry time in nanoseconds
54904d2a 522 *
40daca54 523 * Modify a timer to expire at @expire_time
54904d2a 524 */
40daca54 525void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
54904d2a 526
ff83c66e
AB
527/**
528 * timer_mod:
40daca54
AB
529 * @ts: the timer
530 * @expire_time: the expire time in the units associated with the timer
ff83c66e 531 *
40daca54
AB
532 * Modify a timer to expiry at @expire_time, taking into
533 * account the scale associated with the timer.
ff83c66e 534 */
40daca54 535void timer_mod(QEMUTimer *ts, int64_t expire_timer);
ff83c66e 536
54904d2a
AB
537/**
538 * timer_pending:
40daca54 539 * @ts: the timer
54904d2a
AB
540 *
541 * Determines whether a timer is pending (i.e. is on the
542 * active list of timers, whether or not it has not yet expired).
543 *
544 * Returns: true if the timer is pending
545 */
546bool timer_pending(QEMUTimer *ts);
547
548/**
549 * timer_expired:
40daca54 550 * @ts: the timer
54904d2a
AB
551 *
552 * Determines whether a timer has expired.
553 *
554 * Returns: true if the timer has expired
555 */
556bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
557
558/**
559 * timer_expire_time_ns:
40daca54 560 * @ts: the timer
54904d2a 561 *
40daca54 562 * Determine the expiry time of a timer
54904d2a 563 *
40daca54 564 * Returns: the expiry time in nanoseconds
54904d2a
AB
565 */
566uint64_t timer_expire_time_ns(QEMUTimer *ts);
567
f9a976b7 568/**
40daca54
AB
569 * timer_get:
570 * @f: the file
571 * @ts: the timer
f9a976b7 572 *
40daca54 573 * Read a timer @ts from a file @f
f9a976b7 574 */
40daca54 575void timer_get(QEMUFile *f, QEMUTimer *ts);
f9a976b7
AB
576
577/**
40daca54
AB
578 * timer_put:
579 * @f: the file
580 * @ts: the timer
581 */
582void timer_put(QEMUFile *f, QEMUTimer *ts);
583
584/*
585 * General utility functions
586 */
587
588/**
589 * qemu_timeout_ns_to_ms:
590 * @ns: nanosecond timeout value
f9a976b7 591 *
40daca54
AB
592 * Convert a nanosecond timeout value (or -1) to
593 * a millisecond value (or -1), always rounding up.
f9a976b7 594 *
40daca54 595 * Returns: millisecond timeout value
f9a976b7 596 */
40daca54 597int qemu_timeout_ns_to_ms(int64_t ns);
f9a976b7 598
54904d2a 599/**
40daca54
AB
600 * qemu_poll_ns:
601 * @fds: Array of file descriptors
602 * @nfds: number of file descriptors
603 * @timeout: timeout in nanoseconds
54904d2a 604 *
40daca54
AB
605 * Perform a poll like g_poll but with a timeout in nanoseconds.
606 * See g_poll documentation for further details.
607 *
608 * Returns: number of fds ready
54904d2a 609 */
40daca54 610int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout);
70c3b557 611
02a03a9f
AB
612/**
613 * qemu_soonest_timeout:
614 * @timeout1: first timeout in nanoseconds (or -1 for infinite)
615 * @timeout2: second timeout in nanoseconds (or -1 for infinite)
616 *
617 * Calculates the soonest of two timeout values. -1 means infinite, which
618 * is later than any other value.
619 *
620 * Returns: soonest timeout value in nanoseconds (or -1 for infinite)
621 */
622static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
623{
624 /* we can abuse the fact that -1 (which means infinite) is a maximal
625 * value when cast to unsigned. As this is disgusting, it's kept in
626 * one inline function.
627 */
628 return ((uint64_t) timeout1 < (uint64_t) timeout2) ? timeout1 : timeout2;
629}
630
ff83c66e 631/**
40daca54 632 * initclocks:
ff83c66e 633 *
40daca54
AB
634 * Initialise the clock & timer infrastructure
635 */
636void init_clocks(void);
637
638int64_t cpu_get_ticks(void);
639void cpu_enable_ticks(void);
640void cpu_disable_ticks(void);
641
642static inline int64_t get_ticks_per_sec(void)
643{
644 return 1000000000LL;
645}
646
40daca54
AB
647/*
648 * Low level clock functions
649 */
87ecb68b 650
c57c846a
BS
651/* real time host monotonic timer */
652static inline int64_t get_clock_realtime(void)
653{
654 struct timeval tv;
655
656 gettimeofday(&tv, NULL);
657 return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
658}
659
660/* Warning: don't insert tracepoints into these functions, they are
661 also used by simpletrace backend and tracepoints would cause
662 an infinite recursion! */
663#ifdef _WIN32
664extern int64_t clock_freq;
665
666static inline int64_t get_clock(void)
667{
668 LARGE_INTEGER ti;
669 QueryPerformanceCounter(&ti);
670 return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
671}
672
673#else
674
675extern int use_rt_clock;
676
677static inline int64_t get_clock(void)
678{
d05ef160 679#ifdef CLOCK_MONOTONIC
c57c846a
BS
680 if (use_rt_clock) {
681 struct timespec ts;
682 clock_gettime(CLOCK_MONOTONIC, &ts);
683 return ts.tv_sec * 1000000000LL + ts.tv_nsec;
684 } else
685#endif
686 {
687 /* XXX: using gettimeofday leads to problems if the date
688 changes, so it should be avoided. */
689 return get_clock_realtime();
690 }
691}
692#endif
db1a4972 693
29e922b6 694/* icount */
29e922b6 695int64_t cpu_get_icount(void);
946fb27c 696int64_t cpu_get_clock(void);
29e922b6
BS
697
698/*******************************************/
699/* host CPU ticks (if available) */
700
701#if defined(_ARCH_PPC)
702
703static inline int64_t cpu_get_real_ticks(void)
704{
705 int64_t retval;
706#ifdef _ARCH_PPC64
707 /* This reads timebase in one 64bit go and includes Cell workaround from:
708 http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027052.html
709 */
710 __asm__ __volatile__ ("mftb %0\n\t"
711 "cmpwi %0,0\n\t"
712 "beq- $-8"
713 : "=r" (retval));
714#else
715 /* http://ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html */
716 unsigned long junk;
4a9590f3
AG
717 __asm__ __volatile__ ("mfspr %1,269\n\t" /* mftbu */
718 "mfspr %L0,268\n\t" /* mftb */
719 "mfspr %0,269\n\t" /* mftbu */
29e922b6
BS
720 "cmpw %0,%1\n\t"
721 "bne $-16"
722 : "=r" (retval), "=r" (junk));
723#endif
724 return retval;
725}
726
727#elif defined(__i386__)
728
729static inline int64_t cpu_get_real_ticks(void)
730{
731 int64_t val;
732 asm volatile ("rdtsc" : "=A" (val));
733 return val;
734}
735
736#elif defined(__x86_64__)
737
738static inline int64_t cpu_get_real_ticks(void)
739{
740 uint32_t low,high;
741 int64_t val;
742 asm volatile("rdtsc" : "=a" (low), "=d" (high));
743 val = high;
744 val <<= 32;
745 val |= low;
746 return val;
747}
748
749#elif defined(__hppa__)
750
751static inline int64_t cpu_get_real_ticks(void)
752{
753 int val;
754 asm volatile ("mfctl %%cr16, %0" : "=r"(val));
755 return val;
756}
757
758#elif defined(__ia64)
759
760static inline int64_t cpu_get_real_ticks(void)
761{
762 int64_t val;
763 asm volatile ("mov %0 = ar.itc" : "=r"(val) :: "memory");
764 return val;
765}
766
767#elif defined(__s390__)
768
769static inline int64_t cpu_get_real_ticks(void)
770{
771 int64_t val;
772 asm volatile("stck 0(%1)" : "=m" (val) : "a" (&val) : "cc");
773 return val;
774}
775
9b9c37c3 776#elif defined(__sparc__)
29e922b6
BS
777
778static inline int64_t cpu_get_real_ticks (void)
779{
780#if defined(_LP64)
781 uint64_t rval;
782 asm volatile("rd %%tick,%0" : "=r"(rval));
783 return rval;
784#else
9b9c37c3
RH
785 /* We need an %o or %g register for this. For recent enough gcc
786 there is an "h" constraint for that. Don't bother with that. */
29e922b6
BS
787 union {
788 uint64_t i64;
789 struct {
790 uint32_t high;
791 uint32_t low;
792 } i32;
793 } rval;
9b9c37c3
RH
794 asm volatile("rd %%tick,%%g1; srlx %%g1,32,%0; mov %%g1,%1"
795 : "=r"(rval.i32.high), "=r"(rval.i32.low) : : "g1");
29e922b6
BS
796 return rval.i64;
797#endif
798}
799
800#elif defined(__mips__) && \
801 ((defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__))
802/*
803 * binutils wants to use rdhwr only on mips32r2
804 * but as linux kernel emulate it, it's fine
805 * to use it.
806 *
807 */
808#define MIPS_RDHWR(rd, value) { \
809 __asm__ __volatile__ (".set push\n\t" \
810 ".set mips32r2\n\t" \
811 "rdhwr %0, "rd"\n\t" \
812 ".set pop" \
813 : "=r" (value)); \
814 }
815
816static inline int64_t cpu_get_real_ticks(void)
817{
818 /* On kernels >= 2.6.25 rdhwr <reg>, $2 and $3 are emulated */
819 uint32_t count;
820 static uint32_t cyc_per_count = 0;
821
822 if (!cyc_per_count) {
823 MIPS_RDHWR("$3", cyc_per_count);
824 }
825
826 MIPS_RDHWR("$2", count);
827 return (int64_t)(count * cyc_per_count);
828}
829
14a6063a
RH
830#elif defined(__alpha__)
831
832static inline int64_t cpu_get_real_ticks(void)
833{
834 uint64_t cc;
835 uint32_t cur, ofs;
836
837 asm volatile("rpcc %0" : "=r"(cc));
838 cur = cc;
839 ofs = cc >> 32;
840 return cur - ofs;
841}
842
29e922b6
BS
843#else
844/* The host CPU doesn't have an easily accessible cycle counter.
845 Just return a monotonically increasing value. This will be
846 totally wrong, but hopefully better than nothing. */
847static inline int64_t cpu_get_real_ticks (void)
848{
849 static int64_t ticks = 0;
850 return ticks++;
851}
852#endif
853
2d8ebcf9
RH
854#ifdef CONFIG_PROFILER
855static inline int64_t profile_getclock(void)
856{
857 return cpu_get_real_ticks();
858}
859
860extern int64_t qemu_time, qemu_time_start;
861extern int64_t tlb_flush_time;
862extern int64_t dev_time;
863#endif
864
87ecb68b 865#endif