Allow coreboot to initialize CMOS if checksum is invalid.
authorPatrick Georgi <patrick.georgi@secunet.com>
Fri, 14 Jan 2011 07:40:24 +0000 (07:40 +0000)
committerPatrick Georgi <patrick.georgi@coresystems.de>
Fri, 14 Jan 2011 07:40:24 +0000 (07:40 +0000)
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

src/arch/x86/Kconfig
src/mainboard/getac/p470/cmos.layout
src/mainboard/kontron/986lcd-m/cmos.layout
src/mainboard/roda/rk886ex/cmos.layout
src/pc80/Makefile.inc
src/pc80/mc146818rtc_early.c
util/cbfstool/cbfs.h
util/cbfstool/common.c

index 28a65b61a21c2f266eb112330a21b50aa3405572..aacc0982a6c01b8646ef9f12222a02f954ac4de3 100644 (file)
@@ -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
 
index 73ea0310438ceac93dc0c5f3a37656cf3a841ada..f86e479df57e58ceb50df697808e28fd864af5a9 100644 (file)
@@ -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
index a61a9deabf7c2e233d74eac45e2cfc5c0422aa16..6f2647927e4b04aac3162505cc9c01a6ee123089 100644 (file)
@@ -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
 
index 4dc9112061f2740846396df66d898b2b356cd8d1..475823d68e51dedc737ffc72165d6046b4b62889 100644 (file)
@@ -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
index d32dfe985ebea921a7c3cc5c3a0111a6b5adad73..0dc78bb6d0b15725428f1fc269c85c6cf682811a 100644 (file)
@@ -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
+
index d09d6b9df0cae7d5824b7c26a0eee3d4c23302a3..10de0bc54f269d84c0a3f5f8b1816a03b4e5fb42 100644 (file)
@@ -1,5 +1,6 @@
 #include <pc80/mc146818rtc.h>
 #include <fallback.h>
+#include <cbfs.h>
 #if CONFIG_USE_OPTION_TABLE
 #include "option_table.h"
 #endif
 #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.
index 0d33710229a5d1ae1114823eebb6aa6ad08e406d..6fb9edd68cb429e0c0252adbe9d23008f00db011 100644 (file)
@@ -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
index a42585b7761b6e7f107ba395baccd86ed354be47..0fb02004d4fdede7551b7644e5c05fef1c265920 100644 (file)
@@ -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"}
 };