ia64/xen-unstable

view xen/arch/ia64/patch/linux-2.6.7/time.c @ 4169:3fa7a9355f99

bitkeeper revision 1.1236.31.4 (423770a7zebfa9oORBQCP7xh5DgOrg)

Oops, forgot a file.
author djm@kirby.fc.hp.com
date Tue Mar 15 23:32:55 2005 +0000 (2005-03-15)
parents 557e8cf002c3
children 52d3f3c5aed0
line source
1 --- ../../linux-2.6.7/arch/ia64/kernel/time.c 2004-06-15 23:19:01.000000000 -0600
2 +++ arch/ia64/time.c 2005-03-14 17:27:11.000000000 -0700
3 @@ -10,16 +10,22 @@
4 */
5 #include <linux/config.h>
7 +#ifndef XEN
8 #include <linux/cpu.h>
9 +#endif
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 +#ifndef XEN
14 #include <linux/profile.h>
15 +#endif
16 #include <linux/sched.h>
17 #include <linux/time.h>
18 #include <linux/interrupt.h>
19 #include <linux/efi.h>
20 +#ifndef XEN
21 #include <linux/profile.h>
22 +#endif
23 #include <linux/timex.h>
25 #include <asm/machvec.h>
26 @@ -29,6 +35,9 @@
27 #include <asm/sal.h>
28 #include <asm/sections.h>
29 #include <asm/system.h>
30 +#ifdef XEN
31 +#include <asm/ia64_int.h>
32 +#endif
34 extern unsigned long wall_jiffies;
36 @@ -45,6 +54,59 @@
38 #endif
40 +#ifdef XEN
41 +volatile unsigned long last_nsec_offset;
42 +extern rwlock_t xtime_lock;
43 +unsigned long cpu_khz; /* Detected as we calibrate the TSC */
44 +static s_time_t stime_irq; /* System time at last 'time update' */
45 +
46 +static inline u64 get_time_delta(void)
47 +{
48 + return ia64_get_itc();
49 +}
50 +
51 +s_time_t get_s_time(void)
52 +{
53 + s_time_t now;
54 + unsigned long flags;
55 +
56 + read_lock_irqsave(&xtime_lock, flags);
57 +
58 + now = stime_irq + get_time_delta();
59 +
60 + /* Ensure that the returned system time is monotonically increasing. */
61 + {
62 + static s_time_t prev_now = 0;
63 + if ( unlikely(now < prev_now) )
64 + now = prev_now;
65 + prev_now = now;
66 + }
67 +
68 + read_unlock_irqrestore(&xtime_lock, flags);
69 +
70 + return now;
71 +}
72 +
73 +int update_dom_time(struct exec_domain *ed)
74 +{
75 +// FIXME: implement this?
76 +// printf("update_dom_time: called, not implemented, skipping\n");
77 + return 0;
78 +}
79 +
80 +/* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
81 +void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base)
82 +{
83 +// FIXME: Should this be do_settimeofday (from linux)???
84 + printf("do_settime: called, not implemented, stopping\n");
85 + dummy();
86 +}
87 +#endif
88 +
89 +#if 0 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
90 +#endif /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
91 +
92 +#ifndef XEN
93 static void
94 itc_reset (void)
95 {
96 @@ -80,12 +142,15 @@
97 return (elapsed_cycles*local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT;
98 }
100 +#ifndef XEN
101 static struct time_interpolator itc_interpolator = {
102 .get_offset = itc_get_offset,
103 .update = itc_update,
104 .reset = itc_reset
105 };
106 +#endif
108 +#ifndef XEN
109 int
110 do_settimeofday (struct timespec *tv)
111 {
112 @@ -95,7 +160,9 @@
113 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
114 return -EINVAL;
116 +#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
117 write_seqlock_irq(&xtime_lock);
118 +#endif
119 {
120 /*
121 * This is revolting. We need to set "xtime" correctly. However, the value
122 @@ -117,12 +184,15 @@
123 time_esterror = NTP_PHASE_LIMIT;
124 time_interpolator_reset();
125 }
126 +#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
127 write_sequnlock_irq(&xtime_lock);
128 +#endif
129 clock_was_set();
130 return 0;
131 }
133 EXPORT_SYMBOL(do_settimeofday);
134 +#endif
136 void
137 do_gettimeofday (struct timeval *tv)
138 @@ -185,6 +255,7 @@
139 }
141 EXPORT_SYMBOL(do_gettimeofday);
142 +#endif
144 /*
145 * The profiling function is SMP safe. (nothing can mess
146 @@ -195,6 +266,9 @@
147 static inline void
148 ia64_do_profile (struct pt_regs * regs)
149 {
150 +#ifdef XEN
151 +}
152 +#else
153 unsigned long ip, slot;
154 extern cpumask_t prof_cpu_mask;
156 @@ -231,24 +305,89 @@
157 ip = prof_len-1;
158 atomic_inc((atomic_t *)&prof_buffer[ip]);
159 }
160 +#endif
161 +
162 +#ifdef XEN
163 +unsigned long domain0_ready = 0; // FIXME (see below)
164 +#define typecheck(a,b) 1
165 +/* FROM linux/include/linux/jiffies.h */
166 +/*
167 + * These inlines deal with timer wrapping correctly. You are
168 + * strongly encouraged to use them
169 + * 1. Because people otherwise forget
170 + * 2. Because if the timer wrap changes in future you won't have to
171 + * alter your driver code.
172 + *
173 + * time_after(a,b) returns true if the time a is after time b.
174 + *
175 + * Do this with "<0" and ">=0" to only test the sign of the result. A
176 + * good compiler would generate better code (and a really good compiler
177 + * wouldn't care). Gcc is currently neither.
178 + */
179 +#define time_after(a,b) \
180 + (typecheck(unsigned long, a) && \
181 + typecheck(unsigned long, b) && \
182 + ((long)(b) - (long)(a) < 0))
183 +#define time_before(a,b) time_after(b,a)
184 +
185 +#define time_after_eq(a,b) \
186 + (typecheck(unsigned long, a) && \
187 + typecheck(unsigned long, b) && \
188 + ((long)(a) - (long)(b) >= 0))
189 +#define time_before_eq(a,b) time_after_eq(b,a)
190 +#endif
192 static irqreturn_t
193 timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
194 {
195 unsigned long new_itm;
197 +#ifndef XEN
198 if (unlikely(cpu_is_offline(smp_processor_id()))) {
199 return IRQ_HANDLED;
200 }
201 +#endif
202 +#ifdef XEN
203 + if (current->domain == dom0) {
204 + // FIXME: there's gotta be a better way of doing this...
205 + // We have to ensure that domain0 is launched before we
206 + // call vcpu_timer_expired on it
207 + //domain0_ready = 1; // moved to xensetup.c
208 + }
209 + if (domain0_ready && vcpu_timer_expired(dom0->exec_domain[0])) {
210 + vcpu_pend_timer(dom0->exec_domain[0]);
211 + //vcpu_set_next_timer(dom0->exec_domain[0]);
212 + domain_wake(dom0->exec_domain[0]);
213 + }
214 + if (!is_idle_task(current->domain) && current->domain != dom0) {
215 + if (vcpu_timer_expired(current)) {
216 + vcpu_pend_timer(current);
217 + // ensure another timer interrupt happens even if domain doesn't
218 + vcpu_set_next_timer(current);
219 + domain_wake(current);
220 + }
221 + }
222 + raise_actimer_softirq();
223 +#endif
225 +#ifndef XEN
226 platform_timer_interrupt(irq, dev_id, regs);
227 +#endif
229 new_itm = local_cpu_data->itm_next;
231 if (!time_after(ia64_get_itc(), new_itm))
232 +#ifdef XEN
233 + return;
234 +#else
235 printk(KERN_ERR "Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
236 ia64_get_itc(), new_itm);
237 +#endif
239 +#ifdef XEN
240 +// printf("GOT TO HERE!!!!!!!!!!!\n");
241 + //while(1);
242 +#endif
243 ia64_do_profile(regs);
245 while (1) {
246 @@ -269,10 +408,16 @@
247 * another CPU. We need to avoid to SMP race by acquiring the
248 * xtime_lock.
249 */
250 +#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
251 write_seqlock(&xtime_lock);
252 +#endif
253 +#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
254 do_timer(regs);
255 +#endif
256 local_cpu_data->itm_next = new_itm;
257 +#ifdef TURN_ME_OFF_FOR_NOW_IA64_XEN
258 write_sequnlock(&xtime_lock);
259 +#endif
260 } else
261 local_cpu_data->itm_next = new_itm;
263 @@ -292,7 +437,12 @@
264 */
265 while (!time_after(new_itm, ia64_get_itc() + local_cpu_data->itm_delta/2))
266 new_itm += local_cpu_data->itm_delta;
267 +//#ifdef XEN
268 +// vcpu_set_next_timer(current);
269 +//#else
270 +//printf("***** timer_interrupt: Setting itm to %lx\n",new_itm);
271 ia64_set_itm(new_itm);
272 +//#endif
273 /* double check, in case we got hit by a (slow) PMI: */
274 } while (time_after_eq(ia64_get_itc(), new_itm));
275 return IRQ_HANDLED;
276 @@ -307,6 +457,7 @@
277 int cpu = smp_processor_id();
278 unsigned long shift = 0, delta;
280 +printf("ia64_cpu_local_tick: about to call ia64_set_itv\n");
281 /* arrange for the cycle counter to generate a timer interrupt: */
282 ia64_set_itv(IA64_TIMER_VECTOR);
284 @@ -320,6 +471,7 @@
285 shift = (2*(cpu - hi) + 1) * delta/hi/2;
286 }
287 local_cpu_data->itm_next = ia64_get_itc() + delta + shift;
288 +printf("***** ia64_cpu_local_tick: Setting itm to %lx\n",local_cpu_data->itm_next);
289 ia64_set_itm(local_cpu_data->itm_next);
290 }
292 @@ -335,6 +487,7 @@
293 * frequency and then a PAL call to determine the frequency ratio between the ITC
294 * and the base frequency.
295 */
296 +
297 status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM,
298 &platform_base_freq, &platform_base_drift);
299 if (status != 0) {
300 @@ -384,9 +537,11 @@
301 + itc_freq/2)/itc_freq;
303 if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
304 +#ifndef XEN
305 itc_interpolator.frequency = local_cpu_data->itc_freq;
306 itc_interpolator.drift = itc_drift;
307 register_time_interpolator(&itc_interpolator);
308 +#endif
309 }
311 /* Setup the CPU local timer tick */
312 @@ -395,7 +550,9 @@
314 static struct irqaction timer_irqaction = {
315 .handler = timer_interrupt,
316 +#ifndef XEN
317 .flags = SA_INTERRUPT,
318 +#endif
319 .name = "timer"
320 };
322 @@ -403,12 +560,16 @@
323 time_init (void)
324 {
325 register_percpu_irq(IA64_TIMER_VECTOR, &timer_irqaction);
326 +#ifndef XEN
327 efi_gettimeofday(&xtime);
328 +#endif
329 ia64_init_itm();
331 +#ifndef XEN
332 /*
333 * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the
334 * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC).
335 */
336 set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
337 +#endif
338 }