diff options
Diffstat (limited to 'src/drivers/pc80')
-rw-r--r-- | src/drivers/pc80/mc146818rtc.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c index 99d670de42..cc14a412dc 100644 --- a/src/drivers/pc80/mc146818rtc.c +++ b/src/drivers/pc80/mc146818rtc.c @@ -77,6 +77,20 @@ # define RTC_VRT 0x80 /* valid RAM and time */ /**********************************************************************/ +static void rtc_update_cmos_date(u8 has_century) +{ + /* Now setup a default date of Sat 1 January 2000 */ + /* TODO: Set the time as building time? Is it reasonable? */ + 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); + if (has_century) cmos_write(0x20, RTC_CLK_ALTCENTURY); +} + #if CONFIG_USE_OPTION_TABLE static int rtc_checksum_valid(int range_start, int range_end, int cks_loc) { @@ -147,14 +161,7 @@ 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 */ + rtc_update_cmos_date(RTC_HAS_NO_ALTCENTURY); } #endif } @@ -338,3 +345,23 @@ 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_cmos_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 */ + rtc_update_cmos_date(has_century); + } +} |