clock.h revision 32054
1177997Skib/* 2177997Skib * Kernel interface to machine-dependent clock driver. 3177997Skib * Garrett Wollman, September 1994. 4177997Skib * This file is in the public domain. 5177997Skib * 6177997Skib * $Id: clock.h,v 1.29 1997/12/28 13:36:06 phk Exp $ 7177997Skib */ 8177997Skib 9177997Skib#ifndef _MACHINE_CLOCK_H_ 10177997Skib#define _MACHINE_CLOCK_H_ 11177997Skib 12177997Skib#define CPU_CLOCKUPDATE(otime, ntime) cpu_clockupdate((otime), (ntime)) 13177997Skib 14177997Skib#define CPU_THISTICKLEN(dflt) dflt 15177997Skib 16177997Skib#define TSC_COMULTIPLIER_SHIFT 20 17177997Skib#define TSC_MULTIPLIER_SHIFT 32 18177997Skib 19177997Skib#ifdef KERNEL 20177997Skib/* 21177997Skib * i386 to clock driver interface. 22177997Skib * XXX almost all of it is misplaced. i586 stuff is done in isa/clock.c 23177997Skib * and isa stuff is done in i386/microtime.s and i386/support.s. 24177997Skib */ 25177997Skibextern int adjkerntz; 26177997Skibextern int disable_rtc_set; 27177997Skibextern int statclock_disable; 28177997Skibextern u_int timer_freq; 29177997Skibextern int timer0_max_count; 30177997Skibextern u_int timer0_overflow_threshold; 31177997Skibextern u_int timer0_prescaler_count; 32177997Skibextern u_int tsc_bias; 33177997Skibextern u_int tsc_comultiplier; 34227693Sedextern u_int tsc_freq; 35177997Skibextern u_int tsc_multiplier; 36227693Sedextern int wall_cmos_clock; 37177997Skib 38246085Sjhb/* 39246085Sjhb * Driver to clock driver interface. 40246085Sjhb */ 41246085Sjhbstruct clockframe; 42246085Sjhb 43246085Sjhbvoid DELAY __P((int usec)); 44246085Sjhbint acquire_timer0 __P((int rate, 45246085Sjhb void (*function)(struct clockframe *frame))); 46246085Sjhbint acquire_timer2 __P((int mode)); 47246085Sjhbint release_timer0 __P((void)); 48246085Sjhbint release_timer2 __P((void)); 49246085Sjhb#ifndef PC98 50246085Sjhbint rtcin __P((int val)); 51246085Sjhb#else 52246085Sjhbint acquire_timer1 __P((int mode)); 53246085Sjhbint release_timer1 __P((void)); 54246085Sjhb#endif 55246085Sjhbint sysbeep __P((int pitch, int period)); 56246085Sjhb 57283437Sdchagin#ifdef CLOCK_HAIR 58283437Sdchagin 59283437Sdchagin#ifdef PC98 60283437Sdchagin#include <pc98/pc98/pc98.h> /* XXX */ 61283437Sdchagin#else 62283437Sdchagin#include <i386/isa/isa.h> /* XXX */ 63283437Sdchagin#endif 64283437Sdchagin#include <i386/isa/timerreg.h> /* XXX */ 65283437Sdchagin 66283437Sdchaginstatic __inline u_int 67283437Sdchaginclock_latency(void) 68283437Sdchagin{ 69283437Sdchagin u_char high, low; 70283437Sdchagin 71283437Sdchagin outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); 72283437Sdchagin low = inb(TIMER_CNTR0); 73283437Sdchagin high = inb(TIMER_CNTR0); 74283437Sdchagin return (timer0_prescaler_count + timer0_max_count 75283437Sdchagin - ((high << 8) | low)); 76283437Sdchagin} 77283437Sdchagin 78283437Sdchagin/* 79283437Sdchagin * When we update `time', on we also update `tsc_bias' 80283437Sdchagin * atomically. `tsc_bias' is the best available approximation to 81283437Sdchagin * the value of the TSC (mod 2^32) at the time of the i8254 82283437Sdchagin * counter transition that caused the clock interrupt that caused the 83283437Sdchagin * update. clock_latency() gives the time between the transition and 84283437Sdchagin * the update to within a few usec provided another such transition 85283437Sdchagin * hasn't occurred. We don't bother checking for counter overflow as 86283437Sdchagin * in microtime(), since if it occurs then we're close to losing clock 87283437Sdchagin * interrupts. 88283437Sdchagin */ 89283437Sdchaginstatic __inline void 90283437Sdchagincpu_clockupdate(volatile struct timeval *otime, struct timeval *ntime) 91283437Sdchagin{ 92283437Sdchagin if (tsc_freq != 0) { 93283437Sdchagin u_int tsc_count; /* truncated */ 94283437Sdchagin u_int i8254_count; 95283437Sdchagin 96283437Sdchagin disable_intr(); 97283437Sdchagin i8254_count = clock_latency(); 98283437Sdchagin tsc_count = rdtsc(); 99283437Sdchagin tsc_bias = tsc_count 100283437Sdchagin - (u_int) 101177997Skib (((unsigned long long)tsc_comultiplier 102 * i8254_count) 103 >> TSC_COMULTIPLIER_SHIFT); 104 *otime = *ntime; 105 enable_intr(); 106 } else 107 *otime = *ntime; 108} 109 110#endif /* CLOCK_HAIR */ 111 112#endif /* KERNEL */ 113 114#endif /* !_MACHINE_CLOCK_H_ */ 115