1 #include <pc80/mc146818rtc.h>
3 #if CONFIG_USE_OPTION_TABLE
4 #include "option_table.h"
7 #ifndef CONFIG_MAX_REBOOT_CNT
8 #error "CONFIG_MAX_REBOOT_CNT not defined"
10 #if CONFIG_MAX_REBOOT_CNT > 15
11 #error "CONFIG_MAX_REBOOT_CNT too high"
14 #if CONFIG_USE_CMOS_RECOVERY
16 #include <console/loglevel.h>
18 int do_printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
19 #define printk_warning(fmt, arg...) do_printk(BIOS_WARNING ,fmt, ##arg)
20 #define printk_debug(fmt, arg...) do_printk(BIOS_DEBUG ,fmt, ##arg)
23 static int cmos_error(void)
26 /* See if the cmos error condition has been flagged */
27 reg_d = cmos_read(RTC_REG_D);
28 return (reg_d & RTC_VRT) == 0;
31 static int cmos_chksum_valid(void)
33 #if CONFIG_USE_OPTION_TABLE
35 unsigned long sum, old_sum;
37 /* Comput the cmos checksum */
38 for(addr = LB_CKS_RANGE_START; addr <= LB_CKS_RANGE_END; addr++) {
39 sum += cmos_read(addr);
41 sum = (sum & 0xffff) ^ 0xffff;
43 /* Read the stored checksum */
44 old_sum = cmos_read(LB_CKS_LOC) << 8;
45 old_sum |= cmos_read(LB_CKS_LOC+1);
47 return sum == old_sum;
54 static inline int last_boot_normal(void)
57 byte = cmos_read(RTC_BOOT_BYTE);
58 return (byte & (1 << 1));
61 static inline int do_normal_boot(void)
66 if (cmos_error() || !cmos_chksum_valid()) {
67 #if CONFIG_USE_CMOS_RECOVERY
68 char *cmos_default = cbfs_find_file("cmos.default", 0xaa);
70 printk_warning("WARNING - CMOS CORRUPTED. RESTORING DEFAULTS.\n");
71 /* First 14 bytes are reserved for
72 RTC and ignored by nvramtool, too.
73 Only 128 bytes: 128+ requires cmos configuration and
74 contains only suspend-to-ram data, which isn't part
75 of the recovery procedure. */
76 for (i = 14; i < 128; i++) {
77 cmos_write(cmos_default[i], i);
79 /* Now reboot to run with default cmos. */
81 for (;;) asm("hlt"); /* Wait for reset! */
85 /* There are no impossible values, no checksums so just
86 * trust whatever value we have in the the cmos,
87 * but clear the fallback bit.
89 byte = cmos_read(RTC_BOOT_BYTE);
91 byte |= CONFIG_MAX_REBOOT_CNT << 4;
92 cmos_write(byte, RTC_BOOT_BYTE);
95 /* The RTC_BOOT_BYTE is now o.k. see where to go. */
96 byte = cmos_read(RTC_BOOT_BYTE);
98 /* Are we in normal mode? */
100 byte &= 0x0f; /* yes, clear the boot count */
103 /* Properly set the last boot flag */
105 if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
109 /* Are we already at the max count? */
110 if ((byte >> 4) < CONFIG_MAX_REBOOT_CNT) {
111 byte += 1 << 4; /* No, add 1 to the count */
114 byte &= 0xfc; /* Yes, put in fallback mode */
117 /* Save the boot byte */
118 cmos_write(byte, RTC_BOOT_BYTE);
120 return (byte & (1<<1));
123 unsigned read_option(unsigned start, unsigned size, unsigned def)
125 #if CONFIG_USE_OPTION_TABLE
127 byte = cmos_read(start/8);
128 return (byte >> (start & 7U)) & ((1U << size) - 1U);