clock.h revision 13000
11543Srgrimes/*
21543Srgrimes * Kernel interface to machine-dependent clock driver.
31543Srgrimes * Garrett Wollman, September 1994.
41543Srgrimes * This file is in the public domain.
51543Srgrimes *
61543Srgrimes *	$Id: clock.h,v 1.7 1995/12/10 13:38:07 phk Exp $
71543Srgrimes */
81543Srgrimes
91543Srgrimes#ifndef _MACHINE_CLOCK_H_
101543Srgrimes#define	_MACHINE_CLOCK_H_
111543Srgrimes
121543Srgrimes#if defined(I586_CPU) || defined(I686_CPU)
131543Srgrimes
141543Srgrimes#define I586_CYCLECTR(x) \
151543Srgrimes	__asm __volatile(".byte 0x0f, 0x31" : "=A" (x))
161543Srgrimes
171543Srgrimes/*
181543Srgrimes * When we update the clock, we also update this bias value which is
191543Srgrimes * automatically subtracted in microtime().  We assume that CPU_THISTICKLEN()
201543Srgrimes * has been called at some point in the past, so that an appropriate value is
211543Srgrimes * set up in i586_last_tick.  (This works even if we are not being called
221543Srgrimes * from hardclock because hardclock will have run before and will made the
231543Srgrimes * call.)
241543Srgrimes */
251543Srgrimes#define CPU_CLOCKUPDATE(otime, ntime) \
261543Srgrimes	do { \
271543Srgrimes	if(i586_ctr_rate) { \
281543Srgrimes		disable_intr(); \
291543Srgrimes		i586_ctr_bias = i586_last_tick; \
301543Srgrimes		*(otime) = *(ntime); \
311543Srgrimes		enable_intr(); \
321543Srgrimes	} else { \
331543Srgrimes		*(otime) = *(ntime); \
341543Srgrimes	} \
351543Srgrimes	} while(0)
361543Srgrimes
371543Srgrimes#define	CPU_THISTICKLEN(dflt) cpu_thisticklen(dflt)
381543Srgrimes#else
391543Srgrimes#define CPU_CLOCKUPDATE(otime, ntime) \
401543Srgrimes		(*(otime) = *(ntime))
411543Srgrimes#define CPU_THISTICKLEN(dflt) dflt
421543Srgrimes#endif
431543Srgrimes
441543Srgrimes#define		I586_CTR_RATE_SHIFT	8
451543Srgrimes
461543Srgrimes#if defined(KERNEL) && !defined(LOCORE)
471543Srgrimes#include <sys/cdefs.h>
481543Srgrimes#include <machine/frame.h>
491543Srgrimes
501543Srgrimes/*
511543Srgrimes * i386 to clock driver interface.
521543Srgrimes * XXX almost all of it is misplaced.  i586 stuff is done in isa/clock.c
531543Srgrimes * and isa stuff is done in i386/microtime.s and i386/support.s.
541543Srgrimes */
551543Srgrimesextern int	adjkerntz;
561543Srgrimesextern int	disable_rtc_set;
57#if defined(I586_CPU) || defined(I686_CPU)
58extern unsigned	i586_ctr_rate;	/* fixed point */
59extern long long i586_last_tick;
60extern long long i586_ctr_bias;
61#endif
62extern int 	timer0_max_count;
63extern u_int 	timer0_overflow_threshold;
64extern u_int 	timer0_prescaler_count;
65
66#if defined(I586_CPU) || defined(I686_CPU)
67void	calibrate_cyclecounter __P((void));
68#endif
69
70#if defined(I586_CPU) || defined(I686_CPU)
71static __inline u_long
72cpu_thisticklen(u_long dflt)
73{
74	long long old;
75	long rv;
76
77	if (i586_ctr_rate) {
78		old = i586_last_tick;
79		I586_CYCLECTR(i586_last_tick);
80		rv = ((i586_last_tick - old) << I586_CTR_RATE_SHIFT)
81			/ i586_ctr_rate;
82	} else {
83		rv = dflt;
84	}
85	return rv;
86}
87#endif
88
89/*
90 * Driver to clock driver interface.
91 */
92void	DELAY __P((int usec));
93int	acquire_timer0 __P((int rate,
94			    void (*function)(struct clockframe *frame)));
95int	acquire_timer2 __P((int mode));
96int	release_timer0 __P((void));
97int	release_timer2 __P((void));
98int	sysbeep __P((int pitch, int period));
99
100#endif /* KERNEL && !LOCORE */
101
102#endif /* !_MACHINE_CLOCK_H_ */
103