void timer_put(QEMUFile *f, QEMUTimer *ts) { uint64_t expire_time; expire_time = timer_expire_time_ns(ts); qemu_put_be64(f, expire_time); }
/* handle update-ended timer */ static void check_update_timer(RTCState *s) { uint64_t next_update_time; uint64_t guest_nsec; int next_alarm_sec; /* From the data sheet: "Holding the dividers in reset prevents * interrupts from operating, while setting the SET bit allows" * them to occur. However, it will prevent an alarm interrupt * from occurring, because the time of day is not updated. */ if ((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) { timer_del(s->update_timer); return; } if ((s->cmos_data[RTC_REG_C] & REG_C_UF) && (s->cmos_data[RTC_REG_B] & REG_B_SET)) { timer_del(s->update_timer); return; } if ((s->cmos_data[RTC_REG_C] & REG_C_UF) && (s->cmos_data[RTC_REG_C] & REG_C_AF)) { timer_del(s->update_timer); return; } guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC; /* if UF is clear, reprogram to next second */ next_update_time = qemu_clock_get_ns(rtc_clock) + NSEC_PER_SEC - guest_nsec; /* Compute time of next alarm. One second is already accounted * for in next_update_time. */ next_alarm_sec = get_next_alarm(s); s->next_alarm_time = next_update_time + (next_alarm_sec - 1) * NSEC_PER_SEC; if (s->cmos_data[RTC_REG_C] & REG_C_UF) { /* UF is set, but AF is clear. Program the timer to target * the alarm time. */ next_update_time = s->next_alarm_time; } if (next_update_time != timer_expire_time_ns(s->update_timer)) { timer_mod(s->update_timer, next_update_time); } }
static int update_in_progress(RTCState *s) { int64_t guest_nsec; if (!rtc_running(s)) { return 0; } if (timer_pending(s->update_timer)) { int64_t next_update_time = timer_expire_time_ns(s->update_timer); /* Latch UIP until the timer expires. */ if (qemu_clock_get_ns(rtc_clock) >= (next_update_time - UIP_HOLD_LENGTH)) { s->cmos_data[RTC_REG_A] |= REG_A_UIP; return 1; } } 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 - UIP_HOLD_LENGTH)) { return 1; } return 0; }