OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i386/] [kernel/] [time.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*
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
 * 1996-05-03    Ingo Molnar
14
 *      fixed time warps in do_[slow|fast]_gettimeoffset()
15
 * 1997-09-10   Updated NTP code according to technical memorandum Jan '96
16
 *              "A Kernel Model for Precision Timekeeping" by Dave Mills
17
 */
18
#include <linux/errno.h>
19
#include <linux/sched.h>
20
#include <linux/kernel.h>
21
#include <linux/param.h>
22
#include <linux/string.h>
23
#include <linux/mm.h>
24
#include <linux/interrupt.h>
25
#include <linux/time.h>
26
#include <linux/delay.h>
27
 
28
#include <asm/segment.h>
29
#include <asm/io.h>
30
#include <asm/irq.h>
31
#include <asm/delay.h>
32
 
33
#include <linux/mc146818rtc.h>
34
#include <linux/timex.h>
35
#include <linux/config.h>
36
 
37
extern int setup_x86_irq(int, struct irqaction *);
38
 
39
#ifndef CONFIG_APM      /* cycle counter may be unreliable */
40
/* Cycle counter value at the previous timer interrupt.. */
41
static struct {
42
        unsigned long low;
43
        unsigned long high;
44
} init_timer_cc, last_timer_cc;
45
 
46
/*
47
 * This is more assembly than C, but it's also rather
48
 * timing-critical and we have to use assembler to get
49
 * reasonable 64-bit arithmetic
50
 */
51
static unsigned long do_fast_gettimeoffset(void)
52
{
53
        register unsigned long eax asm("ax");
54
        register unsigned long edx asm("dx");
55
        unsigned long tmp, quotient, low_timer, missing_time;
56
 
57
        /* Last jiffy when do_fast_gettimeoffset() was called.. */
58
        static unsigned long last_jiffies=0;
59
 
60
        /* Cached "clocks per usec" value.. */
61
        static unsigned long cached_quotient=0;
62
 
63
        /* The "clocks per usec" value is calculated once each jiffy */
64
        tmp = jiffies;
65
        quotient = cached_quotient;
66
        low_timer = last_timer_cc.low;
67
        missing_time = 0;
68
        if (last_jiffies != tmp) {
69
                last_jiffies = tmp;
70
                /*
71
                 * test for hanging bottom handler (this means xtime is not
72
                 * updated yet)
73
                 */
74
                if (test_bit(TIMER_BH, &bh_active) )
75
                {
76
                        missing_time = 1000020/HZ;
77
                }
78
 
79
                /* Get last timer tick in absolute kernel time */
80
                eax = low_timer;
81
                edx = last_timer_cc.high;
82
                __asm__("subl "SYMBOL_NAME_STR(init_timer_cc)",%0\n\t"
83
                        "sbbl "SYMBOL_NAME_STR(init_timer_cc)"+4,%1"
84
                        :"=a" (eax), "=d" (edx)
85
                        :"0" (eax), "1" (edx));
86
 
87
                /*
88
                 * Divide the 64-bit time with the 32-bit jiffy counter,
89
                 * getting the quotient in clocks.
90
                 *
91
                 * Giving quotient = "average internal clocks per usec"
92
                 */
93
                __asm__("divl %2"
94
                        :"=a" (eax), "=d" (edx)
95
                        :"r" (tmp),
96
                         "0" (eax), "1" (edx));
97
 
98
                edx = 1000020/HZ;
99
                tmp = eax;
100
                eax = 0;
101
 
102
                __asm__("divl %2"
103
                        :"=a" (eax), "=d" (edx)
104
                        :"r" (tmp),
105
                         "0" (eax), "1" (edx));
106
                cached_quotient = eax;
107
                quotient = eax;
108
        }
109
 
110
        /* Read the time counter */
111
        __asm__(".byte 0x0f,0x31"
112
                :"=a" (eax), "=d" (edx));
113
 
114
        /* .. relative to previous jiffy (32 bits is enough) */
115
        edx = 0;
116
        eax -= low_timer;
117
 
118
        /*
119
         * Time offset = (1000020/HZ * time_low) / quotient.
120
         */
121
 
122
        __asm__("mull %2"
123
                :"=a" (eax), "=d" (edx)
124
                :"r" (quotient),
125
                 "0" (eax), "1" (edx));
126
 
127
        /*
128
         * Due to rounding errors (and jiffies inconsistencies),
129
         * we need to check the result so that we'll get a timer
130
         * that is monotonic.
131
         */
132
        if (edx >= 1000020/HZ)
133
                edx = 1000020/HZ-1;
134
 
135
        eax = edx + missing_time;
136
        return eax;
137
}
138
#endif
139
 
140
/* This function must be called with interrupts disabled
141
 * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
142
 *
143
 * However, the pc-audio speaker driver changes the divisor so that
144
 * it gets interrupted rather more often - it loads 64 into the
145
 * counter rather than 11932! This has an adverse impact on
146
 * do_gettimeoffset() -- it stops working! What is also not
147
 * good is that the interval that our timer function gets called
148
 * is no longer 10.0002 ms, but 9.9767 ms. To get around this
149
 * would require using a different timing source. Maybe someone
150
 * could use the RTC - I know that this can interrupt at frequencies
151
 * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
152
 * it so that at startup, the timer code in sched.c would select
153
 * using either the RTC or the 8253 timer. The decision would be
154
 * based on whether there was any other device around that needed
155
 * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
156
 * and then do some jiggery to have a version of do_timer that
157
 * advanced the clock by 1/1024 s. Every time that reached over 1/100
158
 * of a second, then do all the old code. If the time was kept correct
159
 * then do_gettimeoffset could just return 0 - there is no low order
160
 * divider that can be accessed.
161
 *
162
 * Ideally, you would be able to use the RTC for the speaker driver,
163
 * but it appears that the speaker driver really needs interrupt more
164
 * often than every 120 us or so.
165
 *
166
 * Anyway, this needs more thought....          pjsg (1993-08-28)
167
 *
168
 * If you are really that interested, you should be reading
169
 * comp.protocols.time.ntp!
170
 */
171
 
172
#define TICK_SIZE tick
173
 
174
static unsigned long do_slow_gettimeoffset(void)
175
{
176
        int count;
177
        static int count_p = 0;
178
        unsigned long offset = 0;
179
        static unsigned long jiffies_p = 0;
180
 
181
        /*
182
         * cache volatile jiffies temporarily; we have IRQs turned off.
183
         */
184
        unsigned long jiffies_t;
185
 
186
        /* timer count may underflow right here */
187
        outb_p(0x00, 0x43);     /* latch the count ASAP */
188
        count = inb_p(0x40);    /* read the latched count */
189
        count |= inb(0x40) << 8;
190
 
191
        jiffies_t = jiffies;
192
 
193
        /*
194
         * avoiding timer inconsistencies (they are rare, but they happen)...
195
         * there are three kinds of problems that must be avoided here:
196
         *  1. the timer counter underflows
197
         *  2. hardware problem with the timer, not giving us continuous time,
198
         *     the counter does small "jumps" upwards on some Pentium systems,
199
         *     thus causes time warps
200
         *  3. we are after the timer interrupt, but the bottom half handler
201
         *     hasn't executed yet.
202
         */
203
        if( count > count_p ) {
204
                if( jiffies_t == jiffies_p ) {
205
                        if( count > LATCH-LATCH/100 )
206
                                offset = TICK_SIZE;
207
                        else
208
                                /*
209
                                 * argh, the timer is bugging we cant do nothing
210
                                 * but to give the previous clock value.
211
                                 */
212
                                count = count_p;
213
                } else {
214
                        if( test_bit(TIMER_BH, &bh_active) ) {
215
                                /*
216
                                 * we have detected a counter underflow.
217
                                 */
218
                                offset = TICK_SIZE;
219
                                count_p = count;
220
                        } else {
221
                                count_p = count;
222
                                jiffies_p = jiffies_t;
223
                        }
224
                }
225
        } else {
226
                count_p = count;
227
                jiffies_p = jiffies_t;
228
        }
229
 
230
 
231
        count = ((LATCH-1) - count) * TICK_SIZE;
232
        count = (count + LATCH/2) / LATCH;
233
 
234
        return offset + count;
235
}
236
 
237
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
238
 
239
/*
240
 * This version of gettimeofday has near microsecond resolution.
241
 */
242
void do_gettimeofday(struct timeval *tv)
243
{
244
        unsigned long flags;
245
 
246
        save_flags(flags);
247
        cli();
248
        *tv = xtime;
249
        tv->tv_usec += do_gettimeoffset();
250
        if (tv->tv_usec >= 1000000) {
251
                tv->tv_usec -= 1000000;
252
                tv->tv_sec++;
253
        }
254
        restore_flags(flags);
255
}
256
 
257
void do_settimeofday(struct timeval *tv)
258
{
259
        cli();
260
        /* This is revolting. We need to set the xtime.tv_usec
261
         * correctly. However, the value in this location is
262
         * is value at the last tick.
263
         * Discover what correction gettimeofday
264
         * would have done, and then undo it!
265
         */
266
        tv->tv_usec -= do_gettimeoffset();
267
 
268
        if (tv->tv_usec < 0) {
269
                tv->tv_usec += 1000000;
270
                tv->tv_sec--;
271
        }
272
 
273
        xtime = *tv;
274
        time_adjust = 0;         /* stop active adjtime() */
275
        time_status |= STA_UNSYNC;
276
        time_state = TIME_ERROR;        /* p. 24, (a) */
277
        time_maxerror = NTP_PHASE_LIMIT;
278
        time_esterror = NTP_PHASE_LIMIT;
279
        sti();
280
}
281
 
282
 
283
/*
284
 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
285
 * called 500 ms after the second nowtime has started, because when
286
 * nowtime is written into the registers of the CMOS clock, it will
287
 * jump to the next second precisely 500 ms later. Check the Motorola
288
 * MC146818A or Dallas DS12887 data sheet for details.
289
 *
290
 * BUG: This routine does not handle hour overflow properly; it just
291
 *      sets the minutes. Usually you'll only notice that after reboot!
292
 */
293
static int set_rtc_mmss(unsigned long nowtime)
294
{
295
        int retval = 0;
296
        int real_seconds, real_minutes, cmos_minutes;
297
        unsigned char save_control, save_freq_select;
298
 
299
        save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
300
        CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
301
 
302
        save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
303
        CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
304
 
305
        cmos_minutes = CMOS_READ(RTC_MINUTES);
306
        if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
307
                BCD_TO_BIN(cmos_minutes);
308
 
309
        /*
310
         * since we're only adjusting minutes and seconds,
311
         * don't interfere with hour overflow. This avoids
312
         * messing with unknown time zones but requires your
313
         * RTC not to be off by more than 15 minutes
314
         */
315
        real_seconds = nowtime % 60;
316
        real_minutes = nowtime / 60;
317
        if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
318
                real_minutes += 30;             /* correct for half hour time zone */
319
        real_minutes %= 60;
320
 
321
        if (abs(real_minutes - cmos_minutes) < 30) {
322
                if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
323
                        BIN_TO_BCD(real_seconds);
324
                        BIN_TO_BCD(real_minutes);
325
                }
326
                CMOS_WRITE(real_seconds,RTC_SECONDS);
327
                CMOS_WRITE(real_minutes,RTC_MINUTES);
328
        } else {
329
                printk(KERN_WARNING
330
                       "set_rtc_mmss: can't update from %d to %d\n",
331
                       cmos_minutes, real_minutes);
332
                retval = -1;
333
        }
334
 
335
        /* The following flags have to be released exactly in this order,
336
         * otherwise the DS12887 (popular MC146818A clone with integrated
337
         * battery and quartz) will not reset the oscillator and will not
338
         * update precisely 500 ms later. You won't find this mentioned in
339
         * the Dallas Semiconductor data sheets, but who believes data
340
         * sheets anyway ...                           -- Markus Kuhn
341
         */
342
        CMOS_WRITE(save_control, RTC_CONTROL);
343
        CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
344
 
345
        return retval;
346
}
347
 
