Skip to content

Commit

Permalink
Add 'mc146818rtc.external_wakeup' option for qemu
Browse files Browse the repository at this point in the history
Add "mc146818rtc.external_wakeup" for qemu.
When this option is on, Qemu doesn't keep it's own RTC
timer to wake up guest.
It will relay on host to send wakeup guest cmd to wakeup
guest.

Tracked-On: OAM-100922
Signed-off-by: Zhuo Peng <[email protected]>
Signed-off-by: Swee Yee Fonn <[email protected]>
  • Loading branch information
zhuopeng-sg authored and sfonn committed Feb 8, 2022
1 parent f1a0144 commit 9bb08c7
Showing 1 changed file with 72 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
From d4f3baf8936d947b4f45f8a2074825ef09da35e9 Mon Sep 17 00:00:00 2001
From: Zhuocheng Ding <[email protected]>
Date: Wed, 13 Jan 2021 11:29:48 +0800
Subject: [PATCH] mc146818rtc: add external wakeup mode to sync guest wakeup
with host

---
hw/rtc/mc146818rtc.c | 14 ++++++++++++--
include/hw/rtc/mc146818rtc.h | 1 +
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index 5ed0f7b100..81f7152e27 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -79,6 +79,7 @@ static void rtc_update_time(RTCState *s);
static void rtc_set_cmos(RTCState *s, const struct tm *tm);
static inline int rtc_from_bcd(RTCState *s, int a);
static uint64_t get_next_alarm(RTCState *s);
+static void rtc_update_timer(void *opaque);

static inline bool rtc_running(RTCState *s)
{
@@ -122,7 +123,15 @@ void qmp_rtc_reset_reinjection(Error **errp)

void qmp_rtc_refresh_timer(Error **errp)
{
- qemu_notify_event();
+ RTCState *s;
+
+ QLIST_FOREACH(s, &rtc_devices, link) {
+ if (s->external_wakeup && (s->cmos_data[RTC_REG_B] & REG_B_AIE)) {
+ qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC, NULL);
+ } else if (!s->external_wakeup) {
+ qemu_notify_event();
+ }
+ }
}

static bool rtc_policy_slew_deliver_irq(RTCState *s)
@@ -443,7 +452,7 @@ static void rtc_update_timer(void *opaque)

if (qemu_clock_get_ns(rtc_clock) >= s->next_alarm_time) {
irqs |= REG_C_AF;
- if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
+ if (!s->external_wakeup && (s->cmos_data[RTC_REG_B] & REG_B_AIE)) {
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC, NULL);
}
}
@@ -1005,6 +1014,7 @@ static Property mc146818rtc_properties[] = {
DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
lost_tick_policy, LOST_TICK_POLICY_DISCARD),
+ DEFINE_PROP_BOOL("external_wakeup", RTCState, external_wakeup, false),
DEFINE_PROP_END_OF_LIST(),
};

diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h
index 10c93a096a..75afc813b1 100644
--- a/include/hw/rtc/mc146818rtc.h
+++ b/include/hw/rtc/mc146818rtc.h
@@ -35,6 +35,7 @@ typedef struct RTCState {
int64_t next_periodic_time;
/* update-ended timer */
QEMUTimer *update_timer;
+ bool external_wakeup;
uint64_t next_alarm_time;
uint16_t irq_reinject_on_ack_count;
uint32_t irq_coalesced;
--
2.17.1

0 comments on commit 9bb08c7

Please sign in to comment.