1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
5 #include <pc80/mc146818rtc.h>
8 #if CONFIG_MAX_REBOOT_CNT > 15
9 #error "CONFIG_MAX_REBOOT_CNT too high"
12 static int boot_count(uint8_t rtc_byte
)
17 static uint8_t increment_boot_count(uint8_t rtc_byte
)
19 return rtc_byte
+ (1 << 4);
22 static uint8_t boot_set_fallback(uint8_t rtc_byte
)
24 return rtc_byte
& ~RTC_BOOT_NORMAL
;
27 static int boot_use_normal(uint8_t rtc_byte
)
29 return rtc_byte
& RTC_BOOT_NORMAL
;
32 int do_normal_boot(void)
36 if (cmos_error() || (CONFIG(USE_OPTION_TABLE
) && !cmos_lb_cks_valid())) {
38 "Invalid CMOS checksum detected! Force fallback boot...\n");
39 byte
= cmos_read(RTC_BOOT_BYTE
);
40 byte
&= boot_set_fallback(byte
) & 0x0f;
42 cmos_write(byte
, RTC_BOOT_BYTE
);
45 /* The RTC_BOOT_BYTE is now o.k. see where to go. */
46 byte
= cmos_read(RTC_BOOT_BYTE
);
48 /* Are we attempting to boot normally? */
49 if (boot_use_normal(byte
)) {
50 /* Are we already at the max count? */
51 if (boot_count(byte
) < CONFIG_MAX_REBOOT_CNT
)
52 byte
= increment_boot_count(byte
);
54 byte
= boot_set_fallback(byte
);
57 /* Save the boot byte */
58 cmos_write(byte
, RTC_BOOT_BYTE
);
60 /* Return selected code path for this boot attempt */
61 return boot_use_normal(byte
);