aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/rtc/goldfish_rtc.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c
index 01e9d2b083..6ddd45cce0 100644
--- a/hw/rtc/goldfish_rtc.c
+++ b/hw/rtc/goldfish_rtc.c
@@ -94,12 +94,22 @@ static uint64_t goldfish_rtc_read(void *opaque, hwaddr offset,
GoldfishRTCState *s = opaque;
uint64_t r = 0;
+ /*
+ * From the documentation linked at the top of the file:
+ *
+ * To read the value, the kernel must perform an IO_READ(TIME_LOW), which
+ * returns an unsigned 32-bit value, before an IO_READ(TIME_HIGH), which
+ * returns a signed 32-bit value, corresponding to the higher half of the
+ * full value.
+ */
switch (offset) {
case RTC_TIME_LOW:
- r = goldfish_rtc_get_count(s) & 0xffffffff;
+ r = goldfish_rtc_get_count(s);
+ s->time_high = r >> 32;
+ r &= 0xffffffff;
break;
case RTC_TIME_HIGH:
- r = goldfish_rtc_get_count(s) >> 32;
+ r = s->time_high;
break;
case RTC_ALARM_LOW:
r = s->alarm_next & 0xffffffff;
@@ -216,7 +226,7 @@ static const MemoryRegionOps goldfish_rtc_ops = {
static const VMStateDescription goldfish_rtc_vmstate = {
.name = TYPE_GOLDFISH_RTC,
- .version_id = 1,
+ .version_id = 2,
.pre_save = goldfish_rtc_pre_save,
.post_load = goldfish_rtc_post_load,
.fields = (VMStateField[]) {
@@ -225,6 +235,7 @@ static const VMStateDescription goldfish_rtc_vmstate = {
VMSTATE_UINT32(alarm_running, GoldfishRTCState),
VMSTATE_UINT32(irq_pending, GoldfishRTCState),
VMSTATE_UINT32(irq_enabled, GoldfishRTCState),
+ VMSTATE_UINT32(time_high, GoldfishRTCState),
VMSTATE_END_OF_LIST()
}
};