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