svn commit: r280775 - head/sys/amd64/vmm/io

Neel Natu neel at FreeBSD.org
Sat Mar 28 02:55:18 UTC 2015


Author: neel
Date: Sat Mar 28 02:55:16 2015
New Revision: 280775
URL: https://svnweb.freebsd.org/changeset/base/280775

Log:
  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 at nyanisore.net)
  MFC after:	1 week

Modified:
  head/sys/amd64/vmm/io/vrtc.c

Modified: head/sys/amd64/vmm/io/vrtc.c
==============================================================================
--- head/sys/amd64/vmm/io/vrtc.c	Sat Mar 28 02:36:49 2015	(r280774)
+++ head/sys/amd64/vmm/io/vrtc.c	Sat Mar 28 02:55:16 2015	(r280775)
@@ -214,9 +214,27 @@ secs_to_rtc(time_t rtctime, struct vrtc 
 	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) {


More information about the svn-src-head mailing list