Patchwork Initialize CMOS from CBFS if checksum is incorrect

login
register
about
Submitter Patrick Georgi
Date 2011-01-13 10:10:45
Message ID <1294913445.2411.23.camel@linux-0a8x.site>
Download mbox | patch
Permalink /patch/2512/
State Accepted
Headers show

Comments

Patrick Georgi - 2011-01-13 10:10:45
Hi,

attached patch provides a way to initialize the CMOS if the checksum
test failed. For this to work, a CMOS dump must be stored as
"cmos.default" (filetype "cmos default") in CBFS.
After CMOS is rewritten, the system is rebooted to ensure that all parts
of coreboot run with the new (working) configuration.

For a couple of boards, a "cmos_defaults_loaded" field is added to
cmos.layout. This can be used to tell the system that defaults were
applied by setting this flag in cmos.default and parsing/resetting it in
the system.

Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com>
Stefan Reinauer - 2011-01-13 19:16:01
* Patrick Georgi <Patrick.Georgi@secunet.com> [110113 11:10]:
> Hi,
> 
> attached patch provides a way to initialize the CMOS if the checksum
> test failed. For this to work, a CMOS dump must be stored as
> "cmos.default" (filetype "cmos default") in CBFS.
> After CMOS is rewritten, the system is rebooted to ensure that all parts
> of coreboot run with the new (working) configuration.
> 
> For a couple of boards, a "cmos_defaults_loaded" field is added to
> cmos.layout. This can be used to tell the system that defaults were
> applied by setting this flag in cmos.default and parsing/resetting it in
> the system.
> 
> Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com>

Acked-by: Stefan Reinauer <stepan@coreboot.org>

Patch

Index: coreboot-staging/src/mainboard/getac/p470/cmos.layout

===================================================================
--- coreboot-staging.orig/src/mainboard/getac/p470/cmos.layout

+++ coreboot-staging/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
Index: coreboot-staging/src/mainboard/kontron/986lcd-m/cmos.layout

===================================================================
--- coreboot-staging.orig/src/mainboard/kontron/986lcd-m/cmos.layout

+++ coreboot-staging/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
 
Index: coreboot-staging/src/mainboard/roda/rk886ex/cmos.layout

===================================================================
--- coreboot-staging.orig/src/mainboard/roda/rk886ex/cmos.layout

+++ coreboot-staging/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
Index: coreboot-staging/src/pc80/mc146818rtc_early.c

===================================================================
--- coreboot-staging.orig/src/pc80/mc146818rtc_early.c

+++ coreboot-staging/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.
Index: coreboot-staging/util/cbfstool/cbfs.h

===================================================================
--- coreboot-staging.orig/util/cbfstool/cbfs.h

+++ coreboot-staging/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
Index: coreboot-staging/util/cbfstool/common.c

===================================================================
--- coreboot-staging.orig/util/cbfstool/common.c

+++ coreboot-staging/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"}
 };
Index: coreboot-staging/src/arch/x86/Kconfig

===================================================================
--- coreboot-staging.orig/src/arch/x86/Kconfig

+++ coreboot-staging/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
 
Index: coreboot-staging/src/pc80/Makefile.inc

===================================================================
--- coreboot-staging.orig/src/pc80/Makefile.inc

+++ coreboot-staging/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

+