]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/x86/isa/clock.c
Remove pc98 support completely.
[FreeBSD/FreeBSD.git] / sys / x86 / isa / clock.c
1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org>
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * William Jolitz and Don Ahn.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *      from: @(#)clock.c       7.2 (Berkeley) 5/12/91
34  */
35
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38
39 /*
40  * Routines to handle clock hardware.
41  */
42
43 #include "opt_clock.h"
44 #include "opt_isa.h"
45 #include "opt_mca.h"
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/bus.h>
50 #include <sys/lock.h>
51 #include <sys/kdb.h>
52 #include <sys/mutex.h>
53 #include <sys/proc.h>
54 #include <sys/kernel.h>
55 #include <sys/module.h>
56 #include <sys/rman.h>
57 #include <sys/sched.h>
58 #include <sys/smp.h>
59 #include <sys/sysctl.h>
60 #include <sys/timeet.h>
61 #include <sys/timetc.h>
62
63 #include <machine/clock.h>
64 #include <machine/cpu.h>
65 #include <machine/intr_machdep.h>
66 #include <machine/ppireg.h>
67 #include <machine/timerreg.h>
68 #include <x86/init.h>
69
70 #include <isa/rtc.h>
71 #ifdef DEV_ISA
72 #include <isa/isareg.h>
73 #include <isa/isavar.h>
74 #endif
75
76 #ifdef DEV_MCA
77 #include <i386/bios/mca_machdep.h>
78 #endif
79
80 int     clkintr_pending;
81 #ifndef TIMER_FREQ
82 #define TIMER_FREQ   1193182
83 #endif
84 u_int   i8254_freq = TIMER_FREQ;
85 TUNABLE_INT("hw.i8254.freq", &i8254_freq);
86 int     i8254_max_count;
87 static int i8254_timecounter = 1;
88
89 struct mtx clock_lock;
90 static  struct intsrc *i8254_intsrc;
91 static  uint16_t i8254_lastcount;
92 static  uint16_t i8254_offset;
93 static  int     (*i8254_pending)(struct intsrc *);
94 static  int     i8254_ticked;
95
96 struct attimer_softc {
97         int intr_en;
98         int port_rid, intr_rid;
99         struct resource *port_res;
100         struct resource *intr_res;
101         void *intr_handler;
102         struct timecounter tc;
103         struct eventtimer et;
104         int             mode;
105 #define MODE_STOP       0
106 #define MODE_PERIODIC   1
107 #define MODE_ONESHOT    2
108         uint32_t        period;
109 };
110 static struct attimer_softc *attimer_sc = NULL;
111
112 static int timer0_period = -2;
113 static int timer0_mode = 0xffff;
114 static int timer0_last = 0xffff;
115
116 /* Values for timerX_state: */
117 #define RELEASED        0
118 #define RELEASE_PENDING 1
119 #define ACQUIRED        2
120 #define ACQUIRE_PENDING 3
121
122 static  u_char  timer2_state;
123
124 static  unsigned i8254_get_timecount(struct timecounter *tc);
125 static  void    set_i8254_freq(int mode, uint32_t period);
126
127 void
128 clock_init(void)
129 {
130         /* Init the clock lock */
131         mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_NOPROFILE);
132         /* Init the clock in order to use DELAY */
133         init_ops.early_clock_source_init();
134 }
135
136 static int
137 clkintr(void *arg)
138 {
139         struct attimer_softc *sc = (struct attimer_softc *)arg;
140
141         if (i8254_timecounter && sc->period != 0) {
142                 mtx_lock_spin(&clock_lock);
143                 if (i8254_ticked)
144                         i8254_ticked = 0;
145                 else {
146                         i8254_offset += i8254_max_count;
147                         i8254_lastcount = 0;
148                 }
149                 clkintr_pending = 0;
150                 mtx_unlock_spin(&clock_lock);
151         }
152
153         if (sc->et.et_active && sc->mode != MODE_STOP)
154                 sc->et.et_event_cb(&sc->et, sc->et.et_arg);
155
156 #ifdef DEV_MCA
157         /* Reset clock interrupt by asserting bit 7 of port 0x61 */
158         if (MCA_system)
159                 outb(0x61, inb(0x61) | 0x80);
160 #endif
161         return (FILTER_HANDLED);
162 }
163
164 int
165 timer_spkr_acquire(void)
166 {
167         int mode;
168
169         mode = TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT;
170
171         if (timer2_state != RELEASED)
172                 return (-1);
173         timer2_state = ACQUIRED;
174
175         /*
176          * This access to the timer registers is as atomic as possible
177          * because it is a single instruction.  We could do better if we
178          * knew the rate.  Use of splclock() limits glitches to 10-100us,
179          * and this is probably good enough for timer2, so we aren't as
180          * careful with it as with timer0.
181          */
182         outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
183
184         ppi_spkr_on();          /* enable counter2 output to speaker */
185         return (0);
186 }
187
188 int
189 timer_spkr_release(void)
190 {
191
192         if (timer2_state != ACQUIRED)
193                 return (-1);
194         timer2_state = RELEASED;
195         outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
196
197         ppi_spkr_off();         /* disable counter2 output to speaker */
198         return (0);
199 }
200
201 void
202 timer_spkr_setfreq(int freq)
203 {
204
205         freq = i8254_freq / freq;
206         mtx_lock_spin(&clock_lock);
207         outb(TIMER_CNTR2, freq & 0xff);
208         outb(TIMER_CNTR2, freq >> 8);
209         mtx_unlock_spin(&clock_lock);
210 }
211
212 static int
213 getit(void)
214 {
215         int high, low;
216
217         mtx_lock_spin(&clock_lock);
218
219         /* Select timer0 and latch counter value. */
220         outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
221
222         low = inb(TIMER_CNTR0);
223         high = inb(TIMER_CNTR0);
224
225         mtx_unlock_spin(&clock_lock);
226         return ((high << 8) | low);
227 }
228
229 /*
230  * Wait "n" microseconds.
231  * Relies on timer 1 counting down from (i8254_freq / hz)
232  * Note: timer had better have been programmed before this is first used!
233  */
234 void
235 i8254_delay(int n)
236 {
237         int delta, prev_tick, tick, ticks_left;
238 #ifdef DELAYDEBUG
239         int getit_calls = 1;
240         int n1;
241         static int state = 0;
242
243         if (state == 0) {
244                 state = 1;
245                 for (n1 = 1; n1 <= 10000000; n1 *= 10)
246                         DELAY(n1);
247                 state = 2;
248         }
249         if (state == 1)
250                 printf("DELAY(%d)...", n);
251 #endif
252         /*
253          * Read the counter first, so that the rest of the setup overhead is
254          * counted.  Guess the initial overhead is 20 usec (on most systems it
255          * takes about 1.5 usec for each of the i/o's in getit().  The loop
256          * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
257          * multiplications and divisions to scale the count take a while).
258          *
259          * However, if ddb is active then use a fake counter since reading
260          * the i8254 counter involves acquiring a lock.  ddb must not do
261          * locking for many reasons, but it calls here for at least atkbd
262          * input.
263          */
264 #ifdef KDB
265         if (kdb_active)
266                 prev_tick = 1;
267         else
268 #endif
269                 prev_tick = getit();
270         n -= 0;                 /* XXX actually guess no initial overhead */
271         /*
272          * Calculate (n * (i8254_freq / 1e6)) without using floating point
273          * and without any avoidable overflows.
274          */
275         if (n <= 0)
276                 ticks_left = 0;
277         else if (n < 256)
278                 /*
279                  * Use fixed point to avoid a slow division by 1000000.
280                  * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
281                  * 2^15 is the first power of 2 that gives exact results
282                  * for n between 0 and 256.
283                  */
284                 ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
285         else
286                 /*
287                  * Don't bother using fixed point, although gcc-2.7.2
288                  * generates particularly poor code for the long long
289                  * division, since even the slow way will complete long
290                  * before the delay is up (unless we're interrupted).
291                  */
292                 ticks_left = ((u_int)n * (long long)i8254_freq + 999999)
293                              / 1000000;
294
295         while (ticks_left > 0) {
296 #ifdef KDB
297                 if (kdb_active) {
298                         inb(0x84);
299                         tick = prev_tick - 1;
300                         if (tick <= 0)
301                                 tick = i8254_max_count;
302                 } else
303 #endif
304                         tick = getit();
305 #ifdef DELAYDEBUG
306                 ++getit_calls;
307 #endif
308                 delta = prev_tick - tick;
309                 prev_tick = tick;
310                 if (delta < 0) {
311                         delta += i8254_max_count;
312                         /*
313                          * Guard against i8254_max_count being wrong.
314                          * This shouldn't happen in normal operation,
315                          * but it may happen if set_i8254_freq() is
316                          * traced.
317                          */
318                         if (delta < 0)
319                                 delta = 0;
320                 }
321                 ticks_left -= delta;
322         }
323 #ifdef DELAYDEBUG
324         if (state == 1)
325                 printf(" %d calls to getit() at %d usec each\n",
326                        getit_calls, (n + 5) / getit_calls);
327 #endif
328 }
329
330 static void
331 set_i8254_freq(int mode, uint32_t period)
332 {
333         int new_count, new_mode;
334
335         mtx_lock_spin(&clock_lock);
336         if (mode == MODE_STOP) {
337                 if (i8254_timecounter) {
338                         mode = MODE_PERIODIC;
339                         new_count = 0x10000;
340                 } else
341                         new_count = -1;
342         } else {
343                 new_count = min(((uint64_t)i8254_freq * period +
344                     0x80000000LLU) >> 32, 0x10000);
345         }
346         if (new_count == timer0_period)
347                 goto out;
348         i8254_max_count = ((new_count & ~0xffff) != 0) ? 0xffff : new_count;
349         timer0_period = (mode == MODE_PERIODIC) ? new_count : -1;
350         switch (mode) {
351         case MODE_STOP:
352                 new_mode = TIMER_SEL0 | TIMER_INTTC | TIMER_16BIT;
353                 outb(TIMER_MODE, new_mode);
354                 outb(TIMER_CNTR0, 0);
355                 outb(TIMER_CNTR0, 0);
356                 break;
357         case MODE_PERIODIC:
358                 new_mode = TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT;
359                 outb(TIMER_MODE, new_mode);
360                 outb(TIMER_CNTR0, new_count & 0xff);
361                 outb(TIMER_CNTR0, new_count >> 8);
362                 break;
363         case MODE_ONESHOT:
364                 if (new_count < 256 && timer0_last < 256) {
365                         new_mode = TIMER_SEL0 | TIMER_INTTC | TIMER_LSB;
366                         if (new_mode != timer0_mode)
367                                 outb(TIMER_MODE, new_mode);
368                         outb(TIMER_CNTR0, new_count & 0xff);
369                         break;
370                 }
371                 new_mode = TIMER_SEL0 | TIMER_INTTC | TIMER_16BIT;
372                 if (new_mode != timer0_mode)
373                         outb(TIMER_MODE, new_mode);
374                 outb(TIMER_CNTR0, new_count & 0xff);
375                 outb(TIMER_CNTR0, new_count >> 8);
376                 break;
377         default:
378                 panic("set_i8254_freq: unknown operational mode");
379         }
380         timer0_mode = new_mode;
381         timer0_last = new_count;
382 out:
383         mtx_unlock_spin(&clock_lock);
384 }
385
386 static void
387 i8254_restore(void)
388 {
389
390         timer0_period = -2;
391         timer0_mode = 0xffff;
392         timer0_last = 0xffff;
393         if (attimer_sc != NULL)
394                 set_i8254_freq(attimer_sc->mode, attimer_sc->period);
395         else
396                 set_i8254_freq(MODE_STOP, 0);
397 }
398
399 #ifndef __amd64__
400 /*
401  * Restore all the timers non-atomically (XXX: should be atomically).
402  *
403  * This function is called from pmtimer_resume() to restore all the timers.
404  * This should not be necessary, but there are broken laptops that do not
405  * restore all the timers on resume. The APM spec was at best vague on the
406  * subject.
407  * pmtimer is used only with the old APM power management, and not with
408  * acpi, which is required for amd64, so skip it in that case.
409  */
410 void
411 timer_restore(void)
412 {
413
414         i8254_restore();                /* restore i8254_freq and hz */
415         atrtc_restore();                /* reenable RTC interrupts */
416 }
417 #endif
418
419 /* This is separate from startrtclock() so that it can be called early. */
420 void
421 i8254_init(void)
422 {
423
424         set_i8254_freq(MODE_STOP, 0);
425 }
426
427 void
428 startrtclock()
429 {
430
431         init_TSC();
432 }
433
434 void
435 cpu_initclocks(void)
436 {
437 #ifdef EARLY_AP_STARTUP
438         struct thread *td;
439         int i;
440
441         td = curthread;
442         cpu_initclocks_bsp();
443         CPU_FOREACH(i) {
444                 if (i == 0)
445                         continue;
446                 thread_lock(td);
447                 sched_bind(td, i);
448                 thread_unlock(td);
449                 cpu_initclocks_ap();
450         }
451         thread_lock(td);
452         if (sched_is_bound(td))
453                 sched_unbind(td);
454         thread_unlock(td);
455 #else
456         cpu_initclocks_bsp();
457 #endif
458 }
459
460 static int
461 sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
462 {
463         int error;
464         u_int freq;
465
466         /*
467          * Use `i8254' instead of `timer' in external names because `timer'
468          * is too generic.  Should use it everywhere.
469          */
470         freq = i8254_freq;
471         error = sysctl_handle_int(oidp, &freq, 0, req);
472         if (error == 0 && req->newptr != NULL) {
473                 i8254_freq = freq;
474                 if (attimer_sc != NULL) {
475                         set_i8254_freq(attimer_sc->mode, attimer_sc->period);
476                         attimer_sc->tc.tc_frequency = freq;
477                 } else {
478                         set_i8254_freq(MODE_STOP, 0);
479                 }
480         }
481         return (error);
482 }
483
484 SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
485     0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU",
486     "i8254 timer frequency");
487
488 static unsigned
489 i8254_get_timecount(struct timecounter *tc)
490 {
491         device_t dev = (device_t)tc->tc_priv;
492         struct attimer_softc *sc = device_get_softc(dev);
493         register_t flags;
494         uint16_t count;
495         u_int high, low;
496
497         if (sc->period == 0)
498                 return (i8254_max_count - getit());
499
500 #ifdef __amd64__
501         flags = read_rflags();
502 #else
503         flags = read_eflags();
504 #endif
505         mtx_lock_spin(&clock_lock);
506
507         /* Select timer0 and latch counter value. */
508         outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
509
510         low = inb(TIMER_CNTR0);
511         high = inb(TIMER_CNTR0);
512         count = i8254_max_count - ((high << 8) | low);
513         if (count < i8254_lastcount ||
514             (!i8254_ticked && (clkintr_pending ||
515             ((count < 20 || (!(flags & PSL_I) &&
516             count < i8254_max_count / 2u)) &&
517             i8254_pending != NULL && i8254_pending(i8254_intsrc))))) {
518                 i8254_ticked = 1;
519                 i8254_offset += i8254_max_count;
520         }
521         i8254_lastcount = count;
522         count += i8254_offset;
523         mtx_unlock_spin(&clock_lock);
524         return (count);
525 }
526
527 static int
528 attimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
529 {
530         device_t dev = (device_t)et->et_priv;
531         struct attimer_softc *sc = device_get_softc(dev);
532
533         if (period != 0) {
534                 sc->mode = MODE_PERIODIC;
535                 sc->period = period;
536         } else {
537                 sc->mode = MODE_ONESHOT;
538                 sc->period = first;
539         }
540         if (!sc->intr_en) {
541                 i8254_intsrc->is_pic->pic_enable_source(i8254_intsrc);
542                 sc->intr_en = 1;
543         }
544         set_i8254_freq(sc->mode, sc->period);
545         return (0);
546 }
547
548 static int
549 attimer_stop(struct eventtimer *et)
550 {
551         device_t dev = (device_t)et->et_priv;
552         struct attimer_softc *sc = device_get_softc(dev);
553         
554         sc->mode = MODE_STOP;
555         sc->period = 0;
556         set_i8254_freq(sc->mode, sc->period);
557         return (0);
558 }
559
560 #ifdef DEV_ISA
561 /*
562  * Attach to the ISA PnP descriptors for the timer
563  */
564 static struct isa_pnp_id attimer_ids[] = {
565         { 0x0001d041 /* PNP0100 */, "AT timer" },
566         { 0 }
567 };
568
569 static int
570 attimer_probe(device_t dev)
571 {
572         int result;
573         
574         result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids);
575         /* ENOENT means no PnP-ID, device is hinted. */
576         if (result == ENOENT) {
577                 device_set_desc(dev, "AT timer");
578                 return (BUS_PROBE_LOW_PRIORITY);
579         }
580         return (result);
581 }
582
583 static int
584 attimer_attach(device_t dev)
585 {
586         struct attimer_softc *sc;
587         rman_res_t s;
588         int i;
589
590         attimer_sc = sc = device_get_softc(dev);
591         bzero(sc, sizeof(struct attimer_softc));
592         if (!(sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
593             &sc->port_rid, IO_TIMER1, IO_TIMER1 + 3, 4, RF_ACTIVE)))
594                 device_printf(dev,"Warning: Couldn't map I/O.\n");
595         i8254_intsrc = intr_lookup_source(0);
596         if (i8254_intsrc != NULL)
597                 i8254_pending = i8254_intsrc->is_pic->pic_source_pending;
598         resource_int_value(device_get_name(dev), device_get_unit(dev),
599             "timecounter", &i8254_timecounter);
600         set_i8254_freq(MODE_STOP, 0);
601         if (i8254_timecounter) {
602                 sc->tc.tc_get_timecount = i8254_get_timecount;
603                 sc->tc.tc_counter_mask = 0xffff;
604                 sc->tc.tc_frequency = i8254_freq;
605                 sc->tc.tc_name = "i8254";
606                 sc->tc.tc_quality = 0;
607                 sc->tc.tc_priv = dev;
608                 tc_init(&sc->tc);
609         }
610         if (resource_int_value(device_get_name(dev), device_get_unit(dev),
611             "clock", &i) != 0 || i != 0) {
612                 sc->intr_rid = 0;
613                 while (bus_get_resource(dev, SYS_RES_IRQ, sc->intr_rid,
614                     &s, NULL) == 0 && s != 0)
615                         sc->intr_rid++;
616                 if (!(sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ,
617                     &sc->intr_rid, 0, 0, 1, RF_ACTIVE))) {
618                         device_printf(dev,"Can't map interrupt.\n");
619                         return (0);
620                 }
621                 /* Dirty hack, to make bus_setup_intr to not enable source. */
622                 i8254_intsrc->is_handlers++;
623                 if ((bus_setup_intr(dev, sc->intr_res,
624                     INTR_MPSAFE | INTR_TYPE_CLK,
625                     (driver_filter_t *)clkintr, NULL,
626                     sc, &sc->intr_handler))) {
627                         device_printf(dev, "Can't setup interrupt.\n");
628                         i8254_intsrc->is_handlers--;
629                         return (0);
630                 }
631                 i8254_intsrc->is_handlers--;
632                 i8254_intsrc->is_pic->pic_enable_intr(i8254_intsrc);
633                 sc->et.et_name = "i8254";
634                 sc->et.et_flags = ET_FLAGS_PERIODIC;
635                 if (!i8254_timecounter)
636                         sc->et.et_flags |= ET_FLAGS_ONESHOT;
637                 sc->et.et_quality = 100;
638                 sc->et.et_frequency = i8254_freq;
639                 sc->et.et_min_period = (0x0002LLU << 32) / i8254_freq;
640                 sc->et.et_max_period = (0xfffeLLU << 32) / i8254_freq;
641                 sc->et.et_start = attimer_start;
642                 sc->et.et_stop = attimer_stop;
643                 sc->et.et_priv = dev;
644                 et_register(&sc->et);
645         }
646         return(0);
647 }
648
649 static int
650 attimer_resume(device_t dev)
651 {
652
653         i8254_restore();
654         return (0);
655 }
656
657 static device_method_t attimer_methods[] = {
658         /* Device interface */
659         DEVMETHOD(device_probe,         attimer_probe),
660         DEVMETHOD(device_attach,        attimer_attach),
661         DEVMETHOD(device_detach,        bus_generic_detach),
662         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
663         DEVMETHOD(device_suspend,       bus_generic_suspend),
664         DEVMETHOD(device_resume,        attimer_resume),
665         { 0, 0 }
666 };
667
668 static driver_t attimer_driver = {
669         "attimer",
670         attimer_methods,
671         sizeof(struct attimer_softc),
672 };
673
674 static devclass_t attimer_devclass;
675
676 DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
677 DRIVER_MODULE(attimer, acpi, attimer_driver, attimer_devclass, 0, 0);
678
679 #endif /* DEV_ISA */