]>
Commit | Line | Data |
---|---|---|
7eda085c | 1 | /* |
ef71b8f1 SK |
2 | * i386 CMOS starts out with 14 bytes clock data alpha has something |
3 | * similar, but with details depending on the machine type. | |
7eda085c | 4 | * |
ef71b8f1 SK |
5 | * byte 0: seconds 0-59 |
6 | * byte 2: minutes 0-59 | |
7 | * byte 4: hours 0-23 in 24hr mode, | |
8 | * 1-12 in 12hr mode, with high bit unset/set | |
9 | * if am/pm. | |
10 | * byte 6: weekday 1-7, Sunday=1 | |
11 | * byte 7: day of the month 1-31 | |
12 | * byte 8: month 1-12 | |
13 | * byte 9: year 0-99 | |
7eda085c | 14 | * |
ef71b8f1 SK |
15 | * Numbers are stored in BCD/binary if bit 2 of byte 11 is unset/set The |
16 | * clock is in 12hr/24hr mode if bit 1 of byte 11 is unset/set The clock is | |
17 | * undefined (being updated) if bit 7 of byte 10 is set. The clock is frozen | |
18 | * (to be updated) by setting bit 7 of byte 11 Bit 7 of byte 14 indicates | |
19 | * whether the CMOS clock is reliable: it is 1 if RTC power has been good | |
20 | * since this bit was last read; it is 0 when the battery is dead and system | |
21 | * power has been off. | |
22 | * | |
23 | * Avoid setting the RTC clock within 2 seconds of the day rollover that | |
24 | * starts a new month or enters daylight saving time. | |
7eda085c KZ |
25 | * |
26 | * The century situation is messy: | |
ef71b8f1 SK |
27 | * |
28 | * Usually byte 50 (0x32) gives the century (in BCD, so 19 or 20 hex), but | |
29 | * IBM PS/2 has (part of) a checksum there and uses byte 55 (0x37). | |
30 | * Sometimes byte 127 (0x7f) or Bank 1, byte 0x48 gives the century. The | |
31 | * original RTC will not access any century byte; some modern versions will. | |
32 | * If a modern RTC or BIOS increments the century byte it may go from 0x19 | |
33 | * to 0x20, but in some buggy cases 0x1a is produced. | |
7eda085c | 34 | */ |
7eda085c KZ |
35 | /* |
36 | * A struct tm has int fields | |
ef71b8f1 SK |
37 | * tm_sec 0-59, 60 or 61 only for leap seconds |
38 | * tm_min 0-59 | |
39 | * tm_hour 0-23 | |
40 | * tm_mday 1-31 | |
41 | * tm_mon 0-11 | |
42 | * tm_year number of years since 1900 | |
43 | * tm_wday 0-6, 0=Sunday | |
44 | * tm_yday 0-365 | |
45 | * tm_isdst >0: yes, 0: no, <0: unknown | |
7eda085c KZ |
46 | */ |
47 | ||
5213517f | 48 | #include <errno.h> |
998f392a SK |
49 | #include <fcntl.h> |
50 | #include <stdio.h> | |
51 | #include <string.h> | |
52 | #include <time.h> | |
53 | #include <unistd.h> | |
54 | ||
55 | #include "c.h" | |
7eda085c KZ |
56 | #include "nls.h" |
57 | ||
cfb8ed19 | 58 | #if defined(__i386__) || defined(__x86_64__) |
363ce071 | 59 | # ifdef HAVE_SYS_IO_H |
ef71b8f1 | 60 | # include <sys/io.h> |
363ce071 | 61 | # elif defined(HAVE_ASM_IO_H) |
ef71b8f1 | 62 | # include <asm/io.h> /* for inb, outb */ |
363ce071 | 63 | # else |
ef71b8f1 SK |
64 | /* |
65 | * Disable cmos access; we can no longer use asm/io.h, since the kernel does | |
66 | * not export that header. | |
67 | */ | |
68 | #undef __i386__ | |
cfb8ed19 | 69 | #undef __x86_64__ |
390c72eb SK |
70 | void outb(int a __attribute__ ((__unused__)), |
71 | int b __attribute__ ((__unused__))) | |
ef71b8f1 SK |
72 | { |
73 | } | |
74 | ||
390c72eb | 75 | int inb(int c __attribute__ ((__unused__))) |
ef71b8f1 SK |
76 | { |
77 | return 0; | |
78 | } | |
cfb8ed19 | 79 | #endif /* __i386__ __x86_64__ */ |
363ce071 | 80 | |
ffc43748 | 81 | #elif defined(__alpha__) |
3baf5ac7 AH |
82 | # ifdef HAVE_SYS_IO_H |
83 | # include <sys/io.h> | |
84 | # else | |
ffc43748 | 85 | /* <asm/io.h> fails to compile, probably because of u8 etc */ |
ef71b8f1 SK |
86 | extern unsigned int inb(unsigned long port); |
87 | extern void outb(unsigned char b, unsigned long port); | |
3baf5ac7 AH |
88 | extern int iopl(int level); |
89 | # endif | |
7eda085c | 90 | #else |
93f90e13 | 91 | static void outb(int a __attribute__ ((__unused__)), |
390c72eb | 92 | int b __attribute__ ((__unused__))) |
ef71b8f1 SK |
93 | { |
94 | } | |
95 | ||
93f90e13 | 96 | static int inb(int c __attribute__ ((__unused__))) |
ef71b8f1 SK |
97 | { |
98 | return 0; | |
99 | } | |
100 | #endif /* __alpha__ */ | |
7eda085c | 101 | |
c7f75390 | 102 | #include "hwclock.h" |
7eda085c KZ |
103 | |
104 | #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) | |
105 | #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) | |
106 | ||
63cccae4 KZ |
107 | /* |
108 | * The epoch. | |
109 | * | |
ef71b8f1 SK |
110 | * Unix uses 1900 as epoch for a struct tm, and 1970 for a time_t. But what |
111 | * was written to CMOS? | |
112 | * | |
113 | * Digital DECstations use 1928 - this is on a mips or alpha Digital Unix | |
114 | * uses 1952, e.g. on AXPpxi33. Windows NT uses 1980. The ARC console | |
115 | * expects to boot Windows NT and uses 1980. (But a Ruffian uses 1900, just | |
116 | * like SRM.) It is reported that ALPHA_PRE_V1_2_SRM_CONSOLE uses 1958. | |
63cccae4 | 117 | */ |
7eda085c | 118 | #define TM_EPOCH 1900 |
c07ebfa1 | 119 | int cmos_epoch = 1900; |
7eda085c | 120 | |
ef71b8f1 SK |
121 | /* |
122 | * Martin Ostermann writes: | |
123 | * | |
124 | * The problem with the Jensen is twofold: First, it has the clock at a | |
455fe9a0 | 125 | * different address. Secondly, it has a distinction between "local" and |
ef71b8f1 SK |
126 | * normal bus addresses. The local ones pertain to the hardware integrated |
127 | * into the chipset, like serial/parallel ports and of course, the RTC. | |
128 | * Those need to be addressed differently. This is handled fine in the | |
129 | * kernel, and it's not a problem, since this usually gets totally optimized | |
130 | * by the compile. But the i/o routines of (g)libc lack this support so far. | |
131 | * The result of this is, that the old clock program worked only on the | |
132 | * Jensen when USE_DEV_PORT was defined, but not with the normal inb/outb | |
133 | * functions. | |
7eda085c KZ |
134 | */ |
135 | int use_dev_port = 0; /* 1 for Jensen */ | |
136 | int dev_port_fd; | |
137 | unsigned short clock_ctl_addr = 0x70; /* 0x170 for Jensen */ | |
ef71b8f1 | 138 | unsigned short clock_data_addr = 0x71; /* 0x171 for Jensen */ |
7eda085c KZ |
139 | |
140 | int century_byte = 0; /* 0: don't access a century byte | |
ef71b8f1 SK |
141 | * 50 (0x32): usual PC value |
142 | * 55 (0x37): PS/2 | |
143 | */ | |
7eda085c KZ |
144 | |
145 | #ifdef __alpha__ | |
146 | int funkyTOY = 0; /* 1 for PC164/LX164/SX164 type alpha */ | |
147 | #endif | |
148 | ||
149 | #ifdef __alpha | |
150 | ||
ef71b8f1 | 151 | static int is_in_cpuinfo(char *fmt, char *str) |
7eda085c | 152 | { |
ef71b8f1 SK |
153 | FILE *cpuinfo; |
154 | char field[256]; | |
155 | char format[256]; | |
156 | int found = 0; | |
157 | ||
158 | sprintf(format, "%s : %s", fmt, "%255s"); | |
159 | ||
ec3d3e67 AH |
160 | cpuinfo = fopen("/proc/cpuinfo", "r"); |
161 | if (cpuinfo) { | |
162 | do { | |
ef71b8f1 SK |
163 | if (fscanf(cpuinfo, format, field) == 1) { |
164 | if (strncmp(field, str, strlen(str)) == 0) | |
165 | found = 1; | |
166 | break; | |
167 | } | |
ec3d3e67 | 168 | } while (fgets(field, 256, cpuinfo)); |
ef71b8f1 | 169 | fclose(cpuinfo); |
7eda085c | 170 | } |
ef71b8f1 | 171 | return found; |
7eda085c KZ |
172 | } |
173 | ||
ef71b8f1 SK |
174 | /* |
175 | * Set cmos_epoch, either from user options, or by asking the kernel, or by | |
176 | * looking at /proc/cpu_info | |
177 | */ | |
178 | void set_cmos_epoch(int ARCconsole, int SRM) | |
179 | { | |
180 | unsigned long epoch; | |
22853e4a | 181 | |
ef71b8f1 SK |
182 | /* Believe the user */ |
183 | if (epoch_option != -1) { | |
184 | cmos_epoch = epoch_option; | |
185 | return; | |
186 | } | |
7eda085c | 187 | |
ef71b8f1 SK |
188 | if (ARCconsole) |
189 | cmos_epoch = 1980; | |
7eda085c | 190 | |
ef71b8f1 SK |
191 | if (ARCconsole || SRM) |
192 | return; | |
7eda085c | 193 | |
465e9973 | 194 | #ifdef __linux__ |
ef71b8f1 SK |
195 | /* |
196 | * If we can ask the kernel, we don't need guessing from | |
197 | * /proc/cpuinfo | |
198 | */ | |
199 | if (get_epoch_rtc(&epoch, 1) == 0) { | |
200 | cmos_epoch = epoch; | |
201 | return; | |
202 | } | |
465e9973 | 203 | #endif |
7eda085c | 204 | |
ef71b8f1 SK |
205 | /* |
206 | * The kernel source today says: read the year. | |
207 | * | |
208 | * If it is in 0-19 then the epoch is 2000. | |
209 | * If it is in 20-47 then the epoch is 1980. | |
210 | * If it is in 48-69 then the epoch is 1952. | |
211 | * If it is in 70-99 then the epoch is 1928. | |
212 | * | |
213 | * Otherwise the epoch is 1900. | |
214 | * TODO: Clearly, this must be changed before 2019. | |
215 | */ | |
216 | /* | |
217 | * See whether we are dealing with SRM or MILO, as they have | |
218 | * different "epoch" ideas. | |
219 | */ | |
220 | if (is_in_cpuinfo("system serial number", "MILO")) { | |
221 | ARCconsole = 1; | |
222 | if (debug) | |
223 | printf(_("booted from MILO\n")); | |
224 | } | |
7eda085c | 225 | |
ef71b8f1 SK |
226 | /* |
227 | * See whether we are dealing with a RUFFIAN aka Alpha PC-164 UX (or | |
228 | * BX), as they have REALLY different TOY (TimeOfYear) format: BCD, | |
229 | * and not an ARC-style epoch. BCD is detected dynamically, but we | |
230 | * must NOT adjust like ARC. | |
231 | */ | |
232 | if (ARCconsole && is_in_cpuinfo("system type", "Ruffian")) { | |
233 | ARCconsole = 0; | |
234 | if (debug) | |
235 | printf(_("Ruffian BCD clock\n")); | |
236 | } | |
237 | ||
238 | if (ARCconsole) | |
239 | cmos_epoch = 1980; | |
7eda085c | 240 | } |
7eda085c | 241 | |
ef71b8f1 SK |
242 | void set_cmos_access(int Jensen, int funky_toy) |
243 | { | |
244 | ||
245 | /* | |
246 | * See whether we're dealing with a Jensen---it has a weird I/O | |
247 | * system. DEC was just learning how to build Alpha PCs. | |
248 | */ | |
249 | if (Jensen || is_in_cpuinfo("system type", "Jensen")) { | |
250 | use_dev_port = 1; | |
251 | clock_ctl_addr = 0x170; | |
252 | clock_data_addr = 0x171; | |
253 | if (debug) | |
254 | printf(_("clockport adjusted to 0x%x\n"), | |
255 | clock_ctl_addr); | |
256 | } | |
257 | ||
258 | /* | |
259 | * See whether we are dealing with PC164/LX164/SX164, as they have a | |
260 | * TOY that must be accessed differently to work correctly. | |
261 | */ | |
262 | /* Nautilus stuff reported by Neoklis Kyriazis */ | |
263 | if (funky_toy || | |
264 | is_in_cpuinfo("system variation", "PC164") || | |
265 | is_in_cpuinfo("system variation", "LX164") || | |
266 | is_in_cpuinfo("system variation", "SX164") || | |
267 | is_in_cpuinfo("system type", "Nautilus")) { | |
268 | funkyTOY = 1; | |
269 | if (debug) | |
270 | printf(_("funky TOY!\n")); | |
271 | } | |
272 | } | |
273 | #endif /* __alpha */ | |
7eda085c | 274 | |
433c8bea | 275 | #if __alpha__ |
7eda085c | 276 | /* |
ef71b8f1 SK |
277 | * The Alpha doesn't allow user-level code to disable interrupts (for good |
278 | * reasons). Instead, we ensure atomic operation by performing the operation | |
279 | * and checking whether the high 32 bits of the cycle counter changed. If | |
280 | * they did, a context switch must have occurred and we redo the operation. | |
281 | * As long as the operation is reasonably short, it will complete | |
282 | * atomically, eventually. | |
7eda085c | 283 | */ |
7eda085c | 284 | static unsigned long |
ef71b8f1 | 285 | atomic(const char *name, unsigned long (*op) (unsigned long), unsigned long arg) |
7eda085c | 286 | { |
ef71b8f1 SK |
287 | unsigned long ts1, ts2, n, v; |
288 | ||
289 | for (n = 0; n < 1000; ++n) { | |
290 | asm volatile ("rpcc %0":"r=" (ts1)); | |
291 | v = (*op) (arg); | |
292 | asm volatile ("rpcc %0":"r=" (ts2)); | |
293 | ||
294 | if ((ts1 ^ ts2) >> 32 == 0) { | |
295 | return v; | |
296 | } | |
297 | } | |
111c05d3 SK |
298 | errx(EXIT_FAILURE, _("atomic %s failed for 1000 iterations!"), |
299 | name); | |
7eda085c | 300 | } |
7eda085c KZ |
301 | #else |
302 | ||
303 | /* | |
ef71b8f1 | 304 | * Hmmh, this isn't very atomic. Maybe we should force an error instead? |
433c8bea | 305 | * |
ef71b8f1 | 306 | * TODO: optimize the access to CMOS by mlockall(MCL_CURRENT) and SCHED_FIFO |
7eda085c KZ |
307 | */ |
308 | static unsigned long | |
390c72eb SK |
309 | atomic(const char *name __attribute__ ((__unused__)), |
310 | unsigned long (*op) (unsigned long), | |
311 | unsigned long arg) | |
7eda085c | 312 | { |
ef71b8f1 | 313 | return (*op) (arg); |
7eda085c KZ |
314 | } |
315 | ||
316 | #endif | |
317 | ||
ef71b8f1 | 318 | static inline unsigned long cmos_read(unsigned long reg) |
7eda085c | 319 | { |
ef71b8f1 SK |
320 | if (use_dev_port) { |
321 | unsigned char v = reg | 0x80; | |
322 | lseek(dev_port_fd, clock_ctl_addr, 0); | |
323 | if (write(dev_port_fd, &v, 1) == -1 && debug) | |
41a8ff08 | 324 | warn(_("cmos_read(): write to control address %X failed"), |
960cf573 | 325 | clock_ctl_addr); |
ef71b8f1 SK |
326 | lseek(dev_port_fd, clock_data_addr, 0); |
327 | if (read(dev_port_fd, &v, 1) == -1 && debug) | |
548696c4 | 328 | warn(_("cmos_read(): read from data address %X failed"), |
960cf573 | 329 | clock_data_addr); |
ef71b8f1 SK |
330 | return v; |
331 | } else { | |
332 | /* | |
333 | * We only want to read CMOS data, but unfortunately writing | |
334 | * to bit 7 disables (1) or enables (0) NMI; since this bit | |
335 | * is read-only we have to guess the old status. Various | |
336 | * docs suggest that one should disable NMI while | |
337 | * reading/writing CMOS data, and enable it again | |
338 | * afterwards. This would yield the sequence | |
339 | * | |
340 | * outb (reg | 0x80, 0x70); | |
341 | * val = inb(0x71); | |
342 | * outb (0x0d, 0x70); // 0x0d: random read-only location | |
343 | * | |
344 | * Other docs state that "any write to 0x70 should be | |
9e930041 | 345 | * followed by an action to 0x71 or the RTC will be left in |
455fe9a0 | 346 | * an unknown state". Most docs say that it doesn't matter at |
ef71b8f1 SK |
347 | * all what one does. |
348 | */ | |
349 | /* | |
350 | * bit 0x80: disable NMI while reading - should we? Let us | |
351 | * follow the kernel and not disable. Called only with 0 <= | |
352 | * reg < 128 | |
353 | */ | |
354 | outb(reg, clock_ctl_addr); | |
355 | return inb(clock_data_addr); | |
356 | } | |
7eda085c KZ |
357 | } |
358 | ||
ef71b8f1 | 359 | static inline unsigned long cmos_write(unsigned long reg, unsigned long val) |
7eda085c | 360 | { |
ef71b8f1 SK |
361 | if (use_dev_port) { |
362 | unsigned char v = reg | 0x80; | |
363 | lseek(dev_port_fd, clock_ctl_addr, 0); | |
364 | if (write(dev_port_fd, &v, 1) == -1 && debug) | |
41a8ff08 | 365 | warn(_("cmos_write(): write to control address %X failed"), |
960cf573 | 366 | clock_ctl_addr); |
ef71b8f1 SK |
367 | v = (val & 0xff); |
368 | lseek(dev_port_fd, clock_data_addr, 0); | |
369 | if (write(dev_port_fd, &v, 1) == -1 && debug) | |
41a8ff08 | 370 | warn(_("cmos_write(): write to data address %X failed"), |
960cf573 | 371 | clock_data_addr); |
ef71b8f1 SK |
372 | } else { |
373 | outb(reg, clock_ctl_addr); | |
374 | outb(val, clock_data_addr); | |
375 | } | |
376 | return 0; | |
7eda085c KZ |
377 | } |
378 | ||
48d7b13a | 379 | static unsigned long cmos_set_time(unsigned long arg) |
7eda085c | 380 | { |
ef71b8f1 SK |
381 | unsigned char save_control, save_freq_select, pmbit = 0; |
382 | struct tm tm = *(struct tm *)arg; | |
383 | unsigned int century; | |
7eda085c KZ |
384 | |
385 | /* | |
386 | * CMOS byte 10 (clock status register A) has 3 bitfields: | |
387 | * bit 7: 1 if data invalid, update in progress (read-only bit) | |
388 | * (this is raised 224 us before the actual update starts) | |
389 | * 6-4 select base frequency | |
390 | * 010: 32768 Hz time base (default) | |
391 | * 111: reset | |
392 | * all other combinations are manufacturer-dependent | |
393 | * (e.g.: DS1287: 010 = start oscillator, anything else = stop) | |
394 | * 3-0 rate selection bits for interrupt | |
395 | * 0000 none (may stop RTC) | |
396 | * 0001, 0010 give same frequency as 1000, 1001 | |
397 | * 0011 122 microseconds (minimum, 8192 Hz) | |
398 | * .... each increase by 1 halves the frequency, doubles the period | |
399 | * 1111 500 milliseconds (maximum, 2 Hz) | |
400 | * 0110 976.562 microseconds (default 1024 Hz) | |
401 | */ | |
ef71b8f1 SK |
402 | save_control = cmos_read(11); /* tell the clock it's being set */ |
403 | cmos_write(11, (save_control | 0x80)); | |
404 | save_freq_select = cmos_read(10); /* stop and reset prescaler */ | |
405 | cmos_write(10, (save_freq_select | 0x70)); | |
406 | ||
407 | tm.tm_year += TM_EPOCH; | |
408 | century = tm.tm_year / 100; | |
409 | tm.tm_year -= cmos_epoch; | |
410 | tm.tm_year %= 100; | |
411 | tm.tm_mon += 1; | |
412 | tm.tm_wday += 1; | |
413 | ||
414 | if (!(save_control & 0x02)) { /* 12hr mode; the default is 24hr mode */ | |
415 | if (tm.tm_hour == 0) | |
416 | tm.tm_hour = 24; | |
417 | if (tm.tm_hour > 12) { | |
418 | tm.tm_hour -= 12; | |
419 | pmbit = 0x80; | |
420 | } | |
421 | } | |
422 | ||
423 | if (!(save_control & 0x04)) { /* BCD mode - the default */ | |
424 | BIN_TO_BCD(tm.tm_sec); | |
425 | BIN_TO_BCD(tm.tm_min); | |
426 | BIN_TO_BCD(tm.tm_hour); | |
427 | BIN_TO_BCD(tm.tm_wday); | |
428 | BIN_TO_BCD(tm.tm_mday); | |
429 | BIN_TO_BCD(tm.tm_mon); | |
430 | BIN_TO_BCD(tm.tm_year); | |
431 | BIN_TO_BCD(century); | |
432 | } | |
7eda085c | 433 | |
ef71b8f1 SK |
434 | cmos_write(0, tm.tm_sec); |
435 | cmos_write(2, tm.tm_min); | |
436 | cmos_write(4, tm.tm_hour | pmbit); | |
437 | cmos_write(6, tm.tm_wday); | |
438 | cmos_write(7, tm.tm_mday); | |
439 | cmos_write(8, tm.tm_mon); | |
440 | cmos_write(9, tm.tm_year); | |
441 | if (century_byte) | |
442 | cmos_write(century_byte, century); | |
443 | ||
444 | /* | |
445 | * The kernel sources, linux/arch/i386/kernel/time.c, have the | |
446 | * following comment: | |
447 | * | |
448 | * The following flags have to be released exactly in this order, | |
449 | * otherwise the DS12887 (popular MC146818A clone with integrated | |
450 | * battery and quartz) will not reset the oscillator and will not | |
451 | * update precisely 500 ms later. You won't find this mentioned in | |
452 | * the Dallas Semiconductor data sheets, but who believes data | |
453 | * sheets anyway ... -- Markus Kuhn | |
454 | */ | |
455 | cmos_write(11, save_control); | |
456 | cmos_write(10, save_freq_select); | |
457 | return 0; | |
7eda085c KZ |
458 | } |
459 | ||
ef71b8f1 SK |
460 | static int hclock_read(unsigned long reg) |
461 | { | |
7eda085c KZ |
462 | return atomic("clock read", cmos_read, (reg)); |
463 | } | |
464 | ||
ef71b8f1 SK |
465 | static void hclock_set_time(const struct tm *tm) |
466 | { | |
7eda085c KZ |
467 | atomic("set time", cmos_set_time, (unsigned long)(tm)); |
468 | } | |
469 | ||
ef71b8f1 SK |
470 | static inline int cmos_clock_busy(void) |
471 | { | |
7eda085c KZ |
472 | return |
473 | #ifdef __alpha__ | |
ef71b8f1 | 474 | /* poll bit 4 (UF) of Control Register C */ |
7eda085c KZ |
475 | funkyTOY ? (hclock_read(12) & 0x10) : |
476 | #endif | |
ef71b8f1 | 477 | /* poll bit 7 (UIP) of Control Register A */ |
7eda085c KZ |
478 | (hclock_read(10) & 0x80); |
479 | } | |
480 | ||
ef71b8f1 SK |
481 | static int synchronize_to_clock_tick_cmos(void) |
482 | { | |
483 | int i; | |
484 | ||
485 | /* | |
486 | * Wait for rise. Should be within a second, but in case something | |
487 | * weird happens, we have a limit on this loop to reduce the impact | |
488 | * of this failure. | |
489 | */ | |
490 | for (i = 0; !cmos_clock_busy(); i++) | |
491 | if (i >= 10000000) | |
492 | return 1; | |
493 | ||
494 | /* Wait for fall. Should be within 2.228 ms. */ | |
495 | for (i = 0; cmos_clock_busy(); i++) | |
496 | if (i >= 1000000) | |
497 | return 1; | |
498 | return 0; | |
7eda085c KZ |
499 | } |
500 | ||
ef71b8f1 SK |
501 | /* |
502 | * Read the hardware clock and return the current time via <tm> argument. | |
503 | * Assume we have an ISA machine and read the clock directly with CPU I/O | |
504 | * instructions. | |
505 | * | |
506 | * This function is not totally reliable. It takes a finite and | |
507 | * unpredictable amount of time to execute the code below. During that time, | |
508 | * the clock may change and we may even read an invalid value in the middle | |
509 | * of an update. We do a few checks to minimize this possibility, but only | |
510 | * the kernel can actually read the clock properly, since it can execute | |
511 | * code in a short and predictable amount of time (by turning of | |
512 | * interrupts). | |
513 | * | |
514 | * In practice, the chance of this function returning the wrong time is | |
515 | * extremely remote. | |
516 | */ | |
517 | static int read_hardware_clock_cmos(struct tm *tm) | |
518 | { | |
519 | bool got_time = FALSE; | |
520 | unsigned char status, pmbit; | |
521 | ||
522 | status = pmbit = 0; /* just for gcc */ | |
523 | ||
524 | while (!got_time) { | |
525 | /* | |
526 | * Bit 7 of Byte 10 of the Hardware Clock value is the | |
527 | * Update In Progress (UIP) bit, which is on while and 244 | |
528 | * uS before the Hardware Clock updates itself. It updates | |
529 | * the counters individually, so reading them during an | |
530 | * update would produce garbage. The update takes 2mS, so we | |
531 | * could be spinning here that long waiting for this bit to | |
532 | * turn off. | |
533 | * | |
534 | * Furthermore, it is pathologically possible for us to be | |
535 | * in this code so long that even if the UIP bit is not on | |
536 | * at first, the clock has changed while we were running. We | |
537 | * check for that too, and if it happens, we start over. | |
538 | */ | |
539 | if (!cmos_clock_busy()) { | |
540 | /* No clock update in progress, go ahead and read */ | |
541 | tm->tm_sec = hclock_read(0); | |
542 | tm->tm_min = hclock_read(2); | |
543 | tm->tm_hour = hclock_read(4); | |
544 | tm->tm_wday = hclock_read(6); | |
545 | tm->tm_mday = hclock_read(7); | |
546 | tm->tm_mon = hclock_read(8); | |
547 | tm->tm_year = hclock_read(9); | |
548 | status = hclock_read(11); | |
7eda085c | 549 | #if 0 |
ef71b8f1 SK |
550 | if (century_byte) |
551 | century = hclock_read(century_byte); | |
7eda085c | 552 | #endif |
ef71b8f1 SK |
553 | /* |
554 | * Unless the clock changed while we were reading, | |
555 | * consider this a good clock read . | |
556 | */ | |
557 | if (tm->tm_sec == hclock_read(0)) | |
558 | got_time = TRUE; | |
559 | } | |
560 | /* | |
561 | * Yes, in theory we could have been running for 60 seconds | |
562 | * and the above test wouldn't work! | |
563 | */ | |
564 | } | |
7eda085c | 565 | |
ef71b8f1 SK |
566 | if (!(status & 0x04)) { /* BCD mode - the default */ |
567 | BCD_TO_BIN(tm->tm_sec); | |
568 | BCD_TO_BIN(tm->tm_min); | |
569 | pmbit = (tm->tm_hour & 0x80); | |
570 | tm->tm_hour &= 0x7f; | |
571 | BCD_TO_BIN(tm->tm_hour); | |
572 | BCD_TO_BIN(tm->tm_wday); | |
573 | BCD_TO_BIN(tm->tm_mday); | |
574 | BCD_TO_BIN(tm->tm_mon); | |
575 | BCD_TO_BIN(tm->tm_year); | |
7eda085c | 576 | #if 0 |
ef71b8f1 | 577 | BCD_TO_BIN(century); |
7eda085c | 578 | #endif |
ef71b8f1 | 579 | } |
7eda085c | 580 | |
ef71b8f1 SK |
581 | /* |
582 | * We don't use the century byte of the Hardware Clock since we | |
583 | * don't know its address (usually 50 or 55). Here, we follow the | |
584 | * advice of the X/Open Base Working Group: "if century is not | |
585 | * specified, then values in the range [69-99] refer to years in the | |
586 | * twentieth century (1969 to 1999 inclusive), and values in the | |
587 | * range [00-68] refer to years in the twenty-first century (2000 to | |
588 | * 2068 inclusive)." | |
589 | */ | |
590 | tm->tm_wday -= 1; | |
591 | tm->tm_mon -= 1; | |
592 | tm->tm_year += (cmos_epoch - TM_EPOCH); | |
593 | if (tm->tm_year < 69) | |
594 | tm->tm_year += 100; | |
595 | if (pmbit) { | |
596 | tm->tm_hour += 12; | |
597 | if (tm->tm_hour == 24) | |
598 | tm->tm_hour = 0; | |
599 | } | |
7eda085c | 600 | |
ef71b8f1 SK |
601 | tm->tm_isdst = -1; /* don't know whether it's daylight */ |
602 | return 0; | |
603 | } | |
7eda085c | 604 | |
ef71b8f1 SK |
605 | static int set_hardware_clock_cmos(const struct tm *new_broken_time) |
606 | { | |
7eda085c | 607 | |
ef71b8f1 SK |
608 | hclock_set_time(new_broken_time); |
609 | return 0; | |
7eda085c KZ |
610 | } |
611 | ||
cfb8ed19 | 612 | #if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) |
390c72eb | 613 | # if defined(HAVE_IOPL) |
ef71b8f1 SK |
614 | static int i386_iopl(const int level) |
615 | { | |
ef71b8f1 | 616 | return iopl(level); |
390c72eb SK |
617 | } |
618 | # else | |
619 | static int i386_iopl(const int level __attribute__ ((__unused__))) | |
620 | { | |
ef71b8f1 SK |
621 | extern int ioperm(unsigned long from, unsigned long num, int turn_on); |
622 | return ioperm(clock_ctl_addr, 2, 1); | |
390c72eb SK |
623 | } |
624 | # endif | |
7eda085c | 625 | #else |
390c72eb SK |
626 | static int i386_iopl(const int level __attribute__ ((__unused__))) |
627 | { | |
ef71b8f1 | 628 | return -2; |
7eda085c | 629 | } |
390c72eb | 630 | #endif |
7eda085c | 631 | |
ef71b8f1 SK |
632 | static int get_permissions_cmos(void) |
633 | { | |
634 | int rc; | |
635 | ||
636 | if (use_dev_port) { | |
637 | if ((dev_port_fd = open("/dev/port", O_RDWR)) < 0) { | |
289dcc90 | 638 | warn(_("cannot open %s"), "/dev/port"); |
ef71b8f1 SK |
639 | rc = 1; |
640 | } else | |
641 | rc = 0; | |
642 | } else { | |
643 | rc = i386_iopl(3); | |
644 | if (rc == -2) { | |
111c05d3 | 645 | warnx(_("I failed to get permission because I didn't try.")); |
ef71b8f1 SK |
646 | } else if (rc != 0) { |
647 | rc = errno; | |
111c05d3 SK |
648 | warn(_("unable to get I/O port access: " |
649 | "the iopl(3) call failed.")); | |
ef71b8f1 | 650 | if (rc == EPERM && geteuid()) |
111c05d3 | 651 | warnx(_("Probably you need root privileges.\n")); |
ef71b8f1 SK |
652 | } |
653 | } | |
654 | return rc ? 1 : 0; | |
7eda085c KZ |
655 | } |
656 | ||
657 | static struct clock_ops cmos = { | |
b2d97db8 | 658 | N_("Using direct I/O instructions to ISA clock."), |
7eda085c KZ |
659 | get_permissions_cmos, |
660 | read_hardware_clock_cmos, | |
661 | set_hardware_clock_cmos, | |
662 | synchronize_to_clock_tick_cmos, | |
663 | }; | |
664 | ||
ef71b8f1 SK |
665 | /* |
666 | * return &cmos if cmos clock present, NULL otherwise choose this | |
667 | * construction to avoid gcc messages about unused variables | |
668 | */ | |
669 | struct clock_ops *probe_for_cmos_clock(void) | |
670 | { | |
671 | int have_cmos = | |
cfb8ed19 | 672 | #if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) |
7eda085c KZ |
673 | TRUE; |
674 | #else | |
675 | FALSE; | |
676 | #endif | |
ef71b8f1 | 677 | return have_cmos ? &cmos : NULL; |
7eda085c | 678 | } |