tsc.c revision 19173
14Srgrimes/*-
24Srgrimes * Copyright (c) 1990 The Regents of the University of California.
34Srgrimes * All rights reserved.
44Srgrimes *
54Srgrimes * This code is derived from software contributed to Berkeley by
64Srgrimes * William Jolitz and Don Ahn.
74Srgrimes *
84Srgrimes * Redistribution and use in source and binary forms, with or without
94Srgrimes * modification, are permitted provided that the following conditions
104Srgrimes * are met:
114Srgrimes * 1. Redistributions of source code must retain the above copyright
124Srgrimes *    notice, this list of conditions and the following disclaimer.
134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
144Srgrimes *    notice, this list of conditions and the following disclaimer in the
154Srgrimes *    documentation and/or other materials provided with the distribution.
164Srgrimes * 3. All advertising materials mentioning features or use of this software
174Srgrimes *    must display the following acknowledgement:
184Srgrimes *	This product includes software developed by the University of
194Srgrimes *	California, Berkeley and its contributors.
204Srgrimes * 4. Neither the name of the University nor the names of its contributors
214Srgrimes *    may be used to endorse or promote products derived from this software
224Srgrimes *    without specific prior written permission.
234Srgrimes *
244Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
254Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
264Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
274Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
284Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
294Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
304Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
314Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
324Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
334Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
344Srgrimes * SUCH DAMAGE.
354Srgrimes *
36619Srgrimes *	from: @(#)clock.c	7.2 (Berkeley) 5/12/91
3719173Sbde *	$Id: clock.c,v 1.70 1996/10/09 19:47:31 bde Exp $
384Srgrimes */
394Srgrimes
403185Ssos/*
4119173Sbde * Routines to handle clock hardware.
4219173Sbde */
4319173Sbde
4419173Sbde/*
453185Ssos * inittodr, settodr and support routines written
463185Ssos * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
473185Ssos *
483185Ssos * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94
492913Sache */
502913Sache
5116299Spst#include "opt_clock.h"
5218842Sbde#include "opt_cpu.h"
5313228Swollman
542056Swollman#include <sys/param.h>
552056Swollman#include <sys/systm.h>
562056Swollman#include <sys/time.h>
572056Swollman#include <sys/kernel.h>
5815508Sbde#include <sys/sysctl.h>
5915508Sbde
604180Sbde#include <machine/clock.h>
6115508Sbde#ifdef CLK_CALIBRATION_LOOP
6215508Sbde#include <machine/cons.h>
6315508Sbde#endif
6415508Sbde#include <machine/cpu.h>
652056Swollman#include <machine/frame.h>
6615508Sbde
672056Swollman#include <i386/isa/icu.h>
682056Swollman#include <i386/isa/isa.h>
697090Sbde#include <i386/isa/isa_device.h>
702056Swollman#include <i386/isa/rtc.h>
712056Swollman#include <i386/isa/timerreg.h>
724Srgrimes
732873Sbde/*
742873Sbde * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
752873Sbde * can use a simple formula for leap years.
762873Sbde */
772873Sbde#define	LEAPYEAR(y) ((u_int)(y) % 4 == 0)
782913Sache#define DAYSPERYEAR   (31+28+31+30+31+30+31+31+30+31+30+31)
792873Sbde
8015508Sbde#define	TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
814Srgrimes
824180Sbde/*
834180Sbde * Time in timer cycles that it takes for microtime() to disable interrupts
844180Sbde * and latch the count.  microtime() currently uses "cli; outb ..." so it
854180Sbde * normally takes less than 2 timer cycles.  Add a few for cache misses.
864180Sbde * Add a few more to allow for latency in bogus calls to microtime() with
874180Sbde * interrupts already disabled.
884180Sbde */
894180Sbde#define	TIMER0_LATCH_COUNT	20
904180Sbde
914180Sbde/*
9217236Sjoerg * Maximum frequency that we are willing to allow for timer0.  Must be
9317231Sjoerg * low enough to guarantee that the timer interrupt handler returns
9417231Sjoerg * before the next timer interrupt.  Must result in a lower TIMER_DIV
9517231Sjoerg * value than TIMER0_LATCH_COUNT so that we don't have to worry about
9617231Sjoerg * underflow in the calculation of timer0_overflow_threshold.
974180Sbde */
9817231Sjoerg#define	TIMER0_MAX_FREQ		20000
994180Sbde
10015045Sacheint	adjkerntz;		/* local offset	from GMT in seconds */
10115045Sacheint	disable_rtc_set;	/* disable resettodr() if != 0 */
1028448Sbdeu_int	idelayed;
10313000Sdg#if defined(I586_CPU) || defined(I686_CPU)
10419173Sbdeu_int	i586_ctr_bias;
10517353Sbdeu_int	i586_ctr_comultiplier;
10617353Sbdeu_int	i586_ctr_freq;
10717353Sbdeu_int	i586_ctr_multiplier;
1082017Swollman#endif
10915345Snateint	statclock_disable;
1105291Sbdeu_int	stat_imask = SWI_CLOCK_MASK;
11117236Sjoerg#ifdef TIMER_FREQ
11217236Sjoergu_int	timer_freq = TIMER_FREQ;
11317236Sjoerg#else
11417236Sjoergu_int	timer_freq = 1193182;
11517236Sjoerg#endif
11619173Sbdeint	timer0_max_count;
11719173Sbdeu_int	timer0_overflow_threshold;
11819173Sbdeu_int	timer0_prescaler_count;
11919173Sbdeint	wall_cmos_clock;	/* wall	CMOS clock assumed if != 0 */
1201390Ssos
1214180Sbdestatic	int	beeping = 0;
1225291Sbdestatic	u_int	clk_imask = HWI_MASK | SWI_MASK;
1234180Sbdestatic	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
12419173Sbdestatic	u_int	hardclock_max_count;
1254180Sbde/*
1264180Sbde * XXX new_function and timer_func should not handle clockframes, but
1274180Sbde * timer_func currently needs to hold hardclock to handle the
1284180Sbde * timer0_state == 0 case.  We should use register_intr()/unregister_intr()
1294180Sbde * to switch between clkintr() and a slightly different timerintr().
1304180Sbde */
13119173Sbdestatic	void	(*new_function) __P((struct clockframe *frame));
13219173Sbdestatic	u_int	new_rate;
1334180Sbdestatic	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
13415345Snatestatic	u_char	rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
13517231Sjoerg
13617231Sjoerg/* Values for timerX_state: */
13717236Sjoerg#define	RELEASED	0
13817236Sjoerg#define	RELEASE_PENDING	1
13917236Sjoerg#define	ACQUIRED	2
14017236Sjoerg#define	ACQUIRE_PENDING	3
14117231Sjoerg
14217231Sjoergstatic	u_char	timer0_state;
14317231Sjoergstatic	u_char	timer2_state;
14419173Sbdestatic	void	(*timer_func) __P((struct clockframe *frame)) = hardclock;
1454180Sbde
14617353Sbde#if defined(I586_CPU) || defined(I686_CPU)
14717353Sbdestatic	void	set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
14817353Sbde#endif
14917353Sbde
15012724Sphkstatic void
1513185Ssosclkintr(struct clockframe frame)
1522074Swollman{
1531549Srgrimes	timer_func(&frame);
1541442Ssos	switch (timer0_state) {
15517236Sjoerg
15617231Sjoerg	case RELEASED:
1578448Sbde		setdelayed();
1581442Ssos		break;
15917236Sjoerg
16017231Sjoerg	case ACQUIRED:
1614180Sbde		if ((timer0_prescaler_count += timer0_max_count)
1624180Sbde		    >= hardclock_max_count) {
1631549Srgrimes			hardclock(&frame);
1648448Sbde			setdelayed();
1654180Sbde			timer0_prescaler_count -= hardclock_max_count;
1661390Ssos		}
1671442Ssos		break;
16817236Sjoerg
16917231Sjoerg	case ACQUIRE_PENDING:
1708448Sbde		setdelayed();
1714180Sbde		timer0_max_count = TIMER_DIV(new_rate);
1724180Sbde		timer0_overflow_threshold =
1734180Sbde			timer0_max_count - TIMER0_LATCH_COUNT;
1741442Ssos		disable_intr();
1754180Sbde		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
1764180Sbde		outb(TIMER_CNTR0, timer0_max_count & 0xff);
1774180Sbde		outb(TIMER_CNTR0, timer0_max_count >> 8);
1781442Ssos		enable_intr();
1794180Sbde		timer0_prescaler_count = 0;
1801442Ssos		timer_func = new_function;
18117231Sjoerg		timer0_state = ACQUIRED;
1821442Ssos		break;
18317236Sjoerg
18417231Sjoerg	case RELEASE_PENDING:
1854180Sbde		if ((timer0_prescaler_count += timer0_max_count)
1864180Sbde		    >= hardclock_max_count) {
1871549Srgrimes			hardclock(&frame);
1888448Sbde			setdelayed();
1895291Sbde			timer0_max_count = hardclock_max_count;
1904180Sbde			timer0_overflow_threshold =
1914180Sbde				timer0_max_count - TIMER0_LATCH_COUNT;
1921442Ssos			disable_intr();
1934180Sbde			outb(TIMER_MODE,
1944180Sbde			     TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
1954180Sbde			outb(TIMER_CNTR0, timer0_max_count & 0xff);
1964180Sbde			outb(TIMER_CNTR0, timer0_max_count >> 8);
1971442Ssos			enable_intr();
1984180Sbde			/*
1994180Sbde			 * See microtime.s for this magic.
2004180Sbde			 */
20117194Sbde			time.tv_usec += (27465 *
2024180Sbde				(timer0_prescaler_count - hardclock_max_count))
2034180Sbde				>> 15;
2044180Sbde			if (time.tv_usec >= 1000000)
2054180Sbde				time.tv_usec -= 1000000;
2064180Sbde			timer0_prescaler_count = 0;
20717231Sjoerg			timer_func = hardclock;
20817231Sjoerg			timer0_state = RELEASED;
2091442Ssos		}
2101442Ssos		break;
2111442Ssos	}
2121390Ssos}
2131390Ssos
21417231Sjoerg/*
21517236Sjoerg * The acquire and release functions must be called at ipl >= splclock().
21617231Sjoerg */
2171390Ssosint
2184180Sbdeacquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
2191390Ssos{
22017231Sjoerg	static int old_rate;
22117231Sjoerg
22217231Sjoerg	if (rate <= 0 || rate > TIMER0_MAX_FREQ)
22317231Sjoerg		return (-1);
22417231Sjoerg	switch (timer0_state) {
22517231Sjoerg
22617236Sjoerg	case RELEASED:
22717236Sjoerg		timer0_state = ACQUIRE_PENDING;
22817236Sjoerg		break;
22917231Sjoerg
23017236Sjoerg	case RELEASE_PENDING:
23117236Sjoerg		if (rate != old_rate)
23217236Sjoerg			return (-1);
23317236Sjoerg		/*
23417236Sjoerg		 * The timer has been released recently, but is being
23517236Sjoerg		 * re-acquired before the release completed.  In this
23617236Sjoerg		 * case, we simply reclaim it as if it had not been
23717236Sjoerg		 * released at all.
23817236Sjoerg		 */
23917236Sjoerg		timer0_state = ACQUIRED;
24017236Sjoerg		break;
24117236Sjoerg
24217236Sjoerg	default:
24317236Sjoerg		return (-1);	/* busy */
24417231Sjoerg	}
2451442Ssos	new_function = function;
24617231Sjoerg	old_rate = new_rate = rate;
24717231Sjoerg	return (0);
2481390Ssos}
2491390Ssos
2501390Ssosint
2511390Ssosacquire_timer2(int mode)
2521390Ssos{
25317231Sjoerg
25417231Sjoerg	if (timer2_state != RELEASED)
25517231Sjoerg		return (-1);
25617231Sjoerg	timer2_state = ACQUIRED;
25717236Sjoerg
25817236Sjoerg	/*
25917236Sjoerg	 * This access to the timer registers is as atomic as possible
26017236Sjoerg	 * because it is a single instruction.  We could do better if we
26117236Sjoerg	 * knew the rate.  Use of splclock() limits glitches to 10-100us,
26217236Sjoerg	 * and this is probably good enough for timer2, so we aren't as
26317236Sjoerg	 * careful with it as with timer0.
26417236Sjoerg	 */
26517236Sjoerg	outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
26617236Sjoerg
26717231Sjoerg	return (0);
2681390Ssos}
2691390Ssos
2701390Ssosint
2711390Ssosrelease_timer0()
2721390Ssos{
27317231Sjoerg	switch (timer0_state) {
27417231Sjoerg
27517236Sjoerg	case ACQUIRED:
27617236Sjoerg		timer0_state = RELEASE_PENDING;
27717236Sjoerg		break;
27817231Sjoerg
27917236Sjoerg	case ACQUIRE_PENDING:
28017236Sjoerg		/* Nothing happened yet, release quickly. */
28117236Sjoerg		timer0_state = RELEASED;
28217236Sjoerg		break;
28317236Sjoerg
28417236Sjoerg	default:
28517236Sjoerg		return (-1);
28617231Sjoerg	}
28717231Sjoerg	return (0);
2881390Ssos}
2891390Ssos
2901390Ssosint
2911390Ssosrelease_timer2()
2921390Ssos{
29317231Sjoerg
29417231Sjoerg	if (timer2_state != ACQUIRED)
29517231Sjoerg		return (-1);
29617231Sjoerg	timer2_state = RELEASED;
29717236Sjoerg	outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
29817231Sjoerg	return (0);
2991390Ssos}
3001390Ssos
3013185Ssos/*
3023185Ssos * This routine receives statistical clock interrupts from the RTC.
3033185Ssos * As explained above, these occur at 128 interrupts per second.
3043185Ssos * When profiling, we receive interrupts at a rate of 1024 Hz.
3053185Ssos *
3063185Ssos * This does not actually add as much overhead as it sounds, because
3073185Ssos * when the statistical clock is active, the hardclock driver no longer
3083185Ssos * needs to keep (inaccurate) statistics on its own.  This decouples
3093185Ssos * statistics gathering from scheduling interrupts.
3103185Ssos *
3113185Ssos * The RTC chip requires that we read status register C (RTC_INTR)
3123185Ssos * to acknowledge an interrupt, before it will generate the next one.
3133185Ssos */
31412724Sphkstatic void
3153185Ssosrtcintr(struct clockframe frame)
3163185Ssos{
3173185Ssos	u_char stat;
3183185Ssos	stat = rtcin(RTC_INTR);
3193185Ssos	if(stat & RTCIR_PERIOD) {
3203185Ssos		statclock(&frame);
3213185Ssos	}
3223185Ssos}
3231390Ssos
32418297Sbde#include "opt_ddb.h"
3255291Sbde#ifdef DDB
32618297Sbde#include <ddb/ddb.h>
32718297Sbde
32818297SbdeDB_SHOW_COMMAND(rtc, rtc)
3293185Ssos{
3305291Sbde	printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n",
3315291Sbde	       rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY),
3325291Sbde	       rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC),
3335291Sbde	       rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR));
3343185Ssos}
33518297Sbde#endif /* DDB */
3363185Ssos
3371390Ssosstatic int
33810268Sbdegetit(void)
3391390Ssos{
34016428Sbde	u_long ef;
3411390Ssos	int high, low;
3421390Ssos
34316428Sbde	ef = read_eflags();
3441390Ssos	disable_intr();
34516428Sbde
34616428Sbde	/* Select timer0 and latch counter value. */
34719173Sbde	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
34816428Sbde
3491390Ssos	low = inb(TIMER_CNTR0);
3501390Ssos	high = inb(TIMER_CNTR0);
35116428Sbde
35216428Sbde	write_eflags(ef);
3531390Ssos	return ((high << 8) | low);
3541390Ssos}
3551390Ssos
3562017Swollman/*
3571390Ssos * Wait "n" microseconds.
35815508Sbde * Relies on timer 1 counting down from (timer_freq / hz)
3591390Ssos * Note: timer had better have been programmed before this is first used!
3601390Ssos */
3611390Ssosvoid
3621390SsosDELAY(int n)
3631390Ssos{
3642873Sbde	int prev_tick, tick, ticks_left, sec, usec;
3651390Ssos
3661390Ssos#ifdef DELAYDEBUG
3671390Ssos	int getit_calls = 1;
3681390Ssos	int n1;
3691390Ssos	static int state = 0;
3701390Ssos
3711390Ssos	if (state == 0) {
3721390Ssos		state = 1;
3731390Ssos		for (n1 = 1; n1 <= 10000000; n1 *= 10)
3741390Ssos			DELAY(n1);
3751390Ssos		state = 2;
3761390Ssos	}
3771390Ssos	if (state == 1)
3781390Ssos		printf("DELAY(%d)...", n);
3791390Ssos#endif
3801390Ssos	/*
3811390Ssos	 * Read the counter first, so that the rest of the setup overhead is
3821390Ssos	 * counted.  Guess the initial overhead is 20 usec (on most systems it
3831390Ssos	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
3841390Ssos	 * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
3851390Ssos	 * multiplications and divisions to scale the count take a while).
3861390Ssos	 */
38710268Sbde	prev_tick = getit();
3881390Ssos	n -= 20;
3891390Ssos	/*
39015508Sbde	 * Calculate (n * (timer_freq / 1e6)) without using floating point
3911390Ssos	 * and without any avoidable overflows.
3921390Ssos	 */
3931390Ssos	sec = n / 1000000;
3941390Ssos	usec = n - sec * 1000000;
39515508Sbde	ticks_left = sec * timer_freq
39615508Sbde		     + usec * (timer_freq / 1000000)
39715508Sbde		     + usec * ((timer_freq % 1000000) / 1000) / 1000
39815508Sbde		     + usec * (timer_freq % 1000) / 1000000;
39915508Sbde	if (n < 0)
40015508Sbde		ticks_left = 0;	/* XXX timer_freq is unsigned */
4011390Ssos
4021390Ssos	while (ticks_left > 0) {
40310268Sbde		tick = getit();
4041390Ssos#ifdef DELAYDEBUG
4051390Ssos		++getit_calls;
4061390Ssos#endif
4071390Ssos		if (tick > prev_tick)
4084180Sbde			ticks_left -= prev_tick - (tick - timer0_max_count);
4091390Ssos		else
4101390Ssos			ticks_left -= prev_tick - tick;
4111390Ssos		prev_tick = tick;
4121390Ssos	}
4131390Ssos#ifdef DELAYDEBUG
4141390Ssos	if (state == 1)
4151390Ssos		printf(" %d calls to getit() at %d usec each\n",
4161390Ssos		       getit_calls, (n + 5) / getit_calls);
4171390Ssos#endif
4181390Ssos}
4191390Ssos
4201390Ssosstatic void
4213185Ssossysbeepstop(void *chan)
4221390Ssos{
4231390Ssos	outb(IO_PPI, inb(IO_PPI)&0xFC);	/* disable counter2 output to speaker */
4241390Ssos	release_timer2();
4251390Ssos	beeping = 0;
4261390Ssos}
4271390Ssos
4288876Srgrimesint
4291390Ssossysbeep(int pitch, int period)
4301390Ssos{
43117231Sjoerg	int x = splclock();
4321390Ssos
4338876Srgrimes	if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
43417231Sjoerg		if (!beeping) {
43517231Sjoerg			/* Something else owns it. */
43617231Sjoerg			splx(x);
43717231Sjoerg			return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
43817231Sjoerg		}
4391442Ssos	disable_intr();
4401390Ssos	outb(TIMER_CNTR2, pitch);
4411390Ssos	outb(TIMER_CNTR2, (pitch>>8));
4421442Ssos	enable_intr();
4431390Ssos	if (!beeping) {
44417231Sjoerg		/* enable counter2 output to speaker */
44517231Sjoerg		outb(IO_PPI, inb(IO_PPI) | 3);
4461390Ssos		beeping = period;
4472873Sbde		timeout(sysbeepstop, (void *)NULL, period);
4481390Ssos	}
44917231Sjoerg	splx(x);
45017231Sjoerg	return (0);
4511390Ssos}
4521390Ssos
4532913Sache/*
4542913Sache * RTC support routines
4552913Sache */
4562913Sache
45714943Sbdeint
45814943Sbdertcin(reg)
45914943Sbde	int reg;
46014943Sbde{
46114943Sbde	u_char val;
46214943Sbde
46314943Sbde	outb(IO_RTC, reg);
46414943Sbde	inb(0x84);
46514943Sbde	val = inb(IO_RTC + 1);
46614943Sbde	inb(0x84);
46714943Sbde	return (val);
46814943Sbde}
46914943Sbde
47013445Sphkstatic __inline void
4715291Sbdewritertc(u_char reg, u_char val)
4722913Sache{
4735291Sbde	outb(IO_RTC, reg);
4745291Sbde	outb(IO_RTC + 1, val);
4752913Sache}
4762913Sache
47713445Sphkstatic __inline int
4782913Sachereadrtc(int port)
4792913Sache{
48013445Sphk	return(bcd2bin(rtcin(port)));
4812913Sache}
4822913Sache
48315508Sbdestatic u_int
48415508Sbdecalibrate_clocks(void)
48515508Sbde{
48615508Sbde	u_int count, prev_count, tot_count;
48715508Sbde	int sec, start_sec, timeout;
48815508Sbde
48919173Sbde	printf("Calibrating clock(s) relative to mc146818A clock ... ");
49015508Sbde	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
49115508Sbde		goto fail;
49215508Sbde	timeout = 100000000;
49315508Sbde
49415508Sbde	/* Read the mc146818A seconds counter. */
49515508Sbde	for (;;) {
49615508Sbde		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
49715508Sbde			sec = rtcin(RTC_SEC);
49815508Sbde			break;
49915508Sbde		}
50015508Sbde		if (--timeout == 0)
50115508Sbde			goto fail;
50215508Sbde	}
50315508Sbde
50415508Sbde	/* Wait for the mC146818A seconds counter to change. */
50515508Sbde	start_sec = sec;
50615508Sbde	for (;;) {
50715508Sbde		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
50815508Sbde			sec = rtcin(RTC_SEC);
50915508Sbde			if (sec != start_sec)
51015508Sbde				break;
51115508Sbde		}
51215508Sbde		if (--timeout == 0)
51315508Sbde			goto fail;
51415508Sbde	}
51515508Sbde
51615508Sbde	/* Start keeping track of the i8254 counter. */
51715508Sbde	prev_count = getit();
51815508Sbde	if (prev_count == 0 || prev_count > timer0_max_count)
51915508Sbde		goto fail;
52015508Sbde	tot_count = 0;
52115508Sbde
52215508Sbde#if defined(I586_CPU) || defined(I686_CPU)
52315508Sbde	if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)
52415508Sbde		wrmsr(0x10, 0LL);	/* XXX 0x10 is the MSR for the TSC */
52515508Sbde#endif
52615508Sbde
52715508Sbde	/*
52815508Sbde	 * Wait for the mc146818A seconds counter to change.  Read the i8254
52915508Sbde	 * counter for each iteration since this is convenient and only
53015508Sbde	 * costs a few usec of inaccuracy. The timing of the final reads
53115508Sbde	 * of the counters almost matches the timing of the initial reads,
53215508Sbde	 * so the main cause of inaccuracy is the varying latency from
53315508Sbde	 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the
53415508Sbde	 * rtcin(RTC_SEC) that returns a changed seconds count.  The
53515508Sbde	 * maximum inaccuracy from this cause is < 10 usec on 486's.
53615508Sbde	 */
53715508Sbde	start_sec = sec;
53815508Sbde	for (;;) {
53915508Sbde		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP))
54015508Sbde			sec = rtcin(RTC_SEC);
54115508Sbde		count = getit();
54215508Sbde		if (count == 0 || count > timer0_max_count)
54315508Sbde			goto fail;
54415508Sbde		if (count > prev_count)
54515508Sbde			tot_count += prev_count - (count - timer0_max_count);
54615508Sbde		else
54715508Sbde			tot_count += prev_count - count;
54815508Sbde		prev_count = count;
54915508Sbde		if (sec != start_sec)
55015508Sbde			break;
55115508Sbde		if (--timeout == 0)
55215508Sbde			goto fail;
55315508Sbde	}
55415508Sbde
55515508Sbde#if defined(I586_CPU) || defined(I686_CPU)
55615508Sbde	/*
55715508Sbde	 * Read the cpu cycle counter.  The timing considerations are
55815508Sbde	 * similar to those for the i8254 clock.
55915508Sbde	 */
56015508Sbde	if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
56117353Sbde		set_i586_ctr_freq((u_int)rdtsc(), tot_count);
56215508Sbde		printf("i586 clock: %u Hz, ", i586_ctr_freq);
56315508Sbde	}
56415508Sbde#endif
56515508Sbde
56615508Sbde	printf("i8254 clock: %u Hz\n", tot_count);
56715508Sbde	return (tot_count);
56815508Sbde
56915508Sbdefail:
57015508Sbde	printf("failed, using default i8254 clock of %u Hz\n", timer_freq);
57115508Sbde	return (timer_freq);
57215508Sbde}
57315508Sbde
57415508Sbdestatic void
57515508Sbdeset_timer_freq(u_int freq, int intr_freq)
57615508Sbde{
57716874Sbde	u_long ef;
57815508Sbde
57915508Sbde	ef = read_eflags();
58016874Sbde	disable_intr();
58115508Sbde	timer_freq = freq;
58215508Sbde	timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
58315508Sbde	timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
58415508Sbde	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
58515508Sbde	outb(TIMER_CNTR0, timer0_max_count & 0xff);
58615508Sbde	outb(TIMER_CNTR0, timer0_max_count >> 8);
58715508Sbde	write_eflags(ef);
58815508Sbde}
58915508Sbde
5905291Sbde/*
5915291Sbde * Initialize 8253 timer 0 early so that it can be used in DELAY().
5925291Sbde * XXX initialization of other timers is unintentionally left blank.
5935291Sbde */
5941390Ssosvoid
5958876Srgrimesstartrtclock()
596798Swollman{
59715508Sbde	u_int delta, freq;
59815508Sbde
59915508Sbde	writertc(RTC_STATUSA, rtc_statusa);
60015508Sbde	writertc(RTC_STATUSB, RTCSB_24HR);
60115508Sbde
60216874Sbde	set_timer_freq(timer_freq, hz);
60315508Sbde	freq = calibrate_clocks();
60415508Sbde#ifdef CLK_CALIBRATION_LOOP
60515508Sbde	if (bootverbose) {
60615508Sbde		printf(
60715508Sbde		"Press a key on the console to abort clock calibration\n");
60818288Sbde		while (cncheckc() == -1)
60915508Sbde			calibrate_clocks();
61015508Sbde	}
61115508Sbde#endif
61215508Sbde
61315508Sbde	/*
61415508Sbde	 * Use the calibrated i8254 frequency if it seems reasonable.
61515508Sbde	 * Otherwise use the default, and don't use the calibrated i586
61615508Sbde	 * frequency.
61715508Sbde	 */
61815508Sbde	delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
61915508Sbde	if (delta < timer_freq / 100) {
62015508Sbde#ifndef CLK_USE_I8254_CALIBRATION
62116300Spst		if (bootverbose)
62219173Sbde			printf(
62315508Sbde"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
62415508Sbde		freq = timer_freq;
62515508Sbde#endif
62615508Sbde		timer_freq = freq;
62715508Sbde	} else {
62815508Sbde		printf("%d Hz differs from default of %d Hz by more than 1%%\n",
62915508Sbde		       freq, timer_freq);
63015508Sbde#if defined(I586_CPU) || defined(I686_CPU)
63115508Sbde		i586_ctr_freq = 0;
63215508Sbde#endif
63315508Sbde	}
63415508Sbde
63515508Sbde	set_timer_freq(timer_freq, hz);
63615508Sbde
63715508Sbde#if defined(I586_CPU) || defined(I686_CPU)
63815508Sbde#ifndef CLK_USE_I586_CALIBRATION
63917395Sbde	if (i586_ctr_freq != 0) {
64016300Spst		if (bootverbose)
64119173Sbde			printf(
64215508Sbde"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
64315508Sbde		i586_ctr_freq = 0;
64415508Sbde	}
64515508Sbde#endif
64617395Sbde	if (i586_ctr_freq == 0 &&
64715508Sbde	    (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) {
64815508Sbde		/*
64915508Sbde		 * Calibration of the i586 clock relative to the mc146818A
65015508Sbde		 * clock failed.  Do a less accurate calibration relative
65115508Sbde		 * to the i8254 clock.
65215508Sbde		 */
65315508Sbde		wrmsr(0x10, 0LL);	/* XXX */
65415508Sbde		DELAY(1000000);
65517353Sbde		set_i586_ctr_freq((u_int)rdtsc(), timer_freq);
65616300Spst#ifdef CLK_USE_I586_CALIBRATION
65715508Sbde		printf("i586 clock: %u Hz\n", i586_ctr_freq);
65816300Spst#endif
65915508Sbde	}
66015508Sbde#endif
6614Srgrimes}
6624Srgrimes
6632913Sache/*
6642913Sache * Initialize the time of day register,	based on the time base which is, e.g.
6652913Sache * from	a filesystem.
6662913Sache */
6672913Sachevoid
6683185Ssosinittodr(time_t base)
6694Srgrimes{
6702913Sache	unsigned long	sec, days;
6712913Sache	int		yd;
6722913Sache	int		year, month;
6732913Sache	int		y, m, s;
6744Srgrimes
6752913Sache	s = splclock();
6762913Sache	time.tv_sec  = base;
6772913Sache	time.tv_usec = 0;
6782913Sache	splx(s);
6791390Ssos
6802913Sache	/* Look	if we have a RTC present and the time is valid */
6819202Srgrimes	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
6822913Sache		goto wrong_time;
6834Srgrimes
6842913Sache	/* wait	for time update	to complete */
6852913Sache	/* If RTCSA_TUP	is zero, we have at least 244us	before next update */
6862913Sache	while (rtcin(RTC_STATUSA) & RTCSA_TUP);
6874Srgrimes
6882913Sache	days = 0;
6893355Sache#ifdef USE_RTC_CENTURY
6902913Sache	year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY)	* 100;
6913355Sache#else
6923355Sache	year = readrtc(RTC_YEAR) + 1900;
6932913Sache	if (year < 1970)
6943355Sache		year += 100;
6953355Sache#endif
6963355Sache	if (year < 1970)
6972913Sache		goto wrong_time;
6982913Sache	month =	readrtc(RTC_MONTH);
6992913Sache	for (m = 1; m <	month; m++)
7002913Sache		days +=	daysinmonth[m-1];
7012913Sache	if ((month > 2)	&& LEAPYEAR(year))
7022913Sache		days ++;
7032913Sache	days +=	readrtc(RTC_DAY) - 1;
7042913Sache	yd = days;
7052913Sache	for (y = 1970; y < year; y++)
7062913Sache		days +=	DAYSPERYEAR + LEAPYEAR(y);
7072913Sache	sec = ((( days * 24 +
7082913Sache		  readrtc(RTC_HRS)) * 60 +
7092913Sache		  readrtc(RTC_MIN)) * 60 +
7102913Sache		  readrtc(RTC_SEC));
7112913Sache	/* sec now contains the	number of seconds, since Jan 1 1970,
7122913Sache	   in the local	time zone */
7131390Ssos
71415054Sache	sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
7154Srgrimes
7162913Sache	s = splclock();
7172913Sache	time.tv_sec = sec;
7182913Sache	splx(s);
7192913Sache	return;
7202913Sache
7212913Sachewrong_time:
7222913Sache	printf("Invalid	time in	real time clock.\n");
7232913Sache	printf("Check and reset	the date immediately!\n");
7244Srgrimes}
7254Srgrimes
7264Srgrimes/*
7272913Sache * Write system	time back to RTC
7284Srgrimes */
7294180Sbdevoid
7304180Sbderesettodr()
7314Srgrimes{
7322913Sache	unsigned long	tm;
73311872Sphk	int		y, m, s;
7344Srgrimes
7353366Sache	if (disable_rtc_set)
7363366Sache		return;
7373366Sache
7382913Sache	s = splclock();
7392913Sache	tm = time.tv_sec;
7402913Sache	splx(s);
7414Srgrimes
7425291Sbde	/* Disable RTC updates and interrupts. */
7432913Sache	writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
7444Srgrimes
7453366Sache	/* Calculate local time	to put in RTC */
7461390Ssos
74715054Sache	tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
7482913Sache
74913445Sphk	writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
75013445Sphk	writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
75113445Sphk	writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24;	/* Write back Hours   */
7522913Sache
7532913Sache	/* We have now the days	since 01-01-1970 in tm */
7542913Sache	writertc(RTC_WDAY, (tm+4)%7);			/* Write back Weekday */
75513350Sache	for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
75613350Sache	     tm >= m;
75713350Sache	     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
75813350Sache	     tm -= m;
7592913Sache
7602913Sache	/* Now we have the years in y and the day-of-the-year in tm */
76113453Sache	writertc(RTC_YEAR, bin2bcd(y%100));		/* Write back Year    */
76213350Sache#ifdef USE_RTC_CENTURY
76313445Sphk	writertc(RTC_CENTURY, bin2bcd(y/100));		/* ... and Century    */
7643355Sache#endif
76513402Sbde	for (m = 0; ; m++) {
76613402Sbde		int ml;
7672913Sache
76813402Sbde		ml = daysinmonth[m];
76913402Sbde		if (m == 1 && LEAPYEAR(y))
77013402Sbde			ml++;
77113402Sbde		if (tm < ml)
77213402Sbde			break;
77313402Sbde		tm -= ml;
77413402Sbde	}
77513402Sbde
77613445Sphk	writertc(RTC_MONTH, bin2bcd(m + 1));            /* Write back Month   */
77713445Sphk	writertc(RTC_DAY, bin2bcd(tm + 1));             /* Write back Month Day */
7782913Sache
7795291Sbde	/* Reenable RTC updates and interrupts. */
78015345Snate	writertc(RTC_STATUSB, rtc_statusb);
7814Srgrimes}
7824Srgrimes
7834Srgrimes/*
7845291Sbde * Start both clocks running.
7854Srgrimes */
7865291Sbdevoid
7875291Sbdecpu_initclocks()
7884Srgrimes{
7895291Sbde	int diag;
7904Srgrimes
79115345Snate	if (statclock_disable) {
79215345Snate		/*
79315345Snate		 * The stat interrupt mask is different without the
79415345Snate		 * statistics clock.  Also, don't set the interrupt
79515345Snate		 * flag which would normally cause the RTC to generate
79615345Snate		 * interrupts.
79715345Snate		 */
79815345Snate		stat_imask = HWI_MASK | SWI_MASK;
79915345Snate		rtc_statusb = RTCSB_24HR;
80015345Snate	} else {
80115345Snate	        /* Setting stathz to nonzero early helps avoid races. */
80215345Snate		stathz = RTC_NOPROFRATE;
80315345Snate		profhz = RTC_PROFRATE;
80415345Snate        }
8054Srgrimes
8065291Sbde	/* Finish initializing 8253 timer 0. */
8077090Sbde	register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
8087090Sbde		      /* XXX */ (inthand2_t *)clkintr, &clk_imask,
8097090Sbde		      /* unit */ 0);
8104Srgrimes	INTREN(IRQ0);
81113000Sdg#if defined(I586_CPU) || defined(I686_CPU)
81211452Swollman	/*
81311452Swollman	 * Finish setting up anti-jitter measures.
81411452Swollman	 */
81517395Sbde	if (i586_ctr_freq != 0) {
81615508Sbde		i586_last_tick = rdtsc();
81711452Swollman		i586_ctr_bias = i586_last_tick;
81811452Swollman	}
81911452Swollman#endif
8205291Sbde
8215291Sbde	/* Initialize RTC. */
8225291Sbde	writertc(RTC_STATUSA, rtc_statusa);
8235291Sbde	writertc(RTC_STATUSB, RTCSB_24HR);
82415345Snate
82515345Snate	/* Don't bother enabling the statistics clock. */
82615345Snate	if (statclock_disable)
82715345Snate		return;
8285291Sbde	diag = rtcin(RTC_DIAG);
8295291Sbde	if (diag != 0)
8305291Sbde		printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
8317090Sbde	register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
8327090Sbde		      /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
8337090Sbde		      /* unit */ 0);
8342074Swollman	INTREN(IRQ8);
83515345Snate	writertc(RTC_STATUSB, rtc_statusb);
8364Srgrimes}
8374Srgrimes
8384Srgrimesvoid
8391549Srgrimessetstatclockrate(int newhz)
8401549Srgrimes{
8415291Sbde	if (newhz == RTC_PROFRATE)
8422074Swollman		rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
8435291Sbde	else
8442074Swollman		rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
8455291Sbde	writertc(RTC_STATUSA, rtc_statusa);
8461549Srgrimes}
84715508Sbde
84815508Sbdestatic int
84915508Sbdesysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
85015508Sbde{
85115508Sbde	int error;
85215508Sbde	u_int freq;
85315508Sbde
85415508Sbde	/*
85515508Sbde	 * Use `i8254' instead of `timer' in external names because `timer'
85615508Sbde	 * is is too generic.  Should use it everywhere.
85715508Sbde	 */
85815508Sbde	freq = timer_freq;
85915508Sbde	error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
86017353Sbde	if (error == 0 && req->newptr != NULL) {
86115508Sbde		if (timer0_state != 0)
86215508Sbde			return (EBUSY);	/* too much trouble to handle */
86315508Sbde		set_timer_freq(freq, hz);
86417353Sbde#if defined(I586_CPU) || defined(I686_CPU)
86517353Sbde		set_i586_ctr_freq(i586_ctr_freq, timer_freq);
86617353Sbde#endif
86715508Sbde	}
86815508Sbde	return (error);
86915508Sbde}
87015508Sbde
87115508SbdeSYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
87215508Sbde	    0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
87315508Sbde
87415508Sbde#if defined(I586_CPU) || defined(I686_CPU)
87517353Sbdestatic void
87617353Sbdeset_i586_ctr_freq(u_int i586_freq, u_int i8254_freq)
87717353Sbde{
87817395Sbde	u_int comultiplier, multiplier;
87917353Sbde	u_long ef;
88017353Sbde
88117353Sbde	if (i586_freq == 0) {
88217353Sbde		i586_ctr_freq = i586_freq;
88317353Sbde		return;
88417353Sbde	}
88517353Sbde	comultiplier = ((unsigned long long)i586_freq
88617353Sbde			<< I586_CTR_COMULTIPLIER_SHIFT) / i8254_freq;
88717353Sbde	multiplier = (1000000LL << I586_CTR_MULTIPLIER_SHIFT) / i586_freq;
88817353Sbde	ef = read_eflags();
88917353Sbde	disable_intr();
89017353Sbde	i586_ctr_freq = i586_freq;
89117353Sbde	i586_ctr_comultiplier = comultiplier;
89217353Sbde	i586_ctr_multiplier = multiplier;
89317353Sbde	write_eflags(ef);
89417353Sbde}
89517353Sbde
89615508Sbdestatic int
89715508Sbdesysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
89815508Sbde{
89915508Sbde	int error;
90015508Sbde	u_int freq;
90115508Sbde
90217353Sbde	if (cpu_class != CPUCLASS_586 && cpu_class != CPUCLASS_686)
90315508Sbde		return (EOPNOTSUPP);
90415508Sbde	freq = i586_ctr_freq;
90515508Sbde	error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
90617353Sbde	if (error == 0 && req->newptr != NULL)
90717353Sbde		set_i586_ctr_freq(freq, timer_freq);
90815508Sbde	return (error);
90915508Sbde}
91015508Sbde
91115508SbdeSYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW,
91215508Sbde	    0, sizeof(u_int), sysctl_machdep_i586_freq, "I", "");
91315508Sbde#endif /* defined(I586_CPU) || defined(I686_CPU) */
914