ia64/xen-unstable

view xen/arch/i386/time.c @ 945:db2e1ea917df

bitkeeper revision 1.596.1.3 (3fb3b41eWUoRU0H8A0jEX5roXjxKkA)

Many files:
Greatly simplified Xen softirqs. They are now only executed in outermost Xen activation; they are never called within an irq context.
author kaf24@scramble.cl.cam.ac.uk
date Thu Nov 13 16:41:02 2003 +0000 (2003-11-13)
parents cb5916bb9685
children 7a554cbf0f58
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 University of Cambridge
5 ****************************************************************************
6 *
7 * File: i386/time.c
8 * Author: Rolf Neugebar & Keir Fraser
9 *
10 * Environment: Xen Hypervisor
11 * Description: modified version of Linux' time.c
12 * implements system and wall clock time.
13 * based on freebsd's implementation.
14 */
16 /*
17 * linux/arch/i386/kernel/time.c
18 *
19 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
20 */
22 #include <xeno/errno.h>
23 #include <xeno/sched.h>
24 #include <xeno/lib.h>
25 #include <xeno/config.h>
26 #include <xeno/init.h>
27 #include <xeno/interrupt.h>
28 #include <xeno/time.h>
29 #include <xeno/ac_timer.h>
31 #include <asm/io.h>
32 #include <xeno/smp.h>
33 #include <xeno/irq.h>
34 #include <asm/msr.h>
35 #include <asm/mpspec.h>
36 #include <asm/processor.h>
37 #include <asm/fixmap.h>
38 #include <asm/mc146818rtc.h>
40 #ifdef TIME_TRACE
41 #define TRC(_x) _x
42 #else
43 #define TRC(_x)
44 #endif
46 extern rwlock_t xtime_lock;
47 extern unsigned long wall_jiffies;
49 /* GLOBAL */
50 unsigned long cpu_khz; /* Detected as we calibrate the TSC */
51 unsigned long ticks_per_usec; /* TSC ticks per microsecond. */
52 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
53 int timer_ack = 0;
54 int do_timer_lists_from_pit = 0;
56 /* PRIVATE */
57 static unsigned int rdtsc_bitshift; /* Which 32 bits of TSC do we use? */
58 static u64 cpu_freq; /* CPU frequency (Hz) */
59 static u32 st_scale_f; /* Cycles -> ns, fractional part */
60 static u32 st_scale_i; /* Cycles -> ns, integer part */
61 static u32 tsc_irq; /* CPU0's TSC at last 'time update' */
62 static s_time_t stime_irq; /* System time at last 'time update' */
64 static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
65 {
66 u64 full_tsc;
68 write_lock(&xtime_lock);
70 #ifdef CONFIG_X86_IO_APIC
71 if ( timer_ack )
72 {
73 extern spinlock_t i8259A_lock;
74 spin_lock(&i8259A_lock);
75 outb(0x0c, 0x20);
76 /* Ack the IRQ; AEOI will end it automatically. */
77 inb(0x20);
78 spin_unlock(&i8259A_lock);
79 }
80 #endif
82 /*
83 * Updates TSC timestamp (used to interpolate passage of time between
84 * interrupts).
85 */
86 rdtscll(full_tsc);
87 tsc_irq = (u32)(full_tsc >> rdtsc_bitshift);
89 /* Updates xtime (wallclock time). */
90 do_timer(regs);
92 /* Updates system time (nanoseconds since boot). */
93 stime_irq += MILLISECS(1000/HZ);
95 write_unlock(&xtime_lock);
97 /* Rough hack to allow accurate timers to sort-of-work with no APIC. */
98 if ( do_timer_lists_from_pit )
99 __cpu_raise_softirq(smp_processor_id(), AC_TIMER_SOFTIRQ);
100 }
102 static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0,
103 "timer", NULL, NULL};
105 /* ------ Calibrate the TSC -------
106 * Return processor ticks per second / CALIBRATE_FRAC.
107 */
109 #define CLOCK_TICK_RATE 1193180 /* system crystal frequency (Hz) */
110 #define CALIBRATE_FRAC 20 /* calibrate over 50ms */
111 #define CALIBRATE_LATCH ((CLOCK_TICK_RATE+(CALIBRATE_FRAC/2))/CALIBRATE_FRAC)
113 static unsigned long __init calibrate_tsc(void)
114 {
115 unsigned long startlow, starthigh, endlow, endhigh, count;
117 /* Set the Gate high, disable speaker */
118 outb((inb(0x61) & ~0x02) | 0x01, 0x61);
120 /*
121 * Now let's take care of CTC channel 2
122 *
123 * Set the Gate high, program CTC channel 2 for mode 0, (interrupt on
124 * terminal count mode), binary count, load 5 * LATCH count, (LSB and MSB)
125 * to begin countdown.
126 */
127 outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
128 outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
129 outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
131 rdtsc(startlow, starthigh);
132 for ( count = 0; (inb(0x61) & 0x20) == 0; count++ )
133 continue;
134 rdtsc(endlow, endhigh);
136 /* Error if the CTC doesn't behave itself. */
137 if ( count == 0 )
138 return 0;
140 /* [endhigh:endlow] = [endhigh:endlow] - [starthigh:startlow] */
141 __asm__( "subl %2,%0 ; sbbl %3,%1"
142 : "=a" (endlow), "=d" (endhigh)
143 : "g" (startlow), "g" (starthigh), "0" (endlow), "1" (endhigh) );
145 /* If quotient doesn't fit in 32 bits then we return error (zero). */
146 return endhigh ? 0 : endlow;
147 }
150 /***************************************************************************
151 * CMOS Timer functions
152 ***************************************************************************/
154 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
155 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
156 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
157 *
158 * [For the Julian calendar (which was used in Russia before 1917,
159 * Britain & colonies before 1752, anywhere else before 1582,
160 * and is still in use by some communities) leave out the
161 * -year/100+year/400 terms, and add 10.]
162 *
163 * This algorithm was first published by Gauss (I think).
164 *
165 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
166 * machines were long is 32-bit! (However, as time_t is signed, we
167 * will already get problems at other places on 2038-01-19 03:14:08)
168 */
169 static inline unsigned long
170 mktime (unsigned int year, unsigned int mon,
171 unsigned int day, unsigned int hour,
172 unsigned int min, unsigned int sec)
173 {
174 /* 1..12 -> 11,12,1..10: put Feb last since it has a leap day. */
175 if ( 0 >= (int) (mon -= 2) )
176 {
177 mon += 12;
178 year -= 1;
179 }
181 return ((((unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day)+
182 year*365 - 719499
183 )*24 + hour /* now have hours */
184 )*60 + min /* now have minutes */
185 )*60 + sec; /* finally seconds */
186 }
188 static unsigned long __get_cmos_time(void)
189 {
190 unsigned int year, mon, day, hour, min, sec;
192 sec = CMOS_READ(RTC_SECONDS);
193 min = CMOS_READ(RTC_MINUTES);
194 hour = CMOS_READ(RTC_HOURS);
195 day = CMOS_READ(RTC_DAY_OF_MONTH);
196 mon = CMOS_READ(RTC_MONTH);
197 year = CMOS_READ(RTC_YEAR);
199 if ( !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD )
200 {
201 BCD_TO_BIN(sec);
202 BCD_TO_BIN(min);
203 BCD_TO_BIN(hour);
204 BCD_TO_BIN(day);
205 BCD_TO_BIN(mon);
206 BCD_TO_BIN(year);
207 }
209 if ( (year += 1900) < 1970 )
210 year += 100;
212 return mktime(year, mon, day, hour, min, sec);
213 }
215 static unsigned long get_cmos_time(void)
216 {
217 unsigned long res, flags;
218 int i;
220 spin_lock_irqsave(&rtc_lock, flags);
222 /* read RTC exactly on falling edge of update flag */
223 for ( i = 0 ; i < 1000000 ; i++ ) /* may take up to 1 second... */
224 if ( (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) )
225 break;
226 for ( i = 0 ; i < 1000000 ; i++ ) /* must try at least 2.228 ms */
227 if ( !(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) )
228 break;
230 res = __get_cmos_time();
232 spin_unlock_irqrestore(&rtc_lock, flags);
233 return res;
234 }
236 /***************************************************************************
237 * System Time
238 ***************************************************************************/
240 static inline u64 get_time_delta(void)
241 {
242 s32 delta_tsc;
243 u32 low;
244 u64 delta, tsc;
246 rdtscll(tsc);
247 low = (u32)(tsc >> rdtsc_bitshift);
248 delta_tsc = (s32)(low - tsc_irq);
249 if ( unlikely(delta_tsc < 0) ) delta_tsc = 0;
250 delta = ((u64)delta_tsc * st_scale_f);
251 delta >>= 32;
252 delta += ((u64)delta_tsc * st_scale_i);
254 return delta;
255 }
257 s_time_t get_s_time(void)
258 {
259 s_time_t now;
260 unsigned long flags;
262 read_lock_irqsave(&xtime_lock, flags);
264 now = stime_irq + get_time_delta();
266 /* Ensure that the returned system time is monotonically increasing. */
267 {
268 static s_time_t prev_now = 0;
269 if ( unlikely(now < prev_now) )
270 now = prev_now;
271 prev_now = now;
272 }
274 read_unlock_irqrestore(&xtime_lock, flags);
276 return now;
277 }
280 void update_dom_time(shared_info_t *si)
281 {
282 unsigned long flags;
284 read_lock_irqsave(&xtime_lock, flags);
286 si->time_version1++;
287 wmb();
289 /* NB. These two values don't actually ever change. */
290 si->cpu_freq = cpu_freq;
291 si->rdtsc_bitshift = rdtsc_bitshift;
293 si->system_time = stime_irq;
294 si->tsc_timestamp = tsc_irq;
295 si->wc_sec = xtime.tv_sec;
296 si->wc_usec = xtime.tv_usec;
297 si->wc_usec += (jiffies - wall_jiffies) * (1000000 / HZ);
298 while ( si->wc_usec >= 1000000 )
299 {
300 si->wc_usec -= 1000000;
301 si->wc_sec++;
302 }
304 wmb();
305 si->time_version2++;
307 read_unlock_irqrestore(&xtime_lock, flags);
308 }
311 /* Set clock to <secs,usecs> after 00:00:00 UTC, 1 January, 1970. */
312 void do_settime(unsigned long secs, unsigned long usecs, u64 system_time_base)
313 {
314 s64 delta;
315 long _usecs = (long)usecs;
317 write_lock_irq(&xtime_lock);
319 delta = (s64)(stime_irq - system_time_base);
321 _usecs += (long)(delta/1000);
322 _usecs -= (jiffies - wall_jiffies) * (1000000 / HZ);
324 while ( _usecs < 0 )
325 {
326 _usecs += 1000000;
327 secs--;
328 }
330 xtime.tv_sec = secs;
331 xtime.tv_usec = _usecs;
333 write_unlock_irq(&xtime_lock);
335 update_dom_time(current->shared_info);
336 }
339 /* Late init function (after all CPUs are booted). */
340 int __init init_xeno_time()
341 {
342 u64 scale;
343 u64 full_tsc;
344 unsigned int cpu_ghz;
346 cpu_ghz = (unsigned int)(cpu_freq / 1000000000ULL);
347 for ( rdtsc_bitshift = 0; cpu_ghz != 0; rdtsc_bitshift++, cpu_ghz >>= 1 )
348 continue;
350 scale = 1000000000LL << (32 + rdtsc_bitshift);
351 scale /= cpu_freq;
352 st_scale_f = scale & 0xffffffff;
353 st_scale_i = scale >> 32;
355 /* System time ticks from zero. */
356 rdtscll(full_tsc);
357 stime_irq = (s_time_t)0;
358 tsc_irq = (u32)(full_tsc >> rdtsc_bitshift);
360 /* Wallclock time starts as the initial RTC time. */
361 xtime.tv_sec = get_cmos_time();
363 printk("Time init:\n");
364 printk(".... System Time: %lldns\n",
365 NOW());
366 printk(".... cpu_freq: %08X:%08X\n",
367 (u32)(cpu_freq>>32), (u32)cpu_freq);
368 printk(".... scale: %08X:%08X\n",
369 (u32)(scale>>32), (u32)scale);
370 printk(".... Wall Clock: %lds %ldus\n",
371 xtime.tv_sec, xtime.tv_usec);
373 return 0;
374 }
377 /* Early init function. */
378 void __init time_init(void)
379 {
380 unsigned long ticks_per_frac = calibrate_tsc();
382 if ( !ticks_per_frac )
383 panic("Error calibrating TSC\n");
385 ticks_per_usec = ticks_per_frac / (1000000/CALIBRATE_FRAC);
386 cpu_khz = ticks_per_frac / (1000/CALIBRATE_FRAC);
388 cpu_freq = (u64)ticks_per_frac * (u64)CALIBRATE_FRAC;
390 printk("Detected %lu.%03lu MHz processor.\n",
391 cpu_khz / 1000, cpu_khz % 1000);
393 setup_irq(0, &irq0);
394 }