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

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [generic/] [time.c] - Blame information for rev 4

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

Line No. Rev Author Line
1 2 drasko
/*
2
 * Time.
3
 *
4
 * Copyright (C) 2007 Bahadir Balban
5
 *
6
 */
7
#include <l4/types.h>
8
#include <l4/lib/mutex.h>
9
#include <l4/lib/printk.h>
10
#include <l4/generic/irq.h>
11
#include <l4/generic/scheduler.h>
12
#include <l4/generic/time.h>
13
#include <l4/generic/preempt.h>
14
#include <l4/generic/space.h>
15
#include INC_ARCH(exception.h)
16
#include <l4/api/syscall.h>
17
#include <l4/api/errno.h>
18
#include INC_GLUE(ipi.h)        /*FIXME: Remove this */
19
 
20
/* TODO:
21
 * 1) Add RTC support.
22
 * 2) Need to calculate time since EPOCH,
23
 * 3) Jiffies must be initialised to a reasonable value.
24
 */
25
 
26
volatile u32 jiffies = 0;
27
 
28
static inline void increase_jiffies(void)
29
{
30
        jiffies++;
31
}
32
 
33
 
34
/* Internal representation of time since epoch */
35
struct time_info {
36
        int reader;
37
        u32 thz;        /* Ticks in this hertz so far */
38
        u64 sec;        /* Seconds so far */
39
};
40
 
41
static struct time_info systime = { 0 };
42
 
43
/*
44
 * A very basic (probably erroneous)
45
 * rule-of-thumb time calculation.
46
 */
47
void update_system_time(void)
48
{
49
        /* Did we interrupt a reader? Tell it to retry */
50
        if (systime.reader)
51
                systime.reader = 0;
52
 
53
        /* Increase just like jiffies, but reset every second */
54
        systime.thz++;
55
 
56
        /*
57
         * On every 1 second of timer ticks, increase seconds
58
         *
59
         * TODO: Investigate: how do we make sure timer_irq is
60
         * called SCHED_TICKS times per second?
61
         */
62
        if (systime.thz == CONFIG_SCHED_TICKS) {
63
                systime.thz = 0;
64
                systime.sec++;
65
        }
66
}
67
 
68
/* Read system time */
69
int sys_time(struct timeval *tv, int set)
70
{
71
        int retries = 20;
72
        int err;
73
 
74
        if ((err = check_access((unsigned long)tv, sizeof(*tv),
75
                                MAP_USR_RW, 1)) < 0)
76
                return err;
77
 
78
        /* Get time */
79
        if (!set) {
80
                while(retries > 0) {
81
                        systime.reader = 1;
82
                        tv->tv_sec = systime.sec;
83
                        tv->tv_usec = 1000000 * systime.thz / CONFIG_SCHED_TICKS;
84
 
85
                        retries--;
86
                        if (systime.reader)
87
                                break;
88
                }
89
 
90
                /*
91
                 * No need to reset reader since it will be reset
92
                 * on next timer. If no retries return busy.
93
                 */
94
                if (!retries)
95
                        return -EBUSY;
96
                else
97
                        return 0;
98
 
99
        /* Set */
100
        } else {
101
                /*
102
                 * Setting the time not supported yet.
103
                 */
104
                return -ENOSYS;
105
        }
106
}
107
 
108
void update_process_times(void)
109
{
110
        struct ktcb *cur = current;
111
 
112
        if (cur->ticks_left == 0) {
113
                /*
114
                 * Nested irqs and irqs during non-preemptive
115
                 * times could try to deduct ticks below zero.
116
                 * We ignore such states and return.
117
                 */
118
                if (in_nested_irq_context() || !preemptive())
119
                        return;
120
                else /* Otherwise its a bug. */
121
                        BUG();
122
        }
123
 
124
        /*
125
         * These are TASK_RUNNABLE times, i.e. exludes sleeps
126
         * In the future we may use timestamps for accuracy
127
         */
128
        if (in_kernel())
129
                cur->kernel_time++;
130
        else
131
                cur->user_time++;
132
 
133
        cur->ticks_left--;
134
        cur->sched_granule--;
135
 
136
        /* Task has expired its timeslice */
137
        if (!cur->ticks_left)
138
                need_resched = 1;
139
 
140
        /* Task has expired its schedule granularity */
141
        if (!cur->sched_granule)
142
                need_resched = 1;
143
}
144
 
145
int do_timer_irq(void)
146
{
147
        increase_jiffies();
148
        update_process_times();
149
        update_system_time();
150
 
151
#if defined (CONFIG_SMP)
152
        smp_send_ipi(cpu_mask_others(), IPI_TIMER_EVENT);
153
#endif
154
 
155
        return IRQ_HANDLED;
156
}
157
 
158
/* Secondary cpus call this */
159
int secondary_timer_irq(void)
160
{
161
        update_process_times();
162
        return IRQ_HANDLED;
163
}
164
 

powered by: WebSVN 2.1.0

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