qemu-timer.c revision 1091d5d16923c044d35fcacfe845ab6b76e83143
16a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* 26a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * QEMU System Emulator 36a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * 46a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * Copyright (c) 2003-2008 Fabrice Bellard 56a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * 66a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * Permission is hereby granted, free of charge, to any person obtaining a copy 76a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * of this software and associated documentation files (the "Software"), to deal 86a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * in the Software without restriction, including without limitation the rights 96a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * copies of the Software, and to permit persons to whom the Software is 116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * furnished to do so, subject to the following conditions: 126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * 136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * The above copyright notice and this permission notice shall be included in 146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * all copies or substantial portions of the Software. 156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * 166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * THE SOFTWARE. 236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner */ 246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "sysemu.h" 266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "net.h" 276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "monitor.h" 286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "console.h" 296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "hw/hw.h" 316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <unistd.h> 336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <fcntl.h> 346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <time.h> 356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <errno.h> 366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <sys/time.h> 376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <signal.h> 386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __FreeBSD__ 396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <sys/param.h> 406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __linux__ 436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <sys/ioctl.h> 446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <linux/rtc.h> 456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* For the benefit of older linux systems which don't supply it, 466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner we use a local copy of hpet.h. */ 476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* #include <linux/hpet.h> */ 486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "hpet.h" 496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32 526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <windows.h> 536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include <mmsystem.h> 546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#include "qemu-timer.h" 576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Conversion factor from emulated instructions to virtual clock ticks. */ 596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint icount_time_shift; 606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Arbitrarily pick 1MIPS as the minimum allowable speed. */ 616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define MAX_ICOUNT_SHIFT 10 626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Compensate for varying guest execution speed. */ 636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_icount_bias; 646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUTimer *icount_rt_timer; 656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUTimer *icount_vm_timer; 666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/***********************************************************/ 696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* real time host monotonic timer */ 706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t get_clock_realtime(void) 736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct timeval tv; 756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner gettimeofday(&tv, NULL); 776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000); 786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef WIN32 816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t clock_freq; 836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void init_get_clock(void) 856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner LARGE_INTEGER freq; 876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int ret; 886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ret = QueryPerformanceFrequency(&freq); 896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (ret == 0) { 906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Could not calibrate ticks\n"); 916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner exit(1); 926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner clock_freq = freq.QuadPart; 946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t get_clock(void) 976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner LARGE_INTEGER ti; 996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QueryPerformanceCounter(&ti); 1006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq); 1016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 1026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else 1046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int use_rt_clock; 1066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void init_get_clock(void) 1086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 1096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner use_rt_clock = 0; 1106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \ 1116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 1126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner { 1136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct timespec ts; 1146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 1156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner use_rt_clock = 1; 1166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 1196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 1206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t get_clock(void) 1226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 1236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \ 1246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner || defined(__DragonFly__) || defined(__FreeBSD_kernel__) 1256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (use_rt_clock) { 1266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct timespec ts; 1276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner clock_gettime(CLOCK_MONOTONIC, &ts); 1286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return ts.tv_sec * 1000000000LL + ts.tv_nsec; 1296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else 1306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 1316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner { 1326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* XXX: using gettimeofday leads to problems if the date 1336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner changes, so it should be avoided. */ 1346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return get_clock_realtime(); 1356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 1376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 1386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/***********************************************************/ 1406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* guest cycle counter */ 1416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnertypedef struct TimersState { 1436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t cpu_ticks_prev; 1446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t cpu_ticks_offset; 1456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t cpu_clock_offset; 1466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int32_t cpu_ticks_enabled; 1476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t dummy; 1486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} TimersState; 1496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void timer_save(QEMUFile *f, void *opaque) 1516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 1526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner TimersState *s = opaque; 1536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (s->cpu_ticks_enabled) { 1556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner hw_error("cannot save state if virtual timers are running"); 1566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_put_be64(f, s->cpu_ticks_prev); 1586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_put_be64(f, s->cpu_ticks_offset); 1596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_put_be64(f, s->cpu_clock_offset); 1606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int timer_load(QEMUFile *f, void *opaque, int version_id) 1636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 1646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner TimersState *s = opaque; 1656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (version_id != 1 && version_id != 2) 1676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -EINVAL; 1686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (s->cpu_ticks_enabled) { 1696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -EINVAL; 1706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner s->cpu_ticks_prev = qemu_get_sbe64(f); 1726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner s->cpu_ticks_offset = qemu_get_sbe64(f); 1736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (version_id == 2) { 1746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner s->cpu_clock_offset = qemu_get_sbe64(f); 1756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 1776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 1786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1806a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerTimersState timers_state; 1816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 1826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* return the host CPU cycle counter and handle stop/restart */ 1836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t cpu_get_ticks(void) 1846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 1856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (use_icount) { 1866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return cpu_get_icount(); 1876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!timers_state.cpu_ticks_enabled) { 1896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return timers_state.cpu_ticks_offset; 1906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 1916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t ticks; 1926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ticks = cpu_get_real_ticks(); 1936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (timers_state.cpu_ticks_prev > ticks) { 1946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Note: non increasing ticks may happen if the host uses 1956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner software suspend */ 1966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks; 1976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 1986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_ticks_prev = ticks; 1996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return ticks + timers_state.cpu_ticks_offset; 2006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 2016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 2026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* return the host CPU monotonic timer and handle stop/restart */ 2046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t cpu_get_clock(void) 2056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 2066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t ti; 2076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!timers_state.cpu_ticks_enabled) { 2086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return timers_state.cpu_clock_offset; 2096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 2106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ti = get_clock(); 2116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return ti + timers_state.cpu_clock_offset; 2126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 2136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 2146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifndef CONFIG_IOTHREAD 2166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int64_t qemu_icount_delta(void) 2176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 2186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!use_icount) { 2196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 5000 * (int64_t) 1000000; 2206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else if (use_icount == 1) { 2216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* When not using an adaptive execution frequency 2226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner we tend to get badly out of sync with real time, 2236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner so just delay for a reasonable amount of time. */ 2246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 2256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 2266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return cpu_get_icount() - cpu_get_clock(); 2276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 2286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 2296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 2306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* enable cpu_get_ticks() */ 2326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid cpu_enable_ticks(void) 2336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 2346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!timers_state.cpu_ticks_enabled) { 2356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_ticks_offset -= cpu_get_real_ticks(); 2366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_clock_offset -= get_clock(); 2376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_ticks_enabled = 1; 2386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 2396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 2406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* disable cpu_get_ticks() : the clock is stopped. You must not call 2426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner cpu_get_ticks() after that. */ 2436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid cpu_disable_ticks(void) 2446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 2456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (timers_state.cpu_ticks_enabled) { 2466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_ticks_offset = cpu_get_ticks(); 2476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_clock_offset = cpu_get_clock(); 2486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timers_state.cpu_ticks_enabled = 0; 2496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 2506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 2516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/***********************************************************/ 2536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* timers */ 2546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_CLOCK_REALTIME 0 2566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_CLOCK_VIRTUAL 1 2576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_CLOCK_HOST 2 2586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstruct QEMUClock { 2606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int type; 2616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int enabled; 2626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* XXX: add frequency */ 2636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}; 2646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstruct QEMUTimer { 2666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUClock *clock; 2676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t expire_time; 2686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUTimerCB *cb; 2696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner void *opaque; 2706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct QEMUTimer *next; 2716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}; 2726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstruct qemu_alarm_timer { 2746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner char const *name; 2756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int (*start)(struct qemu_alarm_timer *t); 2766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner void (*stop)(struct qemu_alarm_timer *t); 2776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner void (*rearm)(struct qemu_alarm_timer *t); 2786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner void *priv; 2796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner char expired; 2816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner char pending; 2826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}; 2836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic struct qemu_alarm_timer *alarm_timer; 2856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_alarm_pending(void) 2876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 2886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return alarm_timer->pending; 2896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 2906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic inline int alarm_has_dynticks(struct qemu_alarm_timer *t) 2926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 2936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return !!t->rearm; 2946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 2956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 2966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) 2976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 2986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!alarm_has_dynticks(t)) 2996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 3006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->rearm(t); 3026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 3036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* TODO: MIN_TIMER_REARM_US should be optimized */ 3056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define MIN_TIMER_REARM_US 250 3066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32 3086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstruct qemu_alarm_win32 { 3106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner MMRESULT timerId; 3116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner unsigned int period; 3126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} alarm_win32_data = {0, 0}; 3136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int win32_start_timer(struct qemu_alarm_timer *t); 3156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void win32_stop_timer(struct qemu_alarm_timer *t); 3166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void win32_rearm_timer(struct qemu_alarm_timer *t); 3176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else 3196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int unix_start_timer(struct qemu_alarm_timer *t); 3216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void unix_stop_timer(struct qemu_alarm_timer *t); 3226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __linux__ 3246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int dynticks_start_timer(struct qemu_alarm_timer *t); 3266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_stop_timer(struct qemu_alarm_timer *t); 3276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_rearm_timer(struct qemu_alarm_timer *t); 3286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int hpet_start_timer(struct qemu_alarm_timer *t); 3306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void hpet_stop_timer(struct qemu_alarm_timer *t); 3316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int rtc_start_timer(struct qemu_alarm_timer *t); 3336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void rtc_stop_timer(struct qemu_alarm_timer *t); 3346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* __linux__ */ 3366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* _WIN32 */ 3386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Correlation between real and virtual time is always going to be 3406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fairly approximate, so ignore small variation. 3416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner When the guest is idle real and virtual time will be aligned in 3426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner the IO wait loop. */ 3436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10) 3446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void icount_adjust(void) 3466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 3476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t cur_time; 3486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t cur_icount; 3496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t delta; 3506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner static int64_t last_delta; 3516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* If the VM is not running, then do nothing. */ 3526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!vm_running) 3536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 3546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner cur_time = cpu_get_clock(); 3566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner cur_icount = qemu_get_clock(vm_clock); 3576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = cur_icount - cur_time; 3586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ 3596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (delta > 0 3606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner && last_delta + ICOUNT_WOBBLE < delta * 2 3616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner && icount_time_shift > 0) { 3626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* The guest is getting too far ahead. Slow time down. */ 3636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_time_shift--; 3646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 3656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (delta < 0 3666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner && last_delta - ICOUNT_WOBBLE > delta * 2 3676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner && icount_time_shift < MAX_ICOUNT_SHIFT) { 3686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* The guest is getting too far behind. Speed time up. */ 3696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_time_shift++; 3706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 3716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner last_delta = delta; 3726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_icount_bias = cur_icount - (qemu_icount << icount_time_shift); 3736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 3746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void icount_adjust_rt(void * opaque) 3766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 3776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_mod_timer(icount_rt_timer, 3786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(rt_clock) + 1000); 3796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_adjust(); 3806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 3816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void icount_adjust_vm(void * opaque) 3836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 3846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_mod_timer(icount_vm_timer, 3856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10); 3866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_adjust(); 3876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 3886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_icount_round(int64_t count) 3906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 3916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return (count + (1 << icount_time_shift) - 1) >> icount_time_shift; 3926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 3936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 3946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic struct qemu_alarm_timer alarm_timers[] = { 3956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifndef _WIN32 3966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef __linux__ 3976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner {"dynticks", dynticks_start_timer, 3986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner dynticks_stop_timer, dynticks_rearm_timer, NULL}, 3996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* HPET - if available - is preferred */ 4006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner {"hpet", hpet_start_timer, hpet_stop_timer, NULL, NULL}, 4016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* ...otherwise try RTC */ 4026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner {"rtc", rtc_start_timer, rtc_stop_timer, NULL, NULL}, 4036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 4046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner {"unix", unix_start_timer, unix_stop_timer, NULL, NULL}, 4056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else 4066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner {"dynticks", win32_start_timer, 4076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner win32_stop_timer, win32_rearm_timer, &alarm_win32_data}, 4086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner {"win32", win32_start_timer, 4096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner win32_stop_timer, NULL, &alarm_win32_data}, 4106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 4116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner {NULL, } 4126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}; 4136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void show_available_alarms(void) 4156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 4166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int i; 4176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner printf("Available alarm timers, in order of precedence:\n"); 4196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for (i = 0; alarm_timers[i].name; i++) 4206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner printf("%s\n", alarm_timers[i].name); 4216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 4226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid configure_alarms(char const *opt) 4246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 4256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int i; 4266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int cur = 0; 4276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int count = ARRAY_SIZE(alarm_timers) - 1; 4286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner char *arg; 4296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner char *name; 4306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct qemu_alarm_timer tmp; 4316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!strcmp(opt, "?")) { 4336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner show_available_alarms(); 4346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner exit(0); 4356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 4366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner arg = qemu_strdup(opt); 4386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Reorder the array */ 4406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner name = strtok(arg, ","); 4416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner while (name) { 4426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for (i = 0; i < count && alarm_timers[i].name; i++) { 4436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!strcmp(alarm_timers[i].name, name)) 4446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner break; 4456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 4466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (i == count) { 4486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Unknown clock %s\n", name); 4496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto next; 4506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 4516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (i < cur) 4536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Ignore */ 4546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto next; 4556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Swap */ 4576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner tmp = alarm_timers[i]; 4586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner alarm_timers[i] = alarm_timers[cur]; 4596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner alarm_timers[cur] = tmp; 4606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner cur++; 4626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnernext: 4636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner name = strtok(NULL, ","); 4646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 4656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_free(arg); 4676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (cur) { 4696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Disable remaining timers */ 4706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for (i = cur; i < count; i++) 4716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner alarm_timers[i].name = NULL; 4726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 4736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner show_available_alarms(); 4746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner exit(1); 4756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 4766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 4776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define QEMU_NUM_CLOCKS 3 4796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4806a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerQEMUClock *rt_clock; 4816a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerQEMUClock *vm_clock; 4826a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerQEMUClock *host_clock; 4836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUTimer *active_timers[QEMU_NUM_CLOCKS]; 4856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic QEMUClock *qemu_new_clock(int type) 4876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 4886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUClock *clock; 4896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner clock = qemu_mallocz(sizeof(QEMUClock)); 4906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner clock->type = type; 4916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner clock->enabled = 1; 4926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return clock; 4936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 4946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 4956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_clock_enable(QEMUClock *clock, int enabled) 4966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 4976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner clock->enabled = enabled; 4986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 4996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5006a9ef1773bf874dea493ff3861782a1e577b67ddDavid TurnerQEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque) 5016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 5026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUTimer *ts; 5036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts = qemu_mallocz(sizeof(QEMUTimer)); 5056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts->clock = clock; 5066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts->cb = cb; 5076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts->opaque = opaque; 5086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return ts; 5096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 5106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_free_timer(QEMUTimer *ts) 5126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 5136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_free(ts); 5146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 5156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* stop a timer, but do not dealloc it */ 5176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_del_timer(QEMUTimer *ts) 5186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 5196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUTimer **pt, *t; 5206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* NOTE: this code must be signal safe because 5226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_timer_expired() can be called from a signal. */ 5236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner pt = &active_timers[ts->clock->type]; 5246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for(;;) { 5256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t = *pt; 5266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!t) 5276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner break; 5286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (t == ts) { 5296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner *pt = t->next; 5306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner break; 5316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 5326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner pt = &t->next; 5336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 5346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 5356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* modify the current timer so that it will be fired when current_time 5376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner >= expire_time. The corresponding callback will be called. */ 5386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) 5396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 5406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUTimer **pt, *t; 5416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_del_timer(ts); 5436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* add the timer in the sorted list */ 5456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* NOTE: this code must be signal safe because 5466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_timer_expired() can be called from a signal. */ 5476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner pt = &active_timers[ts->clock->type]; 5486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for(;;) { 5496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t = *pt; 5506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!t) 5516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner break; 5526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (t->expire_time > expire_time) 5536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner break; 5546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner pt = &t->next; 5556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 5566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts->expire_time = expire_time; 5576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts->next = *pt; 5586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner *pt = ts; 5596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Rearm if necessary */ 5616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (pt == &active_timers[ts->clock->type]) { 5626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!alarm_timer->pending) { 5636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_rearm_alarm_timer(alarm_timer); 5646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 5656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Interrupt execution to force deadline recalculation. */ 5666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (use_icount) 5676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_notify_event(); 5686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 5696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 5706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_timer_pending(QEMUTimer *ts) 5726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 5736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUTimer *t; 5746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) { 5756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (t == ts) 5766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 1; 5776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 5786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 5796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 5806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time) 5826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 5836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!timer_head) 5846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 5856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return (timer_head->expire_time <= current_time); 5866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 5876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void qemu_run_timers(QEMUClock *clock) 5896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 5906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner QEMUTimer **ptimer_head, *ts; 5916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t current_time; 5926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!clock->enabled) 5946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 5956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 5966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner current_time = qemu_get_clock (clock); 5976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ptimer_head = &active_timers[clock->type]; 5986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for(;;) { 5996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts = *ptimer_head; 6006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!ts || ts->expire_time > current_time) 6016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner break; 6026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* remove timer from the list before calling the callback */ 6036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner *ptimer_head = ts->next; 6046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts->next = NULL; 6056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* run the callback (the timer list can be modified) */ 6076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ts->cb(ts->opaque); 6086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 6106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_get_clock(QEMUClock *clock) 6126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 6136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner switch(clock->type) { 6146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner case QEMU_CLOCK_REALTIME: 6156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return get_clock() / 1000000; 6166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner default: 6176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner case QEMU_CLOCK_VIRTUAL: 6186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (use_icount) { 6196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return cpu_get_icount(); 6206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 6216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return cpu_get_clock(); 6226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner case QEMU_CLOCK_HOST: 6246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return get_clock_realtime(); 6256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 6276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_get_clock_ns(QEMUClock *clock) 6296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 6306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner switch(clock->type) { 6316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner case QEMU_CLOCK_REALTIME: 6326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return get_clock(); 6336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner default: 6346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner case QEMU_CLOCK_VIRTUAL: 6356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (use_icount) { 6366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return cpu_get_icount(); 6376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 6386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return cpu_get_clock(); 6396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner case QEMU_CLOCK_HOST: 6416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return get_clock_realtime(); 6426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 6446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid init_clocks(void) 6466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 6476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner init_get_clock(); 6486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME); 6496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL); 6506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner host_clock = qemu_new_clock(QEMU_CLOCK_HOST); 6516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner rtc_clock = host_clock; 6536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 6546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* save a timer */ 6566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_put_timer(QEMUFile *f, QEMUTimer *ts) 6576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 6586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner uint64_t expire_time; 6596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (qemu_timer_pending(ts)) { 6616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner expire_time = ts->expire_time; 6626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 6636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner expire_time = -1; 6646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_put_be64(f, expire_time); 6666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 6676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_get_timer(QEMUFile *f, QEMUTimer *ts) 6696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 6706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner uint64_t expire_time; 6716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner expire_time = qemu_get_be64(f); 6736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (expire_time != -1) { 6746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_mod_timer(ts, expire_time); 6756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 6766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_del_timer(ts); 6776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 6796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if 0 6816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic const VMStateDescription vmstate_timers = { 6826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner .name = "timer", 6836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner .version_id = 2, 6846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner .minimum_version_id = 1, 6856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner .minimum_version_id_old = 1, 6866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner .fields = (VMStateField []) { 6876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner VMSTATE_INT64(cpu_ticks_offset, TimersState), 6886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner VMSTATE_INT64(dummy, TimersState), 6896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2), 6906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner VMSTATE_END_OF_LIST() 6916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 6926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner}; 6936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 6946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid configure_icount(const char *option) 6966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 6971091d5d16923c044d35fcacfe845ab6b76e83143Ot ten Thije register_savevm("timer", 0, 2, timer_save, timer_load, &timers_state); 6986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 6996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!option) 7006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 7016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (strcmp(option, "auto") != 0) { 7036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_time_shift = strtol(option, NULL, 0); 7046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner use_icount = 1; 7056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 7066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 7076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner use_icount = 2; 7096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* 125MIPS seems a reasonable initial guess at the guest speed. 7116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner It will be corrected fairly quickly anyway. */ 7126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_time_shift = 3; 7136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Have both realtime and virtual time triggers for speed adjustment. 7156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner The realtime trigger catches emulated time passing too slowly, 7166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner the virtual time trigger catches emulated time passing too fast. 7176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner Realtime triggers occur even when idle, so use them less frequently 7186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner than VM triggers. */ 7196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL); 7206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_mod_timer(icount_rt_timer, 7216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(rt_clock) + 1000); 7226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL); 7236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_mod_timer(icount_vm_timer, 7246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10); 7256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 7266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid qemu_run_all_timers(void) 7286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 7296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner alarm_timer->pending = 0; 7306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* rearm timer, if not periodic */ 7326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (alarm_timer->expired) { 7336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner alarm_timer->expired = 0; 7346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_rearm_alarm_timer(alarm_timer); 7356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 7366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* vm time timers */ 7386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (vm_running) { 7396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_run_timers(vm_clock); 7406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 7416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_run_timers(rt_clock); 7436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_run_timers(host_clock); 7446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 7456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32 7476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, 7486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner DWORD_PTR dwUser, DWORD_PTR dw1, 7496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner DWORD_PTR dw2) 7506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else 7516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void host_alarm_handler(int host_signum) 7526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 7536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 7546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct qemu_alarm_timer *t = alarm_timer; 7556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!t) 7566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 7576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if 0 7596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define DISP_FREQ 1000 7606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner { 7616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner static int64_t delta_min = INT64_MAX; 7626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner static int64_t delta_max, delta_cum, last_clock, delta, ti; 7636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner static int count; 7646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ti = qemu_get_clock(vm_clock); 7656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (last_clock != 0) { 7666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = ti - last_clock; 7676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (delta < delta_min) 7686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta_min = delta; 7696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (delta > delta_max) 7706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta_max = delta; 7716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta_cum += delta; 7726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (++count == DISP_FREQ) { 7736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n", 7746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner muldiv64(delta_min, 1000000, get_ticks_per_sec()), 7756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner muldiv64(delta_max, 1000000, get_ticks_per_sec()), 7766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()), 7776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ)); 7786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner count = 0; 7796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta_min = INT64_MAX; 7806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta_max = 0; 7816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta_cum = 0; 7826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 7836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 7846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner last_clock = ti; 7856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 7866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 7876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (alarm_has_dynticks(t) || 7886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner (!use_icount && 7896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL], 7906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(vm_clock))) || 7916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME], 7926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(rt_clock)) || 7936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_timer_expired(active_timers[QEMU_CLOCK_HOST], 7946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(host_clock))) { 7956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 7966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->expired = alarm_has_dynticks(t); 7976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->pending = 1; 7986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_notify_event(); 7996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 8006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 8016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t qemu_next_deadline(void) 8036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 8046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* To avoid problems with overflow limit this to 2^32. */ 8056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t delta = INT32_MAX; 8066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (active_timers[QEMU_CLOCK_VIRTUAL]) { 8086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time - 8096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(vm_clock); 8106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 8116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (active_timers[QEMU_CLOCK_HOST]) { 8126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time - 8136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(host_clock); 8146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (hdelta < delta) 8156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = hdelta; 8166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 8176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (delta < 0) 8196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = 0; 8206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return delta; 8226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 8236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifndef _WIN32 8256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#if defined(__linux__) 8276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#define RTC_FREQ 1024 8296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic uint64_t qemu_next_deadline_dyntick(void) 8316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 8326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t delta; 8336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t rtdelta; 8346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (use_icount) 8366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = INT32_MAX; 8376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner else 8386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = (qemu_next_deadline() + 999) / 1000; 8396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (active_timers[QEMU_CLOCK_REALTIME]) { 8416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time - 8426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_get_clock(rt_clock))*1000; 8436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (rtdelta < delta) 8446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = rtdelta; 8456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 8466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (delta < MIN_TIMER_REARM_US) 8486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = MIN_TIMER_REARM_US; 8496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return delta; 8516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 8526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void enable_sigio_timer(int fd) 8546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 8556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct sigaction act; 8566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* timer signal */ 8586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner sigfillset(&act.sa_mask); 8596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner act.sa_flags = 0; 8606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner act.sa_handler = host_alarm_handler; 8616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner sigaction(SIGIO, &act, NULL); 8636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fcntl_setfl(fd, O_ASYNC); 8646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fcntl(fd, F_SETOWN, getpid()); 8656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 8666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int hpet_start_timer(struct qemu_alarm_timer *t) 8686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 8696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct hpet_info info; 8706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int r, fd; 8716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fd = open("/dev/hpet", O_RDONLY); 8736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (fd < 0) 8746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -1; 8756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Set frequency */ 8776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ); 8786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (r < 0) { 8796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n" 8806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner "error, but for better emulation accuracy type:\n" 8816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n"); 8826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto fail; 8836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 8846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Check capabilities */ 8866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner r = ioctl(fd, HPET_INFO, &info); 8876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (r < 0) 8886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto fail; 8896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Enable periodic mode */ 8916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner r = ioctl(fd, HPET_EPI, 0); 8926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (info.hi_flags && (r < 0)) 8936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto fail; 8946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 8956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Enable interrupt */ 8966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner r = ioctl(fd, HPET_IE_ON, 0); 8976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (r < 0) 8986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto fail; 8996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner enable_sigio_timer(fd); 9016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->priv = (void *)(long)fd; 9026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 9046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerfail: 9056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner close(fd); 9066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -1; 9076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 9086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void hpet_stop_timer(struct qemu_alarm_timer *t) 9106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 9116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int fd = (long)t->priv; 9126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner close(fd); 9146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 9156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int rtc_start_timer(struct qemu_alarm_timer *t) 9176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 9186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int rtc_fd; 9196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner unsigned long current_rtc_freq = 0; 9206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner TFR(rtc_fd = open("/dev/rtc", O_RDONLY)); 9226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (rtc_fd < 0) 9236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -1; 9246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ioctl(rtc_fd, RTC_IRQP_READ, ¤t_rtc_freq); 9256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (current_rtc_freq != RTC_FREQ && 9266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) { 9276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n" 9286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n" 9296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n"); 9306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto fail; 9316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 9326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) { 9336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fail: 9346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner close(rtc_fd); 9356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -1; 9366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 9376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner enable_sigio_timer(rtc_fd); 9396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->priv = (void *)(long)rtc_fd; 9416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 9436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 9446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void rtc_stop_timer(struct qemu_alarm_timer *t) 9466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 9476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int rtc_fd = (long)t->priv; 9486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner close(rtc_fd); 9506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 9516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int dynticks_start_timer(struct qemu_alarm_timer *t) 9536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 9546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct sigevent ev; 9556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timer_t host_timer; 9566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct sigaction act; 9576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner sigfillset(&act.sa_mask); 9596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner act.sa_flags = 0; 9606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner act.sa_handler = host_alarm_handler; 9616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner sigaction(SIGALRM, &act, NULL); 9636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* 9656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * Initialize ev struct to 0 to avoid valgrind complaining 9666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner * about uninitialized data in timer_create call 9676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner */ 9686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner memset(&ev, 0, sizeof(ev)); 9696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ev.sigev_value.sival_int = 0; 9706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ev.sigev_notify = SIGEV_SIGNAL; 9716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner ev.sigev_signo = SIGALRM; 9726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) { 9746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner perror("timer_create"); 9756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* disable dynticks */ 9776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Dynamic Ticks disabled\n"); 9786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -1; 9806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 9816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->priv = (void *)(long)host_timer; 9836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 9856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 9866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_stop_timer(struct qemu_alarm_timer *t) 9886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 9896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timer_t host_timer = (timer_t)(long)t->priv; 9906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timer_delete(host_timer); 9926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 9936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 9946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void dynticks_rearm_timer(struct qemu_alarm_timer *t) 9956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 9966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timer_t host_timer = (timer_t)(long)t->priv; 9976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct itimerspec timeout; 9986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t nearest_delta_us = INT64_MAX; 9996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t current_us; 10006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner assert(alarm_has_dynticks(t)); 10026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!active_timers[QEMU_CLOCK_REALTIME] && 10036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner !active_timers[QEMU_CLOCK_VIRTUAL] && 10046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner !active_timers[QEMU_CLOCK_HOST]) 10056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 10066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner nearest_delta_us = qemu_next_deadline_dyntick(); 10086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* check whether a timer is already running */ 10106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (timer_gettime(host_timer, &timeout)) { 10116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner perror("gettime"); 10126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Internal timer error: aborting\n"); 10136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner exit(1); 10146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 10156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000; 10166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (current_us && current_us <= nearest_delta_us) 10176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 10186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout.it_interval.tv_sec = 0; 10206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */ 10216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout.it_value.tv_sec = nearest_delta_us / 1000000; 10226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000; 10236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) { 10246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner perror("settime"); 10256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Internal timer error: aborting\n"); 10266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner exit(1); 10276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 10286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 10296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* defined(__linux__) */ 10316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int unix_start_timer(struct qemu_alarm_timer *t) 10336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 10346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct sigaction act; 10356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct itimerval itv; 10366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int err; 10376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* timer signal */ 10396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner sigfillset(&act.sa_mask); 10406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner act.sa_flags = 0; 10416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner act.sa_handler = host_alarm_handler; 10426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner sigaction(SIGALRM, &act, NULL); 10446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner itv.it_interval.tv_sec = 0; 10466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* for i386 kernel 2.6 to get 1 ms */ 10476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner itv.it_interval.tv_usec = 999; 10486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner itv.it_value.tv_sec = 0; 10496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner itv.it_value.tv_usec = 10 * 1000; 10506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner err = setitimer(ITIMER_REAL, &itv, NULL); 10526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (err) 10536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -1; 10546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 10566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 10576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void unix_stop_timer(struct qemu_alarm_timer *t) 10596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 10606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct itimerval itv; 10616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner memset(&itv, 0, sizeof(itv)); 10636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner setitimer(ITIMER_REAL, &itv, NULL); 10646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 10656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* !defined(_WIN32) */ 10676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifdef _WIN32 10706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic int win32_start_timer(struct qemu_alarm_timer *t) 10726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 10736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner TIMECAPS tc; 10746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct qemu_alarm_win32 *data = t->priv; 10756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner UINT flags; 10766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner memset(&tc, 0, sizeof(tc)); 10786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeGetDevCaps(&tc, sizeof(tc)); 10796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner data->period = tc.wPeriodMin; 10816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeBeginPeriod(data->period); 10826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner flags = TIME_CALLBACK_FUNCTION; 10846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (alarm_has_dynticks(t)) 10856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner flags |= TIME_ONESHOT; 10866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner else 10876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner flags |= TIME_PERIODIC; 10886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner data->timerId = timeSetEvent(1, // interval (ms) 10906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner data->period, // resolution 10916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner host_alarm_handler, // function 10926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner (DWORD)t, // parameter 10936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner flags); 10946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 10956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!data->timerId) { 10966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n", 10976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner GetLastError()); 10986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeEndPeriod(data->period); 10996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return -1; 11006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 11016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 11036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 11046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void win32_stop_timer(struct qemu_alarm_timer *t) 11066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 11076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct qemu_alarm_win32 *data = t->priv; 11086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeKillEvent(data->timerId); 11106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeEndPeriod(data->period); 11116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 11126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void win32_rearm_timer(struct qemu_alarm_timer *t) 11146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 11156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct qemu_alarm_win32 *data = t->priv; 11166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner assert(alarm_has_dynticks(t)); 11186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!active_timers[QEMU_CLOCK_REALTIME] && 11196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner !active_timers[QEMU_CLOCK_VIRTUAL] && 11206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner !active_timers[QEMU_CLOCK_HOST]) 11216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return; 11226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeKillEvent(data->timerId); 11246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner data->timerId = timeSetEvent(1, 11266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner data->period, 11276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner host_alarm_handler, 11286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner (DWORD)t, 11296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner TIME_ONESHOT | TIME_CALLBACK_FUNCTION); 11306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!data->timerId) { 11326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", 11336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner GetLastError()); 11346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeEndPeriod(data->period); 11366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner exit(1); 11376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 11386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 11396a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11406a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif /* _WIN32 */ 11416a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11426a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerstatic void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason) 11436a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 11446a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (running) 11456a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque); 11466a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 11476a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11486a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint init_timer_alarm(void) 11496a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 11506a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct qemu_alarm_timer *t = NULL; 11516a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int i, err = -1; 11526a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11536a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner for (i = 0; alarm_timers[i].name; i++) { 11546a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t = &alarm_timers[i]; 11556a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11566a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner err = t->start(t); 11576a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!err) 11586a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner break; 11596a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 11606a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11616a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (err) { 11626a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner err = -ENOENT; 11636a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner goto fail; 11646a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 11656a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11666a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* first event is at time 0 */ 11676a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->pending = 1; 11686a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner alarm_timer = t; 11696a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t); 11706a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11716a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 0; 11726a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11736a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerfail: 11746a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return err; 11756a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 11766a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11776a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnervoid quit_timers(void) 11786a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 11796a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner struct qemu_alarm_timer *t = alarm_timer; 11806a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner alarm_timer = NULL; 11816a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner t->stop(t); 11826a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 11836a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11846a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint qemu_calculate_timeout(void) 11856a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 11866a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#ifndef CONFIG_IOTHREAD 11876a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int timeout; 11886a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 11896a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!vm_running) 11906a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout = 5000; 11916a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner else { 11926a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* XXX: use timeout computed from timers */ 11936a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t add; 11946a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t delta; 11956a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Advance virtual time to the next event. */ 11966a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta = qemu_icount_delta(); 11976a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (delta > 0) { 11986a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* If virtual time is ahead of real time then just 11996a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner wait for IO. */ 12006a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout = (delta + 999999) / 1000000; 12016a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } else { 12026a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* Wait for either IO to occur or the next 12036a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timer event. */ 12046a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner add = qemu_next_deadline(); 12056a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner /* We advance the timer before checking for IO. 12066a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner Limit the amount we advance so that early IO 12076a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner activity won't get the guest too far ahead. */ 12086a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (add > 10000000) 12096a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner add = 10000000; 12106a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner delta += add; 12116a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner qemu_icount += qemu_icount_round (add); 12126a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout = delta / 1000000; 12136a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (timeout < 0) 12146a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner timeout = 0; 12156a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 12166a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 12176a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 12186a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return timeout; 12196a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#else /* CONFIG_IOTHREAD */ 12206a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return 1000; 12216a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner#endif 12226a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 12236a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 12246a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner/* Return the virtual CPU time, based on the instruction counter. */ 12256a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turnerint64_t cpu_get_icount(void) 12266a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner{ 12276a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner int64_t icount; 12286a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner CPUState *env = cpu_single_env;; 12296a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner 12306a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount = qemu_icount; 12316a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (env) { 12326a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner if (!can_do_io(env)) { 12336a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner fprintf(stderr, "Bad clock read\n"); 12346a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 12356a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner icount -= (env->icount_decr.u16.low + env->icount_extra); 12366a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner } 12376a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner return qemu_icount_bias + (icount << icount_time_shift); 12386a9ef1773bf874dea493ff3861782a1e577b67ddDavid Turner} 1239