From 4eebcc1fbb4c43444375c6b169ec6fae892b8a46 Mon Sep 17 00:00:00 2001 From: neel Date: Sat, 28 Mar 2015 02:55:16 +0000 Subject: Fix the RTC device model to operate correctly in 12-hour mode. The following table documents the values in the RTC 'hour' field in the two modes: Hour-of-the-day 12-hour mode 24-hour mode 12 AM 12 0 [1-11] AM [1-11] [1-11] 12 PM 0x80 | 12 12 [1-11] PM 0x80 | [1-11] [13-23] Reported by: Julian Hsiao (madoka@nyanisore.net) MFC after: 1 week --- sys/amd64/vmm/io/vrtc.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'sys/amd64/vmm') diff --git a/sys/amd64/vmm/io/vrtc.c b/sys/amd64/vmm/io/vrtc.c index d5e93dc..ab9cabb 100644 --- a/sys/amd64/vmm/io/vrtc.c +++ b/sys/amd64/vmm/io/vrtc.c @@ -214,9 +214,27 @@ secs_to_rtc(time_t rtctime, struct vrtc *vrtc, int force_update) rtc->sec = rtcset(rtc, ct.sec); rtc->min = rtcset(rtc, ct.min); - hour = ct.hour; - if ((rtc->reg_b & RTCSB_24HR) == 0) - hour = (hour % 12) + 1; /* convert to a 12-hour format */ + if (rtc->reg_b & RTCSB_24HR) { + hour = ct.hour; + } else { + /* + * Convert to the 12-hour format. + */ + switch (ct.hour) { + case 0: /* 12 AM */ + case 12: /* 12 PM */ + hour = 12; + break; + default: + /* + * The remaining 'ct.hour' values are interpreted as: + * [1 - 11] -> 1 - 11 AM + * [13 - 23] -> 1 - 11 PM + */ + hour = ct.hour % 12; + break; + } + } rtc->hour = rtcset(rtc, hour); @@ -287,9 +305,26 @@ rtc_to_secs(struct vrtc *vrtc) } error = rtcget(rtc, hour, &ct.hour); if ((rtc->reg_b & RTCSB_24HR) == 0) { - ct.hour -= 1; - if (pm) - ct.hour += 12; + if (ct.hour >= 1 && ct.hour <= 12) { + /* + * Convert from 12-hour format to internal 24-hour + * representation as follows: + * + * 12-hour format ct.hour + * 12 AM 0 + * 1 - 11 AM 1 - 11 + * 12 PM 12 + * 1 - 11 PM 13 - 23 + */ + if (ct.hour == 12) + ct.hour = 0; + if (pm) + ct.hour += 12; + } else { + VM_CTR2(vm, "Invalid RTC 12-hour format %#x/%d", + rtc->hour, ct.hour); + goto fail; + } } if (error || ct.hour < 0 || ct.hour > 23) { -- cgit v1.1