root/arch/i386/kernel/time.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_fast_gettimeoffset
  2. do_slow_gettimeoffset
  3. do_gettimeofday
  4. do_settimeofday
  5. set_rtc_mmss
  6. timer_interrupt
  7. pentium_timer_interrupt
  8. mktime
  9. get_cmos_time
  10. time_init

   1 /*
   2  *  linux/arch/i386/kernel/time.c
   3  *
   4  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
   5  *
   6  * This file contains the PC-specific time handling details:
   7  * reading the RTC at bootup, etc..
   8  * 1994-07-02    Alan Modra
   9  *      fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
  10  * 1995-03-26    Markus Kuhn
  11  *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
  12  *      precision CMOS clock update
  13  */
  14 #include <linux/errno.h>
  15 #include <linux/sched.h>
  16 #include <linux/kernel.h>
  17 #include <linux/param.h>
  18 #include <linux/string.h>
  19 #include <linux/mm.h>
  20 #include <linux/interrupt.h>
  21 
  22 #include <asm/segment.h>
  23 #include <asm/io.h>
  24 #include <asm/irq.h>
  25 
  26 #include <linux/mc146818rtc.h>
  27 #include <linux/timex.h>
  28 #include <linux/config.h>
  29 
  30 extern int setup_x86_irq(int, struct irqaction *);
  31 
  32 /* Cycle counter value at the previous timer interrupt.. */
  33 static unsigned long long last_timer_cc = 0;
  34 static unsigned long long init_timer_cc = 0;
  35 
  36 static unsigned long do_fast_gettimeoffset(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  37 {
  38         unsigned long time_low, time_high;
  39         unsigned long quotient, remainder;
  40 
  41         /* Get last timer tick in absolute kernel time */
  42         __asm__("subl %2,%0\n\t"
  43                 "sbbl %3,%1"
  44                 :"=r" (time_low), "=r" (time_high)
  45                 :"m" (*(0+(long *)&init_timer_cc)),
  46                  "m" (*(1+(long *)&init_timer_cc)),
  47                  "0" (*(0+(long *)&last_timer_cc)),
  48                  "1" (*(1+(long *)&last_timer_cc)));
  49         /*
  50          * Divide the 64-bit time with the 32-bit jiffy counter,
  51          * getting the quotient in clocks.
  52          *
  53          * Giving quotient = "average internal clocks per jiffy"
  54          */
  55         __asm__("divl %2"
  56                 :"=a" (quotient), "=d" (remainder)
  57                 :"r" (jiffies),
  58                  "0" (time_low), "1" (time_high));
  59 
  60         /* Read the time counter */
  61         __asm__(".byte 0x0f,0x31"
  62                 :"=a" (time_low), "=d" (time_high));
  63 
  64         /* .. relative to previous jiffy (32 bits is enough) */
  65         time_low -= (unsigned long) last_timer_cc;
  66 
  67         /*
  68          * Time offset = (1000000/HZ * remainder) / quotient.
  69          */
  70         __asm__("mull %1\n\t"
  71                 "divl %2"
  72                 :"=a" (quotient), "=d" (remainder)
  73                 :"r" (quotient),
  74                  "0" (time_low), "1" (1000000/HZ));
  75 
  76         /*
  77          * Due to rounding errors (and jiffies inconsistencies),
  78          * we need to check the result so that we'll get a timer
  79          * that is monotonous.
  80          */
  81         if (quotient >= 1000000/HZ)
  82                 quotient = 1000000/HZ-1;
  83         return quotient;
  84 }
  85 
  86 /* This function must be called with interrupts disabled 
  87  * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
  88  * 
  89  * However, the pc-audio speaker driver changes the divisor so that
  90  * it gets interrupted rather more often - it loads 64 into the
  91  * counter rather than 11932! This has an adverse impact on
  92  * do_gettimeoffset() -- it stops working! What is also not
  93  * good is that the interval that our timer function gets called
  94  * is no longer 10.0002 ms, but 9.9767 ms. To get around this
  95  * would require using a different timing source. Maybe someone
  96  * could use the RTC - I know that this can interrupt at frequencies
  97  * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
  98  * it so that at startup, the timer code in sched.c would select
  99  * using either the RTC or the 8253 timer. The decision would be
 100  * based on whether there was any other device around that needed
 101  * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
 102  * and then do some jiggery to have a version of do_timer that 
 103  * advanced the clock by 1/1024 s. Every time that reached over 1/100
 104  * of a second, then do all the old code. If the time was kept correct
 105  * then do_gettimeoffset could just return 0 - there is no low order
 106  * divider that can be accessed.
 107  *
 108  * Ideally, you would be able to use the RTC for the speaker driver,
 109  * but it appears that the speaker driver really needs interrupt more
 110  * often than every 120 us or so.
 111  *
 112  * Anyway, this needs more thought....          pjsg (1993-08-28)
 113  * 
 114  * If you are really that interested, you should be reading
 115  * comp.protocols.time.ntp!
 116  */
 117 
 118 #define TICK_SIZE tick
 119 
 120 static unsigned long do_slow_gettimeoffset(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122         int count;
 123         unsigned long offset = 0;
 124 
 125         /* timer count may underflow right here */
 126         outb_p(0x00, 0x43);     /* latch the count ASAP */
 127         count = inb_p(0x40);    /* read the latched count */
 128         count |= inb(0x40) << 8;
 129         /* we know probability of underflow is always MUCH less than 1% */
 130         if (count > (LATCH - LATCH/100)) {
 131                 /* check for pending timer interrupt */
 132                 outb_p(0x0a, 0x20);
 133                 if (inb(0x20) & 1)
 134                         offset = TICK_SIZE;
 135         }
 136         count = ((LATCH-1) - count) * TICK_SIZE;
 137         count = (count + LATCH/2) / LATCH;
 138         return offset + count;
 139 }
 140 
 141 static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
 142 
 143 /*
 144  * This version of gettimeofday has near microsecond resolution.
 145  */
 146 void do_gettimeofday(struct timeval *tv)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148         unsigned long flags;
 149 
 150         save_flags(flags);
 151         cli();
 152         *tv = xtime;
 153         tv->tv_usec += do_gettimeoffset();
 154         if (tv->tv_usec >= 1000000) {
 155                 tv->tv_usec -= 1000000;
 156                 tv->tv_sec++;
 157         }
 158         restore_flags(flags);
 159 }
 160 
 161 void do_settimeofday(struct timeval *tv)
     /* [previous][next][first][last][top][bottom][index][help] */
 162 {
 163         cli();
 164         /* This is revolting. We need to set the xtime.tv_usec
 165          * correctly. However, the value in this location is
 166          * is value at the last tick.
 167          * Discover what correction gettimeofday
 168          * would have done, and then undo it!
 169          */
 170         tv->tv_usec -= do_gettimeoffset();
 171 
 172         if (tv->tv_usec < 0) {
 173                 tv->tv_usec += 1000000;
 174                 tv->tv_sec--;
 175         }
 176 
 177         xtime = *tv;
 178         time_state = TIME_BAD;
 179         time_maxerror = 0x70000000;
 180         time_esterror = 0x70000000;
 181         sti();
 182 }
 183 
 184 
 185 /*
 186  * In order to set the CMOS clock precisely, set_rtc_mmss has to be
 187  * called 500 ms after the second nowtime has started, because when
 188  * nowtime is written into the registers of the CMOS clock, it will
 189  * jump to the next second precisely 500 ms later. Check the Motorola
 190  * MC146818A or Dallas DS12887 data sheet for details.
 191  */
 192 static int set_rtc_mmss(unsigned long nowtime)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194         int retval = 0;
 195         int real_seconds, real_minutes, cmos_minutes;
 196         unsigned char save_control, save_freq_select;
 197 
 198         save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
 199         CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
 200 
 201         save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
 202         CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
 203 
 204         cmos_minutes = CMOS_READ(RTC_MINUTES);
 205         if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
 206                 BCD_TO_BIN(cmos_minutes);
 207 
 208         /*
 209          * since we're only adjusting minutes and seconds,
 210          * don't interfere with hour overflow. This avoids
 211          * messing with unknown time zones but requires your
 212          * RTC not to be off by more than 15 minutes
 213          */
 214         real_seconds = nowtime % 60;
 215         real_minutes = nowtime / 60;
 216         if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
 217                 real_minutes += 30;             /* correct for half hour time zone */
 218         real_minutes %= 60;
 219 
 220         if (abs(real_minutes - cmos_minutes) < 30) {
 221                 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
 222                         BIN_TO_BCD(real_seconds);
 223                         BIN_TO_BCD(real_minutes);
 224                 }
 225                 CMOS_WRITE(real_seconds,RTC_SECONDS);
 226                 CMOS_WRITE(real_minutes,RTC_MINUTES);
 227         } else
 228                 retval = -1;
 229 
 230         /* The following flags have to be released exactly in this order,
 231          * otherwise the DS12887 (popular MC146818A clone with integrated
 232          * battery and quartz) will not reset the oscillator and will not
 233          * update precisely 500 ms later. You won't find this mentioned in
 234          * the Dallas Semiconductor data sheets, but who believes data
 235          * sheets anyway ...                           -- Markus Kuhn
 236          */
 237         CMOS_WRITE(save_control, RTC_CONTROL);
 238         CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
 239 
 240         return retval;
 241 }
 242 
 243 /* last time the cmos clock got updated */
 244 static long last_rtc_update = 0;
 245 
 246 /*
 247  * timer_interrupt() needs to keep up the real-time clock,
 248  * as well as call the "do_timer()" routine every clocktick
 249  */
 250 static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252         do_timer(regs);
 253 
 254         /*
 255          * If we have an externally synchronized Linux clock, then update
 256          * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
 257          * called as close as possible to 500 ms before the new second starts.
 258          */
 259         if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
 260             xtime.tv_usec > 500000 - (tick >> 1) &&
 261             xtime.tv_usec < 500000 + (tick >> 1))
 262           if (set_rtc_mmss(xtime.tv_sec) == 0)
 263             last_rtc_update = xtime.tv_sec;
 264           else
 265             last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 266         /* As we return to user mode fire off the other CPU schedulers.. this is 
 267            basically because we don't yet share IRQ's around. This message is
 268            rigged to be safe on the 386 - basically its a hack, so don't look
 269            closely for now.. */
 270         /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
 271             
 272 }
 273 
 274 /*
 275  * This is the same as the above, except we _also_ save the current
 276  * cycle counter value at the time of the timer interrupt, so that
 277  * we later on can estimate the time of day more exactly.
 278  */
 279 static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281         /* read Pentium cycle counter */
 282         __asm__(".byte 0x0f,0x31"
 283                 :"=a" (((unsigned long *) &last_timer_cc)[0]),
 284                  "=d" (((unsigned long *) &last_timer_cc)[1]));
 285         timer_interrupt(irq, NULL, regs);
 286 }
 287 
 288 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
 289  * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
 290  * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
 291  *
 292  * [For the Julian calendar (which was used in Russia before 1917,
 293  * Britain & colonies before 1752, anywhere else before 1582,
 294  * and is still in use by some communities) leave out the
 295  * -year/100+year/400 terms, and add 10.]
 296  *
 297  * This algorithm was first published by Gauss (I think).
 298  *
 299  * WARNING: this function will overflow on 2106-02-07 06:28:16 on
 300  * machines were long is 32-bit! (However, as time_t is signed, we
 301  * will already get problems at other places on 2038-01-19 03:14:08)
 302  */
 303 static inline unsigned long mktime(unsigned int year, unsigned int mon,
     /* [previous][next][first][last][top][bottom][index][help] */
 304         unsigned int day, unsigned int hour,
 305         unsigned int min, unsigned int sec)
 306 {
 307         if (0 >= (int) (mon -= 2)) {    /* 1..12 -> 11,12,1..10 */
 308                 mon += 12;      /* Puts Feb last since it has leap day */
 309                 year -= 1;
 310         }
 311         return (((
 312             (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
 313               year*365 - 719499
 314             )*24 + hour /* now have hours */
 315            )*60 + min /* now have minutes */
 316           )*60 + sec; /* finally seconds */
 317 }
 318 
 319 unsigned long get_cmos_time(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 320 {
 321         unsigned int year, mon, day, hour, min, sec;
 322         int i;
 323 
 324         /* The Linux interpretation of the CMOS clock register contents:
 325          * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
 326          * RTC registers show the second which has precisely just started.
 327          * Let's hope other operating systems interpret the RTC the same way.
 328          */
 329         /* read RTC exactly on falling edge of update flag */
 330         for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
 331                 if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
 332                         break;
 333         for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
 334                 if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
 335                         break;
 336         do { /* Isn't this overkill ? UIP above should guarantee consistency */
 337                 sec = CMOS_READ(RTC_SECONDS);
 338                 min = CMOS_READ(RTC_MINUTES);
 339                 hour = CMOS_READ(RTC_HOURS);
 340                 day = CMOS_READ(RTC_DAY_OF_MONTH);
 341                 mon = CMOS_READ(RTC_MONTH);
 342                 year = CMOS_READ(RTC_YEAR);
 343         } while (sec != CMOS_READ(RTC_SECONDS));
 344         if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
 345           {
 346             BCD_TO_BIN(sec);
 347             BCD_TO_BIN(min);
 348             BCD_TO_BIN(hour);
 349             BCD_TO_BIN(day);
 350             BCD_TO_BIN(mon);
 351             BCD_TO_BIN(year);
 352           }
 353         if ((year += 1900) < 1970)
 354                 year += 100;
 355         return mktime(year, mon, day, hour, min, sec);
 356 }
 357 
 358 static struct irqaction irq0  = { timer_interrupt, 0, 0, "timer", NULL, NULL};
 359 
 360 void time_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 361 {
 362         xtime.tv_sec = get_cmos_time();
 363         xtime.tv_usec = 0;
 364 
 365         /* If we have the CPU hardware time counters, use them */
 366 #ifndef CONFIG_APM
 367                                 /* Don't use them if a suspend/resume could
 368                                    corrupt the timer value.  This problem
 369                                    needs more debugging. */
 370         if (x86_capability & 16) {
 371                 do_gettimeoffset = do_fast_gettimeoffset;
 372                 /* read Pentium cycle counter */
 373                 __asm__(".byte 0x0f,0x31"
 374                         :"=a" (((unsigned long *) &init_timer_cc)[0]),
 375                          "=d" (((unsigned long *) &init_timer_cc)[1]));
 376                 irq0.handler = pentium_timer_interrupt;
 377         }
 378 #endif
 379         setup_x86_irq(0, &irq0);
 380 }

/* [previous][next][first][last][top][bottom][index][help] */