[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/5] Enable host-clock-based RTC
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH 5/5] Enable host-clock-based RTC |
Date: |
Wed, 09 Sep 2009 17:11:12 +0200 |
User-agent: |
StGIT/0.14.3 |
Allow RTC emulations to use the new host_clock instead of vm_clock. This
has the advantage that the emulated RTC will follow automatically the
host time while it might be tuned via NTP.
Note that some RTC emulations (at least M48T59) already use the host
time unconditionally while others (namely MC146818) do not. This patch
introduces the required infrastructure for selecting the base clock and
only converts MC146818 for now.
Signed-off-by: Jan Kiszka <address@hidden>
---
hw/mc146818rtc.c | 35 ++++++++++++++++-------------------
qemu-options.hx | 14 ++++++++++----
sysemu.h | 1 +
vl.c | 15 ++++++++++++++-
4 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 5c8676e..d339b7a 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -107,8 +107,8 @@ static void rtc_coalesced_timer_update(RTCState *s)
} else {
/* divide each RTC interval to 2 - 8 smaller intervals */
int c = MIN(s->irq_coalesced, 7) + 1;
- int64_t next_clock = qemu_get_clock(vm_clock) +
- muldiv64(s->period / c, ticks_per_sec, 32768);
+ int64_t next_clock = qemu_get_clock(rtc_clock) +
+ muldiv64(s->period / c, ticks_per_sec, 32768);
qemu_mod_timer(s->coalesced_timer, next_clock);
}
}
@@ -231,7 +231,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr,
uint32_t data)
/* UIP bit is read only */
s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
(s->cmos_data[RTC_REG_A] & REG_A_UIP);
- rtc_timer_update(s, qemu_get_clock(vm_clock));
+ rtc_timer_update(s, qemu_get_clock(rtc_clock));
break;
case RTC_REG_B:
if (data & REG_B_SET) {
@@ -245,7 +245,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr,
uint32_t data)
}
}
s->cmos_data[RTC_REG_B] = data;
- rtc_timer_update(s, qemu_get_clock(vm_clock));
+ rtc_timer_update(s, qemu_get_clock(rtc_clock));
break;
case RTC_REG_C:
case RTC_REG_D:
@@ -604,18 +604,17 @@ RTCState *rtc_init_sqw(int base, qemu_irq irq, qemu_irq
sqw_irq, int base_year)
s->base_year = base_year;
rtc_set_date_from_host(s);
- s->periodic_timer = qemu_new_timer(vm_clock,
- rtc_periodic_timer, s);
+ s->periodic_timer = qemu_new_timer(rtc_clock, rtc_periodic_timer, s);
#ifdef TARGET_I386
if (rtc_td_hack)
- s->coalesced_timer = qemu_new_timer(vm_clock, rtc_coalesced_timer, s);
+ s->coalesced_timer =
+ qemu_new_timer(rtc_clock, rtc_coalesced_timer, s);
#endif
- s->second_timer = qemu_new_timer(vm_clock,
- rtc_update_second, s);
- s->second_timer2 = qemu_new_timer(vm_clock,
- rtc_update_second2, s);
+ s->second_timer = qemu_new_timer(rtc_clock, rtc_update_second, s);
+ s->second_timer2 = qemu_new_timer(rtc_clock, rtc_update_second2, s);
- s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) /
100;
+ s->next_second_time =
+ qemu_get_clock(rtc_clock) + (ticks_per_sec * 99) / 100;
qemu_mod_timer(s->second_timer2, s->next_second_time);
register_ioport_write(base, 2, 1, cmos_ioport_write, s);
@@ -725,14 +724,12 @@ RTCState *rtc_mm_init(target_phys_addr_t base, int
it_shift, qemu_irq irq,
s->base_year = base_year;
rtc_set_date_from_host(s);
- s->periodic_timer = qemu_new_timer(vm_clock,
- rtc_periodic_timer, s);
- s->second_timer = qemu_new_timer(vm_clock,
- rtc_update_second, s);
- s->second_timer2 = qemu_new_timer(vm_clock,
- rtc_update_second2, s);
+ s->periodic_timer = qemu_new_timer(rtc_clock, rtc_periodic_timer, s);
+ s->second_timer = qemu_new_timer(rtc_clock, rtc_update_second, s);
+ s->second_timer2 = qemu_new_timer(rtc_clock, rtc_update_second2, s);
- s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) /
100;
+ s->next_second_time =
+ qemu_get_clock(rtc_clock) + (ticks_per_sec * 99) / 100;
qemu_mod_timer(s->second_timer2, s->next_second_time);
io_memory = cpu_register_io_memory(rtc_mm_read, rtc_mm_write, s);
diff --git a/qemu-options.hx b/qemu-options.hx
index ea672ee..253180b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1498,22 +1498,28 @@ DEF("startdate", HAS_ARG, QEMU_OPTION_startdate, "")
#ifdef TARGET_I386
DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \
- "-rtc [base=utc|localtime|date][,drift-fix=on|off]\n" \
- " Set the RTC base, enable Windows time drift fix\n")
+ "-rtc [base=utc|localtime|date][,clock=vm|host][,drift-fix=on|off]\n" \
+ " Set the RTC base and clock, enable Windows time drift
fix\n")
#else
DEF("rtc", HAS_ARG, QEMU_OPTION_rtc, \
- "-rtc [base=utc|localtime|date]\n" \
+ "-rtc [base=utc|localtime|date][,clock=vm|host]\n" \
" Set the RTC base and clock\n")
#endif
STEXI
address@hidden -rtc [base=utc|localtime|@var{date}][,drift-fix=on|off]
address@hidden -rtc
[base=utc|localtime|@var{date}][,clock=vm|rt][,drift-fix=on|off]
Specify @option{base} as @code{utc} or @code{localtime} to let the RTC start
at the current
UTC or local time, respectively. @code{localtime} is required for correct date
in
MS-DOS or Windows. To start at a specific point in time, provide @var{date} in
the
format @code{2006-06-17T16:01:21} or @code{2006-06-17}. The default base is
UTC.
+By default the RTC is driven by a virtual clock (@code{vm}) which is not
subject
+to host time adjustments and does not jump when the guest is supended and
+resumed or migrated. To use the host's system time instead, set @option{clock}
to
address@hidden This is useful if the host time is smoothly following an accurate
+reference clock, e.g. via NTP, and wants to propagate this into the guest.
+
Enable @option{drift-fix} (i386 targets only) if you experience time drift
problems
in Windows with ACPI HAL. This option will try to figure out how many timer
interrupts were not processed by the Windows guest and will re-inject them.
diff --git a/sysemu.h b/sysemu.h
index a018b47..fe4eb53 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -135,6 +135,7 @@ extern int no_quit;
extern int semihosting_enabled;
extern int old_param;
extern int boot_menu;
+extern QEMUClock *rtc_clock;
#define MAX_NODES 64
extern int nb_numa_nodes;
diff --git a/vl.c b/vl.c
index 8437d2c..52bfefe 100644
--- a/vl.c
+++ b/vl.c
@@ -194,6 +194,7 @@ int vm_running;
int autostart;
static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
+QEMUClock *rtc_clock;
int vga_interface_type = VGA_CIRRUS;
#ifdef TARGET_SPARC
int graphic_width = 1024;
@@ -1051,6 +1052,8 @@ static void init_clocks(void)
rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
+
+ rtc_clock = vm_clock;
}
/* save a timer */
@@ -1630,7 +1633,7 @@ static void configure_rtc_date_offset(const char
*startdate, int legacy)
static void configure_rtc(const char *options)
{
static const char * const params[] = {
- "base",
+ "base", "clock",
#ifdef CONFIG_TARGET_I386
"td-hack",
#endif
@@ -1652,6 +1655,16 @@ static void configure_rtc(const char *options)
configure_rtc_date_offset(buf, 0);
}
}
+ if (get_param_value(buf, sizeof(buf), "clock", options)) {
+ if (!strcmp(buf, "vm")) {
+ rtc_clock = vm_clock;
+ } else if (!strcmp(buf, "host")) {
+ rtc_clock = host_clock;
+ } else {
+ fprintf(stderr, "qemu: invalid option value '%s'\n", buf);
+ exit(1);
+ }
+ }
#ifdef CONFIG_TARGET_I386
if (get_param_value(buf, sizeof(buf), "drift-hack", options)) {
if (!strcmp(buf, "on")) {
- [Qemu-devel] [PATCH 0/5] Refactor and enhance RTC configuration, Jan Kiszka, 2009/09/09
- [Qemu-devel] [PATCH 3/5] Introduce QEMU_CLOCK_HOST, Jan Kiszka, 2009/09/09
- [Qemu-devel] [PATCH 1/5] Rename QEMU_TIMER_* to QEMU_CLOCK_*, Jan Kiszka, 2009/09/09
- [Qemu-devel] [PATCH 4/5] Refactor RTC command line switches, Jan Kiszka, 2009/09/09
- [Qemu-devel] [PATCH 5/5] Enable host-clock-based RTC,
Jan Kiszka <=
- [Qemu-devel] [PATCH 2/5] win32: Drop dead dyntick timer code, Jan Kiszka, 2009/09/09
- [Qemu-devel] Re: [PATCH 0/5] Refactor and enhance RTC configuration, Anthony Liguori, 2009/09/09
- Re: [Qemu-devel] Re: [PATCH 0/5] Refactor and enhance RTC configuration, Jamie Lokier, 2009/09/09
- Re: [Qemu-devel] Re: [PATCH 0/5] Refactor and enhance RTC configuration, Jan Kiszka, 2009/09/11