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