tsc.c revision 13402
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.45 1996/01/08 18:50:14 ache 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 <machine/clock.h>
57#include <machine/frame.h>
58#include <i386/isa/icu.h>
59#include <i386/isa/isa.h>
60#include <i386/isa/isa_device.h>
61#include <i386/isa/rtc.h>
62#include <i386/isa/timerreg.h>
63
64/*
65 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
66 * can use a simple formula for leap years.
67 */
68#define	LEAPYEAR(y) ((u_int)(y) % 4 == 0)
69#define DAYSPERYEAR   (31+28+31+30+31+30+31+31+30+31+30+31)
70
71/* X-tals being what they are, it's nice to be able to fudge this one... */
72#ifndef TIMER_FREQ
73#define	TIMER_FREQ	1193182	/* XXX - should be in isa.h */
74#endif
75#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
76
77/*
78 * Time in timer cycles that it takes for microtime() to disable interrupts
79 * and latch the count.  microtime() currently uses "cli; outb ..." so it
80 * normally takes less than 2 timer cycles.  Add a few for cache misses.
81 * Add a few more to allow for latency in bogus calls to microtime() with
82 * interrupts already disabled.
83 */
84#define	TIMER0_LATCH_COUNT	20
85
86/*
87 * Minimum maximum count that we are willing to program into timer0.
88 * Must be large enough to guarantee that the timer interrupt handler
89 * returns before the next timer interrupt.  Must be larger than
90 * TIMER0_LATCH_COUNT so that we don't have to worry about underflow in
91 * the calculation of timer0_overflow_threshold.
92 */
93#define	TIMER0_MIN_MAX_COUNT	TIMER_DIV(20000)
94
95int	adjkerntz = 0;		/* offset from CMOS clock */
96int	disable_rtc_set	= 0;	/* disable resettodr() if != 0 */
97u_int	idelayed;
98#if defined(I586_CPU) || defined(I686_CPU)
99unsigned	i586_ctr_rate;
100long long	i586_ctr_bias;
101long long	i586_last_tick;
102#endif
103u_int	stat_imask = SWI_CLOCK_MASK;
104int 	timer0_max_count;
105u_int 	timer0_overflow_threshold;
106u_int 	timer0_prescaler_count;
107
108static	int	beeping = 0;
109static	u_int	clk_imask = HWI_MASK | SWI_MASK;
110static	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
111static 	u_int	hardclock_max_count;
112/*
113 * XXX new_function and timer_func should not handle clockframes, but
114 * timer_func currently needs to hold hardclock to handle the
115 * timer0_state == 0 case.  We should use register_intr()/unregister_intr()
116 * to switch between clkintr() and a slightly different timerintr().
117 * This will require locking when acquiring and releasing timer0 - the
118 * current (nonexistent) locking doesn't seem to be adequate even now.
119 */
120static 	void	(*new_function) __P((struct clockframe *frame));
121static 	u_int	new_rate;
122static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
123static 	char	timer0_state = 0;
124static	char	timer2_state = 0;
125static 	void	(*timer_func) __P((struct clockframe *frame)) = hardclock;
126
127#if 0
128void
129clkintr(struct clockframe frame)
130{
131	hardclock(&frame);
132	setdelayed();
133}
134#else
135static void
136clkintr(struct clockframe frame)
137{
138	timer_func(&frame);
139	switch (timer0_state) {
140	case 0:
141		setdelayed();
142		break;
143	case 1:
144		if ((timer0_prescaler_count += timer0_max_count)
145		    >= hardclock_max_count) {
146			hardclock(&frame);
147			setdelayed();
148			timer0_prescaler_count -= hardclock_max_count;
149		}
150		break;
151	case 2:
152		setdelayed();
153		timer0_max_count = TIMER_DIV(new_rate);
154		timer0_overflow_threshold =
155			timer0_max_count - TIMER0_LATCH_COUNT;
156		disable_intr();
157		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
158		outb(TIMER_CNTR0, timer0_max_count & 0xff);
159		outb(TIMER_CNTR0, timer0_max_count >> 8);
160		enable_intr();
161		timer0_prescaler_count = 0;
162		timer_func = new_function;
163		timer0_state = 1;
164		break;
165	case 3:
166		if ((timer0_prescaler_count += timer0_max_count)
167		    >= hardclock_max_count) {
168			hardclock(&frame);
169			setdelayed();
170			timer0_max_count = hardclock_max_count;
171			timer0_overflow_threshold =
172				timer0_max_count - TIMER0_LATCH_COUNT;
173			disable_intr();
174			outb(TIMER_MODE,
175			     TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
176			outb(TIMER_CNTR0, timer0_max_count & 0xff);
177			outb(TIMER_CNTR0, timer0_max_count >> 8);
178			enable_intr();
179			/*
180			 * See microtime.s for this magic.
181			 */
182			time.tv_usec += (27645 *
183				(timer0_prescaler_count - hardclock_max_count))
184				>> 15;
185			if (time.tv_usec >= 1000000)
186				time.tv_usec -= 1000000;
187			timer0_prescaler_count = 0;
188			timer_func = hardclock;;
189			timer0_state = 0;
190		}
191		break;
192	}
193}
194#endif
195
196int
197acquire_timer0(int rate, void (*function) __P((struct clockframe *frame)))
198{
199	if (timer0_state || TIMER_DIV(rate) < TIMER0_MIN_MAX_COUNT ||
200	    !function)
201		return -1;
202	new_function = function;
203	new_rate = rate;
204	timer0_state = 2;
205	return 0;
206}
207
208int
209acquire_timer2(int mode)
210{
211	if (timer2_state)
212		return -1;
213	timer2_state = 1;
214	outb(TIMER_MODE, TIMER_SEL2 | (mode &0x3f));
215	return 0;
216}
217
218int
219release_timer0()
220{
221	if (!timer0_state)
222		return -1;
223	timer0_state = 3;
224	return 0;
225}
226
227int
228release_timer2()
229{
230	if (!timer2_state)
231		return -1;
232	timer2_state = 0;
233	outb(TIMER_MODE, TIMER_SEL2|TIMER_SQWAVE|TIMER_16BIT);
234	return 0;
235}
236
237/*
238 * This routine receives statistical clock interrupts from the RTC.
239 * As explained above, these occur at 128 interrupts per second.
240 * When profiling, we receive interrupts at a rate of 1024 Hz.
241 *
242 * This does not actually add as much overhead as it sounds, because
243 * when the statistical clock is active, the hardclock driver no longer
244 * needs to keep (inaccurate) statistics on its own.  This decouples
245 * statistics gathering from scheduling interrupts.
246 *
247 * The RTC chip requires that we read status register C (RTC_INTR)
248 * to acknowledge an interrupt, before it will generate the next one.
249 */
250static void
251rtcintr(struct clockframe frame)
252{
253	u_char stat;
254	stat = rtcin(RTC_INTR);
255	if(stat & RTCIR_PERIOD) {
256		statclock(&frame);
257	}
258}
259
260#ifdef DDB
261static void
262DDB_printrtc(void)
263{
264	printf("%02x/%02x/%02x %02x:%02x:%02x, A = %02x, B = %02x, C = %02x\n",
265	       rtcin(RTC_YEAR), rtcin(RTC_MONTH), rtcin(RTC_DAY),
266	       rtcin(RTC_HRS), rtcin(RTC_MIN), rtcin(RTC_SEC),
267	       rtcin(RTC_STATUSA), rtcin(RTC_STATUSB), rtcin(RTC_INTR));
268}
269#endif
270
271static int
272getit(void)
273{
274	int high, low;
275
276	disable_intr();
277	/* select timer0 and latch counter value */
278	outb(TIMER_MODE, TIMER_SEL0);
279	low = inb(TIMER_CNTR0);
280	high = inb(TIMER_CNTR0);
281	enable_intr();
282	return ((high << 8) | low);
283}
284
285#if defined(I586_CPU) || defined(I686_CPU)
286/*
287 * Figure out how fast the cyclecounter runs.  This must be run with
288 * clock interrupts disabled, but with the timer/counter programmed
289 * and running.
290 */
291void
292calibrate_cyclecounter(void)
293{
294	/*
295	 * Don't need volatile; should always use unsigned if 2's
296	 * complement arithmetic is desired.
297	 */
298	unsigned long long count;
299
300#define howlong 131072UL
301	__asm __volatile(".byte 0x0f, 0x30" : : "A"(0LL), "c" (0x10));
302	DELAY(howlong);
303	__asm __volatile(".byte 0xf,0x31" : "=A" (count));
304
305	i586_ctr_rate = (count << I586_CTR_RATE_SHIFT) / howlong;
306#undef howlong
307}
308#endif
309
310/*
311 * Wait "n" microseconds.
312 * Relies on timer 1 counting down from (TIMER_FREQ / hz)
313 * Note: timer had better have been programmed before this is first used!
314 */
315void
316DELAY(int n)
317{
318	int prev_tick, tick, ticks_left, sec, usec;
319
320#ifdef DELAYDEBUG
321	int getit_calls = 1;
322	int n1;
323	static int state = 0;
324
325	if (state == 0) {
326		state = 1;
327		for (n1 = 1; n1 <= 10000000; n1 *= 10)
328			DELAY(n1);
329		state = 2;
330	}
331	if (state == 1)
332		printf("DELAY(%d)...", n);
333#endif
334	/*
335	 * Read the counter first, so that the rest of the setup overhead is
336	 * counted.  Guess the initial overhead is 20 usec (on most systems it
337	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
338	 * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
339	 * multiplications and divisions to scale the count take a while).
340	 */
341	prev_tick = getit();
342	n -= 20;
343	/*
344	 * Calculate (n * (TIMER_FREQ / 1e6)) without using floating point
345	 * and without any avoidable overflows.
346	 */
347	sec = n / 1000000;
348	usec = n - sec * 1000000;
349	ticks_left = sec * TIMER_FREQ
350		     + usec * (TIMER_FREQ / 1000000)
351		     + usec * ((TIMER_FREQ % 1000000) / 1000) / 1000
352		     + usec * (TIMER_FREQ % 1000) / 1000000;
353
354	while (ticks_left > 0) {
355		tick = getit();
356#ifdef DELAYDEBUG
357		++getit_calls;
358#endif
359		if (tick > prev_tick)
360			ticks_left -= prev_tick - (tick - timer0_max_count);
361		else
362			ticks_left -= prev_tick - tick;
363		prev_tick = tick;
364	}
365#ifdef DELAYDEBUG
366	if (state == 1)
367		printf(" %d calls to getit() at %d usec each\n",
368		       getit_calls, (n + 5) / getit_calls);
369#endif
370}
371
372static void
373sysbeepstop(void *chan)
374{
375	outb(IO_PPI, inb(IO_PPI)&0xFC);	/* disable counter2 output to speaker */
376	release_timer2();
377	beeping = 0;
378}
379
380int
381sysbeep(int pitch, int period)
382{
383
384	if (acquire_timer2(TIMER_SQWAVE|TIMER_16BIT))
385		return -1;
386	disable_intr();
387	outb(TIMER_CNTR2, pitch);
388	outb(TIMER_CNTR2, (pitch>>8));
389	enable_intr();
390	if (!beeping) {
391	outb(IO_PPI, inb(IO_PPI) | 3);	/* enable counter2 output to speaker */
392		beeping = period;
393		timeout(sysbeepstop, (void *)NULL, period);
394	}
395	return 0;
396}
397
398/*
399 * RTC support routines
400 */
401static int
402bcd2int(int bcd)
403{
404	return(bcd/16 *	10 + bcd%16);
405}
406
407static int
408int2bcd(int dez)
409{
410	return(dez/10 *	16 + dez%10);
411}
412
413static inline void
414writertc(u_char reg, u_char val)
415{
416	outb(IO_RTC, reg);
417	outb(IO_RTC + 1, val);
418}
419
420static int
421readrtc(int port)
422{
423	return(bcd2int(rtcin(port)));
424}
425
426/*
427 * Initialize 8253 timer 0 early so that it can be used in DELAY().
428 * XXX initialization of other timers is unintentionally left blank.
429 */
430void
431startrtclock()
432{
433	timer0_max_count = hardclock_max_count = TIMER_DIV(hz);
434	timer0_overflow_threshold = timer0_max_count - TIMER0_LATCH_COUNT;
435	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
436	outb(TIMER_CNTR0, timer0_max_count & 0xff);
437	outb(TIMER_CNTR0, timer0_max_count >> 8);
438}
439
440/*
441 * Initialize the time of day register,	based on the time base which is, e.g.
442 * from	a filesystem.
443 */
444void
445inittodr(time_t base)
446{
447	unsigned long	sec, days;
448	int		yd;
449	int		year, month;
450	int		y, m, s;
451
452	s = splclock();
453	time.tv_sec  = base;
454	time.tv_usec = 0;
455	splx(s);
456
457	/* Look	if we have a RTC present and the time is valid */
458	if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
459		goto wrong_time;
460
461	/* wait	for time update	to complete */
462	/* If RTCSA_TUP	is zero, we have at least 244us	before next update */
463	while (rtcin(RTC_STATUSA) & RTCSA_TUP);
464
465	days = 0;
466#ifdef USE_RTC_CENTURY
467	year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY)	* 100;
468#else
469	year = readrtc(RTC_YEAR) + 1900;
470	if (year < 1970)
471		year += 100;
472#endif
473	if (year < 1970)
474		goto wrong_time;
475	month =	readrtc(RTC_MONTH);
476	for (m = 1; m <	month; m++)
477		days +=	daysinmonth[m-1];
478	if ((month > 2)	&& LEAPYEAR(year))
479		days ++;
480	days +=	readrtc(RTC_DAY) - 1;
481	yd = days;
482	for (y = 1970; y < year; y++)
483		days +=	DAYSPERYEAR + LEAPYEAR(y);
484	sec = ((( days * 24 +
485		  readrtc(RTC_HRS)) * 60 +
486		  readrtc(RTC_MIN)) * 60 +
487		  readrtc(RTC_SEC));
488	/* sec now contains the	number of seconds, since Jan 1 1970,
489	   in the local	time zone */
490
491	sec += tz.tz_minuteswest * 60 + adjkerntz;
492
493	s = splclock();
494	time.tv_sec = sec;
495	splx(s);
496	return;
497
498wrong_time:
499	printf("Invalid	time in	real time clock.\n");
500	printf("Check and reset	the date immediately!\n");
501}
502
503/*
504 * Write system	time back to RTC
505 */
506void
507resettodr()
508{
509	unsigned long	tm;
510	int		y, m, s;
511
512	if (disable_rtc_set)
513		return;
514
515	s = splclock();
516	tm = time.tv_sec;
517	splx(s);
518
519	/* Disable RTC updates and interrupts. */
520	writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
521
522	/* Calculate local time	to put in RTC */
523
524	tm -= tz.tz_minuteswest * 60 + adjkerntz;
525
526	writertc(RTC_SEC, int2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
527	writertc(RTC_MIN, int2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
528	writertc(RTC_HRS, int2bcd(tm%24)); tm /= 24;	/* Write back Hours   */
529
530	/* We have now the days	since 01-01-1970 in tm */
531	writertc(RTC_WDAY, (tm+4)%7);			/* Write back Weekday */
532	for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
533	     tm >= m;
534	     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
535	     tm -= m;
536
537	/* Now we have the years in y and the day-of-the-year in tm */
538#ifdef USE_RTC_CENTURY
539	writertc(RTC_YEAR, int2bcd(y%100));		/* Write back Year    */
540	writertc(RTC_CENTURY, int2bcd(y/100));		/* ... and Century    */
541#else
542	writertc(RTC_YEAR, int2bcd(y - 1900));          /* Write back Year    */
543#endif
544	for (m = 0; ; m++) {
545		int ml;
546
547		ml = daysinmonth[m];
548		if (m == 1 && LEAPYEAR(y))
549			ml++;
550		if (tm < ml)
551			break;
552		tm -= ml;
553	}
554
555	writertc(RTC_MONTH, int2bcd(m + 1));            /* Write back Month   */
556	writertc(RTC_DAY, int2bcd(tm + 1));             /* Write back Month Day */
557
558	/* Reenable RTC updates and interrupts. */
559	writertc(RTC_STATUSB, RTCSB_24HR | RTCSB_PINTR);
560}
561
562/*
563 * Start both clocks running.
564 */
565void
566cpu_initclocks()
567{
568	int diag;
569
570	stathz = RTC_NOPROFRATE;
571	profhz = RTC_PROFRATE;
572
573	/* Finish initializing 8253 timer 0. */
574	register_intr(/* irq */ 0, /* XXX id */ 0, /* flags */ 0,
575		      /* XXX */ (inthand2_t *)clkintr, &clk_imask,
576		      /* unit */ 0);
577	INTREN(IRQ0);
578#if defined(I586_CPU) || defined(I686_CPU)
579	/*
580	 * Finish setting up anti-jitter measures.
581	 */
582	if (i586_ctr_rate) {
583		I586_CYCLECTR(i586_last_tick);
584		i586_ctr_bias = i586_last_tick;
585	}
586#endif
587
588	/* Initialize RTC. */
589	writertc(RTC_STATUSA, rtc_statusa);
590	writertc(RTC_STATUSB, RTCSB_24HR);
591	diag = rtcin(RTC_DIAG);
592	if (diag != 0)
593		printf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
594	register_intr(/* irq */ 8, /* XXX id */ 1, /* flags */ 0,
595		      /* XXX */ (inthand2_t *)rtcintr, &stat_imask,
596		      /* unit */ 0);
597	INTREN(IRQ8);
598	writertc(RTC_STATUSB, RTCSB_24HR | RTCSB_PINTR);
599}
600
601void
602setstatclockrate(int newhz)
603{
604	if (newhz == RTC_PROFRATE)
605		rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
606	else
607		rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
608	writertc(RTC_STATUSA, rtc_statusa);
609}
610