linux-old/kernel/time.c
<<
>>
Prefs
   1/*
   2 *  linux/kernel/time.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *
   6 *  This file contains the interface functions for the various
   7 *  time related system calls: time, stime, gettimeofday, settimeofday,
   8 *                             adjtime
   9 */
  10/*
  11 * Modification history kernel/time.c
  12 * 
  13 * 1993-09-02    Philip Gladstone
  14 *      Created file with time related functions from sched.c and adjtimex() 
  15 * 1993-10-08    Torsten Duwe
  16 *      adjtime interface update and CMOS clock write code
  17 * 1994-07-02    Alan Modra
  18 *      fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
  19 * 1995-03-26    Markus Kuhn
  20 *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
  21 *      precision CMOS clock update
  22 *
  23 * to do: adjtimex() has to be updated to recent (1994-12-13) revision
  24 *        of David Mill's kernel clock model. For more information, check
  25 *        <ftp://louie.udel.edu/pub/ntp/kernel.tar.Z>. 
  26 */
  27
  28#include <linux/errno.h>
  29#include <linux/sched.h>
  30#include <linux/kernel.h>
  31#include <linux/param.h>
  32#include <linux/string.h>
  33#include <linux/mm.h>
  34
  35#include <asm/segment.h>
  36#include <asm/io.h>
  37
  38#include <linux/mc146818rtc.h>
  39#include <linux/timex.h>
  40
  41/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  42 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
  43 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
  44 *
  45 * [For the Julian calendar (which was used in Russia before 1917,
  46 * Britain & colonies before 1752, anywhere else before 1582,
  47 * and is still in use by some communities) leave out the
  48 * -year/100+year/400 terms, and add 10.]
  49 *
  50 * This algorithm was first published by Gauss (I think).
  51 *
  52 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
  53 * machines were long is 32-bit! (However, as time_t is signed, we
  54 * will already get problems at other places on 2038-01-19 03:14:08)
  55 */
  56static inline unsigned long mktime(unsigned int year, unsigned int mon,
  57        unsigned int day, unsigned int hour,
  58        unsigned int min, unsigned int sec)
  59{
  60        if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
  61                mon += 12;      /* Puts Feb last since it has leap day */
  62                year -= 1;
  63        }
  64        return (((
  65            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
  66              year*365 - 719499
  67            )*24 + hour /* now have hours */
  68           )*60 + min /* now have minutes */
  69          )*60 + sec; /* finally seconds */
  70}
  71
  72void time_init(void)
  73{
  74        unsigned int year, mon, day, hour, min, sec;
  75        int i;
  76
  77        /* The Linux interpretation of the CMOS clock register contents:
  78         * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
  79         * RTC registers show the second which has precisely just started.
  80         * Let's hope other operating systems interpret the RTC the same way.
  81         */
  82        /* read RTC exactly on falling edge of update flag */
  83        for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
  84                if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
  85                        break;
  86        for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
  87                if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
  88                        break;
  89        do { /* Isn't this overkill ? UIP above should guarantee consistency */
  90                sec = CMOS_READ(RTC_SECONDS);
  91                min = CMOS_READ(RTC_MINUTES);
  92                hour = CMOS_READ(RTC_HOURS);
  93                day = CMOS_READ(RTC_DAY_OF_MONTH);
  94                mon = CMOS_READ(RTC_MONTH);
  95                year = CMOS_READ(RTC_YEAR);
  96        } while (sec != CMOS_READ(RTC_SECONDS));
  97        if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
  98          {
  99            BCD_TO_BIN(sec);
 100            BCD_TO_BIN(min);
 101            BCD_TO_BIN(hour);
 102            BCD_TO_BIN(day);
 103            BCD_TO_BIN(mon);
 104            BCD_TO_BIN(year);
 105          }
 106        if ((year += 1900) < 1970)
 107                year += 100;
 108        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
 109        xtime.tv_usec = 0;
 110}
 111
 112/* 
 113 * The timezone where the local system is located.  Used as a default by some
 114 * programs who obtain this value by using gettimeofday.
 115 */
 116struct timezone sys_tz = { 0, 0};
 117
 118asmlinkage int sys_time(long * tloc)
 119{
 120        int i, error;
 121
 122        i = CURRENT_TIME;
 123        if (tloc) {
 124                error = verify_area(VERIFY_WRITE, tloc, 4);
 125                if (error)
 126                        return error;
 127                put_fs_long(i,(unsigned long *)tloc);
 128        }
 129        return i;
 130}
 131
 132asmlinkage int sys_stime(unsigned long * tptr)
 133{
 134        int error;
 135        unsigned long value;
 136
 137        if (!suser())
 138                return -EPERM;
 139        error = verify_area(VERIFY_READ, tptr, sizeof(*tptr));
 140        if (error)
 141                return error;
 142        value = get_fs_long(tptr);
 143        cli();
 144        xtime.tv_sec = value;
 145        xtime.tv_usec = 0;
 146        time_status = TIME_BAD;
 147        time_maxerror = 0x70000000;
 148        time_esterror = 0x70000000;
 149        sti();
 150        return 0;
 151}
 152
 153/* This function must be called with interrupts disabled 
 154 * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
 155 * 
 156 * However, the pc-audio speaker driver changes the divisor so that
 157 * it gets interrupted rather more often - it loads 64 into the
 158 * counter rather than 11932! This has an adverse impact on
 159 * do_gettimeoffset() -- it stops working! What is also not
 160 * good is that the interval that our timer function gets called
 161 * is no longer 10.0002 ms, but 9.9767 ms. To get around this
 162 * would require using a different timing source. Maybe someone
 163 * could use the RTC - I know that this can interrupt at frequencies
 164 * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
 165 * it so that at startup, the timer code in sched.c would select
 166 * using either the RTC or the 8253 timer. The decision would be
 167 * based on whether there was any other device around that needed
 168 * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
 169 * and then do some jiggery to have a version of do_timer that 
 170 * advanced the clock by 1/1024 s. Every time that reached over 1/100
 171 * of a second, then do all the old code. If the time was kept correct
 172 * then do_gettimeoffset could just return 0 - there is no low order
 173 * divider that can be accessed.
 174 *
 175 * Ideally, you would be able to use the RTC for the speaker driver,
 176 * but it appears that the speaker driver really needs interrupt more
 177 * often than every 120 us or so.
 178 *
 179 * Anyway, this needs more thought....          pjsg (1993-08-28)
 180 * 
 181 * If you are really that interested, you should be reading
 182 * comp.protocols.time.ntp!
 183 */
 184
 185#define TICK_SIZE tick
 186
 187static inline unsigned long do_gettimeoffset(void)
 188{
 189        int count;
 190        unsigned long offset = 0;
 191
 192        /* timer count may underflow right here */
 193        outb_p(0x00, 0x43);     /* latch the count ASAP */
 194        count = inb_p(0x40);    /* read the latched count */
 195        count |= inb(0x40) << 8;
 196        /* we know probability of underflow is always MUCH less than 1% */
 197        if (count > (LATCH - LATCH/100)) {
 198                /* check for pending timer interrupt */
 199                outb_p(0x0a, 0x20);
 200                if (inb(0x20) & 1)
 201                        offset = TICK_SIZE;
 202        }
 203        count = ((LATCH-1) - count) * TICK_SIZE;
 204        count = (count + LATCH/2) / LATCH;
 205        return offset + count;
 206}
 207
 208/*
 209 * This version of gettimeofday has near microsecond resolution.
 210 */
 211void do_gettimeofday(struct timeval *tv)
 212{
 213        unsigned long flags;
 214
 215        save_flags(flags);
 216        cli();
 217        *tv = xtime;
 218#if defined (__i386__) || defined (__mips__)
 219        tv->tv_usec += do_gettimeoffset();
 220        if (tv->tv_usec >= 1000000) {
 221                tv->tv_usec -= 1000000;
 222                tv->tv_sec++;
 223        }
 224#endif /* !defined (__i386__) && !defined (__mips__) */
 225        restore_flags(flags);
 226}
 227
 228asmlinkage int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
 229{
 230        int error;
 231
 232        if (tv) {
 233                struct timeval ktv;
 234                error = verify_area(VERIFY_WRITE, tv, sizeof *tv);
 235                if (error)
 236                        return error;
 237                do_gettimeofday(&ktv);
 238                put_fs_long(ktv.tv_sec, (unsigned long *) &tv->tv_sec);
 239                put_fs_long(ktv.tv_usec, (unsigned long *) &tv->tv_usec);
 240        }
 241        if (tz) {
 242                error = verify_area(VERIFY_WRITE, tz, sizeof *tz);
 243                if (error)
 244                        return error;
 245                put_fs_long(sys_tz.tz_minuteswest, (unsigned long *) tz);
 246                put_fs_long(sys_tz.tz_dsttime, ((unsigned long *) tz)+1);
 247        }
 248        return 0;
 249}
 250
 251/*
 252 * Adjust the time obtained from the CMOS to be UTC time instead of
 253 * local time.
 254 * 
 255 * This is ugly, but preferable to the alternatives.  Otherwise we
 256 * would either need to write a program to do it in /etc/rc (and risk
 257 * confusion if the program gets run more than once; it would also be 
 258 * hard to make the program warp the clock precisely n hours)  or
 259 * compile in the timezone information into the kernel.  Bad, bad....
 260 *
 261 *                                              - TYT, 1992-01-01
 262 *
 263 * The best thing to do is to keep the CMOS clock in universal time (UTC)
 264 * as real UNIX machines always do it. This avoids all headaches about
 265 * daylight saving times and warping kernel clocks.
 266 */
 267inline static void warp_clock(void)
 268{
 269        cli();
 270        xtime.tv_sec += sys_tz.tz_minuteswest * 60;
 271        sti();
 272}
 273
 274/*
 275 * In case for some reason the CMOS clock has not already been running
 276 * in UTC, but in some local time: The first time we set the timezone,
 277 * we will warp the clock so that it is ticking UTC time instead of
 278 * local time. Presumably, if someone is setting the timezone then we
 279 * are running in an environment where the programs understand about
 280 * timezones. This should be done at boot time in the /etc/rc script,
 281 * as soon as possible, so that the clock can be set right. Otherwise,
 282 * various programs will get confused when the clock gets warped.
 283 */
 284asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz)
 285{
 286        static int      firsttime = 1;
 287        struct timeval  new_tv;
 288        struct timezone new_tz;
 289
 290        if (!suser())
 291                return -EPERM;
 292        if (tv) {
 293                int error = verify_area(VERIFY_READ, tv, sizeof(*tv));
 294                if (error)
 295                        return error;
 296                memcpy_fromfs(&new_tv, tv, sizeof(*tv));
 297        }
 298        if (tz) {
 299                int error = verify_area(VERIFY_READ, tz, sizeof(*tz));
 300                if (error)
 301                        return error;
 302                memcpy_fromfs(&new_tz, tz, sizeof(*tz));
 303        }
 304        if (tz) {
 305                sys_tz = new_tz;
 306                if (firsttime) {
 307                        firsttime = 0;
 308                        if (!tv)
 309                                warp_clock();
 310                }
 311        }
 312        if (tv) {
 313                cli();
 314                /* This is revolting. We need to set the xtime.tv_usec
 315                 * correctly. However, the value in this location is
 316                 * is value at the last tick.
 317                 * Discover what correction gettimeofday
 318                 * would have done, and then undo it!
 319                 */
 320                new_tv.tv_usec -= do_gettimeoffset();
 321
 322                if (new_tv.tv_usec < 0) {
 323                        new_tv.tv_usec += 1000000;
 324                        new_tv.tv_sec--;
 325                }
 326
 327                xtime = new_tv;
 328                time_status = TIME_BAD;
 329                time_maxerror = 0x70000000;
 330                time_esterror = 0x70000000;
 331                sti();
 332        }
 333        return 0;
 334}
 335
 336/* adjtimex mainly allows reading (and writing, if superuser) of
 337 * kernel time-keeping variables. used by xntpd.
 338 */
 339asmlinkage int sys_adjtimex(struct timex *txc_p)
 340{
 341        long ltemp, mtemp, save_adjust;
 342        int error;
 343
 344        /* Local copy of parameter */
 345        struct timex txc;
 346
 347        error = verify_area(VERIFY_WRITE, txc_p, sizeof(struct timex));
 348        if (error)
 349          return error;
 350
 351        /* Copy the user data space into the kernel copy
 352         * structure. But bear in mind that the structures
 353         * may change
 354         */
 355        memcpy_fromfs(&txc, txc_p, sizeof(struct timex));
 356
 357        /* In order to modify anything, you gotta be super-user! */
 358        if (txc.mode && !suser())
 359                return -EPERM;
 360
 361        /* Now we validate the data before disabling interrupts
 362         */
 363
 364        if (txc.mode != ADJ_OFFSET_SINGLESHOT && (txc.mode & ADJ_OFFSET))
 365          /* Microsec field limited to -131000 .. 131000 usecs */
 366          if (txc.offset <= -(1 << (31 - SHIFT_UPDATE))
 367              || txc.offset >= (1 << (31 - SHIFT_UPDATE)))
 368            return -EINVAL;
 369
 370        /* time_status must be in a fairly small range */
 371        if (txc.mode & ADJ_STATUS)
 372          if (txc.status < TIME_OK || txc.status > TIME_BAD)
 373            return -EINVAL;
 374
 375        /* if the quartz is off by more than 10% something is VERY wrong ! */
 376        if (txc.mode & ADJ_TICK)
 377          if (txc.tick < 900000/HZ || txc.tick > 1100000/HZ)
 378            return -EINVAL;
 379
 380        cli();
 381
 382        /* Save for later - semantics of adjtime is to return old value */
 383        save_adjust = time_adjust;
 384
 385        /* If there are input parameters, then process them */
 386        if (txc.mode)
 387        {
 388            if (time_status == TIME_BAD)
 389                time_status = TIME_OK;
 390
 391            if (txc.mode & ADJ_STATUS)
 392                time_status = txc.status;
 393
 394            if (txc.mode & ADJ_FREQUENCY)
 395                time_freq = txc.frequency << (SHIFT_KF - 16);
 396
 397            if (txc.mode & ADJ_MAXERROR)
 398                time_maxerror = txc.maxerror;
 399
 400            if (txc.mode & ADJ_ESTERROR)
 401                time_esterror = txc.esterror;
 402
 403            if (txc.mode & ADJ_TIMECONST)
 404                time_constant = txc.time_constant;
 405
 406            if (txc.mode & ADJ_OFFSET)
 407              if (txc.mode == ADJ_OFFSET_SINGLESHOT)
 408                {
 409                  time_adjust = txc.offset;
 410                }
 411              else /* XXX should give an error if other bits set */
 412                {
 413                  time_offset = txc.offset << SHIFT_UPDATE;
 414                  mtemp = xtime.tv_sec - time_reftime;
 415                  time_reftime = xtime.tv_sec;
 416                  if (mtemp > (MAXSEC+2) || mtemp < 0)
 417                    mtemp = 0;
 418
 419                  if (txc.offset < 0)
 420                    time_freq -= (-txc.offset * mtemp) >>
 421                      (time_constant + time_constant);
 422                  else
 423                    time_freq += (txc.offset * mtemp) >>
 424                      (time_constant + time_constant);
 425
 426                  ltemp = time_tolerance << SHIFT_KF;
 427
 428                  if (time_freq > ltemp)
 429                    time_freq = ltemp;
 430                  else if (time_freq < -ltemp)
 431                    time_freq = -ltemp;
 432                }
 433            if (txc.mode & ADJ_TICK)
 434              tick = txc.tick;
 435
 436        }
 437        txc.offset         = save_adjust;
 438        txc.frequency      = ((time_freq+1) >> (SHIFT_KF - 16));
 439        txc.maxerror       = time_maxerror;
 440        txc.esterror       = time_esterror;
 441        txc.status         = time_status;
 442        txc.time_constant  = time_constant;
 443        txc.precision      = time_precision;
 444        txc.tolerance      = time_tolerance;
 445        txc.time           = xtime;
 446        txc.tick           = tick;
 447
 448        sti();
 449
 450        memcpy_tofs(txc_p, &txc, sizeof(struct timex));
 451        return time_status;
 452}
 453
 454/*
 455 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
 456 * called 500 ms after the second nowtime has started, because when
 457 * nowtime is written into the registers of the CMOS clock, it will
 458 * jump to the next second precisely 500 ms later. Check the Motorola
 459 * MC146818A or Dallas DS12887 data sheet for details.
 460 */
 461int set_rtc_mmss(unsigned long nowtime)
 462{
 463  int retval = 0;
 464  int real_seconds, real_minutes, cmos_minutes;
 465  unsigned char save_control, save_freq_select;
 466
 467  save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
 468  CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
 469
 470  save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
 471  CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
 472
 473  cmos_minutes = CMOS_READ(RTC_MINUTES);
 474  if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
 475    BCD_TO_BIN(cmos_minutes);
 476
 477  /* since we're only adjusting minutes and seconds,
 478   * don't interfere with hour overflow. This avoids
 479   * messing with unknown time zones but requires your
 480   * RTC not to be off by more than 15 minutes
 481   */
 482  real_seconds = nowtime % 60;
 483  real_minutes = nowtime / 60;
 484  if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
 485    real_minutes += 30;         /* correct for half hour time zone */
 486  real_minutes %= 60;
 487
 488  if (abs(real_minutes - cmos_minutes) < 30)
 489    {
 490      if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
 491        {
 492          BIN_TO_BCD(real_seconds);
 493          BIN_TO_BCD(real_minutes);
 494        }
 495      CMOS_WRITE(real_seconds,RTC_SECONDS);
 496      CMOS_WRITE(real_minutes,RTC_MINUTES);
 497    }
 498  else
 499    retval = -1;
 500
 501  /* The following flags have to be released exactly in this order,
 502   * otherwise the DS12887 (popular MC146818A clone with integrated
 503   * battery and quartz) will not reset the oscillator and will not
 504   * update precisely 500 ms later. You won't find this mentioned in
 505   * the Dallas Semiconductor data sheets, but who believes data
 506   * sheets anyway ...                           -- Markus Kuhn
 507   */
 508  CMOS_WRITE(save_control, RTC_CONTROL);
 509  CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
 510
 511  return retval;
 512}
 513
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.