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)
This commit is contained in:
Vincent Palatin 2012-08-07 17:03:40 -07:00 committed by Stefan Reinauer
parent becacec022
commit fa90fd4f2f
2 changed files with 24 additions and 14 deletions

View File

@ -179,6 +179,10 @@ $(obj)/build.h: .xcompile
printf "#define COREBOOT_VERSION \"$(KERNELVERSION)\"\n" >> $(obj)/build.ht
printf "#define COREBOOT_EXTRA_VERSION \"$(COREBOOT_EXTRA_VERSION)\"\n" >> $(obj)/build.ht
printf "#define COREBOOT_BUILD \"`LANG= date`\"\n" >> $(obj)/build.ht
printf "#define COREBOOT_BUILD_YEAR `LANG= date +"%-y"`\n" >> $(obj)/build.ht
printf "#define COREBOOT_BUILD_MONTH `LANG= date +"%-m"` \n" >> $(obj)/build.ht
printf "#define COREBOOT_BUILD_DAY `LANG= date +"%-d"`\n" >> $(obj)/build.ht
printf "#define COREBOOT_BUILD_WEEKDAY `LANG= date +"%-u"`\n" >> $(obj)/build.ht
printf "#define COREBOOT_DMI_DATE \"`LANG= date +"%m/%d/%Y"`\"\n" >> $(obj)/build.ht
printf "\n" >> $(obj)/build.ht
printf "#define COREBOOT_COMPILER \"$(shell LANG= $(CC) --version | head -n1)\"\n" >> $(obj)/build.ht

View File

@ -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);