FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/clock.c
1 /*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz and Don Ahn.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * from: @(#)clock.c 7.2 (Berkeley) 5/12/91
37 * $FreeBSD: src/sys/i386/isa/clock.c,v 1.72.2.5 1999/09/05 08:12:28 peter Exp $
38 */
39
40 /*
41 * Routines to handle clock hardware.
42 */
43
44 /*
45 * inittodr, settodr and support routines written
46 * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
47 *
48 * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94
49 */
50
51 #include "opt_clock.h"
52 #include "opt_cpu.h"
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/time.h>
57 #include <sys/kernel.h>
58 #include <sys/sysctl.h>
59
60 #include <machine/clock.h>
61 #ifdef CLK_CALIBRATION_LOOP
62 #include <machine/cons.h>
63 #endif
64 #include <machine/cpu.h>
65 #include <machine/frame.h>
66
67 #include <i386/isa/icu.h>
68 #include <i386/isa/isa.h>
69 #include <i386/isa/isa_device.h>
70 #include <i386/isa/rtc.h>
71 #include <i386/isa/timerreg.h>
72
73 /*
74 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
75 * can use a simple formula for leap years.
76 */
77 #define LEAPYEAR(y) ((u_int)(y) % 4 == 0)
78 #define DAYSPERYEAR (31+28+31+30+31+30+31+31+30+31+30+31)
79
80 #define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
81
82 /*
83 * Time in timer cycles that it takes for microtime() to disable interrupts
84 * and latch the count. microtime() currently uses "cli; outb ..." so it
85 * normally takes less than 2 timer cycles. Add a few for cache misses.
86 * Add a few more to allow for latency in bogus calls to microtime() with
87 * interrupts already disabled.
88 */
89 #define TIMER0_LATCH_COUNT 20
90
91 /*
92 * Maximum frequency that we are willing to allow for timer0. Must be
93 * low enough to guarantee that the timer interrupt handler returns
94 * before the next timer interrupt. Must result in a lower TIMER_DIV
95 * value than TIMER0_LATCH_COUNT so that we don't have to worry about
96 * underflow in the calculation of timer0_overflow_threshold.
97 */
98 #define TIMER0_MAX_FREQ 20000
99
100 int adjkerntz; /* local offset from GMT in seconds */
101 int disable_rtc_set; /* disable resettodr() if != 0 */
102 u_int idelayed;
103 #if defined(I586_CPU) || defined(I686_CPU)
104 u_int i586_ctr_bias;
105 u_int i586_ctr_comultiplier;
106 u_int i586_ctr_freq;
107 u_int i586_ctr_multiplier;
108 #endif
109 int statclock_disable;
110 u_int stat_imask = SWI_CLOCK_MASK;
111 #ifdef TIMER_FREQ
112 u_int timer_freq = TIMER_FREQ;
113 #else
114 u_int timer_freq = 1193182;
115 #endif
116 int timer0_max_count;
117 u_int timer0_overflow_threshold;
118 u_int timer0_prescaler_count;
119 int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
120
121 static int beeping = 0;
122 static u_int clk_imask = HWI_MASK | SWI_MASK;
123 static const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
124 static u_int hardclock_max_count;
125 /*
126 * XXX new_function and timer_func should not handle clockframes, but
127 * timer_func currently needs to hold hardclock to handle the
128 * timer0_state == 0 case. We should use register_intr()/unregister_intr()
129 * to switch between clkintr() and a slightly different timerintr().
130 */
131 static void (*new_function) __P((struct clockframe *frame));
132 static u_int new_rate;
133 static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
134 static u_char rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
135
136 /* Values for timerX_state: */
137 #define RELEASED 0
138 #define RELEASE_PENDING 1
139 #define ACQUIRED 2
140 #define ACQUIRE_PENDING 3
141
142 static u_char timer0_state;
143 static u_char timer2_state;
144 static void (*timer_func) __P((struct clockframe *frame)) = hardclock;
145
146 #if defined(I586_CPU) || defined(I686_CPU)
147 static void set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
148 #endif
149 static void set_timer_freq(u_int freq, int intr_freq);
150
151 static void
152 clkintr(struct clockframe frame)
153 {
154 timer_func(&frame);
155 switch (timer0_state) {
156
157 case RELEASED:
158 setdelayed();
159 break;
160
161 case ACQUIRED:
162 if ((timer0_prescaler_count += timer0_max_count)
163 >= hardclock_max_count) {
164 hardclock(&frame);
165 setdelayed();
166 timer0_prescaler_count -= hardclock_max_count;
167 }
168 break;
169
170 case ACQUIRE_PENDING:
171 setdelayed();
172 timer0_max_count = TIMER_DIV(new_rate);
173 timer0_overflow_threshold =
174 timer0_max_count - TIMER0_LATCH_COUNT;
175 disable_intr();
176 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
177 outb(TIMER_CNTR0, timer0_max_count & 0xff);
178 outb(TIMER_CNTR0, timer0_max_count >> 8);
179 enable_intr();
180 timer0_prescaler_count = 0;
181 timer_func = new_function;
182 timer0_state = ACQUIRED;
183 break;
184
185 case RELEASE_PENDING:
186 if ((timer0_prescaler_count += timer0_max_count)
187 >= hardclock_max_count) {
188 hardclock(&frame);
189 setdelayed();
190 timer0_max_count = hardclock_max_count;
191 timer0_overflow_threshold =
192 timer0_max_count - TIMER0_LATCH_COUNT;
193 disable_intr();
194 outb(TIMER_MODE,
195 TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
196 outb(TIMER_CNTR0, timer0_max_count & 0xff);
197 outb(TIMER_CNTR0, timer0_max_count >> 8);
198 enable_intr();
199 /*
200 * See microtime.s for this magic.
201 */
202 time.tv_usec += (27465 *
203 (timer0_prescaler_count - hardclock_max_count))
204 >> 15;
205 if (time.tv_usec >= 1000000)
206 time.tv_usec -= 1000000;
207 timer0_prescaler_count = 0;
208 timer_func = hardclock;
209 timer0_state = RELEASED;
210 }
211 break;
212 }
213 }
214
215 /*
216 * The acquire and release functions must be called at ipl >= splclock().
217 */
218 int
219 acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
220 {
221 static int old_rate;
222
223 if (rate <= 0 || rate > TIMER0_MAX_FREQ)
224 return (-1);
225 switch (timer0_state) {
226
227 case RELEASED:
228 timer0_state = ACQUIRE_PENDING;
229 break;
230
231 case RELEASE_PENDING:
232 if (rate != old_rate)
233 return (-1);
234 /*
235 * The timer has been released recently, but is being
236 * re-acquired before the release completed. In this
237 * case, we simply reclaim it as if it had not been
238 * released at all.
239 */
240 timer0_state = ACQUIRED;
241 break;
242
243 default:
244 return (-1); /* busy */
245 }
246 new_function = function;
247 old_rate = new_rate = rate;
248 return (0);
249 }
250
251 int
252 acquire_timer2(int mode)
253 {
254
255 if (timer2_state != RELEASED)
256 return (-1);
257 timer2_state = ACQUIRED;
258
259 /*
260 * This access to the timer registers is as atomic as possible
261 * because it is a single instruction. We could do better if we
262 * knew the rate. Use of splclock() limits glitches to 10-100us,
263 * and this is probably good enough for timer2, so we aren't as
264 * careful with it as with timer0.
265 */
266 outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
267
268 return (0);
269 }
270
271 int
272 release_timer0()
273 {
274 switch (timer0_state) {
275
276 case ACQUIRED:
277 timer0_state = RELEASE_PENDING;
278 break;
279
280 case ACQUIRE_PENDING:
281 /* Nothing happened yet, release quickly. */
282 timer0_state = RELEASED;
283 break;
284
285 default:
286 return (-1);
287 }
288 return (0);
289 }
290
291 int
292 release_timer2()
293 {
294
295 if (timer2_state != ACQUIRED)
296 return (-1);
297 timer2_state = RELEASED;
298 outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
299 return (0);
300 }
301
302 /*
303 * This routine receives statistical clock interrupts from the RTC.
304 * As explained above, these occur at 128 interrupts per second.
305 * When profiling, we receive interrupts at a rate of 1024 Hz.
306 *
307 * This does not actually add as much overhead as it sounds, because
308 * when the statistical clock is active, the hardclock driver no longer
309 * needs to keep (inaccurate) statistics on its own. This decouples
310 * statistics gathering from scheduling interrupts.
311 *
312 * The RTC chip requires that we read status register C (RTC_INTR)
313 * to acknowledge an interrupt, before it will generate the next one.
314 * Under high interrupt load, rtcintr() can be indefinitely delayed and
315 * the clock can tick immediately after the read from RTC_INTR. In this
316 * case, the mc146818A interrupt signal will not drop for long enough
317 * to register with the 8259 PIC. If an interrupt is missed, the stat
318 * clock will halt, considerably degrading system performance. This is
319 * why we use 'while' rather than a more straightforward 'if' below.
320 * Stat clock ticks can still be lost, causing minor loss of accuracy
321 * in the statistics, but the stat clock will no longer stop.
322 */
323 static void
324 rtcintr(struct clockframe frame)
325 {
326 while (rtcin(RTC_INTR) & RTCIR_PERIOD)
327 statclock(&frame);
328 }
329
330 #include "opt_ddb.h"
331 #ifdef DDB
332 #include <ddb/ddb.h>
333
334 DB_SHOW_COMMAND(rtc, rtc)
335 {
336 printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n",
337 rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY),
338 rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC),
339 rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR));
340 }
341 #endif /* DDB */
342
343 static int
344 getit(void)
345 {
346 u_long ef;
347 int high, low;
348
349 ef = read_eflags();
350 disable_intr();
351
352 /* Select timer0 and latch counter value. */
353 outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
354
355 low = inb(TIMER_CNTR0);
356 high = inb(TIMER_CNTR0);
357
358 write_eflags(ef);
359 return ((high << 8) | low);
360 }
361
362 /*
363 * Wait "n" microseconds.
364 * Relies on timer 1 counting down from (timer_freq / hz)
365 * Note: timer had better have been programmed before this is first used!
366 */
367 void
368 DELAY(int n)
369 {
370 int delta, prev_tick, tick, ticks_left;
371
372 #ifdef DELAYDEBUG
373 int getit_calls = 1;
374 int n1;
375 static int state = 0;
376
377 if (state == 0) {
378 state = 1;
379 for (n1 = 1; n1 <= 10000000; n1 *= 10)
380 DELAY(n1);
381 state = 2;
382 }
383 if (state == 1)
384 printf("DELAY(%d)...", n);
385 #endif
386 /*
387 * Guard against the timer being uninitialized if we are called
388 * early for console i/o.
389 */
390 if (timer0_max_count == 0)
391 set_timer_freq(timer_freq, hz);
392
393 /*
394 * Read the counter first, so that the rest of the setup overhead is
395 * counted. Guess the initial overhead is 20 usec (on most systems it
396 * takes about 1.5 usec for each of the i/o's in getit(). The loop
397 * takes about 6 usec on a 486/33 and 13 usec on a 386/20. The
398 * multiplications and divisions to scale the count take a while).
399 */
400 prev_tick = getit();
401 n -= 0; /* XXX actually guess no initial overhead */
402 /*
403 * Calculate (n * (timer_freq / 1e6)) without using floating point
404 * and without any avoidable overflows.
405 */
406 if (n <= 0)
407 ticks_left = 0;
408 else if (n < 256)
409 /*
410 * Use fixed point to avoid a slow division by 1000000.
411 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
412 * 2^15 is the first power of 2 that gives exact results
413 * for n between 0 and 256.
414 */
415 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
416 else
417 /*
418 * Don't bother using fixed point, although gcc-2.7.2
419 * generates particularly poor code for the long long
420 * division, since even the slow way will complete long
421 * before the delay is up (unless we're interrupted).
422 */
423 ticks_left = ((u_int)n * (long long)timer_freq + 999999)
424 / 1000000;
425
426 while (ticks_left > 0) {
427 tick = getit();
428 #ifdef DELAYDEBUG
429 ++getit_calls;
430 #endif
431 delta = prev_tick - tick;
432 prev_tick = tick;
433 if (delta < 0) {
434 delta += timer0_max_count;
435 /*
436 * Guard against timer0_max_count being wrong.
437 * This shouldn't happen in normal operation,
438 * but it may happen if set_timer_freq() is
439 * traced.
440 */
441 if (delta < 0)
442 delta = 0;
443 }
444 ticks_left -= delta;
445 }
446 #ifdef DELAYDEBUG
447 if (state == 1)
448 printf(" %d calls to getit() at %d usec each\n",
449 getit_calls, (n + 5) / getit_calls);
450 #endif
451 }
452
453 static void
454 sysbeepstop(void *chan)
455 {
456 outb(IO_PPI, inb(IO_PPI)&0xFC); /* disable counter2 output to speaker */
457 release_timer2();
458 beeping = 0;
459 }
460
461 int
462 sysbeep(int pitch, int period)
463 {
464 int x = splclock();
465
466 if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
467 if (!beeping) {
468 /* Something else owns it. */
469 splx(x);
470 return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
471 }
472 disable_intr();
473 outb(TIMER_CNTR2, pitch);
474 outb(TIMER_CNTR2, (pitch>>8));
475 enable_intr();
476 if (!beeping) {
477 /* enable counter2 output to speaker */
478 outb(IO_PPI, inb(IO_PPI) | 3);
479 beeping = period;
480 timeout(sysbeepstop, (void *)NULL, period);
481 }
482 splx(x);
483 return (0);
484 }
485
486 /*
487 * RTC support routines
488 */
489
490 int
491 rtcin(reg)
492 int reg;
493 {
494 u_char val;
495
496 outb(IO_RTC, reg);
497 inb(0x84);
498 val = inb(IO_RTC + 1);
499 inb(0x84);
500 return (val);
501 }
502
503 static __inline void
504 writertc(u_char reg, u_char val)
505 {
506 outb(IO_RTC, reg);
507 outb(IO_RTC + 1, val);
508 }
509
510 static __inline int
511 readrtc(int port)
512 {
513 return(bcd2bin(rtcin(port)));
514 }
515
516 static u_int
517 calibrate_clocks(void)
518 {
519 u_int count, prev_count, tot_count;
520 int sec, start_sec, timeout;
521
522 if (bootverbose)
523 printf("Calibrating clock(s) ... ");
524 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
525 goto fail;
526 timeout = 100000000;
527
528 /* Read the mc146818A seconds counter. */
529 for (;;) {
530 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
531 sec = rtcin(RTC_SEC);
532 break;
533 }
534 if (--timeout == 0)
535 goto fail;
536 }
537
538 /* Wait for the mC146818A seconds counter to change. */
539 start_sec = sec;
540 for (;;) {
541 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
542 sec = rtcin(RTC_SEC);
543 if (sec != start_sec)
544 break;
545 }
546 if (--timeout == 0)
547 goto fail;
548 }
549
550 /* Start keeping track of the i8254 counter. */
551 prev_count = getit();
552 if (prev_count == 0 || prev_count > timer0_max_count)
553 goto fail;
554 tot_count = 0;
555
556 #if defined(I586_CPU) || defined(I686_CPU)
557 if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)
558 wrmsr(0x10, 0LL); /* XXX 0x10 is the MSR for the TSC */
559 #endif
560
561 /*
562 * Wait for the mc146818A seconds counter to change. Read the i8254
563 * counter for each iteration since this is convenient and only
564 * costs a few usec of inaccuracy. The timing of the final reads
565 * of the counters almost matches the timing of the initial reads,
566 * so the main cause of inaccuracy is the varying latency from
567 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the
568 * rtcin(RTC_SEC) that returns a changed seconds count. The
569 * maximum inaccuracy from this cause is < 10 usec on 486's.
570 */
571 start_sec = sec;
572 for (;;) {
573 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP))
574 sec = rtcin(RTC_SEC);
575 count = getit();
576 if (count == 0 || count > timer0_max_count)
577 goto fail;
578 if (count > prev_count)
579 tot_count += prev_count - (count - timer0_max_count);
580 else
581 tot_count += prev_count - count;
582 prev_count = count;
583 if (sec != start_sec)
584 break;
585 if (--timeout == 0)
586 goto fail;
587 }
588
589 #if defined(I586_CPU) || defined(I686_CPU)
590 /*
591 * Read the cpu cycle counter. The timing considerations are
592 * similar to those for the i8254 clock.
593 */
594 if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
595 set_i586_ctr_freq((u_int)rdtsc(), tot_count);
596 if (bootverbose)
597 printf("i586 clock: %u Hz, ", i586_ctr_freq);
598 }
599 #endif
600
601 if (bootverbose)
602 printf("i8254 clock: %u Hz\n", tot_count);
603 return (tot_count);
604
605 fail:
606 if (bootverbose)
607 printf("failed, using default i8254 clock of %u Hz\n",
608 timer_freq);
609 return (timer_freq);
610 }
611
612 static void
613 set_timer_freq(u_int freq, int intr_freq)
614 {
615 u_long ef;
616
617 ef = read_eflags();
618 disable_intr();
619 timer_freq = freq;
620 timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
621 timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
622 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
623 outb(TIMER_CNTR0, timer0_max_count & 0xff);
624 outb(TIMER_CNTR0, timer0_max_count >> 8);
625 write_eflags(ef);
626 }
627
628 /*
629 * Initialize 8253 timer 0 early so that it can be used in DELAY().
630 * XXX initialization of other timers is unintentionally left blank.
631 */
632 void
633 startrtclock()
634 {
635 u_int delta, freq;
636
637 writertc(RTC_STATUSA, rtc_statusa);
638 writertc(RTC_STATUSB, RTCSB_24HR);
639
640 set_timer_freq(timer_freq, hz);
641 freq = calibrate_clocks();
642 #ifdef CLK_CALIBRATION_LOOP
643 if (bootverbose) {
644 printf(
645 "Press a key on the console to abort clock calibration\n");
646 while (cncheckc() == -1)
647 calibrate_clocks();
648 }
649 #endif
650
651 /*
652 * Use the calibrated i8254 frequency if it seems reasonable.
653 * Otherwise use the default, and don't use the calibrated i586
654 * frequency.
655 */
656 delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
657 if (delta < timer_freq / 100) {
658 #ifndef CLK_USE_I8254_CALIBRATION
659 if (bootverbose)
660 printf(
661 "CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
662 freq = timer_freq;
663 #endif
664 timer_freq = freq;
665 } else {
666 if (bootverbose)
667 printf(
668 "%d Hz differs from default of %d Hz by more than 1%%\n",
669 freq, timer_freq);
670 #if defined(I586_CPU) || defined(I686_CPU)
671 i586_ctr_freq = 0;
672 #endif
673 }
674
675 set_timer_freq(timer_freq, hz);
676
677 #if defined(I586_CPU) || defined(I686_CPU)
678 #ifndef CLK_USE_I586_CALIBRATION
679 if (i586_ctr_freq != 0) {
680 if (bootverbose)
681 printf(
682 "CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
683 i586_ctr_freq = 0;
684 }
685 #endif
686 if (i586_ctr_freq == 0 &&
687 (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) {
688 /*
689 * Calibration of the i586 clock relative to the mc146818A
690 * clock failed. Do a less accurate calibration relative
691 * to the i8254 clock.
692 */
693 wrmsr(0x10, 0LL); /* XXX */
694 DELAY(1000000);
695 set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
696 #ifdef CLK_USE_I586_CALIBRATION
697 if (bootverbose)
698 printf("i586 clock: %u Hz\n", i586_ctr_freq);
699 #endif
700 }
701 #endif
702 }
703
704 /*
705 * Initialize the time of day register, based on the time base which is, e.g.
706 * from a filesystem.
707 */
708 void
709 inittodr(time_t base)
710 {
711 unsigned long sec, days;
712 int yd;
713 int year, month;
714 int y, m, s;
715
716 s = splclock();
717 time.tv_sec = base;
718 time.tv_usec = 0;
719 splx(s);
720
721 /* Look if we have a RTC present and the time is valid */
722 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
723 goto wrong_time;
724
725 /* wait for time update to complete */
726 /* If RTCSA_TUP is zero, we have at least 244us before next update */
727 while (rtcin(RTC_STATUSA) & RTCSA_TUP);
728
729 days = 0;
730 #ifdef USE_RTC_CENTURY
731 year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
732 #else
733 year = readrtc(RTC_YEAR) + 1900;
734 if (year < 1970)
735 year += 100;
736 #endif
737 if (year < 1970)
738 goto wrong_time;
739 month = readrtc(RTC_MONTH);
740 for (m = 1; m < month; m++)
741 days += daysinmonth[m-1];
742 if ((month > 2) && LEAPYEAR(year))
743 days ++;
744 days += readrtc(RTC_DAY) - 1;
745 yd = days;
746 for (y = 1970; y < year; y++)
747 days += DAYSPERYEAR + LEAPYEAR(y);
748 sec = ((( days * 24 +
749 readrtc(RTC_HRS)) * 60 +
750 readrtc(RTC_MIN)) * 60 +
751 readrtc(RTC_SEC));
752 /* sec now contains the number of seconds, since Jan 1 1970,
753 in the local time zone */
754
755 sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
756
757 s = splclock();
758 time.tv_sec = sec;
759 splx(s);
760 return;
761
762 wrong_time:
763 printf("Invalid time in real time clock.\n");
764 printf("Check and reset the date immediately!\n");
765 }
766
767 /*
768 * Write system time back to RTC
769 */
770 void
771 resettodr()
772 {
773 unsigned long tm;
774 int y, m, s;
775
776 if (disable_rtc_set)
777 return;
778
779 s = splclock();
780 tm = time.tv_sec;
781 splx(s);
782
783 /* Disable RTC updates and interrupts. */
784 writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
785
786 /* Calculate local time to put in RTC */
787
788 tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
789
790 writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60; /* Write back Seconds */
791 writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */
792 writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */
793
794 /* We have now the days since 01-01-1970 in tm */
795 writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */
796 for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
797 tm >= m;
798 y++, m = DAYSPERYEAR + LEAPYEAR(y))
799 tm -= m;
800
801 /* Now we have the years in y and the day-of-the-year in tm */
802 writertc(RTC_YEAR, bin2bcd(y%100)); /* Write back Year */
803 #ifdef USE_RTC_CENTURY
804 writertc(RTC_CENTURY, bin2bcd(y/100)); /* ... and Century */
805 #endif
806 for (m = 0; ; m++) {
807 int ml;
808
809 ml = daysinmonth[m];
810 if (m == 1 && LEAPYEAR(y))
811 ml++;
812 if (tm < ml)
813 break;
814 tm -= ml;
815 }
816
817 writertc(RTC_MONTH, bin2bcd(m + 1)); /* Write back Month */
818 writertc(RTC_DAY, bin2bcd(tm + 1)); /* Write back Month Day */
819
820 /* Reenable RTC updates and interrupts. */
821 writertc(RTC_STATUSB, rtc_statusb);
822 }
823
824 /*
825 * Start both clocks running.
826 */
827 void
828 cpu_initclocks()
829 {
830 int diag;
831
832 if (statclock_disable) {
833 /*
834 * The stat interrupt mask is different without the
835 * statistics clock. Also, don't set the interrupt
836 * flag which would normally cause the RTC to generate
837 * interrupts.
838 */
839 stat_imask = HWI_MASK | SWI_MASK;
840 rtc_statusb = RTCSB_24HR;
841 } else {
842 /* Setting stathz to nonzero early helps avoid races. */
843 stathz = RTC_NOPROFRATE;
844 profhz = RTC_PROFRATE;
845 }
846
847 /* Finish initializing 8253 timer 0. */
848 register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
849 /* XXX */ (inthand2_t *)clkintr, &clk_imask,
850 /* unit */ 0);
851 INTREN(IRQ0);
852 #if defined(I586_CPU) || defined(I686_CPU)
853 /*
854 * Finish setting up anti-jitter measures.
855 */
856 if (i586_ctr_freq != 0)
857 i586_ctr_bias = rdtsc();
858 #endif
859
860 /* Initialize RTC. */
861 writertc(RTC_STATUSA, rtc_statusa);
862 writertc(RTC_STATUSB, RTCSB_24HR);
863
864 /* Don't bother enabling the statistics clock. */
865 if (statclock_disable)
866 return;
867 diag = rtcin(RTC_DIAG);
868 if (diag != 0)
869 printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
870 register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
871 /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
872 /* unit */ 0);
873 INTREN(IRQ8);
874 writertc(RTC_STATUSB, rtc_statusb);
875 }
876
877 void
878 setstatclockrate(int newhz)
879 {
880 if (newhz == RTC_PROFRATE)
881 rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
882 else
883 rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
884 writertc(RTC_STATUSA, rtc_statusa);
885 }
886
887 static int
888 sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
889 {
890 int error;
891 u_int freq;
892
893 /*
894 * Use `i8254' instead of `timer' in external names because `timer'
895 * is is too generic. Should use it everywhere.
896 */
897 freq = timer_freq;
898 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
899 if (error == 0 && req->newptr != NULL) {
900 if (timer0_state != 0)
901 return (EBUSY); /* too much trouble to handle */
902 set_timer_freq(freq, hz);
903 #if defined(I586_CPU) || defined(I686_CPU)
904 set_i586_ctr_freq(i586_ctr_freq, timer_freq);
905 #endif
906 }
907 return (error);
908 }
909
910 SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
911 0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
912
913 #if defined(I586_CPU) || defined(I686_CPU)
914 static void
915 set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq)
916 {
917 u_int comultiplier, multiplier;
918 u_long ef;
919
920 if (i586_freq == 0) {
921 i586_ctr_freq = i586_freq;
922 return;
923 }
924 comultiplier = ((unsigned long long)i586_freq
925 << I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq;
926 multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq;
927 ef = read_eflags();
928 disable_intr();
929 i586_ctr_freq = i586_freq;
930 i586_ctr_comultiplier = comultiplier;
931 i586_ctr_multiplier = multiplier;
932 write_eflags(ef);
933 }
934
935 static int
936 sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
937 {
938 int error;
939 u_int freq;
940
941 if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
942 return (EOPNOTSUPP);
943 freq = i586_ctr_freq;
944 error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
945 if (error == 0 && req->newptr != NULL)
946 set_i586_ctr_freq(freq, timer_freq);
947 return (error);
948 }
949
950 SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW,
951 0, sizeof(u_int), sysctl_machdep_i586_freq, "I", "");
952 #endif /* defined(I586_CPU) || defined(I686_CPU) */
Cache object: 3f7bd126770300cef9e7daf8b6d39cbc
|