summaryrefslogtreecommitdiff
path: root/src/drivers/pc80/mc146818rtc.c
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2012-08-07 17:03:40 -0700
committerStefan Reinauer <stefan.reinauer@coreboot.org>2012-11-07 05:16:04 +0100
commitfa90fd4f2f4aab4da25bb0c89cb408de36443a25 (patch)
treed4ab0fb3ca5d58286d20278219d29c10195862b8 /src/drivers/pc80/mc146818rtc.c
parentbecacec022602ae1ab876c58d8ae69092327b9fe (diff)
rtc: erase CMOS memory after power failure
When a power failure happens on the RTC rail, the CMOS memory (including the RTC registers) is filled with garbage. So, we erase the full first bank (112 bytes) and we reset the RTC date to the build date. To test, disconnect the CMOS battery to produce an RTC power failure, then boot the machine and observe the RTC date is the build date using "cat /sys/class/rtc/rtc0/date" Change-Id: I684bb3ad5079f96825555d4ed84dc0f7914e9884 Signed-off-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-on: http://review.coreboot.org/1697 Reviewed-by: Marc Jones <marcj303@gmail.com> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/drivers/pc80/mc146818rtc.c')
-rw-r--r--src/drivers/pc80/mc146818rtc.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/src/drivers/pc80/mc146818rtc.c b/src/drivers/pc80/mc146818rtc.c
index efeb378d31..d832544b17 100644
--- a/src/drivers/pc80/mc146818rtc.c
+++ b/src/drivers/pc80/mc146818rtc.c
@@ -1,4 +1,5 @@
#include <stdint.h>
+#include <build.h>
#include <console/console.h>
#include <pc80/mc146818rtc.h>
#include <boot/coreboot_tables.h>
@@ -79,15 +80,14 @@
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? */
+ /* Now setup a default date equals to the build date */
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);
+ cmos_write(COREBOOT_BUILD_WEEKDAY, RTC_CLK_DAYOFWEEK);
+ cmos_write(COREBOOT_BUILD_DAY, RTC_CLK_DAYOFMONTH);
+ cmos_write(COREBOOT_BUILD_MONTH, RTC_CLK_MINUTE);
+ cmos_write(COREBOOT_BUILD_YEAR, RTC_CLK_YEAR);
if (has_century) cmos_write(0x20, RTC_CLK_ALTCENTURY);
}
@@ -129,9 +129,10 @@ static void rtc_set_checksum(int range_start, int range_end, int cks_loc)
void rtc_init(int invalid)
{
+ int cmos_invalid = 0;
+ int checksum_invalid = 0;
#if CONFIG_USE_OPTION_TABLE
unsigned char x;
- int cmos_invalid, checksum_invalid;
#endif
printk(BIOS_DEBUG, "RTC Init\n");
@@ -146,17 +147,18 @@ void rtc_init(int invalid)
PC_CKS_RANGE_END,PC_CKS_LOC);
#define CLEAR_CMOS 0
+#else
+#define CLEAR_CMOS 1
+#endif
+
if (invalid || cmos_invalid || checksum_invalid) {
- printk(BIOS_WARNING, "RTC:%s%s%s%s\n",
- invalid?" Clear requested":"",
- cmos_invalid?" Power Problem":"",
- checksum_invalid?" Checksum invalid":"",
- CLEAR_CMOS?" zeroing cmos":"");
#if CLEAR_CMOS
+ int i;
+
cmos_write(0, 0x01);
cmos_write(0, 0x03);
cmos_write(0, 0x05);
- for(i = 10; i < 48; i++) {
+ for(i = 10; i < 128; i++) {
cmos_write(0, i);
}
@@ -164,8 +166,12 @@ void rtc_init(int invalid)
rtc_update_cmos_date(RTC_HAS_NO_ALTCENTURY);
}
#endif
+ printk(BIOS_WARNING, "RTC:%s%s%s%s\n",
+ invalid?" Clear requested":"",
+ cmos_invalid?" Power Problem":"",
+ checksum_invalid?" Checksum invalid":"",
+ CLEAR_CMOS?" zeroing cmos":"");
}
-#endif
/* Setup the real time clock */
cmos_write(RTC_CONTROL_DEFAULT, RTC_CONTROL);