summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2015-03-28 02:55:16 +0000
committerneel <neel@FreeBSD.org>2015-03-28 02:55:16 +0000
commit4eebcc1fbb4c43444375c6b169ec6fae892b8a46 (patch)
treee77625d2e10bdbf12276e1dd3a17c18561a45eef /sys/amd64/vmm
parent2ef15783194ba96d4474939d1e64be02132da111 (diff)
downloadFreeBSD-src-4eebcc1fbb4c43444375c6b169ec6fae892b8a46.zip
FreeBSD-src-4eebcc1fbb4c43444375c6b169ec6fae892b8a46.tar.gz
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
Diffstat (limited to 'sys/amd64/vmm')
-rw-r--r--sys/amd64/vmm/io/vrtc.c47
1 files changed, 41 insertions, 6 deletions
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) {
OpenPOWER on IntegriCloud