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

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