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
This commit is contained in:
Patrick Georgi 2011-01-14 07:40:24 +00:00 committed by Patrick Georgi
parent 4c8e269841
commit a865b17eff
8 changed files with 52 additions and 3 deletions

View 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

View 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

View 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

View 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

View 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

View 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
@ -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.

View 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

View 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"}
};