10 IMPLEMENTATION[ia32,amd64]:
13 #include "globalconfig.h"
15 #define RTC_STATUSA 0x0a /* status register A */
16 #define RTCSA_TUP 0x80 /* time update, don't look now */
17 #define RTCSA_DIVIDER 0x20 /* divider correct for 32768 Hz */
18 #define RTCSA_8192 0x03
19 #define RTCSA_4096 0x04
20 #define RTCSA_2048 0x05
21 #define RTCSA_1024 0x06
22 #define RTCSA_512 0x07
23 #define RTCSA_256 0x08
24 #define RTCSA_128 0x09
28 #define RTC_STATUSB 0x0b /* status register B */
29 #define RTCSB_DST 0x01 /* Daylight Savings Time enable */
30 #define RTCSB_24HR 0x02 /* 0 = 12 hours, 1 = 24 hours */
31 #define RTCSB_BCD 0x04 /* 0 = BCD, 1 = Binary coded time */
32 #define RTCSB_SQWE 0x08 /* 1 = output sqare wave at SQW pin */
33 #define RTCSB_UINTR 0x10 /* 1 = enable update-ended interrupt */
34 #define RTCSB_AINTR 0x20 /* 1 = enable alarm interrupt */
35 #define RTCSB_PINTR 0x40 /* 1 = enable periodic clock interrupt */
36 #define RTCSB_HALT 0x80 /* stop clock updates */
38 #define RTC_INTR 0x0c /* status register C (R) interrupt source */
39 #define RTCIR_UPDATE 0x10 /* update intr */
40 #define RTCIR_ALARM 0x20 /* alarm intr */
41 #define RTCIR_PERIOD 0x40 /* periodic intr */
42 #define RTCIR_INT 0x80 /* interrupt output signal */
47 Rtc::reg_read(unsigned char reg)
49 Io::out8_p(reg, 0x70);
50 return Io::in8_p(0x71);
55 Rtc::reg_write(unsigned char reg, unsigned char val)
61 // set up timer interrupt (~ 1ms)
66 while (reg_read(RTC_STATUSA) & RTCSA_TUP)
67 ; // wait till RTC ready
69 #ifdef CONFIG_SLOW_RTC
70 // set divider to 64 Hz
71 reg_write(RTC_STATUSA, RTCSA_DIVIDER | RTCSA_64);
73 // set divider to 1024 Hz
74 reg_write(RTC_STATUSA, RTCSA_DIVIDER | RTCSA_1024);
78 reg_write(RTC_STATUSB, reg_read(RTC_STATUSB) | RTCSB_PINTR | RTCSB_SQWE);
88 // disable all potential interrupt sources
89 reg_write(RTC_STATUSB,
90 reg_read(RTC_STATUSB) & ~(RTCSB_PINTR | RTCSB_AINTR | RTCSB_UINTR));
100 // set divider to 32 Hz
101 reg_write(RTC_STATUSA, RTCSA_DIVIDER | RTCSA_32);
106 Rtc::set_freq_normal()
108 // set divider to 1024 Hz
109 reg_write(RTC_STATUSA, RTCSA_DIVIDER | RTCSA_1024);
112 // acknowledge RTC interrupt
117 // reset irq by reading the cmos port
118 // do it fast because we are cli'd
119 asm volatile ("movb $0xc, %%al\n\t"
120 "outb %%al,$0x70\n\t"
121 "outb %%al,$0x80\n\t"
122 "inb $0x71,%%al\n\t" : : : "eax");