Revision 25f3151e

b/qemu-timer.c
39 39
#include <sys/param.h>
40 40
#endif
41 41

  
42
#ifdef __linux__
43
#include <sys/ioctl.h>
44
#include <linux/rtc.h>
45
/* For the benefit of older linux systems which don't supply it,
46
   we use a local copy of hpet.h. */
47
/* #include <linux/hpet.h> */
48
#include "hpet.h"
49
#endif
50

  
51 42
#ifdef _WIN32
52 43
#include <windows.h>
53 44
#include <mmsystem.h>
......
234 225
static void dynticks_stop_timer(struct qemu_alarm_timer *t);
235 226
static void dynticks_rearm_timer(struct qemu_alarm_timer *t);
236 227

  
237
static int hpet_start_timer(struct qemu_alarm_timer *t);
238
static void hpet_stop_timer(struct qemu_alarm_timer *t);
239

  
240
static int rtc_start_timer(struct qemu_alarm_timer *t);
241
static void rtc_stop_timer(struct qemu_alarm_timer *t);
242

  
243 228
#endif /* __linux__ */
244 229

  
245 230
#endif /* _WIN32 */
......
304 289
#ifdef __linux__
305 290
    {"dynticks", dynticks_start_timer,
306 291
     dynticks_stop_timer, dynticks_rearm_timer},
307
    /* HPET - if available - is preferred */
308
    {"hpet", hpet_start_timer, hpet_stop_timer, NULL},
309
    /* ...otherwise try RTC */
310
    {"rtc", rtc_start_timer, rtc_stop_timer, NULL},
311 292
#endif
312 293
    {"unix", unix_start_timer, unix_stop_timer, NULL},
313 294
#else
......
822 803

  
823 804
#if defined(__linux__)
824 805

  
825
#define RTC_FREQ 1024
826

  
827
static void enable_sigio_timer(int fd)
828
{
829
    struct sigaction act;
830

  
831
    /* timer signal */
832
    sigfillset(&act.sa_mask);
833
    act.sa_flags = 0;
834
    act.sa_handler = host_alarm_handler;
835

  
836
    sigaction(SIGIO, &act, NULL);
837
    fcntl_setfl(fd, O_ASYNC);
838
    fcntl(fd, F_SETOWN, getpid());
839
}
840

  
841
static int hpet_start_timer(struct qemu_alarm_timer *t)
842
{
843
    struct hpet_info info;
844
    int r, fd;
845

  
846
    fd = qemu_open("/dev/hpet", O_RDONLY);
847
    if (fd < 0)
848
        return -1;
849

  
850
    /* Set frequency */
851
    r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ);
852
    if (r < 0) {
853
        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n"
854
                "error, but for better emulation accuracy type:\n"
855
                "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n");
856
        goto fail;
857
    }
858

  
859
    /* Check capabilities */
860
    r = ioctl(fd, HPET_INFO, &info);
861
    if (r < 0)
862
        goto fail;
863

  
864
    /* Enable periodic mode */
865
    r = ioctl(fd, HPET_EPI, 0);
866
    if (info.hi_flags && (r < 0))
867
        goto fail;
868

  
869
    /* Enable interrupt */
870
    r = ioctl(fd, HPET_IE_ON, 0);
871
    if (r < 0)
872
        goto fail;
873

  
874
    enable_sigio_timer(fd);
875
    t->fd = fd;
876

  
877
    return 0;
878
fail:
879
    close(fd);
880
    return -1;
881
}
882

  
883
static void hpet_stop_timer(struct qemu_alarm_timer *t)
884
{
885
    int fd = t->fd;
886

  
887
    close(fd);
888
}
889

  
890
static int rtc_start_timer(struct qemu_alarm_timer *t)
891
{
892
    int rtc_fd;
893
    unsigned long current_rtc_freq = 0;
894

  
895
    TFR(rtc_fd = qemu_open("/dev/rtc", O_RDONLY));
896
    if (rtc_fd < 0)
897
        return -1;
898
    ioctl(rtc_fd, RTC_IRQP_READ, &current_rtc_freq);
899
    if (current_rtc_freq != RTC_FREQ &&
900
        ioctl(rtc_fd, RTC_IRQP_SET, RTC_FREQ) < 0) {
901
        fprintf(stderr, "Could not configure '/dev/rtc' to have a 1024 Hz timer. This is not a fatal\n"
902
                "error, but for better emulation accuracy either use a 2.6 host Linux kernel or\n"
903
                "type 'echo 1024 > /proc/sys/dev/rtc/max-user-freq' as root.\n");
904
        goto fail;
905
    }
906
    if (ioctl(rtc_fd, RTC_PIE_ON, 0) < 0) {
907
    fail:
908
        close(rtc_fd);
909
        return -1;
910
    }
911

  
912
    enable_sigio_timer(rtc_fd);
913

  
914
    t->fd = rtc_fd;
915

  
916
    return 0;
917
}
918

  
919
static void rtc_stop_timer(struct qemu_alarm_timer *t)
920
{
921
    int rtc_fd = t->fd;
922

  
923
    close(rtc_fd);
924
}
925

  
926 806
static int dynticks_start_timer(struct qemu_alarm_timer *t)
927 807
{
928 808
    struct sigevent ev;

Also available in: Unified diff