348
/* last time the cmos clock got updated */
349
static long last_rtc_update = 0;
350
 
351
/*
352
 * timer_interrupt() needs to keep up the real-time clock,
353
 * as well as call the "do_timer()" routine every clocktick
354
 */
355
static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
356
{
357
        do_timer(regs);
358
 
359
        /*
360
         * If we have an externally synchronized Linux clock, then update
361
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
362
         * called as close as possible to 500 ms before the new second starts.
363
         */
364
        if ((time_status & STA_UNSYNC) == 0 &&
365
            xtime.tv_sec > last_rtc_update + 660 &&
366
            xtime.tv_usec > 500000 - (tick >> 1) &&
367
            xtime.tv_usec < 500000 + (tick >> 1))
368
          if (set_rtc_mmss(xtime.tv_sec) == 0)
369
            last_rtc_update = xtime.tv_sec;
370
          else
371
            last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
372
        /* As we return to user mode fire off the other CPU schedulers.. this is
373
           basically because we don't yet share IRQ's around. This message is
374
           rigged to be safe on the 386 - basically it's a hack, so don't look
375
           closely for now.. */
376
        /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
377
 
378
}
379
 
380
#ifndef CONFIG_APM      /* cycle counter may be unreliable */
381
/*
382
 * This is the same as the above, except we _also_ save the current
383
 * cycle counter value at the time of the timer interrupt, so that
384
 * we later on can estimate the time of day more exactly.
385
 */
