ia64/xen-unstable

view xenolinux-2.4.22-sparse/arch/xeno/kernel/time.c @ 935:87d895822ab8

bitkeeper revision 1.595 (3fb2342et94IEebbXW4EukwRN6mstQ)

time.c:
Fix uptime for xenolinux.
author kaf24@scramble.cl.cam.ac.uk
date Wed Nov 12 13:22:54 2003 +0000 (2003-11-12)
parents cb5916bb9685
children
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*-
2 ****************************************************************************
3 * (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge
4 * (C) 2002-2003 - Keir Fraser - University of Cambridge
5 ****************************************************************************
6 *
7 * File: arch/xeno/kernel/time.c
8 * Author: Rolf Neugebauer and Keir Fraser
9 *
10 * Description: Interface with Xen to get correct notion of time
11 */
13 /*
14 * linux/arch/i386/kernel/time.c
15 *
16 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
17 *
18 * This file contains the PC-specific time handling details:
19 * reading the RTC at bootup, etc..
20 * 1994-07-02 Alan Modra
21 * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
22 * 1995-03-26 Markus Kuhn
23 * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
24 * precision CMOS clock update
25 * 1996-05-03 Ingo Molnar
26 * fixed time warps in do_[slow|fast]_gettimeoffset()
27 * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
28 * "A Kernel Model for Precision Timekeeping" by Dave Mills
29 * 1998-09-05 (Various)
30 * More robust do_fast_gettimeoffset() algorithm implemented
31 * (works with APM, Cyrix 6x86MX and Centaur C6),
32 * monotonic gettimeofday() with fast_get_timeoffset(),
33 * drift-proof precision TSC calibration on boot
34 * (C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
35 * Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
36 * ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
37 * 1998-12-16 Andrea Arcangeli
38 * Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
39 * because was not accounting lost_ticks.
40 * 1998-12-24 Copyright (C) 1998 Andrea Arcangeli
41 * Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
42 * serialize accesses to xtime/lost_ticks).
43 */
45 #include <asm/smp.h>
46 #include <asm/irq.h>
47 #include <asm/msr.h>
48 #include <asm/delay.h>
49 #include <asm/mpspec.h>
50 #include <asm/uaccess.h>
51 #include <asm/processor.h>
53 #include <asm/div64.h>
54 #include <asm/hypervisor.h>
55 #include <asm/hypervisor-ifs/dom0_ops.h>
57 #include <linux/mc146818rtc.h>
58 #include <linux/kernel.h>
59 #include <linux/interrupt.h>
60 #include <linux/time.h>
61 #include <linux/init.h>
62 #include <linux/smp.h>
63 #include <linux/irq.h>
64 #include <linux/sysctl.h>
66 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
67 extern rwlock_t xtime_lock;
68 extern unsigned long wall_jiffies;
70 unsigned long cpu_khz; /* get this from Xen, used elsewhere */
72 static unsigned int rdtsc_bitshift;
73 static u32 st_scale_f; /* convert ticks -> usecs */
74 static u32 st_scale_i; /* convert ticks -> usecs */
76 /* These are peridically updated in shared_info, and then copied here. */
77 static u32 shadow_tsc_stamp;
78 static s64 shadow_system_time;
79 static u32 shadow_time_version;
80 static struct timeval shadow_tv;
82 /*
83 * We use this to ensure that gettimeofday() is monotonically increasing. We
84 * only break this guarantee if the wall clock jumps backwards "a long way".
85 */
86 static struct timeval last_seen_tv = {0,0};
88 #ifdef CONFIG_XENO_PRIV
89 /* Periodically propagate synchronised time base to the RTC and to Xen. */
90 static long last_update_to_rtc, last_update_to_xen;
91 #endif
93 /* Periodically take synchronised time base from Xen, if we need it. */
94 static long last_update_from_xen;
96 static u64 processed_system_time;
98 #define HANDLE_USEC_UNDERFLOW(_tv) \
99 do { \
100 while ( (_tv).tv_usec < 0 ) \
101 { \
102 (_tv).tv_usec += 1000000; \
103 (_tv).tv_sec--; \
104 } \
105 } while ( 0 )
106 #define HANDLE_USEC_OVERFLOW(_tv) \
107 do { \
108 while ( (_tv).tv_usec >= 1000000 ) \
109 { \
110 (_tv).tv_usec -= 1000000; \
111 (_tv).tv_sec++; \
112 } \
113 } while ( 0 )
116 /* Does this guest OS track Xen time, or set its wall clock independently? */
117 static int independent_wallclock = 0;
118 static int __init __independent_wallclock(char *str)
119 {
120 independent_wallclock = 1;
121 return 1;
122 }
123 __setup("independent_wallclock", __independent_wallclock);
126 #ifdef CONFIG_XENO_PRIV
127 /*
128 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
129 * called 500 ms after the second nowtime has started, because when
130 * nowtime is written into the registers of the CMOS clock, it will
131 * jump to the next second precisely 500 ms later. Check the Motorola
132 * MC146818A or Dallas DS12887 data sheet for details.
133 *
134 * BUG: This routine does not handle hour overflow properly; it just
135 * sets the minutes. Usually you'll only notice that after reboot!
136 */
137 static int set_rtc_mmss(unsigned long nowtime)
138 {
139 int retval = 0;
140 int real_seconds, real_minutes, cmos_minutes;
141 unsigned char save_control, save_freq_select;
143 /* gets recalled with irq locally disabled */
144 spin_lock(&rtc_lock);
145 save_control = CMOS_READ(RTC_CONTROL);
146 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
148 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
149 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
151 cmos_minutes = CMOS_READ(RTC_MINUTES);
152 if ( !(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD )
153 BCD_TO_BIN(cmos_minutes);
155 /*
156 * since we're only adjusting minutes and seconds, don't interfere with
157 * hour overflow. This avoids messing with unknown time zones but requires
158 * your RTC not to be off by more than 15 minutes
159 */
160 real_seconds = nowtime % 60;
161 real_minutes = nowtime / 60;
162 if ( ((abs(real_minutes - cmos_minutes) + 15)/30) & 1 )
163 real_minutes += 30; /* correct for half hour time zone */
164 real_minutes %= 60;
166 if ( abs(real_minutes - cmos_minutes) < 30 )
167 {
168 if ( !(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD )
169 {
170 BIN_TO_BCD(real_seconds);
171 BIN_TO_BCD(real_minutes);
172 }
173 CMOS_WRITE(real_seconds,RTC_SECONDS);
174 CMOS_WRITE(real_minutes,RTC_MINUTES);
175 }
176 else
177 {
178 printk(KERN_WARNING
179 "set_rtc_mmss: can't update from %d to %d\n",
180 cmos_minutes, real_minutes);
181 retval = -1;
182 }
184 /* The following flags have to be released exactly in this order,
185 * otherwise the DS12887 (popular MC146818A clone with integrated
186 * battery and quartz) will not reset the oscillator and will not
187 * update precisely 500 ms later. You won't find this mentioned in
188 * the Dallas Semiconductor data sheets, but who believes data
189 * sheets anyway ... -- Markus Kuhn
190 */
191 CMOS_WRITE(save_control, RTC_CONTROL);
192 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
193 spin_unlock(&rtc_lock);
195 return retval;
196 }
197 #endif
200 /* Must be called with the xtime_lock held for writing. */
201 static void get_time_values_from_xen(void)
202 {
203 do {
204 shadow_time_version = HYPERVISOR_shared_info->time_version2;
205 rmb();
206 shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec;
207 shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec;
208 shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp;
209 shadow_system_time = HYPERVISOR_shared_info->system_time;
210 rmb();
211 }
212 while ( shadow_time_version != HYPERVISOR_shared_info->time_version1 );
213 }
215 #define TIME_VALUES_UP_TO_DATE \
216 (shadow_time_version == HYPERVISOR_shared_info->time_version2)
219 static inline unsigned long get_time_delta_usecs(void)
220 {
221 s32 delta_tsc;
222 u32 low;
223 u64 delta, tsc;
225 rdtscll(tsc);
226 low = (u32)(tsc >> rdtsc_bitshift);
227 delta_tsc = (s32)(low - shadow_tsc_stamp);
228 if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
229 delta = ((u64)delta_tsc * st_scale_f);
230 delta >>= 32;
231 delta += ((u64)delta_tsc * st_scale_i);
233 return (unsigned long)delta;
234 }
237 void do_gettimeofday(struct timeval *tv)
238 {
239 unsigned long flags, lost;
240 struct timeval _tv;
242 again:
243 read_lock_irqsave(&xtime_lock, flags);
245 _tv.tv_usec = get_time_delta_usecs();
246 if ( (lost = (jiffies - wall_jiffies)) != 0 )
247 _tv.tv_usec += lost * (1000000 / HZ);
248 _tv.tv_sec = xtime.tv_sec;
249 _tv.tv_usec += xtime.tv_usec;
251 if ( unlikely(!TIME_VALUES_UP_TO_DATE) )
252 {
253 /*
254 * We may have blocked for a long time, rendering our calculations
255 * invalid (e.g. the time delta may have overflowed). Detect that
256 * and recalculate with fresh values.
257 */
258 read_unlock_irqrestore(&xtime_lock, flags);
259 write_lock_irqsave(&xtime_lock, flags);
260 get_time_values_from_xen();
261 write_unlock_irqrestore(&xtime_lock, flags);
262 goto again;
263 }
265 HANDLE_USEC_OVERFLOW(_tv);
267 /* Ensure that time-of-day is monotonically increasing. */
268 if ( (_tv.tv_sec < last_seen_tv.tv_sec) ||
269 ((_tv.tv_sec == last_seen_tv.tv_sec) &&
270 (_tv.tv_usec < last_seen_tv.tv_usec)) )
271 _tv = last_seen_tv;
272 last_seen_tv = _tv;
274 read_unlock_irqrestore(&xtime_lock, flags);
276 *tv = _tv;
277 }
279 void do_settimeofday(struct timeval *tv)
280 {
281 struct timeval newtv;
283 if ( !independent_wallclock && (start_info.dom_id != 0) )
284 return;
286 write_lock_irq(&xtime_lock);
288 /*
289 * Ensure we don't get blocked for a long time so that our time delta
290 * overflows. If that were to happen then our shadow time values would
291 * be stale, so we can retry with fresh ones.
292 */
293 again:
294 tv->tv_usec -= get_time_delta_usecs();
295 if ( unlikely(!TIME_VALUES_UP_TO_DATE) )
296 {
297 get_time_values_from_xen();
298 goto again;
299 }
301 HANDLE_USEC_UNDERFLOW(*tv);
303 newtv = *tv;
305 tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
306 HANDLE_USEC_UNDERFLOW(*tv);
308 xtime = *tv;
309 time_adjust = 0; /* stop active adjtime() */
310 time_status |= STA_UNSYNC;
311 time_maxerror = NTP_PHASE_LIMIT;
312 time_esterror = NTP_PHASE_LIMIT;
314 /* Reset all our running time counts. They make no sense now. */
315 last_seen_tv.tv_sec = 0;
316 last_update_from_xen = 0;
318 #ifdef CONFIG_XENO_PRIV
319 if ( start_info.dom_id == 0 )
320 {
321 dom0_op_t op;
322 last_update_to_rtc = last_update_to_xen = 0;
323 op.cmd = DOM0_SETTIME;
324 op.u.settime.secs = newtv.tv_sec;
325 op.u.settime.usecs = newtv.tv_usec;
326 op.u.settime.system_time = shadow_system_time;
327 write_unlock_irq(&xtime_lock);
328 HYPERVISOR_dom0_op(&op);
329 }
330 else
331 #endif
332 {
333 write_unlock_irq(&xtime_lock);
334 }
335 }
337 asmlinkage long sys_stime(int *tptr)
338 {
339 int value;
340 struct timeval tv;
342 if ( !capable(CAP_SYS_TIME) )
343 return -EPERM;
345 if ( get_user(value, tptr) )
346 return -EFAULT;
348 tv.tv_sec = value;
349 tv.tv_usec = 0;
351 do_settimeofday(&tv);
353 return 0;
354 }
356 #define NS_PER_TICK (1000000000ULL/HZ)
357 static inline void do_timer_interrupt(int irq, void *dev_id,
358 struct pt_regs *regs)
359 {
360 s64 delta;
361 long sec_diff;
363 get_time_values_from_xen();
365 if ( (delta = (s64)(shadow_system_time - processed_system_time)) < 0 )
366 {
367 printk("Timer ISR: Time went backwards: %lld\n", delta);
368 return;
369 }
371 while ( delta >= NS_PER_TICK )
372 {
373 do_timer(regs);
374 delta -= NS_PER_TICK;
375 processed_system_time += NS_PER_TICK;
376 }
378 /*
379 * Take synchronised time from Xen once a minute if we're not
380 * synchronised ourselves, and we haven't chosen to keep an independent
381 * time base.
382 */
383 if ( !independent_wallclock &&
384 ((time_status & STA_UNSYNC) != 0) &&
385 (xtime.tv_sec > (last_update_from_xen + 60)) )
386 {
387 /* Adjust shadow timeval for jiffies that haven't updated xtime yet. */
388 shadow_tv.tv_usec -= (jiffies - wall_jiffies) * (1000000/HZ);
389 HANDLE_USEC_UNDERFLOW(shadow_tv);
391 /*
392 * Reset our running time counts if they are invalidated by a warp
393 * backwards of more than 500ms.
394 */
395 sec_diff = xtime.tv_sec - shadow_tv.tv_sec;
396 if ( unlikely(abs(sec_diff) > 1) ||
397 unlikely(((sec_diff * 1000000) +
398 xtime.tv_usec - shadow_tv.tv_usec) > 500000) )
399 {
400 last_update_to_rtc = last_update_to_xen = 0;
401 last_seen_tv.tv_sec = 0;
402 }
404 /* Update our unsynchronised xtime appropriately. */
405 xtime = shadow_tv;
407 last_update_from_xen = xtime.tv_sec;
408 }
410 #ifdef CONFIG_XENO_PRIV
411 if ( (start_info.dom_id == 0) && ((time_status & STA_UNSYNC) == 0) )
412 {
413 /* Send synchronised time to Xen approximately every minute. */
414 if ( xtime.tv_sec > (last_update_to_xen + 60) )
415 {
416 dom0_op_t op;
417 struct timeval tv = xtime;
419 tv.tv_usec += (jiffies - wall_jiffies) * (1000000/HZ);
420 HANDLE_USEC_OVERFLOW(tv);
422 op.cmd = DOM0_SETTIME;
423 op.u.settime.secs = tv.tv_sec;
424 op.u.settime.usecs = tv.tv_usec;
425 op.u.settime.system_time = shadow_system_time;
426 HYPERVISOR_dom0_op(&op);
428 last_update_to_xen = xtime.tv_sec;
429 }
431 /*
432 * If we have an externally synchronized Linux clock, then update CMOS
433 * clock accordingly every ~11 minutes. Set_rtc_mmss() has to be called
434 * as close as possible to 500 ms before the new second starts.
435 */
436 if ( (xtime.tv_sec > (last_update_to_rtc + 660)) &&
437 (xtime.tv_usec >= (500000 - ((unsigned) tick) / 2)) &&
438 (xtime.tv_usec <= (500000 + ((unsigned) tick) / 2)) )
439 {
440 if ( set_rtc_mmss(xtime.tv_sec) == 0 )
441 last_update_to_rtc = xtime.tv_sec;
442 else
443 last_update_to_rtc = xtime.tv_sec - 600;
444 }
445 }
446 #endif
447 }
449 static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
450 {
451 write_lock(&xtime_lock);
452 while ( !TIME_VALUES_UP_TO_DATE )
453 do_timer_interrupt(irq, NULL, regs);
454 write_unlock(&xtime_lock);
455 }
457 static struct irqaction irq_timer = {
458 timer_interrupt,
459 SA_INTERRUPT,
460 0,
461 "timer",
462 NULL,
463 NULL
464 };
466 void __init time_init(void)
467 {
468 unsigned long long alarm;
469 u64 __cpu_khz, cpu_freq, scale, scale2;
471 __cpu_khz = HYPERVISOR_shared_info->cpu_freq;
472 do_div(__cpu_khz, 1000);
473 cpu_khz = (u32)__cpu_khz;
474 printk("Xen reported: %lu.%03lu MHz processor.\n",
475 cpu_khz / 1000, cpu_khz % 1000);
477 xtime.tv_sec = HYPERVISOR_shared_info->wc_sec;
478 xtime.tv_usec = HYPERVISOR_shared_info->wc_usec;
479 processed_system_time = shadow_system_time;
481 rdtsc_bitshift = HYPERVISOR_shared_info->rdtsc_bitshift;
482 cpu_freq = HYPERVISOR_shared_info->cpu_freq;
484 scale = 1000000LL << (32 + rdtsc_bitshift);
485 do_div(scale, (u32)cpu_freq);
487 if ( (cpu_freq >> 32) != 0 )
488 {
489 scale2 = 1000000LL << rdtsc_bitshift;
490 do_div(scale2, (u32)(cpu_freq>>32));
491 scale += scale2;
492 }
494 st_scale_f = scale & 0xffffffff;
495 st_scale_i = scale >> 32;
497 get_time_values_from_xen();
498 processed_system_time = shadow_system_time;
500 setup_irq(TIMER_IRQ, &irq_timer);
502 rdtscll(alarm);
504 clear_bit(_EVENT_TIMER, &HYPERVISOR_shared_info->events);
505 }
508 /*
509 * /proc/sys/xeno: This really belongs in another file. It can stay here for
510 * now however.
511 */
512 static ctl_table xeno_subtable[] = {
513 {1, "independent_wallclock", &independent_wallclock,
514 sizeof(independent_wallclock), 0644, NULL, proc_dointvec},
515 {0}
516 };
517 static ctl_table xeno_table[] = {
518 {123, "xeno", NULL, 0, 0555, xeno_subtable},
519 {0}
520 };
521 static int __init xeno_sysctl_init(void)
522 {
523 (void)register_sysctl_table(xeno_table, 0);
524 return 0;
525 }
526 __initcall(xeno_sysctl_init);