clock.c revision 15508
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.57 1996/04/22 19:40:28 nate Exp $
38 */
39
40/*
41 * inittodr, settodr and support routines written
42 * by Christoph Robitschko <chmr@edvz.tu-graz.ac.at>
43 *
44 * reintroduced and updated by Chris Stenton <chris@gnome.co.uk> 8/10/94
45 */
46
47/*
48 * Primitive clock interrupt routines.
49 */
50#include "opt_ddb.h"
51
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/time.h>
55#include <sys/kernel.h>
56#include <sys/sysctl.h>
57
58#include <machine/clock.h>
59#ifdef CLK_CALIBRATION_LOOP
60#include <machine/cons.h>
61#endif
62#include <machine/cpu.h>
63#include <machine/frame.h>
64
65#include <i386/isa/icu.h>
66#include <i386/isa/isa.h>
67#include <i386/isa/isa_device.h>
68#include <i386/isa/rtc.h>
69#include <i386/isa/timerreg.h>
70
71/*
72 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
73 * can use a simple formula for leap years.
74 */
75#define	LEAPYEAR(y) ((u_int)(y) % 4 == 0)
76#define DAYSPERYEAR   (31+28+31+30+31+30+31+31+30+31+30+31)
77
78#define	TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
79
80/*
81 * Time in timer cycles that it takes for microtime() to disable interrupts
82 * and latch the count.  microtime() currently uses "cli; outb ..." so it
83 * normally takes less than 2 timer cycles.  Add a few for cache misses.
84 * Add a few more to allow for latency in bogus calls to microtime() with
85 * interrupts already disabled.
86 */
87#define	TIMER0_LATCH_COUNT	20
88
89/*
90 * Minimum maximum count that we are willing to program into timer0.
91 * Must be large enough to guarantee that the timer interrupt handler
92 * returns before the next timer interrupt.  Must be larger than
93 * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
94 * the calculation of timer0_overflow_threshold.
95 */
96#define	TIMER0_MIN_MAX_COUNT	TIMER_DIV(20000)
97
98int	adjkerntz;		/* local offset	from GMT in seconds */
99int	disable_rtc_set;	/* disable resettodr() if != 0 */
100int	wall_cmos_clock;	/* wall	CMOS clock assumed if != 0 */
101
102u_int	idelayed;
103#if defined(I586_CPU) || defined(I686_CPU)
104unsigned	i586_ctr_freq;
105unsigned	i586_ctr_rate;
106long long	i586_ctr_bias;
107long long	i586_last_tick;
108unsigned long	i586_avg_tick;
109#endif
110int	statclock_disable;
111u_int	stat_imask = SWI_CLOCK_MASK;
112int 	timer0_max_count;
113u_int 	timer0_overflow_threshold;
114u_int 	timer0_prescaler_count;
115
116static	int	beeping = 0;
117static	u_int	clk_imask = HWI_MASK | SWI_MASK;
118static	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
119static 	u_int	hardclock_max_count;
120/*
121 * XXX new_function and timer_func should not handle clockframes, but
122 * timer_func currently needs to hold hardclock to handle the
123 * timer0_state == 0 case.  We should use register_intr()/unregister_intr()
124 * to switch between clkintr() and a slightly different timerintr().
125 * This will require locking when acquiring and releasing timer0 - the
126 * current (nonexistent) locking doesn't seem to be adequate even now.
127 */
128static 	void	(*new_function) __P((struct clockframe *frame));
129static 	u_int	new_rate;
130static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
131static	u_char	rtc_statusb = RTCSB_24HR | RTCSB_PINTR;
132#ifdef TIMER_FREQ
133static	u_int	timer_freq = TIMER_FREQ;
134#else
135static	u_int	timer_freq = 1193182;
136#endif
137static 	char	timer0_state = 0;
138static	char	timer2_state = 0;
139static 	void	(*timer_func) __P((struct clockframe *frame)) = hardclock;
140
141#if 0
142void
143clkintr(struct clockframe frame)
144{
145	hardclock(&frame);
146	setdelayed();
147}
148#else
149static void
150clkintr(struct clockframe frame)
151{
152	timer_func(&frame);
153	switch (timer0_state) {
154	case 0:
155		setdelayed();
156		break;
157	case 1:
158		if ((timer0_prescaler_count += timer0_max_count)
159		    >= hardclock_max_count) {
160			hardclock(&frame);
161			setdelayed();
162			timer0_prescaler_count -= hardclock_max_count;
163		}
164		break;
165	case 2:
166		setdelayed();
167		timer0_max_count = TIMER_DIV(new_rate);
168		timer0_overflow_threshold =
169			timer0_max_count - TIMER0_LATCH_COUNT;
170		disable_intr();
171		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
172		outb(TIMER_CNTR0, timer0_max_count & 0xff);
173		outb(TIMER_CNTR0, timer0_max_count >> 8);
174		enable_intr();
175		timer0_prescaler_count = 0;
176		timer_func = new_function;
177		timer0_state = 1;
178		break;
179	case 3:
180		if ((timer0_prescaler_count += timer0_max_count)
181		    >= hardclock_max_count) {
182			hardclock(&frame);
183			setdelayed();
184			timer0_max_count = hardclock_max_count;
185			timer0_overflow_threshold =
186				timer0_max_count - TIMER0_LATCH_COUNT;
187			disable_intr();
188			outb(TIMER_MODE,
189			     TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
190			outb(TIMER_CNTR0, timer0_max_count & 0xff);
191			outb(TIMER_CNTR0, timer0_max_count >> 8);
192			enable_intr();
193			/*
194			 * See microtime.s for this magic.
195			 */
196			time.tv_usec += (27645 *
197				(timer0_prescaler_count - hardclock_max_count))
198				>> 15;
199			if (time.tv_usec >= 1000000)
200				time.tv_usec -= 1000000;
201			timer0_prescaler_count = 0;
202			timer_func = hardclock;;
203			timer0_state = 0;
204		}
205		break;
206	}
207}
208#endif
209
210int
211acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
212{
213	if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
214	    !function)
215		return -1;
216	new_function = function;
217	new_rate = rate;
218	timer0_state = 2;
219	return 0;
220}
221
222int
223acquire_timer2(int mode)
224{
225	if (timer2_state)
226		return -1;
227	timer2_state = 1;
228	outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
229	return 0;
230}
231
232int
233release_timer0()
234{
235	if (!timer0_state)
236		return -1;
237	timer0_state = 3;
238	return 0;
239}
240
241int
242release_timer2()
243{
244	if (!timer2_state)
245		return -1;
246	timer2_state = 0;
247	outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
248	return 0;
249}
250
251/*
252 * This routine receives statistical clock interrupts from the RTC.
253 * As explained above, these occur at 128 interrupts per second.
254 * When profiling, we receive interrupts at a rate of 1024 Hz.
255 *
256 * This does not actually add as much overhead as it sounds, because
257 * when the statistical clock is active, the hardclock driver no longer
258 * needs to keep (inaccurate) statistics on its own.  This decouples
259 * statistics gathering from scheduling interrupts.
260 *
261 * The RTC chip requires that we read status register C (RTC_INTR)
262 * to acknowledge an interrupt, before it will generate the next one.
263 */
264static void
265rtcintr(struct clockframe frame)
266{
267	u_char stat;
268	stat = rtcin(RTC_INTR);
269	if(stat & RTCIR_PERIOD) {
270		statclock(&frame);
271	}
272}
273
274#ifdef DDB
275static void
276DDB_printrtc(void)
277{
278	printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n",
279	       rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY),
280	       rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC),
281	       rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR));
282}
283#endif
284
285static int
286getit(void)
287{
288	int high, low;
289
290	disable_intr();
291	/* select timer0 and latch counter value */
292	outb(TIMER_MODE, TIMER_SEL0);
293	low = inb(TIMER_CNTR0);
294	high = inb(TIMER_CNTR0);
295	enable_intr();
296	return ((high << 8) | low);
297}
298
299/*
300 * Wait "n" microseconds.
301 * Relies on timer 1 counting down from (timer_freq / hz)
302 * Note: timer had better have been programmed before this is first used!
303 */
304void
305DELAY(int n)
306{
307	int prev_tick, tick, ticks_left, sec, usec;
308
309#ifdef DELAYDEBUG
310	int getit_calls = 1;
311	int n1;
312	static int state = 0;
313
314	if (state == 0) {
315		state = 1;
316		for (n1 = 1; n1 <= 10000000; n1 *= 10)
317			DELAY(n1);
318		state = 2;
319	}
320	if (state == 1)
321		printf("DELAY(%d)...", n);
322#endif
323	/*
324	 * Read the counter first, so that the rest of the setup overhead is
325	 * counted.  Guess the initial overhead is 20 usec (on most systems it
326	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
327	 * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
328	 * multiplications and divisions to scale the count take a while).
329	 */
330	prev_tick = getit();
331	n -= 20;
332	/*
333	 * Calculate (n * (timer_freq / 1e6)) without using floating point
334	 * and without any avoidable overflows.
335	 */
336	sec = n / 1000000;
337	usec = n - sec * 1000000;
338	ticks_left = sec * timer_freq
339		     + usec * (timer_freq / 1000000)
340		     + usec * ((timer_freq % 1000000) / 1000) / 1000
341		     + usec * (timer_freq % 1000) / 1000000;
342	if (n < 0)
343		ticks_left = 0;	/* XXX timer_freq is unsigned */
344
345	while (ticks_left > 0) {
346		tick = getit();
347#ifdef DELAYDEBUG
348		++getit_calls;
349#endif
350		if (tick > prev_tick)
351			ticks_left -= prev_tick - (tick - timer0_max_count);
352		else
353			ticks_left -= prev_tick - tick;
354		prev_tick = tick;
355	}
356#ifdef DELAYDEBUG
357	if (state == 1)
358		printf(" %d calls to getit() at %d usec each\n",
359		       getit_calls, (n + 5) / getit_calls);
360#endif
361}
362
363static void
364sysbeepstop(void *chan)
365{
366	outb(IO_PPI, inb(IO_PPI)&0xFC);	/* disable counter2 output to speaker */
367	release_timer2();
368	beeping = 0;
369}
370
371int
372sysbeep(int pitch, int period)
373{
374
375	if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
376		return -1;
377	disable_intr();
378	outb(TIMER_CNTR2, pitch);
379	outb(TIMER_CNTR2, (pitch>>8));
380	enable_intr();
381	if (!beeping) {
382	outb(IO_PPI, inb(IO_PPI) | 3);	/* enable counter2 output to speaker */
383		beeping = period;
384		timeout(sysbeepstop, (void *)NULL, period);
385	}
386	return 0;
387}
388
389/*
390 * RTC support routines
391 */
392
393int
394rtcin(reg)
395	int reg;
396{
397	u_char val;
398
399	outb(IO_RTC, reg);
400	inb(0x84);
401	val = inb(IO_RTC + 1);
402	inb(0x84);
403	return (val);
404}
405
406static __inline void
407writertc(u_char reg, u_char val)
408{
409	outb(IO_RTC, reg);
410	outb(IO_RTC + 1, val);
411}
412
413static __inline int
414readrtc(int port)
415{
416	return(bcd2bin(rtcin(port)));
417}
418
419static u_int
420calibrate_clocks(void)
421{
422	u_int count, prev_count, tot_count;
423	int sec, start_sec, timeout;
424
425	printf("Calibrating clock(s) relative to mc146818A clock ... ");
426	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
427		goto fail;
428	timeout = 100000000;
429
430	/* Read the mc146818A seconds counter. */
431	for (;;) {
432		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
433			sec = rtcin(RTC_SEC);
434			break;
435		}
436		if (--timeout == 0)
437			goto fail;
438	}
439
440	/* Wait for the mC146818A seconds counter to change. */
441	start_sec = sec;
442	for (;;) {
443		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
444			sec = rtcin(RTC_SEC);
445			if (sec != start_sec)
446				break;
447		}
448		if (--timeout == 0)
449			goto fail;
450	}
451
452	/* Start keeping track of the i8254 counter. */
453	prev_count = getit();
454	if (prev_count == 0 || prev_count > timer0_max_count)
455		goto fail;
456	tot_count = 0;
457
458#if defined(I586_CPU) || defined(I686_CPU)
459	if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)
460		wrmsr(0x10, 0LL);	/* XXX 0x10 is the MSR for the TSC */
461#endif
462
463	/*
464	 * Wait for the mc146818A seconds counter to change.  Read the i8254
465	 * counter for each iteration since this is convenient and only
466	 * costs a few usec of inaccuracy. The timing of the final reads
467	 * of the counters almost matches the timing of the initial reads,
468	 * so the main cause of inaccuracy is the varying latency from
469	 * inside getit() or rtcin(RTC_STATUSA) to the beginning of the
470	 * rtcin(RTC_SEC) that returns a changed seconds count.  The
471	 * maximum inaccuracy from this cause is < 10 usec on 486's.
472	 */
473	start_sec = sec;
474	for (;;) {
475		if (!(rtcin(RTC_STATUSA) & RTCSA_TUP))
476			sec = rtcin(RTC_SEC);
477		count = getit();
478		if (count == 0 || count > timer0_max_count)
479			goto fail;
480		if (count > prev_count)
481			tot_count += prev_count - (count - timer0_max_count);
482		else
483			tot_count += prev_count - count;
484		prev_count = count;
485		if (sec != start_sec)
486			break;
487		if (--timeout == 0)
488			goto fail;
489	}
490
491#if defined(I586_CPU) || defined(I686_CPU)
492	/*
493	 * Read the cpu cycle counter.  The timing considerations are
494	 * similar to those for the i8254 clock.
495	 */
496	if (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686) {
497		unsigned long long i586_count;
498
499		i586_count = rdtsc();
500		i586_ctr_freq = i586_count;
501		i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
502		printf("i586 clock: %u Hz, ", i586_ctr_freq);
503	}
504#endif
505
506	printf("i8254 clock: %u Hz\n", tot_count);
507	return (tot_count);
508
509fail:
510	printf("failed, using default i8254 clock of %u Hz\n", timer_freq);
511	return (timer_freq);
512}
513
514static void
515set_timer_freq(u_int freq, int intr_freq)
516{
517	u_long	ef;
518
519	ef = read_eflags();
520	timer_freq = freq;
521	timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
522	timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
523	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
524	outb(TIMER_CNTR0, timer0_max_count & 0xff);
525	outb(TIMER_CNTR0, timer0_max_count >> 8);
526	write_eflags(ef);
527}
528
529/*
530 * Initialize 8253 timer 0 early so that it can be used in DELAY().
531 * XXX initialization of other timers is unintentionally left blank.
532 */
533void
534startrtclock()
535{
536	u_int delta, freq;
537
538	writertc(RTC_STATUSA, rtc_statusa);
539	writertc(RTC_STATUSB, RTCSB_24HR);
540
541	/*
542	 * Temporarily calibrate with a high intr_freq to get a low
543	 * timer0_max_count to help detect bogus i8254 counts.
544	 */
545	set_timer_freq(timer_freq, 20000);
546	freq = calibrate_clocks();
547#ifdef CLK_CALIBRATION_LOOP
548	if (bootverbose) {
549		printf(
550		"Press a key on the console to abort clock calibration\n");
551		while (!cncheckc())
552			calibrate_clocks();
553	}
554#endif
555
556	/*
557	 * Use the calibrated i8254 frequency if it seems reasonable.
558	 * Otherwise use the default, and don't use the calibrated i586
559	 * frequency.
560	 */
561	delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
562	if (delta < timer_freq / 100) {
563#ifndef CLK_USE_I8254_CALIBRATION
564		printf(
565"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
566		freq = timer_freq;
567#endif
568		timer_freq = freq;
569	} else {
570		printf("%d Hz differs from default of %d Hz by more than 1%%\n",
571		       freq, timer_freq);
572#if defined(I586_CPU) || defined(I686_CPU)
573		i586_ctr_freq = 0;
574		i586_ctr_rate = 0;
575#endif
576	}
577
578	set_timer_freq(timer_freq, hz);
579
580#if defined(I586_CPU) || defined(I686_CPU)
581#ifndef CLK_USE_I586_CALIBRATION
582	if (i586_ctr_rate != 0) {
583		printf(
584"CLK_USE_I586_CALIBRATION not specified - using old calibration method\n");
585		i586_ctr_freq = 0;
586		i586_ctr_rate = 0;
587	}
588#endif
589	if (i586_ctr_rate == 0 &&
590	    (cpu_class == CPUCLASS_586 || cpu_class == CPUCLASS_686)) {
591		/*
592		 * Calibration of the i586 clock relative to the mc146818A
593		 * clock failed.  Do a less accurate calibration relative
594		 * to the i8254 clock.
595		 */
596		unsigned long long i586_count;
597
598		wrmsr(0x10, 0LL);	/* XXX */
599		DELAY(1000000);
600		i586_count = rdtsc();
601		i586_ctr_rate = (i586_count << I586_CTR_RATE_SHIFT) / 1000000;
602		printf("i586 clock: %u Hz\n", i586_ctr_freq);
603	}
604#endif
605}
606
607/*
608 * Initialize the time of day register,	based on the time base which is, e.g.
609 * from	a filesystem.
610 */
611void
612inittodr(time_t base)
613{
614	unsigned long	sec, days;
615	int		yd;
616	int		year, month;
617	int		y, m, s;
618
619	s = splclock();
620	time.tv_sec  = base;
621	time.tv_usec = 0;
622	splx(s);
623
624	/* Look	if we have a RTC present and the time is valid */
625	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
626		goto wrong_time;
627
628	/* wait	for time update	to complete */
629	/* If RTCSA_TUP	is zero, we have at least 244us	before next update */
630	while (rtcin(RTC_STATUSA) & RTCSA_TUP);
631
632	days = 0;
633#ifdef USE_RTC_CENTURY
634	year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY)	* 100;
635#else
636	year = readrtc(RTC_YEAR) + 1900;
637	if (year < 1970)
638		year += 100;
639#endif
640	if (year < 1970)
641		goto wrong_time;
642	month =	readrtc(RTC_MONTH);
643	for (m = 1; m <	month; m++)
644		days +=	daysinmonth[m-1];
645	if ((month > 2)	&& LEAPYEAR(year))
646		days ++;
647	days +=	readrtc(RTC_DAY) - 1;
648	yd = days;
649	for (y = 1970; y < year; y++)
650		days +=	DAYSPERYEAR + LEAPYEAR(y);
651	sec = ((( days * 24 +
652		  readrtc(RTC_HRS)) * 60 +
653		  readrtc(RTC_MIN)) * 60 +
654		  readrtc(RTC_SEC));
655	/* sec now contains the	number of seconds, since Jan 1 1970,
656	   in the local	time zone */
657
658	sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
659
660	s = splclock();
661	time.tv_sec = sec;
662	splx(s);
663	return;
664
665wrong_time:
666	printf("Invalid	time in	real time clock.\n");
667	printf("Check and reset	the date immediately!\n");
668}
669
670/*
671 * Write system	time back to RTC
672 */
673void
674resettodr()
675{
676	unsigned long	tm;
677	int		y, m, s;
678
679	if (disable_rtc_set)
680		return;
681
682	s = splclock();
683	tm = time.tv_sec;
684	splx(s);
685
686	/* Disable RTC updates and interrupts. */
687	writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
688
689	/* Calculate local time	to put in RTC */
690
691	tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
692
693	writertc(RTC_SEC, bin2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
694	writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
695	writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24;	/* Write back Hours   */
696
697	/* We have now the days	since 01-01-1970 in tm */
698	writertc(RTC_WDAY, (tm+4)%7);			/* Write back Weekday */
699	for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
700	     tm >= m;
701	     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
702	     tm -= m;
703
704	/* Now we have the years in y and the day-of-the-year in tm */
705	writertc(RTC_YEAR, bin2bcd(y%100));		/* Write back Year    */
706#ifdef USE_RTC_CENTURY
707	writertc(RTC_CENTURY, bin2bcd(y/100));		/* ... and Century    */
708#endif
709	for (m = 0; ; m++) {
710		int ml;
711
712		ml = daysinmonth[m];
713		if (m == 1 && LEAPYEAR(y))
714			ml++;
715		if (tm < ml)
716			break;
717		tm -= ml;
718	}
719
720	writertc(RTC_MONTH, bin2bcd(m + 1));            /* Write back Month   */
721	writertc(RTC_DAY, bin2bcd(tm + 1));             /* Write back Month Day */
722
723	/* Reenable RTC updates and interrupts. */
724	writertc(RTC_STATUSB, rtc_statusb);
725}
726
727/*
728 * Start both clocks running.
729 */
730void
731cpu_initclocks()
732{
733	int diag;
734
735	if (statclock_disable) {
736		/*
737		 * The stat interrupt mask is different without the
738		 * statistics clock.  Also, don't set the interrupt
739		 * flag which would normally cause the RTC to generate
740		 * interrupts.
741		 */
742		stat_imask = HWI_MASK | SWI_MASK;
743		rtc_statusb = RTCSB_24HR;
744	} else {
745	        /* Setting stathz to nonzero early helps avoid races. */
746		stathz = RTC_NOPROFRATE;
747		profhz = RTC_PROFRATE;
748        }
749
750	/* Finish initializing 8253 timer 0. */
751	register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
752		      /* XXX */ (inthand2_t *)clkintr, &clk_imask,
753		      /* unit */ 0);
754	INTREN(IRQ0);
755#if defined(I586_CPU) || defined(I686_CPU)
756	/*
757	 * Finish setting up anti-jitter measures.
758	 */
759	if (i586_ctr_rate) {
760		i586_last_tick = rdtsc();
761		i586_ctr_bias = i586_last_tick;
762	}
763#endif
764
765	/* Initialize RTC. */
766	writertc(RTC_STATUSA, rtc_statusa);
767	writertc(RTC_STATUSB, RTCSB_24HR);
768
769	/* Don't bother enabling the statistics clock. */
770	if (statclock_disable)
771		return;
772	diag = rtcin(RTC_DIAG);
773	if (diag != 0)
774		printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
775	register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
776		      /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
777		      /* unit */ 0);
778	INTREN(IRQ8);
779	writertc(RTC_STATUSB, rtc_statusb);
780}
781
782void
783setstatclockrate(int newhz)
784{
785	if (newhz == RTC_PROFRATE)
786		rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
787	else
788		rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
789	writertc(RTC_STATUSA, rtc_statusa);
790}
791
792static int
793sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
794{
795	int error;
796	u_int freq;
797
798	/*
799	 * Use `i8254' instead of `timer' in external names because `timer'
800	 * is is too generic.  Should use it everywhere.
801	 */
802	freq = timer_freq;
803	error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
804	if (error == 0 && freq != timer_freq) {
805		if (timer0_state != 0)
806			return (EBUSY);	/* too much trouble to handle */
807		set_timer_freq(freq, hz);
808	}
809	return (error);
810}
811
812SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
813	    0, sizeof(u_int), sysctl_machdep_i8254_freq, "I", "");
814
815#if defined(I586_CPU) || defined(I686_CPU)
816static int
817sysctl_machdep_i586_freq SYSCTL_HANDLER_ARGS
818{
819	int error;
820	u_int freq;
821
822	if (i586_ctr_rate == 0)
823		return (EOPNOTSUPP);
824	freq = i586_ctr_freq;
825	error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
826	if (error == 0 && freq != i586_ctr_freq) {
827		i586_ctr_freq = freq;
828		i586_ctr_rate = ((unsigned long long)freq <<
829				 I586_CTR_RATE_SHIFT) / 1000000;
830	}
831	return (error);
832}
833
834SYSCTL_PROC(_machdep, OID_AUTO, i586_freq, CTLTYPE_INT | CTLFLAG_RW,
835	    0, sizeof(u_int), sysctl_machdep_i586_freq, "I", "");
836#endif /* defined(I586_CPU) || defined(I686_CPU) */
837