xref: /freebsd/sys/i386/include/clock.h (revision 05c7a37afb48ddd5ee1bd921a5d46fe59cc70b15)
1 /*
2  * Kernel interface to machine-dependent clock driver.
3  * Garrett Wollman, September 1994.
4  * This file is in the public domain.
5  *
6  *	$Id: clock.h,v 1.10 1996/03/31 04:05:17 bde Exp $
7  */
8 
9 #ifndef _MACHINE_CLOCK_H_
10 #define	_MACHINE_CLOCK_H_
11 
12 #if defined(I586_CPU) || defined(I686_CPU)
13 
14 #define I586_CYCLECTR(x) \
15 	__asm __volatile(".byte 0x0f, 0x31" : "=A" (x))
16 
17 /*
18  * When we update the clock, we also update this bias value which is
19  * automatically subtracted in microtime().  We assume that CPU_THISTICKLEN()
20  * has been called at some point in the past, so that an appropriate value is
21  * set up in i586_last_tick.  (This works even if we are not being called
22  * from hardclock because hardclock will have run before and will made the
23  * call.)
24  */
25 #define CPU_CLOCKUPDATE(otime, ntime) \
26 	do { \
27 	if(i586_ctr_rate) { \
28 		disable_intr(); \
29 		i586_ctr_bias = i586_last_tick; \
30 		*(otime) = *(ntime); \
31 		enable_intr(); \
32 	} else { \
33 		*(otime) = *(ntime); \
34 	} \
35 	} while(0)
36 
37 #define	CPU_THISTICKLEN(dflt) cpu_thisticklen(dflt)
38 #else
39 #define CPU_CLOCKUPDATE(otime, ntime) \
40 		(*(otime) = *(ntime))
41 #define CPU_THISTICKLEN(dflt) dflt
42 #endif
43 
44 #define		I586_CTR_RATE_SHIFT	8
45 
46 #if defined(KERNEL) && !defined(LOCORE)
47 #include <sys/cdefs.h>
48 #include <machine/frame.h>
49 
50 /*
51  * i386 to clock driver interface.
52  * XXX almost all of it is misplaced.  i586 stuff is done in isa/clock.c
53  * and isa stuff is done in i386/microtime.s and i386/support.s.
54  */
55 extern int	adjkerntz;
56 extern int	disable_rtc_set;
57 extern int	wall_cmos_clock;
58 
59 #if defined(I586_CPU) || defined(I686_CPU)
60 extern unsigned	i586_ctr_rate;	/* fixed point */
61 extern long long i586_last_tick;
62 extern long long i586_ctr_bias;
63 extern unsigned long i586_avg_tick;
64 #endif
65 extern int 	timer0_max_count;
66 extern u_int 	timer0_overflow_threshold;
67 extern u_int 	timer0_prescaler_count;
68 
69 #if defined(I586_CPU) || defined(I686_CPU)
70 void	calibrate_cyclecounter __P((void));
71 #endif
72 
73 #if defined(I586_CPU) || defined(I686_CPU)
74 static __inline u_long
75 cpu_thisticklen(u_long dflt)
76 {
77 	long long old;
78 	long len;
79 
80 	if (i586_ctr_rate) {
81 		old = i586_last_tick;
82 		I586_CYCLECTR(i586_last_tick);
83 		len = ((i586_last_tick - old) << I586_CTR_RATE_SHIFT)
84 			/ i586_ctr_rate;
85 		i586_avg_tick = i586_avg_tick * 15 / 16 + len / 16;
86 	}
87 	return dflt;
88 }
89 #endif
90 
91 /*
92  * Driver to clock driver interface.
93  */
94 void	DELAY __P((int usec));
95 int	acquire_timer0 __P((int rate,
96 			    void (*function)(struct clockframe *frame)));
97 int	acquire_timer2 __P((int mode));
98 int	release_timer0 __P((void));
99 int	release_timer2 __P((void));
100 int	rtcin __P((int val));
101 int	sysbeep __P((int pitch, int period));
102 
103 #endif /* KERNEL && !LOCORE */
104 
105 #endif /* !_MACHINE_CLOCK_H_ */
106