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