7 static uint8_t read_cmos(const uint8_t reg
)
9 /* we don't to cause any undefined behaviour by reading above CMOS RAM */
10 if(reg
>= 64){return 0;}
16 static void write_cmos(uint8_t reg
, uint8_t val
)
18 /* we don't to cause any undefined behaviour by reading above CMOS RAM */
19 if(reg
>= 64){return;}
25 static uint16_t cmos_checksum()
32 for(i
= 16; i
< 46; i
++)
33 {checksum
+= read_cmos(i
);}
35 return hs2net_16(checksum
);
38 static void rtc_handler(int vector
, struct interrupt_stack
*is
)
40 time
.second
= bcd2bin(read_cmos(0x00));
41 time
.minute
= bcd2bin(read_cmos(0x02));
42 time
.hour
= bcd2bin(read_cmos(0x04));
43 time
.day_of_week
= bcd2bin(read_cmos(0x06));
44 time
.day_of_month
= bcd2bin(read_cmos(0x07));
45 time
.month
= bcd2bin(read_cmos(0x08));
47 uint8_t year
= bcd2bin(read_cmos(0x09));
48 uint16_t century
= bcd2bin(read_cmos(0x32));
51 time
.year
= century
+ year
;
53 read_cmos(0x0C); /* clear pending interrupts */
57 static void force_update()
59 read_cmos(0x0C); /* clear pending interrupts */
61 time
.second
= bcd2bin(read_cmos(0x00));
62 time
.minute
= bcd2bin(read_cmos(0x02));
63 time
.hour
= bcd2bin(read_cmos(0x04));
64 time
.day_of_week
= bcd2bin(read_cmos(0x06));
65 time
.day_of_month
= bcd2bin(read_cmos(0x07));
66 time
.month
= bcd2bin(read_cmos(0x08));
68 uint8_t year
= bcd2bin(read_cmos(0x09));
69 uint16_t century
= bcd2bin(read_cmos(0x32));
72 time
.year
= century
+ year
;
78 uint16_t theirs
, ours
;
80 theirs
= read_cmos(46) & 0xFF;
81 theirs
+= ((read_cmos(47) << 8) & 0xFF00);
83 ours
= cmos_checksum();
85 /* QEMU seems to not use the checksum field, so we have to take this with a grain of salt. */
88 console_printf(get_vterm(0), "CMOS: checksum error. theirs = %x, ours = %x \n", theirs
, ours
);
91 /* this, on the other hand, is not to be looked over lightly */
92 if(!(read_cmos(0x0D) & 0x80))
94 console_printf(get_vterm(0), "CMOS: data invalid (status register D = %x) \n", read_cmos(0x0D));
98 status_b
= read_cmos(0x0B);
99 status_b
|= 0x12; /* set UI and 24h */
100 status_b
&= 0x9F; /* clear PI and AI */
101 write_cmos(0x0B, status_b
);
104 interrupt_set_handler(irq_to_int(8), &rtc_handler
);
107 read_cmos(0x0C); /* clear pending interrupts */
110 console_printf(get_vterm(0), "RTC: current time = %u:%u:%u, date = %u/%u/%u\n", time
.hour
, time
.minute
, time
.second
, time
.month
, time
.day_of_month
, time
.year
);