386
static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
387
{
388
        /* read Pentium cycle counter */
389
        __asm__(".byte 0x0f,0x31"
390
                :"=a" (last_timer_cc.low),
391
                 "=d" (last_timer_cc.high));
392
        timer_interrupt(irq, NULL, regs);
393
}
394
#endif
395
 
396
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
397
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
398
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
399
 *
400
 * [For the Julian calendar (which was used in Russia before 1917,
401
 * Britain & colonies before 1752, anywhere else before 1582,
402
 * and is still in use by some communities) leave out the
403
 * -year/100+year/400 terms, and add 10.]
404
 *
405
 * This algorithm was first published by Gauss (I think).
406
 *
407
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
408
 * machines were long is 32-bit! (However, as time_t is signed, we
409
 * will already get problems at other places on 2038-01-19 03:14:08)
410
 */
411
static inline unsigned long mktime(unsigned int year, unsigned int mon,
412
        unsigned int day, unsigned int hour,
413
        unsigned int min, unsigned int sec)
414
{
415
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
416
                mon += 12;      /* Puts Feb last since it has leap day */
417
                year -= 1;
418
        }
419
        return (((
420
            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
421
              year*365 - 719499
422
            )*24 + hour /* now have hours */
423
           )*60 + min /* now have minutes */
424
          )*60 + sec; /* finally seconds */
