pcrtc.c revision 127016
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 * $FreeBSD: head/sys/pc98/cbus/pcrtc.c 127016 2004-03-15 10:39:01Z imp $
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_isa.h"
57#include "opt_mca.h"
58
59#include <sys/param.h>
60#include <sys/systm.h>
61#include <sys/bus.h>
62#include <sys/limits.h>
63#include <sys/lock.h>
64#include <sys/mutex.h>
65#include <sys/proc.h>
66#include <sys/time.h>
67#include <sys/timetc.h>
68#include <sys/kernel.h>
69#include <sys/sysctl.h>
70#include <sys/cons.h>
71#include <sys/power.h>
72
73#include <machine/clock.h>
74#include <machine/cputypes.h>
75#include <machine/frame.h>
76#include <machine/intr_machdep.h>
77#include <machine/md_var.h>
78#include <machine/psl.h>
79
80#if defined(SMP)
81#include <machine/smp.h>
82#endif
83#include <machine/specialreg.h>
84
85#include <i386/isa/icu.h>
86#include <pc98/pc98/pc98.h>
87#include <pc98/pc98/pc98_machdep.h>
88#ifdef DEV_ISA
89#include <isa/isavar.h>
90#endif
91#include <i386/isa/timerreg.h>
92
93/*
94 * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
95 * can use a simple formula for leap years.
96 */
97#define	LEAPYEAR(y) (((u_int)(y) % 4 == 0) ? 1 : 0)
98#define DAYSPERYEAR   (31+28+31+30+31+30+31+31+30+31+30+31)
99
100#define	TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
101
102#ifndef BURN_BRIDGES
103/*
104 * Time in timer cycles that it takes for microtime() to disable interrupts
105 * and latch the count.  microtime() currently uses "cli; outb ..." so it
106 * normally takes less than 2 timer cycles.  Add a few for cache misses.
107 * Add a few more to allow for latency in bogus calls to microtime() with
108 * interrupts already disabled.
109 */
110#define	TIMER0_LATCH_COUNT	20
111
112/*
113 * Maximum frequency that we are willing to allow for timer0.  Must be
114 * low enough to guarantee that the timer interrupt handler returns
115 * before the next timer interrupt.
116 */
117#define	TIMER0_MAX_FREQ		20000
118#endif
119
120int	adjkerntz;		/* local offset from GMT in seconds */
121int	clkintr_pending;
122int	disable_rtc_set;	/* disable resettodr() if != 0 */
123int	pscnt = 1;
124int	psdiv = 1;
125int	statclock_disable;
126#ifndef TIMER_FREQ
127#define TIMER_FREQ   2457600
128#endif
129u_int	timer_freq = TIMER_FREQ;
130int	timer0_max_count;
131int	wall_cmos_clock;	/* wall CMOS clock assumed if != 0 */
132struct mtx clock_lock;
133
134static	int	beeping = 0;
135static	const u_char daysinmonth[] = {31,28,31,30,31,30,31,31,30,31,30,31};
136static	u_int	hardclock_max_count;
137static	u_int32_t i8254_lastcount;
138static	u_int32_t i8254_offset;
139static	int	i8254_ticked;
140static	struct intsrc *i8254_intsrc;
141#ifndef BURN_BRIDGES
142/*
143 * XXX new_function and timer_func should not handle clockframes, but
144 * timer_func currently needs to hold hardclock to handle the
145 * timer0_state == 0 case.  We should use inthand_add()/inthand_remove()
146 * to switch between clkintr() and a slightly different timerintr().
147 */
148static	void	(*new_function)(struct clockframe *frame);
149static	u_int	new_rate;
150static	u_int	timer0_prescaler_count;
151static	u_char	timer0_state;
152#endif
153
154/* Values for timerX_state: */
155#define	RELEASED	0
156#define	RELEASE_PENDING	1
157#define	ACQUIRED	2
158#define	ACQUIRE_PENDING	3
159
160static 	u_char	timer1_state;
161static	u_char	timer2_state;
162static	void	(*timer_func)(struct clockframe *frame) = hardclock;
163static void rtc_serialcombit(int);
164static void rtc_serialcom(int);
165static int rtc_inb(void);
166static void rtc_outb(int);
167
168static	unsigned i8254_get_timecount(struct timecounter *tc);
169static	void	set_timer_freq(u_int freq, int intr_freq);
170
171static struct timecounter i8254_timecounter = {
172	i8254_get_timecount,	/* get_timecount */
173	0,			/* no poll_pps */
174	~0u,			/* counter_mask */
175	0,			/* frequency */
176	"i8254",		/* name */
177	0			/* quality */
178};
179
180static void
181clkintr(struct clockframe *frame)
182{
183
184	if (timecounter->tc_get_timecount == i8254_get_timecount) {
185		mtx_lock_spin(&clock_lock);
186		if (i8254_ticked)
187			i8254_ticked = 0;
188		else {
189			i8254_offset += timer0_max_count;
190			i8254_lastcount = 0;
191		}
192		clkintr_pending = 0;
193		mtx_unlock_spin(&clock_lock);
194	}
195	timer_func(frame);
196#ifdef SMP
197	if (timer_func == hardclock)
198		forward_hardclock();
199#endif
200#ifndef BURN_BRIDGES
201	switch (timer0_state) {
202
203	case RELEASED:
204		break;
205
206	case ACQUIRED:
207		if ((timer0_prescaler_count += timer0_max_count)
208		    >= hardclock_max_count) {
209			timer0_prescaler_count -= hardclock_max_count;
210			hardclock(frame);
211#ifdef SMP
212			forward_hardclock();
213#endif
214		}
215		break;
216
217	case ACQUIRE_PENDING:
218		mtx_lock_spin(&clock_lock);
219		i8254_offset = i8254_get_timecount(NULL);
220		i8254_lastcount = 0;
221		timer0_max_count = TIMER_DIV(new_rate);
222		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
223		outb(TIMER_CNTR0, timer0_max_count & 0xff);
224		outb(TIMER_CNTR0, timer0_max_count >> 8);
225		mtx_unlock_spin(&clock_lock);
226		timer_func = new_function;
227		timer0_state = ACQUIRED;
228		break;
229
230	case RELEASE_PENDING:
231		if ((timer0_prescaler_count += timer0_max_count)
232		    >= hardclock_max_count) {
233			mtx_lock_spin(&clock_lock);
234			i8254_offset = i8254_get_timecount(NULL);
235			i8254_lastcount = 0;
236			timer0_max_count = hardclock_max_count;
237			outb(TIMER_MODE,
238			     TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
239			outb(TIMER_CNTR0, timer0_max_count & 0xff);
240			outb(TIMER_CNTR0, timer0_max_count >> 8);
241			mtx_unlock_spin(&clock_lock);
242			timer0_prescaler_count = 0;
243			timer_func = hardclock;
244			timer0_state = RELEASED;
245			hardclock(frame);
246#ifdef SMP
247			forward_hardclock();
248#endif
249		}
250		break;
251	}
252#endif
253}
254
255#ifndef BURN_BRIDGES
256/*
257 * The acquire and release functions must be called at ipl >= splclock().
258 */
259int
260acquire_timer0(int rate, void (*function)(struct clockframe *frame))
261{
262	static int old_rate;
263
264	if (rate <= 0 || rate > TIMER0_MAX_FREQ)
265		return (-1);
266	switch (timer0_state) {
267
268	case RELEASED:
269		timer0_state = ACQUIRE_PENDING;
270		break;
271
272	case RELEASE_PENDING:
273		if (rate != old_rate)
274			return (-1);
275		/*
276		 * The timer has been released recently, but is being
277		 * re-acquired before the release completed.  In this
278		 * case, we simply reclaim it as if it had not been
279		 * released at all.
280		 */
281		timer0_state = ACQUIRED;
282		break;
283
284	default:
285		return (-1);	/* busy */
286	}
287	new_function = function;
288	old_rate = new_rate = rate;
289	return (0);
290}
291#endif
292
293int
294acquire_timer1(int mode)
295{
296
297	if (timer1_state != RELEASED)
298		return (-1);
299	timer1_state = ACQUIRED;
300
301	/*
302	 * This access to the timer registers is as atomic as possible
303	 * because it is a single instruction.  We could do better if we
304	 * knew the rate.  Use of splclock() limits glitches to 10-100us,
305	 * and this is probably good enough for timer2, so we aren't as
306	 * careful with it as with timer0.
307	 */
308	outb(TIMER_MODE, TIMER_SEL1 | (mode & 0x3f));
309
310	return (0);
311}
312
313int
314acquire_timer2(int mode)
315{
316
317	if (timer2_state != RELEASED)
318		return (-1);
319	timer2_state = ACQUIRED;
320
321	/*
322	 * This access to the timer registers is as atomic as possible
323	 * because it is a single instruction.  We could do better if we
324	 * knew the rate.  Use of splclock() limits glitches to 10-100us,
325	 * and this is probably good enough for timer2, so we aren't as
326	 * careful with it as with timer0.
327	 */
328	outb(TIMER_MODE, TIMER_SEL2 | (mode & 0x3f));
329
330	return (0);
331}
332
333#ifndef BURN_BRIDGES
334int
335release_timer0()
336{
337	switch (timer0_state) {
338
339	case ACQUIRED:
340		timer0_state = RELEASE_PENDING;
341		break;
342
343	case ACQUIRE_PENDING:
344		/* Nothing happened yet, release quickly. */
345		timer0_state = RELEASED;
346		break;
347
348	default:
349		return (-1);
350	}
351	return (0);
352}
353#endif
354
355int
356release_timer1()
357{
358
359	if (timer1_state != ACQUIRED)
360		return (-1);
361	timer1_state = RELEASED;
362	outb(TIMER_MODE, TIMER_SEL1 | TIMER_SQWAVE | TIMER_16BIT);
363	return (0);
364}
365
366int
367release_timer2()
368{
369
370	if (timer2_state != ACQUIRED)
371		return (-1);
372	timer2_state = RELEASED;
373	outb(TIMER_MODE, TIMER_SEL2 | TIMER_SQWAVE | TIMER_16BIT);
374	return (0);
375}
376
377
378static int
379getit(void)
380{
381	int high, low;
382
383	mtx_lock_spin(&clock_lock);
384
385	/* Select timer0 and latch counter value. */
386	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
387
388	low = inb(TIMER_CNTR0);
389	high = inb(TIMER_CNTR0);
390
391	mtx_unlock_spin(&clock_lock);
392	return ((high << 8) | low);
393}
394
395/*
396 * Wait "n" microseconds.
397 * Relies on timer 1 counting down from (timer_freq / hz)
398 * Note: timer had better have been programmed before this is first used!
399 */
400void
401DELAY(int n)
402{
403	int delta, prev_tick, tick, ticks_left;
404
405#ifdef DELAYDEBUG
406	int getit_calls = 1;
407	int n1;
408	static int state = 0;
409
410	if (state == 0) {
411		state = 1;
412		for (n1 = 1; n1 <= 10000000; n1 *= 10)
413			DELAY(n1);
414		state = 2;
415	}
416	if (state == 1)
417		printf("DELAY(%d)...", n);
418#endif
419	/*
420	 * Guard against the timer being uninitialized if we are called
421	 * early for console i/o.
422	 */
423	if (timer0_max_count == 0)
424		set_timer_freq(timer_freq, hz);
425
426	/*
427	 * Read the counter first, so that the rest of the setup overhead is
428	 * counted.  Guess the initial overhead is 20 usec (on most systems it
429	 * takes about 1.5 usec for each of the i/o's in getit().  The loop
430	 * takes about 6 usec on a 486/33 and 13 usec on a 386/20.  The
431	 * multiplications and divisions to scale the count take a while).
432	 *
433	 * However, if ddb is active then use a fake counter since reading
434	 * the i8254 counter involves acquiring a lock.  ddb must not go
435	 * locking for many reasons, but it calls here for at least atkbd
436	 * input.
437	 */
438#ifdef DDB
439	if (db_active)
440		prev_tick = 0;
441	else
442#endif
443		prev_tick = getit();
444	n -= 0;			/* XXX actually guess no initial overhead */
445	/*
446	 * Calculate (n * (timer_freq / 1e6)) without using floating point
447	 * and without any avoidable overflows.
448	 */
449	if (n <= 0)
450		ticks_left = 0;
451	else if (n < 256)
452		/*
453		 * Use fixed point to avoid a slow division by 1000000.
454		 * 39099 = 1193182 * 2^15 / 10^6 rounded to nearest.
455		 * 2^15 is the first power of 2 that gives exact results
456		 * for n between 0 and 256.
457		 */
458		ticks_left = ((u_int)n * 39099 + (1 << 15) - 1) >> 15;
459	else
460		/*
461		 * Don't bother using fixed point, although gcc-2.7.2
462		 * generates particularly poor code for the long long
463		 * division, since even the slow way will complete long
464		 * before the delay is up (unless we're interrupted).
465		 */
466		ticks_left = ((u_int)n * (long long)timer_freq + 999999)
467			     / 1000000;
468
469	while (ticks_left > 0) {
470#ifdef DDB
471		if (db_active) {
472			outb(0x5f, 0);
473			tick = prev_tick + 1;
474		} else
475#endif
476			tick = getit();
477#ifdef DELAYDEBUG
478		++getit_calls;
479#endif
480		delta = prev_tick - tick;
481		prev_tick = tick;
482		if (delta < 0) {
483			delta += timer0_max_count;
484			/*
485			 * Guard against timer0_max_count being wrong.
486			 * This shouldn't happen in normal operation,
487			 * but it may happen if set_timer_freq() is
488			 * traced.
489			 */
490			if (delta < 0)
491				delta = 0;
492		}
493		ticks_left -= delta;
494	}
495#ifdef DELAYDEBUG
496	if (state == 1)
497		printf(" %d calls to getit() at %d usec each\n",
498		       getit_calls, (n + 5) / getit_calls);
499#endif
500}
501
502static void
503sysbeepstop(void *chan)
504{
505	outb(IO_PPI, inb(IO_PPI)|0x08);	/* disable counter1 output to speaker */
506	release_timer1();
507	beeping = 0;
508}
509
510int
511sysbeep(int pitch, int period)
512{
513	int x = splclock();
514
515	if (acquire_timer1(TIMER_SQWAVE|TIMER_16BIT))
516		if (!beeping) {
517			/* Something else owns it. */
518			splx(x);
519			return (-1); /* XXX Should be EBUSY, but nobody cares anyway. */
520		}
521	disable_intr();
522	outb(0x3fdb, pitch);
523	outb(0x3fdb, (pitch>>8));
524	enable_intr();
525	if (!beeping) {
526		/* enable counter1 output to speaker */
527		outb(IO_PPI, (inb(IO_PPI) & 0xf7));
528		beeping = period;
529		timeout(sysbeepstop, (void *)NULL, period);
530	}
531	splx(x);
532	return (0);
533}
534
535
536unsigned int delaycount;
537#define FIRST_GUESS	0x2000
538static void findcpuspeed(void)
539{
540	int i;
541	int remainder;
542
543	/* Put counter in count down mode */
544	outb(TIMER_MODE, TIMER_SEL0 | TIMER_16BIT | TIMER_RATEGEN);
545	outb(TIMER_CNTR0, 0xff);
546	outb(TIMER_CNTR0, 0xff);
547	for (i = FIRST_GUESS; i; i--)
548		;
549	remainder = getit();
550	delaycount = (FIRST_GUESS * TIMER_DIV(1000)) / (0xffff - remainder);
551}
552
553static u_int
554calibrate_clocks(void)
555{
556	int	timeout;
557	u_int	count, prev_count, tot_count;
558	u_short	sec, start_sec;
559
560	if (bootverbose)
561	        printf("Calibrating clock(s) ... ");
562	/* Check ARTIC. */
563	if (!(PC98_SYSTEM_PARAMETER(0x458) & 0x80) &&
564	    !(PC98_SYSTEM_PARAMETER(0x45b) & 0x04))
565		goto fail;
566	timeout = 100000000;
567
568	/* Read the ARTIC. */
569	sec = inw(0x5e);
570
571	/* Wait for the ARTIC to changes. */
572	start_sec = sec;
573	for (;;) {
574		sec = inw(0x5e);
575		if (sec != start_sec)
576			break;
577		if (--timeout == 0)
578			goto fail;
579	}
580	prev_count = getit();
581	if (prev_count == 0 || prev_count > timer0_max_count)
582		goto fail;
583	tot_count = 0;
584
585	start_sec = sec;
586	for (;;) {
587		sec = inw(0x5e);
588		count = getit();
589		if (count == 0 || count > timer0_max_count)
590			goto fail;
591		if (count > prev_count)
592			tot_count += prev_count - (count - timer0_max_count);
593		else
594			tot_count += prev_count - count;
595		prev_count = count;
596		if ((sec == start_sec + 1200) ||
597		    (sec < start_sec &&
598		        (u_int)sec + 0x10000 == (u_int)start_sec + 1200))
599			break;
600		if (--timeout == 0)
601			goto fail;
602	}
603
604	if (bootverbose) {
605	        printf("i8254 clock: %u Hz\n", tot_count);
606	}
607	return (tot_count);
608
609fail:
610	if (bootverbose)
611	        printf("failed, using default i8254 clock of %u Hz\n",
612		       timer_freq);
613	return (timer_freq);
614}
615
616static void
617set_timer_freq(u_int freq, int intr_freq)
618{
619	int new_timer0_max_count;
620
621	mtx_lock_spin(&clock_lock);
622	timer_freq = freq;
623	new_timer0_max_count = hardclock_max_count = TIMER_DIV(intr_freq);
624	if (new_timer0_max_count != timer0_max_count) {
625		timer0_max_count = new_timer0_max_count;
626		outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
627		outb(TIMER_CNTR0, timer0_max_count & 0xff);
628		outb(TIMER_CNTR0, timer0_max_count >> 8);
629	}
630	mtx_unlock_spin(&clock_lock);
631}
632
633static void
634i8254_restore(void)
635{
636
637	mtx_lock_spin(&clock_lock);
638	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
639	outb(TIMER_CNTR0, timer0_max_count & 0xff);
640	outb(TIMER_CNTR0, timer0_max_count >> 8);
641	mtx_unlock_spin(&clock_lock);
642}
643
644
645/*
646 * Restore all the timers non-atomically (XXX: should be atomically).
647 *
648 * This function is called from pmtimer_resume() to restore all the timers.
649 * This should not be necessary, but there are broken laptops that do not
650 * restore all the timers on resume.
651 */
652void
653timer_restore(void)
654{
655
656	i8254_restore();		/* restore timer_freq and hz */
657}
658
659/*
660 * Initialize 8254 timer 0 early so that it can be used in DELAY().
661 * XXX initialization of other timers is unintentionally left blank.
662 */
663void
664startrtclock()
665{
666	u_int delta, freq;
667
668	findcpuspeed();
669	if (pc98_machine_type & M_8M)
670		timer_freq = 1996800L; /* 1.9968 MHz */
671	else
672		timer_freq = 2457600L; /* 2.4576 MHz */
673
674	set_timer_freq(timer_freq, hz);
675	freq = calibrate_clocks();
676#ifdef CLK_CALIBRATION_LOOP
677	if (bootverbose) {
678		printf(
679		"Press a key on the console to abort clock calibration\n");
680		while (cncheckc() == -1)
681			calibrate_clocks();
682	}
683#endif
684
685	/*
686	 * Use the calibrated i8254 frequency if it seems reasonable.
687	 * Otherwise use the default, and don't use the calibrated i586
688	 * frequency.
689	 */
690	delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
691	if (delta < timer_freq / 100) {
692#ifndef CLK_USE_I8254_CALIBRATION
693		if (bootverbose)
694			printf(
695"CLK_USE_I8254_CALIBRATION not specified - using default frequency\n");
696		freq = timer_freq;
697#endif
698		timer_freq = freq;
699	} else {
700		if (bootverbose)
701			printf(
702		    "%d Hz differs from default of %d Hz by more than 1%%\n",
703			       freq, timer_freq);
704	}
705
706	set_timer_freq(timer_freq, hz);
707	i8254_timecounter.tc_frequency = timer_freq;
708	tc_init(&i8254_timecounter);
709
710	init_TSC();
711}
712
713static void
714rtc_serialcombit(int i)
715{
716	outb(IO_RTC, ((i&0x01)<<5)|0x07);
717	DELAY(1);
718	outb(IO_RTC, ((i&0x01)<<5)|0x17);
719	DELAY(1);
720	outb(IO_RTC, ((i&0x01)<<5)|0x07);
721	DELAY(1);
722}
723
724static void
725rtc_serialcom(int i)
726{
727	rtc_serialcombit(i&0x01);
728	rtc_serialcombit((i&0x02)>>1);
729	rtc_serialcombit((i&0x04)>>2);
730	rtc_serialcombit((i&0x08)>>3);
731	outb(IO_RTC, 0x07);
732	DELAY(1);
733	outb(IO_RTC, 0x0f);
734	DELAY(1);
735	outb(IO_RTC, 0x07);
736 	DELAY(1);
737}
738
739static void
740rtc_outb(int val)
741{
742	int s;
743	int sa = 0;
744
745	for (s=0;s<8;s++) {
746	    sa = ((val >> s) & 0x01) ? 0x27 : 0x07;
747	    outb(IO_RTC, sa);		/* set DI & CLK 0 */
748	    DELAY(1);
749	    outb(IO_RTC, sa | 0x10);	/* CLK 1 */
750	    DELAY(1);
751	}
752	outb(IO_RTC, sa & 0xef);	/* CLK 0 */
753}
754
755static int
756rtc_inb(void)
757{
758	int s;
759	int sa = 0;
760
761	for (s=0;s<8;s++) {
762	    sa |= ((inb(0x33) & 0x01) << s);
763	    outb(IO_RTC, 0x17);	/* CLK 1 */
764	    DELAY(1);
765	    outb(IO_RTC, 0x07);	/* CLK 0 */
766	    DELAY(2);
767	}
768	return sa;
769}
770
771/*
772 * Initialize the time of day register, based on the time base which is, e.g.
773 * from a filesystem.
774 */
775void
776inittodr(time_t base)
777{
778	unsigned long	sec, days;
779	int		year, month;
780	int		y, m, s;
781	struct timespec ts;
782	int		second, min, hour;
783
784	if (base) {
785		s = splclock();
786		ts.tv_sec = base;
787		ts.tv_nsec = 0;
788		tc_setclock(&ts);
789		splx(s);
790	}
791
792	rtc_serialcom(0x03);	/* Time Read */
793	rtc_serialcom(0x01);	/* Register shift command. */
794	DELAY(20);
795
796	second = bcd2bin(rtc_inb() & 0xff);	/* sec */
797	min = bcd2bin(rtc_inb() & 0xff);	/* min */
798	hour = bcd2bin(rtc_inb() & 0xff);	/* hour */
799	days = bcd2bin(rtc_inb() & 0xff) - 1;	/* date */
800
801	month = (rtc_inb() >> 4) & 0x0f;	/* month */
802	for (m = 1; m <	month; m++)
803		days +=	daysinmonth[m-1];
804	year = bcd2bin(rtc_inb() & 0xff) + 1900;	/* year */
805	/* 2000 year problem */
806	if (year < 1995)
807		year += 100;
808	if (year < 1970)
809		goto wrong_time;
810	for (y = 1970; y < year; y++)
811		days +=	DAYSPERYEAR + LEAPYEAR(y);
812	if ((month > 2)	&& LEAPYEAR(year))
813		days ++;
814	sec = ((( days * 24 +
815		  hour) * 60 +
816		  min) * 60 +
817		  second);
818	/* sec now contains the	number of seconds, since Jan 1 1970,
819	   in the local	time zone */
820
821	s = splhigh();
822
823	sec += tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
824
825	y = time_second - sec;
826	if (y <= -2 || y >= 2) {
827		/* badly off, adjust it */
828		ts.tv_sec = sec;
829		ts.tv_nsec = 0;
830		tc_setclock(&ts);
831	}
832	splx(s);
833	return;
834
835wrong_time:
836	printf("Invalid time in real time clock.\n");
837	printf("Check and reset the date immediately!\n");
838}
839
840/*
841 * Write system time back to RTC
842 */
843void
844resettodr()
845{
846	unsigned long	tm;
847	int		y, m, s;
848	int		wd;
849
850	if (disable_rtc_set)
851		return;
852
853	s = splclock();
854	tm = time_second;
855	splx(s);
856
857	rtc_serialcom(0x01);	/* Register shift command. */
858
859	/* Calculate local time	to put in RTC */
860
861	tm -= tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
862
863	rtc_outb(bin2bcd(tm%60)); tm /= 60;	/* Write back Seconds */
864	rtc_outb(bin2bcd(tm%60)); tm /= 60;	/* Write back Minutes */
865	rtc_outb(bin2bcd(tm%24)); tm /= 24;	/* Write back Hours   */
866
867	/* We have now the days	since 01-01-1970 in tm */
868	wd = (tm + 4) % 7 + 1;			/* Write back Weekday */
869	for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
870	     tm >= m;
871	     y++,      m = DAYSPERYEAR + LEAPYEAR(y))
872	     tm -= m;
873
874	/* Now we have the years in y and the day-of-the-year in tm */
875	for (m = 0; ; m++) {
876		int ml;
877
878		ml = daysinmonth[m];
879		if (m == 1 && LEAPYEAR(y))
880			ml++;
881		if (tm < ml)
882			break;
883		tm -= ml;
884	}
885
886	m++;
887	rtc_outb(bin2bcd(tm+1));		/* Write back Day     */
888	rtc_outb((m << 4) | wd);		/* Write back Month & Weekday  */
889	rtc_outb(bin2bcd(y%100));		/* Write back Year    */
890
891	rtc_serialcom(0x02);	/* Time set & Counter hold command. */
892	rtc_serialcom(0x00);	/* Register hold command. */
893}
894
895
896/*
897 * Start both clocks running.
898 */
899void
900cpu_initclocks()
901{
902
903	/* Finish initializing 8254 timer 0. */
904	intr_add_handler("clk", 0, (driver_intr_t *)clkintr, NULL,
905	    INTR_TYPE_CLK | INTR_FAST, NULL);
906
907	init_TSC_tc();
908}
909
910void
911cpu_startprofclock(void)
912{
913}
914
915void
916cpu_stopprofclock(void)
917{
918}
919
920static int
921sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
922{
923	int error;
924	u_int freq;
925
926	/*
927	 * Use `i8254' instead of `timer' in external names because `timer'
928	 * is is too generic.  Should use it everywhere.
929	 */
930	freq = timer_freq;
931	error = sysctl_handle_int(oidp, &freq, sizeof(freq), req);
932	if (error == 0 && req->newptr != NULL) {
933#ifndef BURN_BRIDGES
934		if (timer0_state != RELEASED)
935			return (EBUSY);	/* too much trouble to handle */
936#endif
937		set_timer_freq(freq, hz);
938		i8254_timecounter.tc_frequency = freq;
939	}
940	return (error);
941}
942
943SYSCTL_PROC(_machdep, OID_AUTO, i8254_freq, CTLTYPE_INT | CTLFLAG_RW,
944    0, sizeof(u_int), sysctl_machdep_i8254_freq, "IU", "");
945
946static unsigned
947i8254_get_timecount(struct timecounter *tc)
948{
949	u_int count;
950	u_int high, low;
951	u_int eflags;
952
953	eflags = read_eflags();
954	mtx_lock_spin(&clock_lock);
955
956	/* Select timer0 and latch counter value. */
957	outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH);
958
959	low = inb(TIMER_CNTR0);
960	high = inb(TIMER_CNTR0);
961	count = timer0_max_count - ((high << 8) | low);
962	if (count < i8254_lastcount ||
963	    (!i8254_ticked && (clkintr_pending ||
964	    ((count < 20 || (!(eflags & PSL_I) && count < timer0_max_count / 2u)) &&
965	    i8254_intsrc != NULL &&
966	    i8254_intsrc->is_pic->pic_source_pending(i8254_intsrc))))) {
967		i8254_ticked = 1;
968		i8254_offset += timer0_max_count;
969	}
970	i8254_lastcount = count;
971	count += i8254_offset;
972	mtx_unlock_spin(&clock_lock);
973	return (count);
974}
975
976#ifdef DEV_ISA
977/*
978 * Attach to the ISA PnP descriptors for the timer and realtime clock.
979 */
980static struct isa_pnp_id attimer_ids[] = {
981	{ 0x0001d041 /* PNP0100 */, "AT timer" },
982	{ 0x000bd041 /* PNP0B00 */, "AT realtime clock" },
983	{ 0 }
984};
985
986static int
987attimer_probe(device_t dev)
988{
989	int result;
990
991	if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, attimer_ids)) <= 0)
992		device_quiet(dev);
993	return(result);
994}
995
996static int
997attimer_attach(device_t dev)
998{
999	return(0);
1000}
1001
1002static device_method_t attimer_methods[] = {
1003	/* Device interface */
1004	DEVMETHOD(device_probe,		attimer_probe),
1005	DEVMETHOD(device_attach,	attimer_attach),
1006	DEVMETHOD(device_detach,	bus_generic_detach),
1007	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
1008	DEVMETHOD(device_suspend,	bus_generic_suspend),	/* XXX stop statclock? */
1009	DEVMETHOD(device_resume,	bus_generic_resume),	/* XXX restart statclock? */
1010	{ 0, 0 }
1011};
1012
1013static driver_t attimer_driver = {
1014	"attimer",
1015	attimer_methods,
1016	1,		/* no softc */
1017};
1018
1019static devclass_t attimer_devclass;
1020
1021DRIVER_MODULE(attimer, isa, attimer_driver, attimer_devclass, 0, 0);
1022#endif /* DEV_ISA */
1023