linux-bk/include/linux/timex.h
<<
>>
Prefs
   1/*****************************************************************************
   2 *                                                                           *
   3 * Copyright (c) David L. Mills 1993                                         *
   4 *                                                                           *
   5 * Permission to use, copy, modify, and distribute this software and its     *
   6 * documentation for any purpose and without fee is hereby granted, provided *
   7 * that the above copyright notice appears in all copies and that both the   *
   8 * copyright notice and this permission notice appear in supporting          *
   9 * documentation, and that the name University of Delaware not be used in    *
  10 * advertising or publicity pertaining to distribution of the software       *
  11 * without specific, written prior permission.  The University of Delaware   *
  12 * makes no representations about the suitability this software for any      *
  13 * purpose.  It is provided "as is" without express or implied warranty.     *
  14 *                                                                           *
  15 *****************************************************************************/
  16
  17/*
  18 * Modification history timex.h
  19 *
  20 * 29 Dec 97    Russell King
  21 *      Moved CLOCK_TICK_RATE, CLOCK_TICK_FACTOR and FINETUNE to asm/timex.h
  22 *      for ARM machines
  23 *
  24 *  9 Jan 97    Adrian Sun
  25 *      Shifted LATCH define to allow access to alpha machines.
  26 *
  27 * 26 Sep 94    David L. Mills
  28 *      Added defines for hybrid phase/frequency-lock loop.
  29 *
  30 * 19 Mar 94    David L. Mills
  31 *      Moved defines from kernel routines to header file and added new
  32 *      defines for PPS phase-lock loop.
  33 *
  34 * 20 Feb 94    David L. Mills
  35 *      Revised status codes and structures for external clock and PPS
  36 *      signal discipline.
  37 *
  38 * 28 Nov 93    David L. Mills
  39 *      Adjusted parameters to improve stability and increase poll
  40 *      interval.
  41 *
  42 * 17 Sep 93    David L. Mills
  43 *      Created file $NTP/include/sys/timex.h
  44 * 07 Oct 93    Torsten Duwe
  45 *      Derived linux/timex.h
  46 * 1995-08-13    Torsten Duwe
  47 *      kernel PLL updated to 1994-12-13 specs (rfc-1589)
  48 * 1997-08-30    Ulrich Windl
  49 *      Added new constant NTP_PHASE_LIMIT
  50 */
  51#ifndef _LINUX_TIMEX_H
  52#define _LINUX_TIMEX_H
  53
  54#include <linux/config.h>
  55#include <linux/compiler.h>
  56
  57#include <asm/param.h>
  58
  59/*
  60 * The following defines establish the engineering parameters of the PLL
  61 * model. The HZ variable establishes the timer interrupt frequency, 100 Hz
  62 * for the SunOS kernel, 256 Hz for the Ultrix kernel and 1024 Hz for the
  63 * OSF/1 kernel. The SHIFT_HZ define expresses the same value as the
  64 * nearest power of two in order to avoid hardware multiply operations.
  65 */
  66#if HZ >= 12 && HZ < 24
  67# define SHIFT_HZ       4
  68#elif HZ >= 24 && HZ < 48
  69# define SHIFT_HZ       5
  70#elif HZ >= 48 && HZ < 96
  71# define SHIFT_HZ       6
  72#elif HZ >= 96 && HZ < 192
  73# define SHIFT_HZ       7
  74#elif HZ >= 192 && HZ < 384
  75# define SHIFT_HZ       8
  76#elif HZ >= 384 && HZ < 768
  77# define SHIFT_HZ       9
  78#elif HZ >= 768 && HZ < 1536
  79# define SHIFT_HZ       10
  80#else
  81# error You lose.
  82#endif
  83
  84/*
  85 * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen
  86 * for a slightly underdamped convergence characteristic. SHIFT_KH
  87 * establishes the damping of the FLL and is chosen by wisdom and black
  88 * art.
  89 *
  90 * MAXTC establishes the maximum time constant of the PLL. With the
  91 * SHIFT_KG and SHIFT_KF values given and a time constant range from
  92 * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours,
  93 * respectively.
  94 */
  95#define SHIFT_KG 6              /* phase factor (shift) */
  96#define SHIFT_KF 16             /* PLL frequency factor (shift) */
  97#define SHIFT_KH 2              /* FLL frequency factor (shift) */
  98#define MAXTC 6                 /* maximum time constant (shift) */
  99
 100/*
 101 * The SHIFT_SCALE define establishes the decimal point of the time_phase
 102 * variable which serves as an extension to the low-order bits of the
 103 * system clock variable. The SHIFT_UPDATE define establishes the decimal
 104 * point of the time_offset variable which represents the current offset
 105 * with respect to standard time. The FINENSEC define represents 1 nsec in
 106 * scaled units.
 107 *
 108 * SHIFT_USEC defines the scaling (shift) of the time_freq and
 109 * time_tolerance variables, which represent the current frequency
 110 * offset and maximum frequency tolerance.
 111 *
 112 * FINENSEC is 1 ns in SHIFT_UPDATE units of the time_phase variable.
 113 */
 114#define SHIFT_SCALE 22          /* phase scale (shift) */
 115#define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */
 116#define SHIFT_USEC 16           /* frequency offset scale (shift) */
 117#define FINENSEC (1L << (SHIFT_SCALE - 10)) /* ~1 ns in phase units */
 118
 119#define MAXPHASE 512000L        /* max phase error (us) */
 120#define MAXFREQ (512L << SHIFT_USEC)  /* max frequency error (ppm) */
 121#define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */
 122#define MINSEC 16L              /* min interval between updates (s) */
 123#define MAXSEC 1200L            /* max interval between updates (s) */
 124#define NTP_PHASE_LIMIT (MAXPHASE << 5) /* beyond max. dispersion */
 125
 126/*
 127 * The following defines are used only if a pulse-per-second (PPS)
 128 * signal is available and connected via a modem control lead, such as
 129 * produced by the optional ppsclock feature incorporated in the Sun
 130 * asynch driver. They establish the design parameters of the frequency-
 131 * lock loop used to discipline the CPU clock oscillator to the PPS
 132 * signal.
 133 *
 134 * PPS_AVG is the averaging factor for the frequency loop, as well as
 135 * the time and frequency dispersion.
 136 *
 137 * PPS_SHIFT and PPS_SHIFTMAX specify the minimum and maximum
 138 * calibration intervals, respectively, in seconds as a power of two.
 139 *
 140 * PPS_VALID is the maximum interval before the PPS signal is considered
 141 * invalid and protocol updates used directly instead.
 142 *
 143 * MAXGLITCH is the maximum interval before a time offset of more than
 144 * MAXTIME is believed.
 145 */
 146#define PPS_AVG 2               /* pps averaging constant (shift) */
 147#define PPS_SHIFT 2             /* min interval duration (s) (shift) */
 148#define PPS_SHIFTMAX 8          /* max interval duration (s) (shift) */
 149#define PPS_VALID 120           /* pps signal watchdog max (s) */
 150#define MAXGLITCH 30            /* pps signal glitch max (s) */
 151
 152/*
 153 * Pick up the architecture specific timex specifications
 154 */
 155#include <asm/timex.h>
 156
 157/* LATCH is used in the interval timer and ftape setup. */
 158#define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ)  /* For divider */
 159
 160/* Suppose we want to devide two numbers NOM and DEN: NOM/DEN, the we can
 161 * improve accuracy by shifting LSH bits, hence calculating:
 162 *     (NOM << LSH) / DEN
 163 * This however means trouble for large NOM, because (NOM << LSH) may no
 164 * longer fit in 32 bits. The following way of calculating this gives us
 165 * some slack, under the following conditions:
 166 *   - (NOM / DEN) fits in (32 - LSH) bits.
 167 *   - (NOM % DEN) fits in (32 - LSH) bits.
 168 */
 169#define SH_DIV(NOM,DEN,LSH) (   ((NOM / DEN) << LSH)                    \
 170                             + (((NOM % DEN) << LSH) + DEN / 2) / DEN)
 171
 172/* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */
 173#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))
 174
 175/* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */
 176#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))
 177
 178/* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */
 179#define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
 180
 181/* TICK_USEC_TO_NSEC is the time between ticks in nsec assuming real ACTHZ and  */
 182/* a value TUSEC for TICK_USEC (can be set bij adjtimex)                */
 183#define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8))
 184
 185
 186#include <linux/time.h>
 187/*
 188 * syscall interface - used (mainly by NTP daemon)
 189 * to discipline kernel clock oscillator
 190 */
 191struct timex {
 192        unsigned int modes;     /* mode selector */
 193        long offset;            /* time offset (usec) */
 194        long freq;              /* frequency offset (scaled ppm) */
 195        long maxerror;          /* maximum error (usec) */
 196        long esterror;          /* estimated error (usec) */
 197        int status;             /* clock command/status */
 198        long constant;          /* pll time constant */
 199        long precision;         /* clock precision (usec) (read only) */
 200        long tolerance;         /* clock frequency tolerance (ppm)
 201                                 * (read only)
 202                                 */
 203        struct timeval time;    /* (read only) */
 204        long tick;              /* (modified) usecs between clock ticks */
 205
 206        long ppsfreq;           /* pps frequency (scaled ppm) (ro) */
 207        long jitter;            /* pps jitter (us) (ro) */
 208        int shift;              /* interval duration (s) (shift) (ro) */
 209        long stabil;            /* pps stability (scaled ppm) (ro) */
 210        long jitcnt;            /* jitter limit exceeded (ro) */
 211        long calcnt;            /* calibration intervals (ro) */
 212        long errcnt;            /* calibration errors (ro) */
 213        long stbcnt;            /* stability limit exceeded (ro) */
 214
 215        int  :32; int  :32; int  :32; int  :32;
 216        int  :32; int  :32; int  :32; int  :32;
 217        int  :32; int  :32; int  :32; int  :32;
 218};
 219
 220/*
 221 * Mode codes (timex.mode)
 222 */
 223#define ADJ_OFFSET              0x0001  /* time offset */
 224#define ADJ_FREQUENCY           0x0002  /* frequency offset */
 225#define ADJ_MAXERROR            0x0004  /* maximum time error */
 226#define ADJ_ESTERROR            0x0008  /* estimated time error */
 227#define ADJ_STATUS              0x0010  /* clock status */
 228#define ADJ_TIMECONST           0x0020  /* pll time constant */
 229#define ADJ_TICK                0x4000  /* tick value */
 230#define ADJ_OFFSET_SINGLESHOT   0x8001  /* old-fashioned adjtime */
 231
 232/* xntp 3.4 compatibility names */
 233#define MOD_OFFSET      ADJ_OFFSET
 234#define MOD_FREQUENCY   ADJ_FREQUENCY
 235#define MOD_MAXERROR    ADJ_MAXERROR
 236#define MOD_ESTERROR    ADJ_ESTERROR
 237#define MOD_STATUS      ADJ_STATUS
 238#define MOD_TIMECONST   ADJ_TIMECONST
 239#define MOD_CLKB        ADJ_TICK
 240#define MOD_CLKA        ADJ_OFFSET_SINGLESHOT /* 0x8000 in original */
 241
 242
 243/*
 244 * Status codes (timex.status)
 245 */
 246#define STA_PLL         0x0001  /* enable PLL updates (rw) */
 247#define STA_PPSFREQ     0x0002  /* enable PPS freq discipline (rw) */
 248#define STA_PPSTIME     0x0004  /* enable PPS time discipline (rw) */
 249#define STA_FLL         0x0008  /* select frequency-lock mode (rw) */
 250
 251#define STA_INS         0x0010  /* insert leap (rw) */
 252#define STA_DEL         0x0020  /* delete leap (rw) */
 253#define STA_UNSYNC      0x0040  /* clock unsynchronized (rw) */
 254#define STA_FREQHOLD    0x0080  /* hold frequency (rw) */
 255
 256#define STA_PPSSIGNAL   0x0100  /* PPS signal present (ro) */
 257#define STA_PPSJITTER   0x0200  /* PPS signal jitter exceeded (ro) */
 258#define STA_PPSWANDER   0x0400  /* PPS signal wander exceeded (ro) */
 259#define STA_PPSERROR    0x0800  /* PPS signal calibration error (ro) */
 260
 261#define STA_CLOCKERR    0x1000  /* clock hardware fault (ro) */
 262
 263#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
 264    STA_PPSERROR | STA_CLOCKERR) /* read-only bits */
 265
 266/*
 267 * Clock states (time_state)
 268 */
 269#define TIME_OK         0       /* clock synchronized, no leap second */
 270#define TIME_INS        1       /* insert leap second */
 271#define TIME_DEL        2       /* delete leap second */
 272#define TIME_OOP        3       /* leap second in progress */
 273#define TIME_WAIT       4       /* leap second has occurred */
 274#define TIME_ERROR      5       /* clock not synchronized */
 275#define TIME_BAD        TIME_ERROR /* bw compat */
 276
 277#ifdef __KERNEL__
 278/*
 279 * kernel variables
 280 * Note: maximum error = NTP synch distance = dispersion + delay / 2;
 281 * estimated error = NTP dispersion.
 282 */
 283extern unsigned long tick_usec;         /* USER_HZ period (usec) */
 284extern unsigned long tick_nsec;         /* ACTHZ          period (nsec) */
 285extern int tickadj;                     /* amount of adjustment per tick */
 286
 287/*
 288 * phase-lock loop variables
 289 */
 290extern int time_state;          /* clock status */
 291extern int time_status;         /* clock synchronization status bits */
 292extern long time_offset;        /* time adjustment (us) */
 293extern long time_constant;      /* pll time constant */
 294extern long time_tolerance;     /* frequency tolerance (ppm) */
 295extern long time_precision;     /* clock precision (us) */
 296extern long time_maxerror;      /* maximum error */
 297extern long time_esterror;      /* estimated error */
 298
 299extern long time_phase;         /* phase offset (scaled us) */
 300extern long time_freq;          /* frequency offset (scaled ppm) */
 301extern long time_adj;           /* tick adjust (scaled 1 / HZ) */
 302extern long time_reftime;       /* time at last adjustment (s) */
 303
 304extern long time_adjust;        /* The amount of adjtime left */
 305extern long time_next_adjust;   /* Value for time_adjust at next tick */
 306
 307/* interface variables pps->timer interrupt */
 308extern long pps_offset;         /* pps time offset (us) */
 309extern long pps_jitter;         /* time dispersion (jitter) (us) */
 310extern long pps_freq;           /* frequency offset (scaled ppm) */
 311extern long pps_stabil;         /* frequency dispersion (scaled ppm) */
 312extern long pps_valid;          /* pps signal watchdog counter */
 313
 314/* interface variables pps->adjtimex */
 315extern int pps_shift;           /* interval duration (s) (shift) */
 316extern long pps_jitcnt;         /* jitter limit exceeded */
 317extern long pps_calcnt;         /* calibration intervals */
 318extern long pps_errcnt;         /* calibration errors */
 319extern long pps_stbcnt;         /* stability limit exceeded */
 320
 321#ifdef CONFIG_TIME_INTERPOLATION
 322
 323struct time_interpolator {
 324        /* cache-hot stuff first: */
 325        unsigned long (*get_offset) (void);
 326        void (*update) (long);
 327        void (*reset) (void);
 328
 329        /* cache-cold stuff follows here: */
 330        struct time_interpolator *next;
 331        unsigned long frequency;        /* frequency in counts/second */
 332        long drift;                     /* drift in parts-per-million (or -1) */
 333};
 334
 335extern volatile unsigned long last_nsec_offset;
 336#ifndef __HAVE_ARCH_CMPXCHG
 337extern spin_lock_t last_nsec_offset_lock;
 338#endif
 339extern struct time_interpolator *time_interpolator;
 340
 341extern void register_time_interpolator(struct time_interpolator *);
 342extern void unregister_time_interpolator(struct time_interpolator *);
 343
 344/* Called with xtime WRITE-lock acquired.  */
 345static inline void
 346time_interpolator_update(long delta_nsec)
 347{
 348        struct time_interpolator *ti = time_interpolator;
 349
 350        if (last_nsec_offset > 0) {
 351#ifdef __HAVE_ARCH_CMPXCHG
 352                unsigned long new, old;
 353
 354                do {
 355                        old = last_nsec_offset;
 356                        if (old > delta_nsec)
 357                                new = old - delta_nsec;
 358                        else
 359                                new = 0;
 360                } while (cmpxchg(&last_nsec_offset, old, new) != old);
 361#else
 362                /*
 363                 * This really hurts, because it serializes gettimeofday(), but without an
 364                 * atomic single-word compare-and-exchange, there isn't all that much else
 365                 * we can do.
 366                 */
 367                spin_lock(&last_nsec_offset_lock);
 368                {
 369                        last_nsec_offset -= min(last_nsec_offset, delta_nsec);
 370                }
 371                spin_unlock(&last_nsec_offset_lock);
 372#endif
 373        }
 374
 375        if (ti)
 376                (*ti->update)(delta_nsec);
 377}
 378
 379/* Called with xtime WRITE-lock acquired.  */
 380static inline void
 381time_interpolator_reset(void)
 382{
 383        struct time_interpolator *ti = time_interpolator;
 384
 385        last_nsec_offset = 0;
 386        if (ti)
 387                (*ti->reset)();
 388}
 389
 390/* Called with xtime READ-lock acquired.  */
 391static inline unsigned long
 392time_interpolator_get_offset(void)
 393{
 394        struct time_interpolator *ti = time_interpolator;
 395        if (ti)
 396                return (*ti->get_offset)();
 397        return last_nsec_offset;
 398}
 399
 400#else /* !CONFIG_TIME_INTERPOLATION */
 401
 402static inline void
 403time_interpolator_update(long delta_nsec)
 404{
 405}
 406
 407static inline void
 408time_interpolator_reset(void)
 409{
 410}
 411
 412static inline unsigned long
 413time_interpolator_get_offset(void)
 414{
 415        return 0;
 416}
 417
 418#endif /* !CONFIG_TIME_INTERPOLATION */
 419
 420#endif /* KERNEL */
 421
 422#endif /* LINUX_TIMEX_H */
 423
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.