aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Georgi <patrick.georgi@secunet.com>2011-01-14 07:40:24 +0000
committerPatrick Georgi <patrick.georgi@coresystems.de>2011-01-14 07:40:24 +0000
commita865b17eff05fa3936494716401f6aa9a9ef6358 (patch)
tree3c0baa84f61c582638fd0c333a1020c5aa8519b0
parent4c8e269841bbdfd3325b8eb98a651a8b1df85399 (diff)
Allow coreboot to initialize CMOS if checksum is invalid.
If a file "cmos.default", type "cmos default"(0xaa) is in CBFS, a wrong checksum leads to coreboot rewriting the first 128 bytes (except for clock data) with the data in cmos.default, then reboots the system so every component of coreboot works with the same set of values. Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com> Acked-by: Stefan Reinauer <stepan@coreboot.org> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6253 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
-rw-r--r--src/arch/x86/Kconfig7
-rw-r--r--src/mainboard/getac/p470/cmos.layout5
-rw-r--r--src/mainboard/kontron/986lcd-m/cmos.layout5
-rw-r--r--src/mainboard/roda/rk886ex/cmos.layout5
-rw-r--r--src/pc80/Makefile.inc5
-rw-r--r--src/pc80/mc146818rtc_early.c26
-rw-r--r--util/cbfstool/cbfs.h1
-rw-r--r--util/cbfstool/common.c1
8 files changed, 52 insertions, 3 deletions
diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig
index 28a65b61a2..aacc0982a6 100644
--- a/src/arch/x86/Kconfig
+++ b/src/arch/x86/Kconfig
@@ -91,6 +91,13 @@ config PC80_SYSTEM
config BOOTBLOCK_NORTHBRIDGE_INIT
string
+config HAVE_CMOS_DEFAULT
+ def_bool n
+
+config CMOS_DEFAULT_FILE
+ string
+ depends on HAVE_CMOS_DEFAULT
+
config BOOTBLOCK_SOUTHBRIDGE_INIT
string
diff --git a/src/mainboard/getac/p470/cmos.layout b/src/mainboard/getac/p470/cmos.layout
index 73ea031043..f86e479df5 100644
--- a/src/mainboard/getac/p470/cmos.layout
+++ b/src/mainboard/getac/p470/cmos.layout
@@ -92,7 +92,8 @@ entries
# coreboot config options: bootloader
416 512 s 0 boot_devices
928 8 h 0 boot_default
-#936 48 r 0 unused
+936 1 e 8 cmos_defaults_loaded
+#937 47 r 0 unused
# coreboot config options: check sums
984 16 h 0 check_sum
@@ -136,6 +137,8 @@ enumerations
7 0 Disable
7 1 Enable
7 2 Keep
+8 0 No
+8 1 Yes
# -----------------------------------------------------------------
checksums
diff --git a/src/mainboard/kontron/986lcd-m/cmos.layout b/src/mainboard/kontron/986lcd-m/cmos.layout
index a61a9deabf..6f2647927e 100644
--- a/src/mainboard/kontron/986lcd-m/cmos.layout
+++ b/src/mainboard/kontron/986lcd-m/cmos.layout
@@ -90,7 +90,8 @@ entries
# coreboot config options: bootloader
416 512 s 0 boot_devices
928 8 h 0 boot_default
-#936 12 r 0 unused
+936 1 e 11 cmos_defaults_loaded
+#937 11 r 0 unused
# coreboot config options: mainboard specific options
948 2 e 8 cpufan_cruise_control
@@ -187,6 +188,8 @@ enumerations
#10 13 69/156
#10 14 72/161
#10 15 75/167
+11 0 No
+11 1 Yes
# -----------------------------------------------------------------
checksums
diff --git a/src/mainboard/roda/rk886ex/cmos.layout b/src/mainboard/roda/rk886ex/cmos.layout
index 4dc9112061..475823d68e 100644
--- a/src/mainboard/roda/rk886ex/cmos.layout
+++ b/src/mainboard/roda/rk886ex/cmos.layout
@@ -92,7 +92,8 @@ entries
# coreboot config options: bootloader
416 512 s 0 boot_devices
928 8 h 0 boot_default
-#936 48 r 0 unused
+936 1 e 8 cmos_defaults_loaded
+#937 47 r 0 unused
# coreboot config options: check sums
984 16 h 0 check_sum
@@ -136,6 +137,8 @@ enumerations
7 0 Disable
7 1 Enable
7 2 Keep
+8 0 No
+8 1 Yes
# -----------------------------------------------------------------
checksums
diff --git a/src/pc80/Makefile.inc b/src/pc80/Makefile.inc
index d32dfe985e..0dc78bb6d0 100644
--- a/src/pc80/Makefile.inc
+++ b/src/pc80/Makefile.inc
@@ -10,3 +10,8 @@ subdirs-y += vga
$(obj)/pc80/mc146818rtc.ramstage.o : $(OPTION_TABLE_H)
$(obj)/pc80/mc146818rtc_early.romstage.o : $(OPTION_TABLE_H)
+
+cbfs-files-$(CONFIG_HAVE_CMOS_DEFAULT) += $(CONFIG_CMOS_DEFAULT_FILE)
+$(CONFIG_CMOS_DEFAULT_FILE)-name := cmos.default
+$(CONFIG_CMOS_DEFAULT_FILE)-type := 0xaa
+
diff --git a/src/pc80/mc146818rtc_early.c b/src/pc80/mc146818rtc_early.c
index d09d6b9df0..10de0bc54f 100644
--- a/src/pc80/mc146818rtc_early.c
+++ b/src/pc80/mc146818rtc_early.c
@@ -1,5 +1,6 @@
#include <pc80/mc146818rtc.h>
#include <fallback.h>
+#include <cbfs.h>
#if CONFIG_USE_OPTION_TABLE
#include "option_table.h"
#endif
@@ -11,11 +12,18 @@
#error "CONFIG_MAX_REBOOT_CNT too high"
#endif
+#include <console/loglevel.h>
+
+int do_printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+#define printk_warning(fmt, arg...) do_printk(BIOS_WARNING ,fmt, ##arg)
+#define printk_debug(fmt, arg...) do_printk(BIOS_DEBUG ,fmt, ##arg)
+
static int cmos_error(void)
{
unsigned char reg_d;
/* See if the cmos error condition has been flagged */
reg_d = cmos_read(RTC_REG_D);
+ printk_debug("CMOS_REG_D(VRT): %x\n", reg_d & RTC_VRT);
return (reg_d & RTC_VRT) == 0;
}
@@ -35,6 +43,7 @@ static int cmos_chksum_valid(void)
old_sum = cmos_read(LB_CKS_LOC) << 8;
old_sum |= cmos_read(LB_CKS_LOC+1);
+ printk_debug("CMOS checksum: old = %lx, new=%lx\n", old_sum, sum);
return sum == old_sum;
#else
return 0;
@@ -51,9 +60,26 @@ static inline int last_boot_normal(void)
static inline int do_normal_boot(void)
{
+ char *cmos_default = cbfs_find_file("cmos.default", 0xaa);
unsigned char byte;
+ int i;
if (cmos_error() || !cmos_chksum_valid()) {
+ if (cmos_default) {
+ printk_warning("WARNING - CMOS CORRUPTED. RESTORING DEFAULTS.\n");
+ /* First 14 bytes are reserved for
+ RTC and ignored by nvramtool, too.
+ Only 128 bytes: 128+ requires cmos configuration and
+ contains only suspend-to-ram data, which isn't part
+ of the recovery procedure. */
+ for (i = 14; i < 128; i++) {
+ cmos_write(cmos_default[i], i);
+ }
+ /* Now reboot to run with default cmos. */
+ outb(0x06, 0xcf9);
+ for (;;) asm("hlt"); /* Wait for reset! */
+ }
+
/* There are no impossible values, no checksums so just
* trust whatever value we have in the the cmos,
* but clear the fallback bit.
diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index 0d33710229..6fb9edd68c 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -76,6 +76,7 @@ struct cbfs_payload {
#define CBFS_COMPONENT_VSA 0x51
#define CBFS_COMPONENT_MBI 0x52
#define CBFS_COMPONENT_MICROCODE 0x53
+#define CBFS_COMPONENT_CMOS_DEFAULT 0xaa
/* The deleted type is chosen to be a value
* that can be written in a FLASH from all other
diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c
index a42585b776..0fb02004d4 100644
--- a/util/cbfstool/common.c
+++ b/util/cbfstool/common.c
@@ -145,6 +145,7 @@ struct filetypes_t {
{CBFS_COMPONENT_VSA, "vsa"},
{CBFS_COMPONENT_MBI, "mbi"},
{CBFS_COMPONENT_MICROCODE, "microcode"},
+ {CBFS_COMPONENT_CMOS_DEFAULT, "cmos default"},
{CBFS_COMPONENT_DELETED, "deleted"},
{CBFS_COMPONENT_NULL, "null"}
};