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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [m68k/] [kernel/] [time.c] - Blame information for rev 1275

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

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/arch/m68k/kernel/time.c
3
 *
4
 *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
5
 *
6
 * This file contains the m68k-specific time handling details.
7
 * Most of the stuff is located in the machine specific files.
8
 *
9
 * 1997-09-10   Updated NTP code according to technical memorandum Jan '96
10
 *              "A Kernel Model for Precision Timekeeping" by Dave Mills
11
 */
12
 
13
#include <linux/config.h> /* CONFIG_HEARTBEAT */
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/machdep.h>
22
#include <asm/io.h>
23
 
24
#include <linux/timex.h>
25
 
26
 
27
static inline int set_rtc_mmss(unsigned long nowtime)
28
{
29
  if (mach_set_clock_mmss)
30
    return mach_set_clock_mmss (nowtime);
31
  return -1;
32
}
33
 
34
static inline void do_profile (unsigned long pc)
35
{
36
        if (prof_buffer && current->pid) {
37
                extern int _stext;
38
                pc -= (unsigned long) &_stext;
39
                pc >>= prof_shift;
40
                if (pc < prof_len)
41
                        ++prof_buffer[pc];
42
                else
43
                /*
44
                 * Don't ignore out-of-bounds PC values silently,
45
                 * put them into the last histogram slot, so if
46
                 * present, they will show up as a sharp peak.
47
                 */
48
                        ++prof_buffer[prof_len-1];
49
        }
50
}
51
 
52
/*
53
 * timer_interrupt() needs to keep up the real-time clock,
54
 * as well as call the "do_timer()" routine every clocktick
55
 */
56
static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
57
{
58
        do_timer(regs);
59
 
60
        if (!user_mode(regs))
61
                do_profile(regs->pc);
62
 
63
#ifdef CONFIG_HEARTBEAT
64
        /* use power LED as a heartbeat instead -- much more useful
65
           for debugging -- based on the version for PReP by Cort */
66
        /* acts like an actual heart beat -- ie thump-thump-pause... */
67
        if (mach_heartbeat) {
68
            static unsigned cnt = 0, period = 0, dist = 0;
69
 
70
            if (cnt == 0 || cnt == dist)
71
                mach_heartbeat( 1 );
72
            else if (cnt == 7 || cnt == dist+7)
73
                mach_heartbeat( 0 );
74
 
75
            if (++cnt > period) {
76
                cnt = 0;
77
                /* The hyperbolic function below modifies the heartbeat period
78
                 * length in dependency of the current (5min) load. It goes
79
                 * through the points f(0)=126, f(1)=86, f(5)=51,
80
                 * f(inf)->30. */
81
                period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
82
                dist = period / 4;
83
            }
84
        }
85
#endif /* CONFIG_HEARTBEAT */
86
}
87
 
88
void time_init(void)
89
{
90
        unsigned int year, mon, day, hour, min, sec;
91
 
92
        extern void arch_gettod(int *year, int *mon, int *day, int *hour,
93
                                int *min, int *sec);
94
 
95
        arch_gettod (&year, &mon, &day, &hour, &min, &sec);
96
 
97
        if ((year += 1900) < 1970)
98
                year += 100;
99
        xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
100
        xtime.tv_usec = 0;
101
 
102
        mach_sched_init(timer_interrupt);
103
}
104
 
105
extern rwlock_t xtime_lock;
106
 
107
/*
108
 * This version of gettimeofday has near microsecond resolution.
109
 */
110
void do_gettimeofday(struct timeval *tv)
111
{
112
        extern unsigned long wall_jiffies;
113
        unsigned long flags;
114
        unsigned long usec, sec, lost;
115
 
116
        read_lock_irqsave(&xtime_lock, flags);
117
        usec = mach_gettimeoffset();
118
        lost = jiffies - wall_jiffies;
119
        if (lost)
120
                usec += lost * (1000000/HZ);
121
        sec = xtime.tv_sec;
122
        usec += xtime.tv_usec;
123
        read_unlock_irqrestore(&xtime_lock, flags);
124
 
125
        while (usec >= 1000000) {
126
                usec -= 1000000;
127
                sec++;
128
        }
129
 
130
        tv->tv_sec = sec;
131
        tv->tv_usec = usec;
132
}
133
 
134
void do_settimeofday(struct timeval *tv)
135
{
136
        write_lock_irq(&xtime_lock);
137
        /* This is revolting. We need to set the xtime.tv_usec
138
         * correctly. However, the value in this location is
139
         * is value at the last tick.
140
         * Discover what correction gettimeofday
141
         * would have done, and then undo it!
142
         */
143
        tv->tv_usec -= mach_gettimeoffset();
144
 
145
        while (tv->tv_usec < 0) {
146
                tv->tv_usec += 1000000;
147
                tv->tv_sec--;
148
        }
149
 
150
        xtime = *tv;
151
        time_adjust = 0;         /* stop active adjtime() */
152
        time_status |= STA_UNSYNC;
153
        time_maxerror = NTP_PHASE_LIMIT;
154
        time_esterror = NTP_PHASE_LIMIT;
155
        write_unlock_irq(&xtime_lock);
156
}

powered by: WebSVN 2.1.0

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