From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: yang.z.zhang@intel.com, mdroth@linux.vnet.ibm.com, quintela@redhat.com
Subject: [Qemu-devel] [PATCH 05/10] RTC: Update the RTC clock only when reading it
Date: Wed, 1 Aug 2012 18:41:47 +0200 [thread overview]
Message-ID: <1343839312-24030-6-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1343839312-24030-1-git-send-email-pbonzini@redhat.com>
From: Yang Zhang <yang.z.zhang@intel.com>
Calculate guest RTC based on the time of the last update, instead of
using timers. The formula is
(base_rtc + guest_time_now - guest_time_last_update + offset)
Base_rtc is the RTC value when the RTC was last updated.
Guest_time_now is the guest time when the access happens.
Guest_time_last_update was the guest time when the RTC was last updated.
Offset is used when divider reset happens or the set bit is toggled.
The timer is kept in order to signal interrupts, but it only needs to
run when either UF or AF is cleared. When the bits are both set, the
timer does not run.
UIP is now synthesized when reading register A. If the timer is not set,
or if there is more than one second before it (as is the case at the
end of this series), the leading edge of UIP is computed and the rising
edge occurs 220us later. If the update timer occurs within one second,
however, the rising edge of the AF and UF bits should coincide withe
the falling edge of UIP. We do not know exactly when this will happen
because there could be delays in the servicing of the timer. Hence, in
this case reading register A only computes for the rising edge of UIP,
and latches the bit until the timer is fired and clears it.
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/mc146818rtc.c | 321 +++++++++++++++++++++++++++++++-----------------------
1 file changed, 186 insertions(+), 135 deletions(-)
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 293f174..2c34a82 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -45,6 +45,8 @@
# define DPRINTF_C(format, ...) do { } while (0)
#endif
+#define NSEC_PER_SEC 1000000000LL
+
#define RTC_REINJECT_ON_ACK_COUNT 20
typedef struct RTCState {
@@ -54,27 +56,40 @@ typedef struct RTCState {
uint8_t cmos_index;
struct tm current_tm;
int32_t base_year;
+ uint64_t base_rtc;
+ uint64_t last_update;
+ int64_t offset;
qemu_irq irq;
qemu_irq sqw_irq;
int it_shift;
/* periodic timer */
QEMUTimer *periodic_timer;
int64_t next_periodic_time;
- /* second update */
- int64_t next_second_time;
+ /* update-ended timer */
+ QEMUTimer *update_timer;
uint16_t irq_reinject_on_ack_count;
uint32_t irq_coalesced;
uint32_t period;
QEMUTimer *coalesced_timer;
- QEMUTimer *second_timer;
- QEMUTimer *second_timer2;
Notifier clock_reset_notifier;
LostTickPolicy lost_tick_policy;
Notifier suspend_notifier;
} RTCState;
static void rtc_set_time(RTCState *s);
-static void rtc_copy_date(RTCState *s);
+static void rtc_update_time(RTCState *s);
+static void rtc_set_cmos(RTCState *s);
+static inline int rtc_from_bcd(RTCState *s, int a);
+
+static uint64_t get_guest_rtc_ns(RTCState *s)
+{
+ uint64_t guest_rtc;
+ uint64_t guest_clock = qemu_get_clock_ns(rtc_clock);
+
+ guest_rtc = s->base_rtc * NSEC_PER_SEC
+ + guest_clock - s->last_update + s->offset;
+ return guest_rtc;
+}
#ifdef TARGET_I386
static void rtc_coalesced_timer_update(RTCState *s)
@@ -110,6 +125,7 @@ static void rtc_coalesced_timer(void *opaque)
}
#endif
+/* handle periodic timer */
static void periodic_timer_update(RTCState *s, int64_t current_time)
{
int period_code, period;
@@ -175,6 +191,100 @@ static void rtc_periodic_timer(void *opaque)
}
}
+/* handle update-ended timer */
+static void check_update_timer(RTCState *s)
+{
+ uint64_t next_update_time;
+ uint64_t guest_nsec;
+
+ /* From the data sheet: setting the SET bit does not prevent
+ * interrupts from occurring! However, it will prevent an
+ * alarm interrupt from occurring, because the time of day is
+ * not updated.
+ */
+ if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
+ (s->cmos_data[RTC_REG_B] & REG_B_SET)) {
+ qemu_del_timer(s->update_timer);
+ return;
+ }
+ if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
+ (s->cmos_data[RTC_REG_C] & REG_C_AF)) {
+ qemu_del_timer(s->update_timer);
+ return;
+ }
+
+ guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC;
+ /* reprogram to next second */
+ next_update_time = qemu_get_clock_ns(rtc_clock)
+ + NSEC_PER_SEC - guest_nsec;
+ if (next_update_time != qemu_timer_expire_time_ns(s->update_timer)) {
+ qemu_mod_timer(s->update_timer, next_update_time);
+ }
+}
+
+static inline uint8_t convert_hour(RTCState *s, uint8_t hour)
+{
+ if (!(s->cmos_data[RTC_REG_B] & REG_B_24H)) {
+ hour %= 12;
+ if (s->cmos_data[RTC_HOURS] & 0x80) {
+ hour += 12;
+ }
+ }
+ return hour;
+}
+
+static uint32_t check_alarm(RTCState *s)
+{
+ uint8_t alarm_hour, alarm_min, alarm_sec;
+ uint8_t cur_hour, cur_min, cur_sec;
+
+ alarm_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]);
+ alarm_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]);
+ alarm_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]);
+ alarm_hour = convert_hour(s, alarm_hour);
+
+ cur_sec = rtc_from_bcd(s, s->cmos_data[RTC_SECONDS]);
+ cur_min = rtc_from_bcd(s, s->cmos_data[RTC_MINUTES]);
+ cur_hour = rtc_from_bcd(s, s->cmos_data[RTC_HOURS]);
+ cur_hour = convert_hour(s, cur_hour);
+
+ if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0
+ || alarm_sec == cur_sec) &&
+ ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0
+ || alarm_min == cur_min) &&
+ ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0
+ || alarm_hour == cur_hour)) {
+ return 1;
+ }
+ return 0;
+
+}
+
+static void rtc_update_timer(void *opaque)
+{
+ RTCState *s = opaque;
+ int32_t irqs = REG_C_UF;
+ int32_t new_irqs;
+
+ /* UIP might have been latched, update time and clear it. */
+ rtc_update_time(s);
+ s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
+
+ if (check_alarm(s)) {
+ irqs |= REG_C_AF;
+ if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
+ }
+ }
+ new_irqs = irqs & ~s->cmos_data[RTC_REG_C];
+ s->cmos_data[RTC_REG_C] |= irqs;
+ if ((new_irqs & s->cmos_data[RTC_REG_B]) != 0) {
+ s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
+ qemu_irq_raise(s->irq);
+ }
+ check_update_timer(s);
+}
+
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
{
RTCState *s = opaque;
@@ -189,6 +299,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
case RTC_MINUTES_ALARM:
case RTC_HOURS_ALARM:
s->cmos_data[s->cmos_index] = data;
+ check_update_timer(s);
break;
case RTC_SECONDS:
case RTC_MINUTES:
@@ -201,6 +312,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
/* if in set mode, do not update the time */
if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
rtc_set_time(s);
+ check_update_timer(s);
}
break;
case RTC_REG_A:
@@ -208,15 +320,21 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
(s->cmos_data[RTC_REG_A] & REG_A_UIP);
periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
+ check_update_timer(s);
break;
case RTC_REG_B:
if (data & REG_B_SET) {
+ /* update cmos to when the rtc was stopping */
+ if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
+ rtc_update_time(s);
+ }
/* set mode: reset UIP mode */
s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
data &= ~REG_B_UIE;
} else {
/* if disabling set mode, update the time */
if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
+ s->offset = get_guest_rtc_ns(s) % NSEC_PER_SEC;
rtc_set_time(s);
}
}
@@ -231,6 +349,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
}
s->cmos_data[RTC_REG_B] = data;
periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
+ check_update_timer(s);
break;
case RTC_REG_C:
case RTC_REG_D:
@@ -279,10 +398,13 @@ static void rtc_set_time(RTCState *s)
tm->tm_mon = rtc_from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
tm->tm_year = rtc_from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900;
+ s->base_rtc = mktimegm(tm);
+ s->last_update = qemu_get_clock_ns(rtc_clock);
+
rtc_change_mon_event(tm);
}
-static void rtc_copy_date(RTCState *s)
+static void rtc_set_cmos(RTCState *s)
{
const struct tm *tm = &s->current_tm;
int year;
@@ -308,122 +430,41 @@ static void rtc_copy_date(RTCState *s)
s->cmos_data[RTC_YEAR] = rtc_to_bcd(s, year);
}
-/* month is between 0 and 11. */
-static int get_days_in_month(int month, int year)
+static void rtc_update_time(RTCState *s)
{
- static const int days_tab[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- int d;
- if ((unsigned )month >= 12)
- return 31;
- d = days_tab[month];
- if (month == 1) {
- if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
- d++;
- }
- return d;
+ struct tm *ret;
+ time_t guest_sec;
+ int64_t guest_nsec;
+
+ guest_nsec = get_guest_rtc_ns(s);
+ guest_sec = guest_nsec / NSEC_PER_SEC;
+ ret = gmtime(&guest_sec);
+ s->current_tm = *ret;
+ rtc_set_cmos(s);
}
-/* update 'tm' to the next second */
-static void rtc_next_second(struct tm *tm)
+static int update_in_progress(RTCState *s)
{
- int days_in_month;
-
- tm->tm_sec++;
- if ((unsigned)tm->tm_sec >= 60) {
- tm->tm_sec = 0;
- tm->tm_min++;
- if ((unsigned)tm->tm_min >= 60) {
- tm->tm_min = 0;
- tm->tm_hour++;
- if ((unsigned)tm->tm_hour >= 24) {
- tm->tm_hour = 0;
- /* next day */
- tm->tm_wday++;
- if ((unsigned)tm->tm_wday >= 7)
- tm->tm_wday = 0;
- days_in_month = get_days_in_month(tm->tm_mon,
- tm->tm_year + 1900);
- tm->tm_mday++;
- if (tm->tm_mday < 1) {
- tm->tm_mday = 1;
- } else if (tm->tm_mday > days_in_month) {
- tm->tm_mday = 1;
- tm->tm_mon++;
- if (tm->tm_mon >= 12) {
- tm->tm_mon = 0;
- tm->tm_year++;
- }
- }
- }
- }
- }
-}
-
-
-static void rtc_update_second(void *opaque)
-{
- RTCState *s = opaque;
- int64_t delay;
-
- /* if the oscillator is not in normal operation, we do not update */
- if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
- s->next_second_time += get_ticks_per_sec();
- qemu_mod_timer(s->second_timer, s->next_second_time);
- } else {
- rtc_next_second(&s->current_tm);
-
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- /* update in progress bit */
- s->cmos_data[RTC_REG_A] |= REG_A_UIP;
- }
- /* should be 244 us = 8 / 32768 seconds, but currently the
- timers do not have the necessary resolution. */
- delay = (get_ticks_per_sec() * 1) / 100;
- if (delay < 1)
- delay = 1;
- qemu_mod_timer(s->second_timer2,
- s->next_second_time + delay);
- }
-}
-
-static void rtc_update_second2(void *opaque)
-{
- RTCState *s = opaque;
+ int64_t guest_nsec;
- if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
- rtc_copy_date(s);
+ if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
+ return 0;
}
-
- /* check alarm */
- if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
- rtc_from_bcd(s, s->cmos_data[RTC_SECONDS_ALARM]) == s->current_tm.tm_sec) &&
- ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
- rtc_from_bcd(s, s->cmos_data[RTC_MINUTES_ALARM]) == s->current_tm.tm_min) &&
- ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
- rtc_from_bcd(s, s->cmos_data[RTC_HOURS_ALARM]) == s->current_tm.tm_hour)) {
-
- s->cmos_data[RTC_REG_C] |= REG_C_AF;
- if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
- qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
- qemu_irq_raise(s->irq);
- s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
+ if (qemu_timer_pending(s->update_timer)) {
+ int64_t next_update_time = qemu_timer_expire_time_ns(s->update_timer);
+ /* Latch UIP until the timer expires. */
+ if (qemu_get_clock_ns(rtc_clock) >= (next_update_time - 244000)) {
+ s->cmos_data[RTC_REG_A] |= REG_A_UIP;
+ return 1;
}
}
- /* update ended interrupt */
- s->cmos_data[RTC_REG_C] |= REG_C_UF;
- if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
- s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
- qemu_irq_raise(s->irq);
+ guest_nsec = get_guest_rtc_ns(s);
+ /* UIP bit will be set at last 244us of every second. */
+ if ((guest_nsec % NSEC_PER_SEC) >= (NSEC_PER_SEC - 244000)) {
+ return 1;
}
-
- /* clear update in progress bit */
- s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
-
- s->next_second_time += get_ticks_per_sec();
- qemu_mod_timer(s->second_timer, s->next_second_time);
+ return 0;
}
static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
@@ -441,15 +482,28 @@ static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
case RTC_DAY_OF_MONTH:
case RTC_MONTH:
case RTC_YEAR:
+ /* if not in set mode, calibrate cmos before
+ * reading*/
+ if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
+ rtc_update_time(s);
+ }
ret = s->cmos_data[s->cmos_index];
break;
case RTC_REG_A:
+ if (update_in_progress(s)) {
+ s->cmos_data[s->cmos_index] |= REG_A_UIP;
+ } else {
+ s->cmos_data[s->cmos_index] &= ~REG_A_UIP;
+ }
ret = s->cmos_data[s->cmos_index];
break;
case RTC_REG_C:
ret = s->cmos_data[s->cmos_index];
qemu_irq_lower(s->irq);
s->cmos_data[RTC_REG_C] = 0x00;
+ if (ret & (REG_C_UF | REG_C_AF)) {
+ check_update_timer(s);
+ }
#ifdef TARGET_I386
if(s->irq_coalesced &&
(s->cmos_data[RTC_REG_B] & REG_B_PIE) &&
@@ -484,13 +538,6 @@ void rtc_set_memory(ISADevice *dev, int addr, int val)
s->cmos_data[addr] = val;
}
-void rtc_set_date(ISADevice *dev, const struct tm *tm)
-{
- RTCState *s = DO_UPCAST(RTCState, dev, dev);
- s->current_tm = *tm;
- rtc_copy_date(s);
-}
-
/* PC cmos mappings */
#define REG_IBM_CENTURY_BYTE 0x32
#define REG_IBM_PS2_CENTURY_BYTE 0x37
@@ -501,9 +548,15 @@ static void rtc_set_date_from_host(ISADevice *dev)
struct tm tm;
int val;
- /* set the CMOS date */
qemu_get_timedate(&tm, 0);
- rtc_set_date(dev, &tm);
+
+ s->base_rtc = mktimegm(&tm);
+ s->last_update = qemu_get_clock_ns(rtc_clock);
+ s->offset = 0;
+
+ /* set the CMOS date */
+ s->current_tm = tm;
+ rtc_set_cmos(s);
val = rtc_to_bcd(s, (tm.tm_year / 100) + 19);
rtc_set_memory(dev, REG_IBM_CENTURY_BYTE, val);
@@ -526,9 +579,9 @@ static int rtc_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_rtc = {
.name = "mc146818rtc",
- .version_id = 2,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
+ .version_id = 3,
+ .minimum_version_id = 3,
+ .minimum_version_id_old = 3,
.post_load = rtc_post_load,
.fields = (VMStateField []) {
VMSTATE_BUFFER(cmos_data, RTCState),
@@ -542,11 +595,12 @@ static const VMStateDescription vmstate_rtc = {
VMSTATE_INT32(current_tm.tm_year, RTCState),
VMSTATE_TIMER(periodic_timer, RTCState),
VMSTATE_INT64(next_periodic_time, RTCState),
- VMSTATE_INT64(next_second_time, RTCState),
- VMSTATE_TIMER(second_timer, RTCState),
- VMSTATE_TIMER(second_timer2, RTCState),
VMSTATE_UINT32_V(irq_coalesced, RTCState, 2),
VMSTATE_UINT32_V(period, RTCState, 2),
+ VMSTATE_UINT64_V(base_rtc, RTCState, 3),
+ VMSTATE_UINT64_V(last_update, RTCState, 3),
+ VMSTATE_INT64_V(offset, RTCState, 3),
+ VMSTATE_TIMER_V(update_timer, RTCState, 3),
VMSTATE_END_OF_LIST()
}
};
@@ -557,9 +611,8 @@ static void rtc_notify_clock_reset(Notifier *notifier, void *data)
int64_t now = *(int64_t *)data;
rtc_set_date_from_host(&s->dev);
- s->next_second_time = now + (get_ticks_per_sec() * 99) / 100;
- qemu_mod_timer(s->second_timer2, s->next_second_time);
periodic_timer_update(s, now);
+ check_update_timer(s);
#ifdef TARGET_I386
if (s->lost_tick_policy == LOST_TICK_SLEW) {
rtc_coalesced_timer_update(s);
@@ -581,6 +634,7 @@ static void rtc_reset(void *opaque)
s->cmos_data[RTC_REG_B] &= ~(REG_B_PIE | REG_B_AIE | REG_B_SQWE);
s->cmos_data[RTC_REG_C] &= ~(REG_C_UF | REG_C_IRQF | REG_C_PF | REG_C_AF);
+ check_update_timer(s);
qemu_irq_lower(s->irq);
@@ -606,6 +660,7 @@ static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
ISADevice *isa = ISA_DEVICE(obj);
RTCState *s = DO_UPCAST(RTCState, dev, isa);
+ rtc_update_time(s);
visit_start_struct(v, NULL, "struct tm", name, 0, errp);
visit_type_int32(v, &s->current_tm.tm_year, "tm_year", errp);
visit_type_int32(v, &s->current_tm.tm_mon, "tm_mon", errp);
@@ -642,8 +697,8 @@ static int rtc_initfn(ISADevice *dev)
#endif
s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
- s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s);
- s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s);
+ s->update_timer = qemu_new_timer_ns(rtc_clock, rtc_update_timer, s);
+ check_update_timer(s);
s->clock_reset_notifier.notify = rtc_notify_clock_reset;
qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
@@ -651,10 +706,6 @@ static int rtc_initfn(ISADevice *dev)
s->suspend_notifier.notify = rtc_notify_suspend;
qemu_register_suspend_notifier(&s->suspend_notifier);
- s->next_second_time =
- qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
- qemu_mod_timer(s->second_timer2, s->next_second_time);
-
memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
isa_register_ioport(dev, &s->io, base);
--
1.7.10.4
next prev parent reply other threads:[~2012-08-01 16:42 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-01 16:41 [Qemu-devel] [PATCH 0/10] Remove periodic wakeup from RTC timer Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 01/10] RTC: Remove the logic to update time format when DM bit changed Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 02/10] RTC: Rename rtc_timer_update Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 03/10] RTC: Update interrupt state when interrupts are masked/unmasked Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 06/10] vmstate: add VMSTATE_TIMER_V Paolo Bonzini
2012-08-02 8:56 ` Juan Quintela
2012-08-02 9:02 ` Paolo Bonzini
2012-08-01 16:41 ` Paolo Bonzini [this message]
2012-08-01 19:48 ` [Qemu-devel] [PATCH 05/10] RTC: Update the RTC clock only when reading it Anthony Liguori
2012-08-02 9:09 ` Juan Quintela
2012-08-02 9:14 ` Paolo Bonzini
2012-08-02 9:58 ` Juan Quintela
2012-08-01 16:41 ` [Qemu-devel] [PATCH 06/10] RTC: Add divider reset support Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 07/10] RTC: Do not fire timer periodically to catch next alarm Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 08/10] RTC: Get and set time without going through s->current_tm Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 09/10] RTC: Remove the current_tm field Paolo Bonzini
2012-08-01 16:41 ` [Qemu-devel] [PATCH 10/10] RTC: Allow to migrate from old QEMU Paolo Bonzini
2012-08-01 19:51 ` [Qemu-devel] [PATCH 0/10] Remove periodic wakeup from RTC timer Anthony Liguori
2012-08-02 6:32 ` Paolo Bonzini
2012-08-02 0:44 ` Zhang, Yang Z
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1343839312-24030-6-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=yang.z.zhang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).