[coreboot] Patch set updated for coreboot: 41b3dd0 RTC: Add a routine to check if the CMOS date is valid

Zheng Bao (zheng.bao@amd.com) gerrit at coreboot.org
Thu Aug 2 08:46:34 CEST 2012


Zheng Bao (zheng.bao at amd.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1389

-gerrit

commit 41b3dd08ffc03c4b434cad25256b03bfb89a0107
Author: zbao <fishbaozi at gmail.com>
Date:   Thu Aug 2 16:30:23 2012 +0800

    RTC: Add a routine to check if the CMOS date is valid
    
    If the CMOS is cleared or someone writes some random date/time
    on purpose, the CMOS date register has a invalid date. This will
    hurts some OS, like Windows 7, which hangs at MS logo forever.
    When we detect that, we need to write a reasonable date in CMOS.
    
    Change-Id: Ic1c7a2d60e711265686441c77bdf7891a7efb42e
    Signed-off-by: Zheng Bao <zheng.bao at amd.com>
    Signed-off-by: zbao <fishbaozi at gmail.com>
---
 src/drivers/pc80/mc146818rtc.c |   42 +++++++++++++++++++++++++++++++++------
 src/include/pc80/mc146818rtc.h |    5 ++++
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c
index 99d670d..60cd14c 100644
--- a/src/drivers/pc80/mc146818rtc.c
+++ b/src/drivers/pc80/mc146818rtc.c
@@ -148,13 +148,13 @@ void rtc_init(int invalid)
 
 		if (cmos_invalid) {
 			/* Now setup a default date of Sat 1 January 2000 */
-			cmos_write(0, 0x00); /* seconds */
-			cmos_write(0, 0x02); /* minutes */
-			cmos_write(1, 0x04); /* hours */
-			cmos_write(7, 0x06); /* day of week */
-			cmos_write(1, 0x07); /* day of month */
-			cmos_write(1, 0x08); /* month */
-			cmos_write(0, 0x09); /* year */
+			cmos_write(0, RTC_CLK_SECOND);
+			cmos_write(0, RTC_CLK_MINUTE);
+			cmos_write(1, RTC_CLK_HOUR);
+			cmos_write(7, RTC_CLK_DAYOFWEEK);
+			cmos_write(1, RTC_CLK_DAYOFMONTH);
+			cmos_write(1, RTC_CLK_MINUTE);
+			cmos_write(0, RTC_CLK_YEAR);
 		}
 #endif
 	}
@@ -338,3 +338,31 @@ int set_option(const char *name, void *value)
 	return 0;
 }
 #endif /* CONFIG_USE_OPTION_TABLE */
+
+/*
+ * If the CMOS is cleared, the rtc_reg has the invalid date. That
+ * hurts some OSes. Even if we don't set USE_OPTION_TABLE, we need
+ * to make sure the date is valid.
+ */
+void rtc_check_update_coms_date(u8 has_century)
+{
+	u8 year, century;
+
+	/* Note: We need to check if the hardware supports RTC_CLK_ALTCENTURY. */
+	century	= has_century ? cmos_read(RTC_CLK_ALTCENTURY) : 0;
+	year	= cmos_read(RTC_CLK_YEAR);
+
+	/* TODO: If century is 0xFF, 100% that the cmos is cleared.
+	 * Other than that, so far rtc_year is the only entry to check if the date is valid. */
+	if (century > 0x99 || year > 0x99) {	/* Invalid date */
+		/* Now setup a default date of Sat 1 January 2000 */
+		cmos_write(0, RTC_CLK_SECOND);
+		cmos_write(0, RTC_CLK_MINUTE);
+		cmos_write(1, RTC_CLK_HOUR);
+		cmos_write(7, RTC_CLK_DAYOFWEEK);
+		cmos_write(1, RTC_CLK_DAYOFMONTH);
+		cmos_write(1, RTC_CLK_MINUTE);
+		cmos_write(0, RTC_CLK_YEAR);
+		has_century ? cmos_write(0x20, RTC_CLK_ALTCENTURY) : NULL;
+	}
+}
diff --git a/src/include/pc80/mc146818rtc.h b/src/include/pc80/mc146818rtc.h
index 9f18ba4..58b307e 100644
--- a/src/include/pc80/mc146818rtc.h
+++ b/src/include/pc80/mc146818rtc.h
@@ -87,6 +87,10 @@
 #define RTC_CLK_DAYOFMONTH	7
 #define RTC_CLK_MONTH		8
 #define RTC_CLK_YEAR		9
+#define RTC_CLK_ALTCENTURY	0x32
+
+#define RTC_HAS_ALTCENTURY	1
+#define RTC_HAS_NO_ALTCENTURY	0
 
 /* On PCs, the checksum is built only over bytes 16..45 */
 #define PC_CKS_RANGE_START	16
@@ -136,6 +140,7 @@ static inline void cmos_write32(u8 offset, u32 value)
 
 #if !defined(__ROMCC__)
 void rtc_init(int invalid);
+void rtc_check_update_coms_date(u8 has_century);
 #if CONFIG_USE_OPTION_TABLE
 int set_option(const char *name, void *val);
 int get_option(void *dest, const char *name);




More information about the coreboot mailing list