Avoid reading/writing to cmos at runtime to get the QEMU century information. Instead, read it at startup and cache the info.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/clock.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/src/clock.c b/src/clock.c index 3edcaf5..39df13b 100644 --- a/src/clock.c +++ b/src/clock.c @@ -13,6 +13,7 @@ #include "bregs.h" // struct bregs #include "biosvar.h" // GET_GLOBAL #include "usb-hid.h" // usb_check_event +#include "paravirt.h" // runningOnQEMU()
// RTC register flags #define RTC_A_UIP 0x80 @@ -281,6 +282,8 @@ bcd2bin(u8 val) return (val & 0xf) + ((val >> 4) * 10); }
+u8 Century VARLOW; + void timer_setup(void) { @@ -297,6 +300,17 @@ timer_setup(void) ticks = ((u64)ticks * PIT_TICK_RATE) / PIT_TICK_INTERVAL; SET_BDA(timer_counter, ticks);
+ // Setup Century storage + if (runningOnQEMU()) { + Century = inb_cmos(CMOS_CENTURY); + } else { + u8 year = inb_cmos(CMOS_RTC_YEAR); + if (year > 0x80) + Century = 0x19; + else + Century = 0x20; + } + enable_hwirq(0, FUNC16(entry_08)); enable_hwirq(8, FUNC16(entry_70)); } @@ -420,14 +434,7 @@ handle_1a04(struct bregs *regs) regs->cl = inb_cmos(CMOS_RTC_YEAR); regs->dh = inb_cmos(CMOS_RTC_MONTH); regs->dl = inb_cmos(CMOS_RTC_DAY_MONTH); - if (CONFIG_COREBOOT) { - if (regs->cl > 0x80) - regs->ch = 0x19; - else - regs->ch = 0x20; - } else { - regs->ch = inb_cmos(CMOS_CENTURY); - } + regs->ch = GET_LOW(Century); regs->al = regs->ch; set_success(regs); } @@ -454,8 +461,7 @@ handle_1a05(struct bregs *regs) outb_cmos(regs->cl, CMOS_RTC_YEAR); outb_cmos(regs->dh, CMOS_RTC_MONTH); outb_cmos(regs->dl, CMOS_RTC_DAY_MONTH); - if (!CONFIG_COREBOOT) - outb_cmos(regs->ch, CMOS_CENTURY); + SET_LOW(Century, regs->ch); // clear halt-clock bit u8 val8 = inb_cmos(CMOS_STATUS_B) & ~RTC_B_SET; outb_cmos(val8, CMOS_STATUS_B);