425
}
426
 
427
/* not static: needed by APM */
428
unsigned long get_cmos_time(void)
429
{
430
        unsigned int year, mon, day, hour, min, sec;
431
        int i;
432
 
433
        /* The Linux interpretation of the CMOS clock register contents:
434
         * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
435
         * RTC registers show the second which has precisely just started.
436
         * Let's hope other operating systems interpret the RTC the same way.
437
         */
438
        /* read RTC exactly on falling edge of update flag */
439
        for (i = 0 ; i < 1000000 ; i++)  /* may take up to 1 second... */
440
                if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
441
                        break;
442
        for (i = 0 ; i < 1000000 ; i++)  /* must try at least 2.228 ms */
443
                if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
444
                        break;
445
        do { /* Isn't this overkill ? UIP above should guarantee consistency */
446
                sec = CMOS_READ(RTC_SECONDS);
447
                min = CMOS_READ(RTC_MINUTES);
448
                hour = CMOS_READ(RTC_HOURS);
449
                day = CMOS_READ(RTC_DAY_OF_MONTH);
450
                mon = CMOS_READ(RTC_MONTH);
451
                year = CMOS_READ(RTC_YEAR);
452
        } while (sec != CMOS_READ(RTC_SECONDS));
453
        if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
454
          {
455
            BCD_TO_BIN(sec);
456
            BCD_TO_BIN(min);
457
            BCD_TO_BIN(hour);
458
            BCD_TO_BIN(day);
459
            BCD_TO_BIN(mon);
460
            BCD_TO_BIN(year);
461
          }
462
        if ((year += 1900) < 1970)
463
                year += 100;
464
        return mktime(year, mon, day, hour, min, sec);
465
}
466
 
467
static struct irqaction irq0  = { timer_interrupt, 0, 0, "timer", NULL, NULL};
468
 
469
void time_init(void)
470
{
471
        xtime.tv_sec = get_cmos_time();
472
        xtime.tv_usec = 0;
473
 
474
        /* If we have the CPU hardware time counters, use them */
475
#ifndef CONFIG_APM
476
                                /* Don't use them if a suspend/resume could
477
                                   corrupt the timer value.  This problem
478
                                   needs more debugging. */
479
        if (x86_capability & 16)
480
                if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) {
481
                        do_gettimeoffset = do_fast_gettimeoffset;
482
 
483
                        if( strcmp( x86_vendor_id, "AuthenticAMD" ) == 0 ) {
484
                                if( x86 == 5 ) {
485
                                        if( x86_model == 0 ) {
486
                                                /* turn on cycle counters during power down */
487
                                                __asm__ __volatile__ (" movl $0x83, %%ecx \n \
488
                                                                        .byte 0x0f,0x32 \n \
489
                                                                        orl $1,%%eax \n \
490
                                                                        .byte 0x0f,0x30 \n "
491
                                                                        : : : "ax", "cx", "dx" );
492
                                                udelay(500);
493
                                        }
494
                                }
495
                        }
496
 
497
                        /* read Pentium cycle counter */
498
                        __asm__(".byte 0x0f,0x31"
499
                                :"=a" (init_timer_cc.low),
500
                                "=d" (init_timer_cc.high));
501
                        irq0.handler = pentium_timer_interrupt;
502
                }
503
#endif
504
        setup_x86_irq(0, &irq0);
505
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.