]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/isa/clock.c
This commit was generated by cvs2svn to compensate for changes in r169942,
[FreeBSD/FreeBSD.git] / 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  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *      from: @(#)clock.c       7.2 (Berkeley) 5/12/91
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 /*
39  * Routines to handle clock hardware.
40  */
41
42 /*
43  * inittodr, settodr and support routines written
44  * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
45  *
46  * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94
47  */
48
49 #include "opt_apic.h"
50 #include "opt_clock.h"
51 #include "opt_isa.h"
52 #include "opt_mca.h"
53 #include "opt_xbox.h"
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/bus.h>
58 #include <sys/clock.h>
59 #include <sys/lock.h>
60 #include <sys/kdb.h>
61 #include <sys/mutex.h>
62 #include <sys/proc.h>
63 #include <sys/time.h>
64 #include <sys/timetc.h>
65 #include <sys/kernel.h>
66 #include <sys/limits.h>
67 #include <sys/module.h>
68 #include <sys/sched.h>
69 #include <sys/sysctl.h>
70 #include <sys/cons.h>
71 #include <sys/power.h>
72
73 #include <machine/clock.h>
74 #include <machine/cpu.h>
75 #include <machine/cputypes.h>
76 #include <machine/frame.h>
77 #include <machine/intr_machdep.h>
78 #include <machine/md_var.h>
79 #include <machine/psl.h>
80 #ifdef DEV_APIC
81 #include <machine/apicvar.h>
82 #endif
83 #include <machine/specialreg.h>
84 #include <machine/ppireg.h>
85 #include <machine/timerreg.h>
86
87 #include <isa/rtc.h>
88 #ifdef DEV_ISA
89 #include <isa/isareg.h>
90 #include <isa/isavar.h>
91 #endif
92
93 #ifdef DEV_MCA
94 #include <i386/bios/mca_machdep.h>
95 #endif
96
97 #define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
98
99 int     clkintr_pending;
100 int     pscnt = 1;
101 int     psdiv = 1;
102 int     statclock_disable;
103 #ifndef TIMER_FREQ
104 #define TIMER_FREQ   1193182
105 #endif
106 u_int   timer_freq = TIMER_FREQ;
107 int     timer0_max_count;
108 int     timer0_real_max_count;
109 #define RTC_LOCK        mtx_lock_spin(&clock_lock)
110 #define RTC_UNLOCK      mtx_unlock_spin(&clock_lock)
111
112 static  int     beeping = 0;
113 static  struct mtx clock_lock;
114 static  struct intsrc *i8254_intsrc;
115 static  u_int32_t i8254_lastcount;
116 static  u_int32_t i8254_offset;
117 static  int     (*i8254_pending)(struct intsrc *);
118 static  int     i8254_ticked;
119 static  int     using_lapic_timer;
120 static  int     rtc_reg = -1;
121 static  u_char  rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
122 static  u_char  rtc_statusb = RTCSB_24HR;
123
124 /* Values for timerX_state: */
125 #define RELEASED        0
126 #define RELEASE_PENDING 1
127 #define ACQUIRED        2
128 #define ACQUIRE_PENDING 3
129
130 static  u_char  timer2_state;
131
132 static  unsigned i8254_get_timecount(struct timecounter *tc);
133 static  unsigned i8254_simple_get_timecount(struct timecounter *tc);
134 static  void    set_timer_freq(u_int freq, int intr_freq);
135
136 static struct timecounter i8254_timecounter = {
137         i8254_get_timecount,    /* get_timecount */
138         0,                      /* no poll_pps */
139         ~0u,                    /* counter_mask */
140         0,                      /* frequency */
141         "i8254",                /* name */
142         0                       /* quality */
143 };
144
145 static int
146 clkintr(struct trapframe *frame)
147 {
148
149         if (timecounter->tc_get_timecount == i8254_get_timecount) {
150                 mtx_lock_spin(&clock_lock);
151                 if (i8254_ticked)
152                         i8254_ticked = 0;
153                 else {
154                         i8254_offset += timer0_max_count;
155                         i8254_lastcount = 0;
156                 }
157                 clkintr_pending = 0;
158                 mtx_unlock_spin(&clock_lock);
159         }
160         KASSERT(!using_lapic_timer, ("clk interrupt enabled with lapic timer"));
161         hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
162 #ifdef DEV_MCA
163         /* Reset clock interrupt by asserting bit 7 of port 0x61 */
164         if (MCA_system)
165                 outb(0x61, inb(0x61) | 0x80);
166 #endif
167         return (FILTER_HANDLED);
168 }
169
170 int
171 acquire_timer2(int mode)
172 {
173
174         if (timer2_state != RELEASED)
175                 return (-1);
176         timer2_state = ACQUIRED;
177
178         /*
179          * This access to the timer registers is as atomic as possible
180          * because it is a single instruction.  We could do better if we
181          * knew the rate.  Use of splclock() limits glitches to 10-100us,
182          * and this is probably good enough for timer2, so we aren't as
183          * careful with it as with timer0.
184          */
185         outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
186
187         return (0);
188 }
189
190 int
191 release_timer2()
192 {
193
194         if (timer2_state != ACQUIRED)
195                 return (-1);
196         timer2_state = RELEASED;
197         outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
198         return (0);
199 }
200
201 /*
202  * This routine receives statistical clock interrupts from the RTC.
203  * As explained above, these occur at 128 interrupts per second.
204  * When profiling, we receive interrupts at a rate of 1024 Hz.
205  *
206  * This does not actually add as much overhead as it sounds, because
207  * when the statistical clock is active, the hardclock driver no longer
208  * needs to keep (inaccurate) statistics on its own.  This decouples
209  * statistics gathering from scheduling interrupts.
210  *
211  * The RTC chip requires that we read status register C (RTC_INTR)
212  * to acknowledge an interrupt, before it will generate the next one.
213  * Under high interrupt load, rtcintr() can be indefinitely delayed and
214  * the clock can tick immediately after the read from RTC_INTR.  In this
215  * case, the mc146818A interrupt signal will not drop for long enough
216  * to register with the 8259 PIC.  If an interrupt is missed, the stat
217  * clock will halt, considerably degrading system performance.  This is
218  * why we use 'while' rather than a more straightforward 'if' below.
219  * Stat clock ticks can still be lost, causing minor loss of accuracy
220  * in the statistics, but the stat clock will no longer stop.
221  */
222 static int
223 rtcintr(struct trapframe *frame)
224 {
225
226         while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
227                 if (profprocs != 0) {
228                         if (--pscnt == 0)
229                                 pscnt = psdiv;
230                         profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
231                 }
232                 if (pscnt == psdiv)
233                         statclock(TRAPF_USERMODE(frame));
234         }
235         return (FILTER_HANDLED);
236 }
237
238 #include "opt_ddb.h"
239 #ifdef DDB
240 #include <ddb/ddb.h>
241
242 DB_SHOW_COMMAND(rtc, rtc)
243 {
244         printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n",
245                rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY),
246                rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC),
247                rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR));
248 }
249 #endif /* DDB */
250
251 static int
252 getit(void)
253 {
254         int high, low;
255
256         mtx_lock_spin(&clock_lock);
257
258         /* Select timer0 and latch counter value. */
259         outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
260
261         low = inb(TIMER_CNTR0);
262         high = inb(TIMER_CNTR0);
263
264         mtx_unlock_spin(&clock_lock);
265         return ((high << 8) | low);
266 }
267
268 /*
269  * Wait "n" microseconds.
270  * Relies on timer 1 counting down from (timer_freq / hz)
271  * Note: timer had better have been programmed before this is first used!
272  */
273 void
274 DELAY(int n)
275 {
276         int delta, prev_tick, tick, ticks_left;
277
278 #ifdef DELAYDEBUG
279         int getit_calls = 1;
280         int n1;
281         static int state = 0;
282 #endif
283
284         if (tsc_freq != 0 && !tsc_is_broken) {
285                 uint64_t start, end, now;
286
287                 sched_pin();
288                 start = rdtsc();
289                 end = start + (tsc_freq * n) / 1000000;
290                 do {
291                         now = rdtsc();
292                 } while (now < end || (now > start && end < start));
293                 sched_unpin();
294                 return;
295         }
296 #ifdef DELAYDEBUG
297         if (state == 0) {
298                 state = 1;
299                 for (n1 = 1; n1 <= 10000000; n1 *= 10)
300                         DELAY(n1);
301                 state = 2;
302         }
303         if (state == 1)
304                 printf("DELAY(%d)...", n);
305 #endif
306         /*
307          * Read the counter first, so that the rest of the setup overhead is
308          * counted.  Guess the initial overhead is 20 usec (on most systems it
309          * takes about 1.5 usec for each of the i/o's in getit().  The loop
310          * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
311          * multiplications and divisions to scale the count take a while).
312          *
313          * However, if ddb is active then use a fake counter since reading
314          * the i8254 counter involves acquiring a lock.  ddb must not do
315          * locking for many reasons, but it calls here for at least atkbd
316          * input.
317          */
318 #ifdef KDB
319         if (kdb_active)
320                 prev_tick = 1;
321         else
322 #endif
323                 prev_tick = getit();
324         n -= 0;                 /* XXX actually guess no initial overhead */
325         /*
326          * Calculate (n * (timer_freq / 1e6)) without using floating point
327          * and without any avoidable overflows.
328          */
329         if (n <= 0)
330                 ticks_left = 0;
331         else if (n < 256)
332                 /*
333                  * Use fixed point to avoid a slow division by 1000000.
334                  * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
335                  * 2^15 is the first power of 2 that gives exact results
336                  * for n between 0 and 256.
337                  */
338                 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
339         else
340                 /*
341                  * Don't bother using fixed point, although gcc-2.7.2
342                  * generates particularly poor code for the long long
343                  * division, since even the slow way will complete long
344                  * before the delay is up (unless we're interrupted).
345                  */
346                 ticks_left = ((u_int)n * (long long)timer_freq + 999999)
347                              / 1000000;
348
349         while (ticks_left > 0) {
350 #ifdef KDB
351                 if (kdb_active) {
352                         inb(0x84);
353                         tick = prev_tick - 1;
354                         if (tick <= 0)
355                                 tick = timer0_max_count;
356                 } else
357 #endif
358                         tick = getit();
359 #ifdef DELAYDEBUG
360                 ++getit_calls;
361 #endif
362                 delta = prev_tick - tick;
363                 prev_tick = tick;
364                 if (delta < 0) {
365                         delta += timer0_max_count;
366                         /*
367                          * Guard against timer0_max_count being wrong.
368                          * This shouldn't happen in normal operation,
369                          * but it may happen if set_timer_freq() is
370                          * traced.
371                          */
372                         if (delta < 0)
373                                 delta = 0;
374                 }
375                 ticks_left -= delta;
376         }
377 #ifdef DELAYDEBUG
378         if (state == 1)
379                 printf(" %d calls to getit() at %d usec each\n",
380                        getit_calls, (n + 5) / getit_calls);
381 #endif
382 }
383
384 static void
385 sysbeepstop(void *chan)
386 {
387         ppi_spkr_off();         /* disable counter2 output to speaker */
388         timer_spkr_release();
389         beeping = 0;
390 }
391
392 int
393 sysbeep(int pitch, int period)
394 {
395         int x = splclock();
396
397         if (timer_spkr_acquire())
398                 if (!beeping) {
399                         /* Something else owns it. */
400                         splx(x);
401                         return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
402                 }
403         mtx_lock_spin(&clock_lock);
404         spkr_set_pitch(pitch);
405         mtx_unlock_spin(&clock_lock);
406         if (!beeping) {
407                 /* enable counter2 output to speaker */
408                 ppi_spkr_on();
409                 beeping = period;
410                 timeout(sysbeepstop, (void *)NULL, period);
411         }
412         splx(x);
413         return (0);
414 }
415
416 /*
417  * RTC support routines
418  */
419
420 int
421 rtcin(reg)
422         int reg;
423 {
424         u_char val;
425
426         RTC_LOCK;
427         if (rtc_reg != reg) {
428                 inb(0x84);
429                 outb(IO_RTC, reg);
430                 rtc_reg = reg;
431                 inb(0x84);
432         }
433         val = inb(IO_RTC + 1);
434         RTC_UNLOCK;
435         return (val);
436 }
437
438 static void
439 writertc(int reg, u_char val)
440 {
441
442         RTC_LOCK;
443         if (rtc_reg != reg) {
444                 inb(0x84);
445                 outb(IO_RTC, reg);
446                 rtc_reg = reg;
447                 inb(0x84);
448         }
449         outb(IO_RTC + 1, val);
450         inb(0x84);
451         RTC_UNLOCK;
452 }
453
454 static __inline int
455 readrtc(int port)
456 {
457         return(bcd2bin(rtcin(port)));
458 }
459
460 static u_int
461 calibrate_clocks(void)
462 {
463         u_int count, prev_count, tot_count;
464         int sec, start_sec, timeout;
465
466         if (bootverbose)
467                 printf("Calibrating clock(s) ... ");
468         if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
469                 goto fail;
470         timeout = 100000000;
471
472         /* Read the mc146818A seconds counter. */
473         for (;;) {
474                 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
475                         sec = rtcin(RTC_SEC);
476                         break;
477                 }
478                 if (--timeout == 0)
479                         goto fail;
480         }
481
482         /* Wait for the mC146818A seconds counter to change. */
483         start_sec = sec;
484         for (;;) {
485                 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
486                         sec = rtcin(RTC_SEC);
487                         if (sec != start_sec)
488                                 break;
489                 }
490                 if (--timeout == 0)
491                         goto fail;
492         }
493
494         /* Start keeping track of the i8254 counter. */
495         prev_count = getit();
496         if (prev_count == 0 || prev_count > timer0_max_count)
497                 goto fail;
498         tot_count = 0;
499
500         /*
501          * Wait for the mc146818A seconds counter to change.  Read the i8254
502          * counter for each iteration since this is convenient and only
503          * costs a few usec of inaccuracy. The timing of the final reads
504          * of the counters almost matches the timing of the initial reads,
505          * so the main cause of inaccuracy is the varying latency from 
506          * inside getit() or rtcin(RTC_STATUSA) to the beginning of the
507          * rtcin(RTC_SEC) that returns a changed seconds count.  The
508          * maximum inaccuracy from this cause is < 10 usec on 486's.
509          */
510         start_sec = sec;
511         for (;;) {
512                 if (!(rtcin(RTC_STATUSA) & RTCSA_TUP))
513                         sec = rtcin(RTC_SEC);
514                 count = getit();
515                 if (count == 0 || count > timer0_max_count)
516                         goto fail;
517                 if (count > prev_count)
518                         tot_count += prev_count - (count - timer0_max_count);
519                 else
520                         tot_count += prev_count - count;
521                 prev_count = count;
522                 if (sec != start_sec)
523                         break;
524                 if (--timeout == 0)
525                         goto fail;
526         }
527
528         if (bootverbose) {
529                 printf("i8254 clock: %u Hz\n", tot_count);
530         }
531         return (tot_count);
532
533 fail:
534         if (bootverbose)
535                 printf("failed, using default i8254 clock of %u Hz\n",
536                        timer_freq);
537         return (timer_freq);
538 }
539
540 static void
541 set_timer_freq(u_int freq, int intr_freq)
542 {
543         int new_timer0_real_max_count;
544
545         i8254_timecounter.tc_frequency = freq;
546         mtx_lock_spin(&clock_lock);
547         timer_freq = freq;
548         if (using_lapic_timer)
549                 new_timer0_real_max_count = 0x10000;
550         else
551                 new_timer0_real_max_count = TIMER_DIV(intr_freq);
552         if (new_timer0_real_max_count != timer0_real_max_count) {
553                 timer0_real_max_count = new_timer0_real_max_count;
554                 if (timer0_real_max_count == 0x10000)
555                         timer0_max_count = 0xffff;
556                 else
557                         timer0_max_count = timer0_real_max_count;
558                 outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
559                 outb(TIMER_CNTR0, timer0_real_max_count & 0xff);
560                 outb(TIMER_CNTR0, timer0_real_max_count >> 8);
561         }
562         mtx_unlock_spin(&clock_lock);
563 }
564
565 static void
566 i8254_restore(void)
567 {
568
569         mtx_lock_spin(&clock_lock);
570         outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
571         outb(TIMER_CNTR0, timer0_real_max_count & 0xff);
572         outb(TIMER_CNTR0, timer0_real_max_count >> 8);
573         mtx_unlock_spin(&clock_lock);
574 }
575
576 static void
577 rtc_restore(void)
578 {
579
580         /* Restore all of the RTC's "status" (actually, control) registers. */
581         /* XXX locking is needed for RTC access. */
582         rtc_reg = -1;
583         writertc(RTC_STATUSB, RTCSB_24HR);
584         writertc(RTC_STATUSA, rtc_statusa);
585         writertc(RTC_STATUSB, rtc_statusb);
586         rtcin(RTC_INTR);
587 }
588
589 /*
590  * Restore all the timers non-atomically (XXX: should be atomically).
591  *
592  * This function is called from pmtimer_resume() to restore all the timers.
593  * This should not be necessary, but there are broken laptops that do not
594  * restore all the timers on resume.
595  */
596 void
597 timer_restore(void)
598 {
599
600         i8254_restore();                /* restore timer_freq and hz */
601         rtc_restore();                  /* reenable RTC interrupts */
602 }
603
604 /* This is separate from startrtclock() so that it can be called early. */
605 void
606 i8254_init(void)
607 {
608
609         mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE);
610         set_timer_freq(timer_freq, hz);
611 }
612
613 void
614 startrtclock()
615 {
616         u_int delta, freq;
617
618         writertc(RTC_STATUSA, rtc_statusa);
619         writertc(RTC_STATUSB, RTCSB_24HR);
620
621         freq = calibrate_clocks();
622 #ifdef CLK_CALIBRATION_LOOP
623         if (bootverbose) {
624                 printf(
625                 "Press a key on the console to abort clock calibration\n");
626                 while (cncheckc() == -1)
627                         calibrate_clocks();
628         }
629 #endif
630
631         /*
632          * Use the calibrated i8254 frequency if it seems reasonable.
633          * Otherwise use the default, and don't use the calibrated i586
634          * frequency.
635          */
636         delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
637         if (delta < timer_freq / 100) {
638 #ifndef CLK_USE_I8254_CALIBRATION
639                 if (bootverbose)
640                         printf(
641 "CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
642                 freq = timer_freq;
643 #endif
644                 timer_freq = freq;
645         } else {
646                 if (bootverbose)
647                         printf(
648                     "%d Hz differs from default of %d Hz by more than 1%%\n",
649                                freq, timer_freq);
650         }
651
652         set_timer_freq(timer_freq, hz);
653         tc_init(&i8254_timecounter);
654
655         init_TSC();
656 }
657
658 /*
659  * Initialize the time of day register, based on the time base which is, e.g.
660  * from a filesystem.
661  */
662 void
663 inittodr(time_t base)
664 {
665         int s;
666         struct timespec ts;
667         struct clocktime ct;
668
669         if (base) {
670                 s = splclock();
671                 ts.tv_sec = base;
672                 ts.tv_nsec = 0;
673                 tc_setclock(&ts);
674                 splx(s);
675         }
676
677         /* Look if we have a RTC present and the time is valid */
678         if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) {
679                 printf("Invalid time in real time clock.\n");
680                 printf("Check and reset the date immediately!\n");
681                 return;
682         }
683
684         /* wait for time update to complete */
685         /* If RTCSA_TUP is zero, we have at least 244us before next update */
686         s = splhigh();
687         while (rtcin(RTC_STATUSA) & RTCSA_TUP) {
688                 splx(s);
689                 s = splhigh();
690         }
691         ct.nsec = 0;
692         ct.sec = readrtc(RTC_SEC);
693         ct.min = readrtc(RTC_MIN);
694         ct.hour = readrtc(RTC_HRS);
695         ct.day = readrtc(RTC_DAY);
696         ct.dow = readrtc(RTC_WDAY) - 1;
697         ct.mon = readrtc(RTC_MONTH);
698         ct.year = readrtc(RTC_YEAR);
699 #ifdef USE_RTC_CENTURY
700         ct.year += readrtc(RTC_CENTURY) * 100;
701 #else
702         ct.year += 2000;
703 #endif
704         clock_ct_to_ts(&ct, &ts);
705         ts.tv_sec += utc_offset();
706         tc_setclock(&ts);
707 }
708
709 /*
710  * Write system time back to RTC
711  */
712 void
713 resettodr()
714 {
715         struct timespec ts;
716         struct clocktime ct;
717
718         if (disable_rtc_set)
719                 return;
720
721         getnanotime(&ts);
722         ts.tv_sec -= utc_offset();
723         clock_ts_to_ct(&ts, &ct);
724
725         /* Disable RTC updates and interrupts. */
726         writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
727
728         writertc(RTC_SEC, bin2bcd(ct.sec));             /* Write back Seconds */
729         writertc(RTC_MIN, bin2bcd(ct.min));             /* Write back Minutes */
730         writertc(RTC_HRS, bin2bcd(ct.hour));            /* Write back Hours   */
731
732         writertc(RTC_WDAY, ct.dow + 1);                 /* Write back Weekday */
733         writertc(RTC_DAY, bin2bcd(ct.day));             /* Write back Day */
734         writertc(RTC_MONTH, bin2bcd(ct.mon));           /* Write back Month   */
735         writertc(RTC_YEAR, bin2bcd(ct.year % 100));     /* Write back Year    */
736 #ifdef USE_RTC_CENTURY
737         writertc(RTC_CENTURY, bin2bcd(ct.year / 100));  /* ... and Century    */
738 #endif
739
740         /* Reenable RTC updates and interrupts. */
741         writertc(RTC_STATUSB, rtc_statusb);
742         rtcin(RTC_INTR);
743 }
744
745
746 /*
747  * Start both clocks running.
748  */
749 void
750 cpu_initclocks()
751 {
752         int diag;
753
754 #ifdef DEV_APIC
755         using_lapic_timer = lapic_setup_clock();
756 #endif
757         /*
758          * If we aren't using the local APIC timer to drive the kernel
759          * clocks, setup the interrupt handler for the 8254 timer 0 so
760          * that it can drive hardclock().  Otherwise, change the 8254
761          * timecounter to user a simpler algorithm.
762          */
763         if (!using_lapic_timer) {
764                 intr_add_handler("clk", 0, (driver_filter_t *)clkintr, NULL,
765                     NULL, INTR_TYPE_CLK, NULL);
766                 i8254_intsrc = intr_lookup_source(0);
767                 if (i8254_intsrc != NULL)
768                         i8254_pending =
769                             i8254_intsrc->is_pic->pic_source_pending;
770         } else {
771                 i8254_timecounter.tc_get_timecount =
772                     i8254_simple_get_timecount;
773                 i8254_timecounter.tc_counter_mask = 0xffff;
774                 set_timer_freq(timer_freq, hz);
775         }
776
777         /* Initialize RTC. */
778         writertc(RTC_STATUSA, rtc_statusa);
779         writertc(RTC_STATUSB, RTCSB_24HR);
780
781         /*
782          * If the separate statistics clock hasn't been explicility disabled
783          * and we aren't already using the local APIC timer to drive the
784          * kernel clocks, then setup the RTC to periodically interrupt to
785          * drive statclock() and profclock().
786          */
787         if (!statclock_disable && !using_lapic_timer) {
788                 diag = rtcin(RTC_DIAG);
789                 if (diag != 0)
790                         printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
791
792                 /* Setting stathz to nonzero early helps avoid races. */
793                 stathz = RTC_NOPROFRATE;
794                 profhz = RTC_PROFRATE;
795
796                 /* Enable periodic interrupts from the RTC. */
797                 rtc_statusb |= RTCSB_PINTR;
798                 intr_add_handler("rtc", 8, (driver_filter_t *)rtcintr, NULL, NULL,
799                     INTR_TYPE_CLK, NULL);
800
801                 writertc(RTC_STATUSB, rtc_statusb);
802                 rtcin(RTC_INTR);
803         }
804
805         init_TSC_tc();
806 }
807
808 void
809 cpu_startprofclock(void)
810 {
811
812         if (using_lapic_timer)
813                 return;
814         rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
815         writertc(RTC_STATUSA, rtc_statusa);
816         psdiv = pscnt = psratio;
817 }
818
819 void
820 cpu_stopprofclock(void)
821 {
822
823         if (using_lapic_timer)
824                 return;
825         rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
826         writertc(RTC_STATUSA, rtc_statusa);
827         psdiv = pscnt = 1;
828 }
829
830 static int
831 sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
832 {
833         int error;
834         u_int freq;
835
836         /*
837          * Use `i8254' instead of `timer' in external names because `timer'
838          * is is too generic.  Should use it everywhere.
839          */
840         freq = timer_freq;
841         error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
842         if (error == 0 && req->newptr != NULL)
843                 set_timer_freq(freq, hz);
844         return (error);
845 }
846
847 SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
848     0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU", "");
849
850 static unsigned
851 i8254_simple_get_timecount(struct timecounter *tc)
852 {
853
854         return (timer0_max_count - getit());
855 }
856
857 static unsigned
858 i8254_get_timecount(struct timecounter *tc)
859 {
860         u_int count;
861         u_int high, low;
862         u_int eflags;
863
864         eflags = read_eflags();
865         mtx_lock_spin(&clock_lock);
866
867         /* Select timer0 and latch counter value. */
868         outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
869
870         low = inb(TIMER_CNTR0);
871         high = inb(TIMER_CNTR0);
872         count = timer0_max_count - ((high << 8) | low);
873         if (count < i8254_lastcount ||
874             (!i8254_ticked && (clkintr_pending ||
875             ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
876             i8254_pending != NULL && i8254_pending(i8254_intsrc))))) {
877                 i8254_ticked = 1;
878                 i8254_offset += timer0_max_count;
879         }
880         i8254_lastcount = count;
881         count += i8254_offset;
882         mtx_unlock_spin(&clock_lock);
883         return (count);
884 }
885
886 #ifdef DEV_ISA
887 /*
888  * Attach to the ISA PnP descriptors for the timer and realtime clock.
889  */
890 static struct isa_pnp_id attimer_ids[] = {
891         { 0x0001d041 /* PNP0100 */, "AT timer" },
892         { 0x000bd041 /* PNP0B00 */, "AT realtime clock" },
893         { 0 }
894 };
895
896 static int
897 attimer_probe(device_t dev)
898 {
899         int result;
900         
901         if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids)) <= 0)
902                 device_quiet(dev);
903         return(result);
904 }
905
906 static int
907 attimer_attach(device_t dev)
908 {
909         return(0);
910 }
911
912 static device_method_t attimer_methods[] = {
913         /* Device interface */
914         DEVMETHOD(device_probe,         attimer_probe),
915         DEVMETHOD(device_attach,        attimer_attach),
916         DEVMETHOD(device_detach,        bus_generic_detach),
917         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
918         DEVMETHOD(device_suspend,       bus_generic_suspend),   /* XXX stop statclock? */
919         DEVMETHOD(device_resume,        bus_generic_resume),    /* XXX restart statclock? */
920         { 0, 0 }
921 };
922
923 static driver_t attimer_driver = {
924         "attimer",
925         attimer_methods,
926         1,              /* no softc */
927 };
928
929 static devclass_t attimer_devclass;
930
931 DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
932 DRIVER_MODULE(attimer, acpi, attimer_driver, attimer_devclass, 0, 0);
933 #endif /* DEV_ISA */