pcrtc.c revision 76209
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: head/sys/pc98/cbus/pcrtc.c 76209 2001-05-02 13:51:49Z kato $
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/*
52 * modified for PC98 by Kakefuda
53 */
54
55#include "opt_clock.h"
56#include "opt_apm.h"
57#include "opt_mca.h"
58
59#include <sys/param.h>
60#include <sys/systm.h>
61#include <sys/bus.h>
62#include <sys/ipl.h>
63#include <sys/lock.h>
64#include <sys/mutex.h>
65#include <sys/proc.h>
66#include <sys/time.h>
67#include <sys/timetc.h>
68#include <sys/kernel.h>
69#include <sys/sysctl.h>
70#include <sys/cons.h>
71
72#include <machine/clock.h>
73#ifdef CLK_CALIBRATION_LOOP
74#endif
75#include <machine/cputypes.h>
76#include <machine/frame.h>
77#include <machine/limits.h>
78#include <machine/md_var.h>
79#include <machine/psl.h>
80#ifdef APIC_IO
81#include <machine/segments.h>
82#endif
83#if defined(SMP) || defined(APIC_IO)
84#include <machine/smp.h>
85#endif /* SMP || APIC_IO */
86#include <machine/specialreg.h>
87
88#include <i386/isa/icu.h>
89#ifdef PC98
90#include <pc98/pc98/pc98.h>
91#include <pc98/pc98/pc98_machdep.h>
92#include <i386/isa/isa_device.h>
93#else
94#include <i386/isa/isa.h>
95#include <isa/rtc.h>
96#endif
97#include <isa/isavar.h>
98#include <i386/isa/timerreg.h>
99
100#include <i386/isa/intr_machdep.h>
101
102#ifdef DEV_MCA
103#include <i386/isa/mca_machdep.h>
104#endif
105
106#ifdef APIC_IO
107#include <i386/isa/intr_machdep.h>
108/* The interrupt triggered by the 8254 (timer) chip */
109int apic_8254_intr;
110static u_long read_intr_count __P((int vec));
111static void setup_8254_mixed_mode __P((void));
112#endif
113
114/*
115 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
116 * can use a simple formula for leap years.
117 */
118#define	LEAPYEAR(y) ((u_int)(y) % 4 == 0)
119#define DAYSPERYEAR   (31+28+31+30+31+30+31+31+30+31+30+31)
120
121#define	TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
122
123/*
124 * Time in timer cycles that it takes for microtime() to disable interrupts
125 * and latch the count.  microtime() currently uses "cli; outb ..." so it
126 * normally takes less than 2 timer cycles.  Add a few for cache misses.
127 * Add a few more to allow for latency in bogus calls to microtime() with
128 * interrupts already disabled.
129 */
130#define	TIMER0_LATCH_COUNT	20
131
132/*
133 * Maximum frequency that we are willing to allow for timer0.  Must be
134 * low enough to guarantee that the timer interrupt handler returns
135 * before the next timer interrupt.
136 */
137#define	TIMER0_MAX_FREQ		20000
138
139int	adjkerntz;		/* local offset from GMT in seconds */
140int	clkintr_pending;
141int	disable_rtc_set;	/* disable resettodr() if != 0 */
142int	statclock_disable;
143#ifndef TIMER_FREQ
144#ifdef PC98
145#define	TIMER_FREQ	2457600;
146#else /* IBM-PC */
147#define	TIMER_FREQ	1193182;
148#endif /* PC98 */
149#endif
150u_int	timer_freq = TIMER_FREQ;
151int	timer0_max_count;
152u_int	tsc_freq;
153int	tsc_is_broken;
154u_int	tsc_present;
155int	wall_cmos_clock;	/* wall CMOS clock assumed if != 0 */
156struct mtx clock_lock;
157
158static	int	beeping = 0;
159static	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
160static	u_int	hardclock_max_count;
161static	u_int32_t i8254_lastcount;
162static	u_int32_t i8254_offset;
163static	int	i8254_ticked;
164/*
165 * XXX new_function and timer_func should not handle clockframes, but
166 * timer_func currently needs to hold hardclock to handle the
167 * timer0_state == 0 case.  We should use inthand_add()/inthand_remove()
168 * to switch between clkintr() and a slightly different timerintr().
169 */
170static	void	(*new_function) __P((struct clockframe *frame));
171static	u_int	new_rate;
172#ifndef PC98
173static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
174static	u_char	rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
175#endif
176static	u_int	timer0_prescaler_count;
177
178/* Values for timerX_state: */
179#define	RELEASED	0
180#define	RELEASE_PENDING	1
181#define	ACQUIRED	2
182#define	ACQUIRE_PENDING	3
183
184static	u_char	timer0_state;
185#ifdef	PC98
186static 	u_char	timer1_state;
187#endif
188static	u_char	timer2_state;
189static	void	(*timer_func) __P((struct clockframe *frame)) = hardclock;
190#ifdef PC98
191static void rtc_serialcombit __P((int));
192static void rtc_serialcom __P((int));
193static int rtc_inb __P((void));
194static void rtc_outb __P((int));
195#endif
196
197static	unsigned i8254_get_timecount __P((struct timecounter *tc));
198static	unsigned tsc_get_timecount __P((struct timecounter *tc));
199static	void	set_timer_freq(u_int freq, int intr_freq);
200
201static struct timecounter tsc_timecounter = {
202	tsc_get_timecount,	/* get_timecount */
203	0,			/* no poll_pps */
204 	~0u,			/* counter_mask */
205	0,			/* frequency */
206	 "TSC"			/* name */
207};
208
209SYSCTL_OPAQUE(_debug, OID_AUTO, tsc_timecounter, CTLFLAG_RD,
210	&tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", "");
211
212static struct timecounter i8254_timecounter = {
213	i8254_get_timecount,	/* get_timecount */
214	0,			/* no poll_pps */
215	~0u,			/* counter_mask */
216	0,			/* frequency */
217	"i8254"			/* name */
218};
219
220SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
221	&i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", "");
222
223static void
224clkintr(struct clockframe frame)
225{
226
227	if (timecounter->tc_get_timecount == i8254_get_timecount) {
228		mtx_lock_spin(&clock_lock);
229		if (i8254_ticked)
230			i8254_ticked = 0;
231		else {
232			i8254_offset += timer0_max_count;
233			i8254_lastcount = 0;
234		}
235		clkintr_pending = 0;
236		mtx_unlock_spin(&clock_lock);
237	}
238	timer_func(&frame);
239#ifdef SMP
240	if (timer_func == hardclock)
241		forward_hardclock();
242#endif
243	switch (timer0_state) {
244
245	case RELEASED:
246		break;
247
248	case ACQUIRED:
249		if ((timer0_prescaler_count += timer0_max_count)
250		    >= hardclock_max_count) {
251			timer0_prescaler_count -= hardclock_max_count;
252			hardclock(&frame);
253#ifdef SMP
254			forward_hardclock();
255#endif
256		}
257		break;
258
259	case ACQUIRE_PENDING:
260		mtx_lock_spin(&clock_lock);
261		i8254_offset = i8254_get_timecount(NULL);
262		i8254_lastcount = 0;
263		timer0_max_count = TIMER_DIV(new_rate);
264		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
265		outb(TIMER_CNTR0, timer0_max_count & 0xff);
266		outb(TIMER_CNTR0, timer0_max_count >> 8);
267		mtx_unlock_spin(&clock_lock);
268		timer_func = new_function;
269		timer0_state = ACQUIRED;
270		break;
271
272	case RELEASE_PENDING:
273		if ((timer0_prescaler_count += timer0_max_count)
274		    >= hardclock_max_count) {
275			mtx_lock_spin(&clock_lock);
276			i8254_offset = i8254_get_timecount(NULL);
277			i8254_lastcount = 0;
278			timer0_max_count = hardclock_max_count;
279			outb(TIMER_MODE,
280			     TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
281			outb(TIMER_CNTR0, timer0_max_count & 0xff);
282			outb(TIMER_CNTR0, timer0_max_count >> 8);
283			mtx_unlock_spin(&clock_lock);
284			timer0_prescaler_count = 0;
285			timer_func = hardclock;
286			timer0_state = RELEASED;
287			hardclock(&frame);
288#ifdef SMP
289			forward_hardclock();
290#endif
291		}
292		break;
293	}
294#ifdef DEV_MCA
295	/* Reset clock interrupt by asserting bit 7 of port 0x61 */
296	if (MCA_system)
297		outb(0x61, inb(0x61) | 0x80);
298#endif
299}
300
301/*
302 * The acquire and release functions must be called at ipl >= splclock().
303 */
304int
305acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
306{
307	static int old_rate;
308
309	if (rate <= 0 || rate > TIMER0_MAX_FREQ)
310		return (-1);
311	switch (timer0_state) {
312
313	case RELEASED:
314		timer0_state = ACQUIRE_PENDING;
315		break;
316
317	case RELEASE_PENDING:
318		if (rate != old_rate)
319			return (-1);
320		/*
321		 * The timer has been released recently, but is being
322		 * re-acquired before the release completed.  In this
323		 * case, we simply reclaim it as if it had not been
324		 * released at all.
325		 */
326		timer0_state = ACQUIRED;
327		break;
328
329	default:
330		return (-1);	/* busy */
331	}
332	new_function = function;
333	old_rate = new_rate = rate;
334	return (0);
335}
336
337#ifdef PC98
338int
339acquire_timer1(int mode)
340{
341
342	if (timer1_state != RELEASED)
343		return (-1);
344	timer1_state = ACQUIRED;
345
346	/*
347	 * This access to the timer registers is as atomic as possible
348	 * because it is a single instruction.  We could do better if we
349	 * knew the rate.  Use of splclock() limits glitches to 10-100us,
350	 * and this is probably good enough for timer2, so we aren't as
351	 * careful with it as with timer0.
352	 */
353	outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
354
355	return (0);
356}
357#endif
358
359int
360acquire_timer2(int mode)
361{
362
363	if (timer2_state != RELEASED)
364		return (-1);
365	timer2_state = ACQUIRED;
366
367	/*
368	 * This access to the timer registers is as atomic as possible
369	 * because it is a single instruction.  We could do better if we
370	 * knew the rate.  Use of splclock() limits glitches to 10-100us,
371	 * and this is probably good enough for timer2, so we aren't as
372	 * careful with it as with timer0.
373	 */
374	outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
375
376	return (0);
377}
378
379int
380release_timer0()
381{
382	switch (timer0_state) {
383
384	case ACQUIRED:
385		timer0_state = RELEASE_PENDING;
386		break;
387
388	case ACQUIRE_PENDING:
389		/* Nothing happened yet, release quickly. */
390		timer0_state = RELEASED;
391		break;
392
393	default:
394		return (-1);
395	}
396	return (0);
397}
398
399#ifdef PC98
400int
401release_timer1()
402{
403
404	if (timer1_state != ACQUIRED)
405		return (-1);
406	timer1_state = RELEASED;
407	outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
408	return (0);
409}
410#endif
411
412int
413release_timer2()
414{
415
416	if (timer2_state != ACQUIRED)
417		return (-1);
418	timer2_state = RELEASED;
419	outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
420	return (0);
421}
422
423#ifndef PC98
424/*
425 * This routine receives statistical clock interrupts from the RTC.
426 * As explained above, these occur at 128 interrupts per second.
427 * When profiling, we receive interrupts at a rate of 1024 Hz.
428 *
429 * This does not actually add as much overhead as it sounds, because
430 * when the statistical clock is active, the hardclock driver no longer
431 * needs to keep (inaccurate) statistics on its own.  This decouples
432 * statistics gathering from scheduling interrupts.
433 *
434 * The RTC chip requires that we read status register C (RTC_INTR)
435 * to acknowledge an interrupt, before it will generate the next one.
436 * Under high interrupt load, rtcintr() can be indefinitely delayed and
437 * the clock can tick immediately after the read from RTC_INTR.  In this
438 * case, the mc146818A interrupt signal will not drop for long enough
439 * to register with the 8259 PIC.  If an interrupt is missed, the stat
440 * clock will halt, considerably degrading system performance.  This is
441 * why we use 'while' rather than a more straightforward 'if' below.
442 * Stat clock ticks can still be lost, causing minor loss of accuracy
443 * in the statistics, but the stat clock will no longer stop.
444 */
445static void
446rtcintr(struct clockframe frame)
447{
448	while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
449		statclock(&frame);
450#ifdef SMP
451		forward_statclock();
452#endif
453	}
454}
455
456#include "opt_ddb.h"
457#ifdef DDB
458#include <ddb/ddb.h>
459
460DB_SHOW_COMMAND(rtc, rtc)
461{
462	printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n",
463	       rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY),
464	       rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC),
465	       rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR));
466}
467#endif /* DDB */
468#endif /* for PC98 */
469
470static int
471getit(void)
472{
473	int high, low;
474
475	mtx_lock_spin(&clock_lock);
476
477	/* Select timer0 and latch counter value. */
478	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
479
480	low = inb(TIMER_CNTR0);
481	high = inb(TIMER_CNTR0);
482
483	mtx_unlock_spin(&clock_lock);
484	return ((high << 8) | low);
485}
486
487/*
488 * Wait "n" microseconds.
489 * Relies on timer 1 counting down from (timer_freq / hz)
490 * Note: timer had better have been programmed before this is first used!
491 */
492void
493DELAY(int n)
494{
495	int delta, prev_tick, tick, ticks_left;
496
497#ifdef DELAYDEBUG
498	int getit_calls = 1;
499	int n1;
500	static int state = 0;
501
502	if (state == 0) {
503		state = 1;
504		for (n1 = 1; n1 <= 10000000; n1 *= 10)
505			DELAY(n1);
506		state = 2;
507	}
508	if (state == 1)
509		printf("DELAY(%d)...", n);
510#endif
511	/*
512	 * Guard against the timer being uninitialized if we are called
513	 * early for console i/o.
514	 */
515	if (timer0_max_count == 0)
516		set_timer_freq(timer_freq, hz);
517
518	/*
519	 * Read the counter first, so that the rest of the setup overhead is
520	 * counted.  Guess the initial overhead is 20 usec (on most systems it
521	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
522	 * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
523	 * multiplications and divisions to scale the count take a while).
524	 */
525	prev_tick = getit();
526	n -= 0;			/* XXX actually guess no initial overhead */
527	/*
528	 * Calculate (n * (timer_freq / 1e6)) without using floating point
529	 * and without any avoidable overflows.
530	 */
531	if (n <= 0)
532		ticks_left = 0;
533	else if (n < 256)
534		/*
535		 * Use fixed point to avoid a slow division by 1000000.
536		 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
537		 * 2^15 is the first power of 2 that gives exact results
538		 * for n between 0 and 256.
539		 */
540		ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
541	else
542		/*
543		 * Don't bother using fixed point, although gcc-2.7.2
544		 * generates particularly poor code for the long long
545		 * division, since even the slow way will complete long
546		 * before the delay is up (unless we're interrupted).
547		 */
548		ticks_left = ((u_int)n * (long long)timer_freq + 999999)
549			     / 1000000;
550
551	while (ticks_left > 0) {
552		tick = getit();
553#ifdef DELAYDEBUG
554		++getit_calls;
555#endif
556		delta = prev_tick - tick;
557		prev_tick = tick;
558		if (delta < 0) {
559			delta += timer0_max_count;
560			/*
561			 * Guard against timer0_max_count being wrong.
562			 * This shouldn't happen in normal operation,
563			 * but it may happen if set_timer_freq() is
564			 * traced.
565			 */
566			if (delta < 0)
567				delta = 0;
568		}
569		ticks_left -= delta;
570	}
571#ifdef DELAYDEBUG
572	if (state == 1)
573		printf(" %d calls to getit() at %d usec each\n",
574		       getit_calls, (n + 5) / getit_calls);
575#endif
576}
577
578static void
579sysbeepstop(void *chan)
580{
581#ifdef PC98	/* PC98 */
582	outb(IO_PPI, inb(IO_PPI)|0x08);	/* disable counter1 output to speaker */
583	release_timer1();
584#else
585	outb(IO_PPI, inb(IO_PPI)&0xFC);	/* disable counter2 output to speaker */
586	release_timer2();
587#endif
588	beeping = 0;
589}
590
591int
592sysbeep(int pitch, int period)
593{
594	int x = splclock();
595
596#ifdef PC98
597	if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
598		if (!beeping) {
599			/* Something else owns it. */
600			splx(x);
601			return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
602		}
603	disable_intr();
604	outb(0x3fdb, pitch);
605	outb(0x3fdb, (pitch>>8));
606	enable_intr();
607	if (!beeping) {
608		/* enable counter1 output to speaker */
609		outb(IO_PPI, (inb(IO_PPI) & 0xf7));
610		beeping = period;
611		timeout(sysbeepstop, (void *)NULL, period);
612	}
613#else
614	if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
615		if (!beeping) {
616			/* Something else owns it. */
617			splx(x);
618			return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
619		}
620	mtx_lock_spin(&clock_lock);
621	outb(TIMER_CNTR2, pitch);
622	outb(TIMER_CNTR2, (pitch>>8));
623	mtx_unlock_spin(&clock_lock);
624	if (!beeping) {
625		/* enable counter2 output to speaker */
626		outb(IO_PPI, inb(IO_PPI) | 3);
627		beeping = period;
628		timeout(sysbeepstop, (void *)NULL, period);
629	}
630#endif
631	splx(x);
632	return (0);
633}
634
635#ifndef PC98
636/*
637 * RTC support routines
638 */
639
640int
641rtcin(reg)
642	int reg;
643{
644	int s;
645	u_char val;
646
647	s = splhigh();
648	outb(IO_RTC, reg);
649	inb(0x84);
650	val = inb(IO_RTC + 1);
651	inb(0x84);
652	splx(s);
653	return (val);
654}
655
656static __inline void
657writertc(u_char reg, u_char val)
658{
659	int s;
660
661	s = splhigh();
662	inb(0x84);
663	outb(IO_RTC, reg);
664	inb(0x84);
665	outb(IO_RTC + 1, val);
666	inb(0x84);		/* XXX work around wrong order in rtcin() */
667	splx(s);
668}
669
670static __inline int
671readrtc(int port)
672{
673	return(bcd2bin(rtcin(port)));
674}
675#endif
676
677#ifdef PC98
678unsigned int delaycount;
679#define FIRST_GUESS	0x2000
680static void findcpuspeed(void)
681{
682	int i;
683	int remainder;
684
685	/* Put counter in count down mode */
686	outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
687	outb(TIMER_CNTR0, 0xff);
688	outb(TIMER_CNTR0, 0xff);
689	for (i = FIRST_GUESS; i; i--)
690		;
691	remainder = getit();
692	delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff - remainder);
693}
694#endif
695
696#ifdef PC98
697static u_int
698calibrate_clocks(void)
699{
700	int	timeout;
701	u_int	count, prev_count, tot_count;
702	u_short	sec, start_sec;
703
704	if (bootverbose)
705	        printf("Calibrating clock(s) ... ");
706	/* Check ARTIC. */
707	if (!(PC98_SYSTEM_PARAMETER(0x458) & 0x80) &&
708	    !(PC98_SYSTEM_PARAMETER(0x45b) & 0x04))
709		goto fail;
710	timeout = 100000000;
711
712	/* Read the ARTIC. */
713	sec = inw(0x5e);
714
715	/* Wait for the ARTIC to changes. */
716	start_sec = sec;
717	for (;;) {
718		sec = inw(0x5e);
719		if (sec != start_sec)
720			break;
721		if (--timeout == 0)
722			goto fail;
723	}
724	prev_count = getit();
725	if (prev_count == 0 || prev_count > timer0_max_count)
726		goto fail;
727	tot_count = 0;
728
729	if (tsc_present)
730		wrmsr(0x10, 0LL);	/* XXX 0x10 is the MSR for the TSC */
731	start_sec = sec;
732	for (;;) {
733		sec = inw(0x5e);
734		count = getit();
735		if (count == 0 || count > timer0_max_count)
736			goto fail;
737		if (count > prev_count)
738			tot_count += prev_count - (count - timer0_max_count);
739		else
740			tot_count += prev_count - count;
741		prev_count = count;
742		if ((sec == start_sec + 1200) ||
743		    (sec < start_sec &&
744		        (u_int)sec + 0x10000 == (u_int)start_sec + 1200))
745			break;
746		if (--timeout == 0)
747			goto fail;
748	}
749	/*
750	 * Read the cpu cycle counter.  The timing considerations are
751	 * similar to those for the i8254 clock.
752	 */
753	if (tsc_present)
754		tsc_freq = rdtsc();
755
756	if (bootverbose) {
757		if (tsc_present)
758		        printf("TSC clock: %u Hz, ", tsc_freq);
759	        printf("i8254 clock: %u Hz\n", tot_count);
760	}
761	return (tot_count);
762
763fail:
764	if (bootverbose)
765	        printf("failed, using default i8254 clock of %u Hz\n",
766		       timer_freq);
767	return (timer_freq);
768}
769#else
770static u_int
771calibrate_clocks(void)
772{
773	u_int64_t old_tsc;
774	u_int count, prev_count, tot_count;
775	int sec, start_sec, timeout;
776
777	if (bootverbose)
778	        printf("Calibrating clock(s) ... ");
779	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
780		goto fail;
781	timeout = 100000000;
782
783	/* Read the mc146818A seconds counter. */
784	for (;;) {
785		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
786			sec = rtcin(RTC_SEC);
787			break;
788		}
789		if (--timeout == 0)
790			goto fail;
791	}
792
793	/* Wait for the mC146818A seconds counter to change. */
794	start_sec = sec;
795	for (;;) {
796		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
797			sec = rtcin(RTC_SEC);
798			if (sec != start_sec)
799				break;
800		}
801		if (--timeout == 0)
802			goto fail;
803	}
804
805	/* Start keeping track of the i8254 counter. */
806	prev_count = getit();
807	if (prev_count == 0 || prev_count > timer0_max_count)
808		goto fail;
809	tot_count = 0;
810
811	if (tsc_present)
812		old_tsc = rdtsc();
813	else
814		old_tsc = 0;		/* shut up gcc */
815
816	/*
817	 * Wait for the mc146818A seconds counter to change.  Read the i8254
818	 * counter for each iteration since this is convenient and only
819	 * costs a few usec of inaccuracy. The timing of the final reads
820	 * of the counters almost matches the timing of the initial reads,
821	 * so the main cause of inaccuracy is the varying latency from
822	 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the
823	 * rtcin(RTC_SEC) that returns a changed seconds count.  The
824	 * maximum inaccuracy from this cause is < 10 usec on 486's.
825	 */
826	start_sec = sec;
827	for (;;) {
828		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP))
829			sec = rtcin(RTC_SEC);
830		count = getit();
831		if (count == 0 || count > timer0_max_count)
832			goto fail;
833		if (count > prev_count)
834			tot_count += prev_count - (count - timer0_max_count);
835		else
836			tot_count += prev_count - count;
837		prev_count = count;
838		if (sec != start_sec)
839			break;
840		if (--timeout == 0)
841			goto fail;
842	}
843
844	/*
845	 * Read the cpu cycle counter.  The timing considerations are
846	 * similar to those for the i8254 clock.
847	 */
848	if (tsc_present)
849		tsc_freq = rdtsc() - old_tsc;
850
851	if (bootverbose) {
852		if (tsc_present)
853		        printf("TSC clock: %u Hz, ", tsc_freq);
854	        printf("i8254 clock: %u Hz\n", tot_count);
855	}
856	return (tot_count);
857
858fail:
859	if (bootverbose)
860	        printf("failed, using default i8254 clock of %u Hz\n",
861		       timer_freq);
862	return (timer_freq);
863}
864#endif	/* !PC98 */
865
866static void
867set_timer_freq(u_int freq, int intr_freq)
868{
869	int new_timer0_max_count;
870
871	mtx_lock_spin(&clock_lock);
872	timer_freq = freq;
873	new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
874	if (new_timer0_max_count != timer0_max_count) {
875		timer0_max_count = new_timer0_max_count;
876		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
877		outb(TIMER_CNTR0, timer0_max_count & 0xff);
878		outb(TIMER_CNTR0, timer0_max_count >> 8);
879	}
880	mtx_unlock_spin(&clock_lock);
881}
882
883/*
884 * i8254_restore is called from apm_default_resume() to reload
885 * the countdown register.
886 * this should not be necessary but there are broken laptops that
887 * do not restore the countdown register on resume.
888 * when it happnes, it messes up the hardclock interval and system clock,
889 * which leads to the infamous "calcru: negative time" problem.
890 */
891void
892i8254_restore(void)
893{
894
895	mtx_lock_spin(&clock_lock);
896	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
897	outb(TIMER_CNTR0, timer0_max_count & 0xff);
898	outb(TIMER_CNTR0, timer0_max_count >> 8);
899	mtx_unlock_spin(&clock_lock);
900}
901
902/*
903 * Initialize 8254 timer 0 early so that it can be used in DELAY().
904 * XXX initialization of other timers is unintentionally left blank.
905 */
906void
907startrtclock()
908{
909	u_int delta, freq;
910
911#ifdef PC98
912	findcpuspeed();
913	if (pc98_machine_type & M_8M)
914		timer_freq = 1996800L; /* 1.9968 MHz */
915	else
916		timer_freq = 2457600L; /* 2.4576 MHz */
917#endif /* PC98 */
918
919	if (cpu_feature & CPUID_TSC)
920		tsc_present = 1;
921	else
922		tsc_present = 0;
923
924#ifndef PC98
925	writertc(RTC_STATUSA, rtc_statusa);
926	writertc(RTC_STATUSB, RTCSB_24HR);
927#endif
928
929	set_timer_freq(timer_freq, hz);
930	freq = calibrate_clocks();
931#ifdef CLK_CALIBRATION_LOOP
932	if (bootverbose) {
933		printf(
934		"Press a key on the console to abort clock calibration\n");
935		while (cncheckc() == -1)
936			calibrate_clocks();
937	}
938#endif
939
940	/*
941	 * Use the calibrated i8254 frequency if it seems reasonable.
942	 * Otherwise use the default, and don't use the calibrated i586
943	 * frequency.
944	 */
945	delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
946	if (delta < timer_freq / 100) {
947#ifndef CLK_USE_I8254_CALIBRATION
948		if (bootverbose)
949			printf(
950"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
951		freq = timer_freq;
952#endif
953		timer_freq = freq;
954	} else {
955		if (bootverbose)
956			printf(
957		    "%d Hz differs from default of %d Hz by more than 1%%\n",
958			       freq, timer_freq);
959		tsc_freq = 0;
960	}
961
962	set_timer_freq(timer_freq, hz);
963	i8254_timecounter.tc_frequency = timer_freq;
964	tc_init(&i8254_timecounter);
965
966#ifndef CLK_USE_TSC_CALIBRATION
967	if (tsc_freq != 0) {
968		if (bootverbose)
969			printf(
970"CLK_USE_TSC_CALIBRATION not specified - using old calibration method\n");
971		tsc_freq = 0;
972	}
973#endif
974	if (tsc_present && tsc_freq == 0) {
975		/*
976		 * Calibration of the i586 clock relative to the mc146818A
977		 * clock failed.  Do a less accurate calibration relative
978		 * to the i8254 clock.
979		 */
980		u_int64_t old_tsc = rdtsc();
981
982		DELAY(1000000);
983		tsc_freq = rdtsc() - old_tsc;
984#ifdef CLK_USE_TSC_CALIBRATION
985		if (bootverbose)
986			printf("TSC clock: %u Hz (Method B)\n", tsc_freq);
987#endif
988	}
989
990#if !defined(SMP)
991	/*
992	 * We can not use the TSC in SMP mode, until we figure out a
993	 * cheap (impossible), reliable and precise (yeah right!)  way
994	 * to synchronize the TSCs of all the CPUs.
995	 * Curse Intel for leaving the counter out of the I/O APIC.
996	 */
997
998#ifdef DEV_APM
999	/*
1000	 * We can not use the TSC if we support APM. Precise timekeeping
1001	 * on an APM'ed machine is at best a fools pursuit, since
1002	 * any and all of the time spent in various SMM code can't
1003	 * be reliably accounted for.  Reading the RTC is your only
1004	 * source of reliable time info.  The i8254 looses too of course
1005	 * but we need to have some kind of time...
1006	 * We don't know at this point whether APM is going to be used
1007	 * or not, nor when it might be activated.  Play it safe.
1008	 */
1009	{
1010	int disabled = 0;
1011	resource_int_value("apm", 0, "disabled", &disabled);
1012	if (disabled == 0)
1013		return;
1014	}
1015#endif /* DEV_APM */
1016
1017	if (tsc_present && tsc_freq != 0 && !tsc_is_broken) {
1018		tsc_timecounter.tc_frequency = tsc_freq;
1019		tc_init(&tsc_timecounter);
1020	}
1021
1022#endif /* !defined(SMP) */
1023}
1024
1025#ifdef PC98
1026static void
1027rtc_serialcombit(int i)
1028{
1029	outb(IO_RTC, ((i&0x01)<<5)|0x07);
1030	DELAY(1);
1031	outb(IO_RTC, ((i&0x01)<<5)|0x17);
1032	DELAY(1);
1033	outb(IO_RTC, ((i&0x01)<<5)|0x07);
1034	DELAY(1);
1035}
1036
1037static void
1038rtc_serialcom(int i)
1039{
1040	rtc_serialcombit(i&0x01);
1041	rtc_serialcombit((i&0x02)>>1);
1042	rtc_serialcombit((i&0x04)>>2);
1043	rtc_serialcombit((i&0x08)>>3);
1044	outb(IO_RTC, 0x07);
1045	DELAY(1);
1046	outb(IO_RTC, 0x0f);
1047	DELAY(1);
1048	outb(IO_RTC, 0x07);
1049 	DELAY(1);
1050}
1051
1052static void
1053rtc_outb(int val)
1054{
1055	int s;
1056	int sa = 0;
1057
1058	for (s=0;s<8;s++) {
1059	    sa = ((val >> s) & 0x01) ? 0x27 : 0x07;
1060	    outb(IO_RTC, sa);		/* set DI & CLK 0 */
1061	    DELAY(1);
1062	    outb(IO_RTC, sa | 0x10);	/* CLK 1 */
1063	    DELAY(1);
1064	}
1065	outb(IO_RTC, sa & 0xef);	/* CLK 0 */
1066}
1067
1068static int
1069rtc_inb(void)
1070{
1071	int s;
1072	int sa = 0;
1073
1074	for (s=0;s<8;s++) {
1075	    sa |= ((inb(0x33) & 0x01) << s);
1076	    outb(IO_RTC, 0x17);	/* CLK 1 */
1077	    DELAY(1);
1078	    outb(IO_RTC, 0x07);	/* CLK 0 */
1079	    DELAY(2);
1080	}
1081	return sa;
1082}
1083#endif /* PC-98 */
1084
1085/*
1086 * Initialize the time of day register, based on the time base which is, e.g.
1087 * from a filesystem.
1088 */
1089void
1090inittodr(time_t base)
1091{
1092	unsigned long	sec, days;
1093#ifndef PC98
1094	int		yd;
1095#endif
1096	int		year, month;
1097	int		y, m, s;
1098	struct timespec ts;
1099#ifdef PC98
1100	int		second, min, hour;
1101#endif
1102
1103	if (base) {
1104		s = splclock();
1105		ts.tv_sec = base;
1106		ts.tv_nsec = 0;
1107		tc_setclock(&ts);
1108		splx(s);
1109	}
1110
1111#ifdef PC98
1112	rtc_serialcom(0x03);	/* Time Read */
1113	rtc_serialcom(0x01);	/* Register shift command. */
1114	DELAY(20);
1115
1116	second = bcd2bin(rtc_inb() & 0xff);	/* sec */
1117	min = bcd2bin(rtc_inb() & 0xff);	/* min */
1118	hour = bcd2bin(rtc_inb() & 0xff);	/* hour */
1119	days = bcd2bin(rtc_inb() & 0xff) - 1;	/* date */
1120
1121	month = (rtc_inb() >> 4) & 0x0f;	/* month */
1122	for (m = 1; m <	month; m++)
1123		days +=	daysinmonth[m-1];
1124	year = bcd2bin(rtc_inb() & 0xff) + 1900;	/* year */
1125	/* 2000 year problem */
1126	if (year < 1995)
1127		year += 100;
1128	if (year < 1970)
1129		goto wrong_time;
1130	for (y = 1970; y < year; y++)
1131		days +=	DAYSPERYEAR + LEAPYEAR(y);
1132	if ((month > 2)	&& LEAPYEAR(year))
1133		days ++;
1134	sec = ((( days * 24 +
1135		  hour) * 60 +
1136		  min) * 60 +
1137		  second);
1138	/* sec now contains the	number of seconds, since Jan 1 1970,
1139	   in the local	time zone */
1140
1141	s = splhigh();
1142#else	/* IBM-PC */
1143	/* Look if we have a RTC present and the time is valid */
1144	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
1145		goto wrong_time;
1146
1147	/* wait for time update to complete */
1148	/* If RTCSA_TUP is zero, we have at least 244us before next update */
1149	s = splhigh();
1150	while (rtcin(RTC_STATUSA) & RTCSA_TUP) {
1151		splx(s);
1152		s = splhigh();
1153	}
1154
1155	days = 0;
1156#ifdef USE_RTC_CENTURY
1157	year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
1158#else
1159	year = readrtc(RTC_YEAR) + 1900;
1160	if (year < 1970)
1161		year += 100;
1162#endif
1163	if (year < 1970) {
1164		splx(s);
1165		goto wrong_time;
1166	}
1167	month = readrtc(RTC_MONTH);
1168	for (m = 1; m < month; m++)
1169		days += daysinmonth[m-1];
1170	if ((month > 2) && LEAPYEAR(year))
1171		days ++;
1172	days += readrtc(RTC_DAY) - 1;
1173	yd = days;
1174	for (y = 1970; y < year; y++)
1175		days += DAYSPERYEAR + LEAPYEAR(y);
1176	sec = ((( days * 24 +
1177		  readrtc(RTC_HRS)) * 60 +
1178		  readrtc(RTC_MIN)) * 60 +
1179		  readrtc(RTC_SEC));
1180	/* sec now contains the number of seconds, since Jan 1 1970,
1181	   in the local time zone */
1182#endif
1183
1184	sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
1185
1186	y = time_second - sec;
1187	if (y <= -2 || y >= 2) {
1188		/* badly off, adjust it */
1189		ts.tv_sec = sec;
1190		ts.tv_nsec = 0;
1191		tc_setclock(&ts);
1192	}
1193	splx(s);
1194	return;
1195
1196wrong_time:
1197	printf("Invalid time in real time clock.\n");
1198	printf("Check and reset the date immediately!\n");
1199}
1200
1201/*
1202 * Write system time back to RTC
1203 */
1204void
1205resettodr()
1206{
1207	unsigned long	tm;
1208	int		y, m, s;
1209#ifdef PC98
1210	int		wd;
1211#endif
1212
1213	if (disable_rtc_set)
1214		return;
1215
1216	s = splclock();
1217	tm = time_second;
1218	splx(s);
1219
1220#ifdef PC98
1221	rtc_serialcom(0x01);	/* Register shift command. */
1222
1223	/* Calculate local time	to put in RTC */
1224
1225	tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
1226
1227	rtc_outb(bin2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
1228	rtc_outb(bin2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
1229	rtc_outb(bin2bcd(tm%24)); tm /= 24;	/* Write back Hours   */
1230
1231	/* We have now the days	since 01-01-1970 in tm */
1232	wd = (tm+4)%7;
1233	for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
1234	     tm >= m;
1235	     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
1236	     tm -= m;
1237
1238	/* Now we have the years in y and the day-of-the-year in tm */
1239	for (m = 0; ; m++) {
1240		int ml;
1241
1242		ml = daysinmonth[m];
1243		if (m == 1 && LEAPYEAR(y))
1244			ml++;
1245		if (tm < ml)
1246			break;
1247		tm -= ml;
1248	}
1249
1250	m++;
1251	rtc_outb(bin2bcd(tm+1));		/* Write back Day     */
1252	rtc_outb((m << 4) | wd);		/* Write back Month & Weekday  */
1253	rtc_outb(bin2bcd(y%100));		/* Write back Year    */
1254
1255	rtc_serialcom(0x02);	/* Time set & Counter hold command. */
1256	rtc_serialcom(0x00);	/* Register hold command. */
1257#else
1258	/* Disable RTC updates and interrupts. */
1259	writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
1260
1261	/* Calculate local time to put in RTC */
1262
1263	tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
1264
1265	writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
1266	writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
1267	writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24;	/* Write back Hours   */
1268
1269	/* We have now the days since 01-01-1970 in tm */
1270	writertc(RTC_WDAY, (tm+4)%7);			/* Write back Weekday */
1271	for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
1272	     tm >= m;
1273	     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
1274	     tm -= m;
1275
1276	/* Now we have the years in y and the day-of-the-year in tm */
1277	writertc(RTC_YEAR, bin2bcd(y%100));		/* Write back Year    */
1278#ifdef USE_RTC_CENTURY
1279	writertc(RTC_CENTURY, bin2bcd(y/100));		/* ... and Century    */
1280#endif
1281	for (m = 0; ; m++) {
1282		int ml;
1283
1284		ml = daysinmonth[m];
1285		if (m == 1 && LEAPYEAR(y))
1286			ml++;
1287		if (tm < ml)
1288			break;
1289		tm -= ml;
1290	}
1291
1292	writertc(RTC_MONTH, bin2bcd(m + 1));            /* Write back Month   */
1293	writertc(RTC_DAY, bin2bcd(tm + 1));             /* Write back Month Day */
1294
1295	/* Reenable RTC updates and interrupts. */
1296	writertc(RTC_STATUSB, rtc_statusb);
1297#endif /* PC98 */
1298}
1299
1300
1301/*
1302 * Start both clocks running.
1303 */
1304void
1305cpu_initclocks()
1306{
1307#ifdef APIC_IO
1308	int apic_8254_trial;
1309	void *clkdesc;
1310#endif /* APIC_IO */
1311#ifndef PC98
1312	int diag;
1313
1314	if (statclock_disable) {
1315		/*
1316		 * The stat interrupt mask is different without the
1317		 * statistics clock.  Also, don't set the interrupt
1318		 * flag which would normally cause the RTC to generate
1319		 * interrupts.
1320		 */
1321		rtc_statusb = RTCSB_24HR;
1322	} else {
1323	        /* Setting stathz to nonzero early helps avoid races. */
1324		stathz = RTC_NOPROFRATE;
1325		profhz = RTC_PROFRATE;
1326        }
1327#endif
1328
1329	/* Finish initializing 8253 timer 0. */
1330#ifdef APIC_IO
1331
1332	apic_8254_intr = isa_apic_irq(0);
1333	apic_8254_trial = 0;
1334	if (apic_8254_intr >= 0 ) {
1335		if (apic_int_type(0, 0) == 3)
1336			apic_8254_trial = 1;
1337	} else {
1338		/* look for ExtInt on pin 0 */
1339		if (apic_int_type(0, 0) == 3) {
1340			apic_8254_intr = apic_irq(0, 0);
1341			setup_8254_mixed_mode();
1342		} else
1343			panic("APIC_IO: Cannot route 8254 interrupt to CPU");
1344	}
1345
1346	inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL,
1347	    INTR_TYPE_CLK | INTR_FAST, &clkdesc);
1348	INTREN(1 << apic_8254_intr);
1349
1350#else /* APIC_IO */
1351
1352	/*
1353	 * XXX Check the priority of this interrupt handler.  I
1354	 * couldn't find anything suitable in the BSD/OS code (grog,
1355	 * 19 July 2000).
1356	 */
1357	inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL,
1358	    INTR_TYPE_CLK | INTR_FAST, NULL);
1359	INTREN(IRQ0);
1360
1361#endif /* APIC_IO */
1362
1363#ifndef PC98
1364	/* Initialize RTC. */
1365	writertc(RTC_STATUSA, rtc_statusa);
1366	writertc(RTC_STATUSB, RTCSB_24HR);
1367
1368	/* Don't bother enabling the statistics clock. */
1369	if (statclock_disable)
1370		return;
1371	diag = rtcin(RTC_DIAG);
1372	if (diag != 0)
1373		printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
1374#endif /* !PC98 */
1375
1376#ifndef PC98
1377#ifdef APIC_IO
1378	if (isa_apic_irq(8) != 8)
1379		panic("APIC RTC != 8");
1380#endif /* APIC_IO */
1381
1382	inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL,
1383	    INTR_TYPE_CLK | INTR_FAST, NULL);
1384
1385#ifdef APIC_IO
1386	INTREN(APIC_IRQ8);
1387#else
1388	INTREN(IRQ8);
1389#endif /* APIC_IO */
1390
1391	writertc(RTC_STATUSB, rtc_statusb);
1392#endif /* PC98 */
1393
1394#ifdef APIC_IO
1395	if (apic_8254_trial) {
1396
1397		printf("APIC_IO: Testing 8254 interrupt delivery\n");
1398		while (read_intr_count(8) < 6)
1399			;	/* nothing */
1400		if (read_intr_count(apic_8254_intr) < 3) {
1401			/*
1402			 * The MP table is broken.
1403			 * The 8254 was not connected to the specified pin
1404			 * on the IO APIC.
1405			 * Workaround: Limited variant of mixed mode.
1406			 */
1407			INTRDIS(1 << apic_8254_intr);
1408			inthand_remove(clkdesc);
1409			printf("APIC_IO: Broken MP table detected: "
1410			       "8254 is not connected to "
1411			       "IOAPIC #%d intpin %d\n",
1412			       int_to_apicintpin[apic_8254_intr].ioapic,
1413			       int_to_apicintpin[apic_8254_intr].int_pin);
1414			/*
1415			 * Revoke current ISA IRQ 0 assignment and
1416			 * configure a fallback interrupt routing from
1417			 * the 8254 Timer via the 8259 PIC to the
1418			 * an ExtInt interrupt line on IOAPIC #0 intpin 0.
1419			 * We reuse the low level interrupt handler number.
1420			 */
1421			if (apic_irq(0, 0) < 0) {
1422				revoke_apic_irq(apic_8254_intr);
1423				assign_apic_irq(0, 0, apic_8254_intr);
1424			}
1425			apic_8254_intr = apic_irq(0, 0);
1426			setup_8254_mixed_mode();
1427			inthand_add("clk", apic_8254_intr,
1428				    (driver_intr_t *)clkintr, NULL,
1429				    INTR_TYPE_CLK | INTR_FAST, NULL);
1430			INTREN(1 << apic_8254_intr);
1431		}
1432
1433	}
1434	if (apic_int_type(0, 0) != 3 ||
1435	    int_to_apicintpin[apic_8254_intr].ioapic != 0 ||
1436	    int_to_apicintpin[apic_8254_intr].int_pin != 0)
1437		printf("APIC_IO: routing 8254 via IOAPIC #%d intpin %d\n",
1438		       int_to_apicintpin[apic_8254_intr].ioapic,
1439		       int_to_apicintpin[apic_8254_intr].int_pin);
1440	else
1441		printf("APIC_IO: "
1442		       "routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
1443#endif
1444
1445}
1446
1447#ifdef APIC_IO
1448static u_long
1449read_intr_count(int vec)
1450{
1451	u_long *up;
1452	up = intr_countp[vec];
1453	if (up)
1454		return *up;
1455	return 0UL;
1456}
1457
1458static void
1459setup_8254_mixed_mode()
1460{
1461	/*
1462	 * Allow 8254 timer to INTerrupt 8259:
1463	 *  re-initialize master 8259:
1464	 *   reset; prog 4 bytes, single ICU, edge triggered
1465	 */
1466	outb(IO_ICU1, 0x13);
1467#ifdef PC98
1468	outb(IO_ICU1 + 2, NRSVIDT);	/* start vector (unused) */
1469	outb(IO_ICU1 + 2, 0x00);	/* ignore slave */
1470	outb(IO_ICU1 + 2, 0x03);	/* auto EOI, 8086 */
1471	outb(IO_ICU1 + 2, 0xfe);	/* unmask INT0 */
1472#else
1473	outb(IO_ICU1 + 1, NRSVIDT);	/* start vector (unused) */
1474	outb(IO_ICU1 + 1, 0x00);	/* ignore slave */
1475	outb(IO_ICU1 + 1, 0x03);	/* auto EOI, 8086 */
1476	outb(IO_ICU1 + 1, 0xfe);	/* unmask INT0 */
1477#endif
1478	/* program IO APIC for type 3 INT on INT0 */
1479	if (ext_int_setup(0, 0) < 0)
1480		panic("8254 redirect via APIC pin0 impossible!");
1481}
1482#endif
1483
1484void
1485setstatclockrate(int newhz)
1486{
1487#ifndef PC98
1488	if (newhz == RTC_PROFRATE)
1489		rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
1490	else
1491		rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
1492	writertc(RTC_STATUSA, rtc_statusa);
1493#endif
1494}
1495
1496static int
1497sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
1498{
1499	int error;
1500	u_int freq;
1501
1502	/*
1503	 * Use `i8254' instead of `timer' in external names because `timer'
1504	 * is is too generic.  Should use it everywhere.
1505	 */
1506	freq = timer_freq;
1507	error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
1508	if (error == 0 && req->newptr != NULL) {
1509		if (timer0_state != RELEASED)
1510			return (EBUSY);	/* too much trouble to handle */
1511		set_timer_freq(freq, hz);
1512		i8254_timecounter.tc_frequency = freq;
1513		tc_update(&i8254_timecounter);
1514	}
1515	return (error);
1516}
1517
1518SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
1519    0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
1520
1521static int
1522sysctl_machdep_tsc_freq(SYSCTL_HANDLER_ARGS)
1523{
1524	int error;
1525	u_int freq;
1526
1527	if (tsc_timecounter.tc_frequency == 0)
1528		return (EOPNOTSUPP);
1529	freq = tsc_freq;
1530	error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
1531	if (error == 0 && req->newptr != NULL) {
1532		tsc_freq = freq;
1533		tsc_timecounter.tc_frequency = tsc_freq;
1534		tc_update(&tsc_timecounter);
1535	}
1536	return (error);
1537}
1538
1539SYSCTL_PROC(_machdep, OID_AUTO, tsc_freq, CTLTYPE_INT | CTLFLAG_RW,
1540    0, sizeof(u_int), sysctl_machdep_tsc_freq, "I", "");
1541
1542static unsigned
1543i8254_get_timecount(struct timecounter *tc)
1544{
1545	u_int count;
1546	u_int high, low;
1547	u_int eflags;
1548
1549	eflags = read_eflags();
1550	mtx_lock_spin(&clock_lock);
1551
1552	/* Select timer0 and latch counter value. */
1553	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
1554
1555	low = inb(TIMER_CNTR0);
1556	high = inb(TIMER_CNTR0);
1557	count = timer0_max_count - ((high << 8) | low);
1558	if (count < i8254_lastcount ||
1559	    (!i8254_ticked && (clkintr_pending ||
1560	    ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
1561#ifdef APIC_IO
1562#define	lapic_irr1	((volatile u_int *)&lapic)[0x210 / 4]	/* XXX XXX */
1563	    /* XXX this assumes that apic_8254_intr is < 24. */
1564	    (lapic_irr1 & (1 << apic_8254_intr))))
1565#else
1566	    (inb(IO_ICU1) & 1)))
1567#endif
1568	    )) {
1569		i8254_ticked = 1;
1570		i8254_offset += timer0_max_count;
1571	}
1572	i8254_lastcount = count;
1573	count += i8254_offset;
1574	mtx_unlock_spin(&clock_lock);
1575	return (count);
1576}
1577
1578static unsigned
1579tsc_get_timecount(struct timecounter *tc)
1580{
1581	return (rdtsc());
1582}
1583
1584/*
1585 * Attach to the ISA PnP descriptors for the timer and realtime clock.
1586 */
1587static struct isa_pnp_id attimer_ids[] = {
1588	{ 0x0001d041 /* PNP0100 */, "AT timer" },
1589	{ 0x000bd041 /* PNP0B00 */, "AT realtime clock" },
1590	{ 0 }
1591};
1592
1593static int
1594attimer_probe(device_t dev)
1595{
1596	int result;
1597
1598	if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids)) <= 0)
1599		device_quiet(dev);
1600	return(result);
1601}
1602
1603static int
1604attimer_attach(device_t dev)
1605{
1606	return(0);
1607}
1608
1609static device_method_t attimer_methods[] = {
1610	/* Device interface */
1611	DEVMETHOD(device_probe,		attimer_probe),
1612	DEVMETHOD(device_attach,	attimer_attach),
1613	DEVMETHOD(device_detach,	bus_generic_detach),
1614	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
1615	DEVMETHOD(device_suspend,	bus_generic_suspend),	/* XXX stop statclock? */
1616	DEVMETHOD(device_resume,	bus_generic_resume),	/* XXX restart statclock? */
1617	{ 0, 0 }
1618};
1619
1620static driver_t attimer_driver = {
1621	"attimer",
1622	attimer_methods,
1623	1,		/* no softc */
1624};
1625
1626static devclass_t attimer_devclass;
1627
1628DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
1629