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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i960/] [kernel/] [time.c] - Blame information for rev 1623

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*
2
 *  linux/arch/i960/kernel/time.c
3
 *
4
 *  Copyright (C) 1999  Keith Adams     <kma@cse.ogi.edu>
5
 *                      Oregon Graduate Institute
6
 *
7
 *  Based on:
8
 *
9
 *  linux/arch/m68knommu/kernel/time.c
10
 *
11
 *  Copyright (C) 1998  D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
12
 *                      Kenneth Albanowski <kjahds@kjahds.com>,
13
 *                      The Silver Hammer Group, Ltd.
14
 *
15
 *  Copied/hacked from:
16
 *
17
 *  linux/arch/m68k/kernel/time.c
18
 *
19
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
20
 *
21
 * This file contains the i960-specific time handling details.
22
 */
23
 
24
#include <linux/config.h>
25
#include <linux/errno.h>
26
#include <linux/sched.h>
27
#include <linux/kernel.h>
28
#include <linux/param.h>
29
#include <linux/string.h>
30
#include <linux/mm.h>
31
 
32
#include <asm/machdep.h>
33
#include <asm/segment.h>
34
#include <asm/io.h>
35
 
36
#include <linux/timex.h>
37
 
38
 
39
/*
40
 * XXX: bloody hell. We need to have figured out our machine's MHZ, and
41
 * programmed its clock accordingly.
42
 */
43
static inline int set_rtc_mmss(unsigned long nowtime)
44
{
45
        return -1;
46
}
47
 
48
int do_reboot = 0;
49
 
50
/*
51
 * timer_interrupt() needs to keep up the real-time clock,
52
 * as well as call the "do_timer()" routine every clocktick
53
 */
54
void timer_interrupt(struct pt_regs * regs)
55
{
56
        /* last time the cmos clock got updated */
57
        static long last_rtc_update=0;
58
 
59
        do_timer(regs);
60
 
61
        /*
62
         * If we have an externally synchronized Linux clock, then update
63
         * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
64
         * called as close as possible to 500 ms before the new second starts.
65
         */
66
        if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
67
            xtime.tv_usec > 500000 - (tick >> 1) &&
68
            xtime.tv_usec < 500000 + (tick >> 1))
69
                if (set_rtc_mmss(xtime.tv_sec) == 0)
70
                        last_rtc_update = xtime.tv_sec;
71
                else
72
                        last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
73
 
74
}
75
 
76
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
77
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
78
 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
79
 *
80
 * [For the Julian calendar (which was used in Russia before 1917,
81
 * Britain & colonies before 1752, anywhere else before 1582,
82
 * and is still in use by some communities) leave out the
83
 * -year/100+year/400 terms, and add 10.]
84
 *
85
 * This algorithm was first published by Gauss (I think).
86
 *
87
 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
88
 * machines were long is 32-bit! (However, as time_t is signed, we
89
 * will already get problems at other places on 2038-01-19 03:14:08)
90
 */
91
static inline unsigned long mktime(unsigned int year, unsigned int mon,
92
        unsigned int day, unsigned int hour,
93
        unsigned int min, unsigned int sec)
94
{
95
        if (0 >= (int) (mon -= 2)) {     /* 1..12 -> 11,12,1..10 */
96
                mon += 12;      /* Puts Feb last since it has leap day */
97
                year -= 1;
98
        }
99
        return (((
100
            (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
101
              year*365 - 719499
102
            )*24 + hour /* now have hours */
103
           )*60 + min /* now have minutes */
104
          )*60 + sec; /* finally seconds */
105
}
106
 
107
void time_init(void)
108
{
109
        unsigned int year, mon, day, hour, min, sec;
110
 
111
        extern void arch_gettod(int *year, int *mon, int *day, int *hour,
112
                                int *min, int *sec);
113
 
114
        arch_gettod (&year, &mon, &day, &hour, &min, &sec);
115
 
116
        if ((year += 1900) < 1970)
117
                year += 100;
118
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
119
        xtime.tv_usec = 0;
120
 
121
#ifdef CONFIG_M68328
122
        (*((volatile unsigned short*)0xFFFFF610)) = /*0x1000;*/ 0xd7e4;
123
        (*((volatile unsigned short*)0xFFFFF60c)) = 0x33; /* Reset */
124
        (*((volatile unsigned short*)0xFFFFF60e)) = 0x2;  /* divider */
125
        (*((volatile unsigned long*)0xFFFFF304)) &= ~2;   /* Enable interrupt */
126
#endif
127
#ifdef CONFIG_M68332
128
        *(volatile unsigned short *)0xfffa22 = 0x0140;  /* ipl 6, vec 0x40 */
129
        *(volatile unsigned short *)0xfffa24 = 0x00a3;  /* 50 Hz */
130
#endif
131
}
132
 
133
/*
134
 * This version of gettimeofday has near microsecond resolution.
135
 */
136
void do_gettimeofday(struct timeval *tv)
137
{
138
        unsigned long flags;
139
 
140
        save_flags(flags);
141
        cli();
142
        *tv = xtime;
143
        restore_flags(flags);
144
}
145
 
146
void do_settimeofday(struct timeval *tv)
147
{
148
        cli();
149
        /* This is revolting. We need to set the xtime.tv_usec
150
         * correctly. However, the value in this location is
151
         * is value at the last tick.
152
         * Discover what correction gettimeofday
153
         * would have done, and then undo it!
154
         */
155
#if 0    
156
        tv->tv_usec -= mach_gettimeoffset();
157
#endif
158
 
159
        if (tv->tv_usec < 0) {
160
                tv->tv_usec += 1000000;
161
                tv->tv_sec--;
162
        }
163
 
164
        xtime = *tv;
165
        time_state = TIME_BAD;
166
        time_maxerror = MAXPHASE;
167
        time_esterror = MAXPHASE;
168
        sti();
169
}

powered by: WebSVN 2.1.0

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