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