2 * linux/arch/ia64/kernel/time.c
4 * Copyright (C) 1998-2001 Hewlett-Packard Co
5 * Copyright (C) 1998-2000 Stephane Eranian <eranian@hpl.hp.com>
6 * Copyright (C) 1999-2001 David Mosberger <davidm@hpl.hp.com>
7 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
8 * Copyright (C) 1999-2000 VA Linux Systems
9 * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com>
11 #include <linux/config.h>
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/sched.h>
16 #include <linux/time.h>
17 #include <linux/interrupt.h>
18 #include <linux/efi.h>
20 #include <asm/delay.h>
21 #include <asm/hw_irq.h>
22 #include <asm/ptrace.h>
24 #include <asm/system.h>
26 extern rwlock_t xtime_lock
;
27 extern unsigned long wall_jiffies
;
28 extern unsigned long last_time_offset
;
30 #ifdef CONFIG_IA64_DEBUG_IRQ
32 unsigned long last_cli_ip
;
37 do_profile (unsigned long ip
)
39 extern unsigned long prof_cpu_mask
;
45 if (!((1UL << smp_processor_id()) & prof_cpu_mask
))
48 ip
-= (unsigned long) &_stext
;
51 * Don't ignore out-of-bounds IP values silently, put them into the last
52 * histogram slot, so if present, they will show up as a sharp peak.
54 if (ip
> prof_len
- 1)
57 atomic_inc((atomic_t
*) &prof_buffer
[ip
]);
61 * Return the number of micro-seconds that elapsed since the last update to jiffy. The
62 * xtime_lock must be at least read-locked when calling this routine.
64 static inline unsigned long
67 unsigned long elapsed_cycles
, lost
= jiffies
- wall_jiffies
;
68 unsigned long now
, last_tick
;
69 # define time_keeper_id 0 /* smp_processor_id() of time-keeper */
71 last_tick
= (cpu_data(time_keeper_id
)->itm_next
72 - (lost
+ 1)*cpu_data(time_keeper_id
)->itm_delta
);
75 if ((long) (now
- last_tick
) < 0) {
76 printk(KERN_ERR
"CPU %d: now < last_tick (now=0x%lx,last_tick=0x%lx)!\n",
77 smp_processor_id(), now
, last_tick
);
78 return last_time_offset
;
80 elapsed_cycles
= now
- last_tick
;
81 return (elapsed_cycles
*local_cpu_data
->usec_per_cyc
) >> IA64_USEC_PER_CYC_SHIFT
;
85 do_settimeofday (struct timeval
*tv
)
87 write_lock_irq(&xtime_lock
);
90 * This is revolting. We need to set "xtime" correctly. However, the value
91 * in this location is the value at the most recent update of wall time.
92 * Discover what correction gettimeofday would have done, and then undo
95 tv
->tv_usec
-= gettimeoffset();
97 while (tv
->tv_usec
< 0) {
98 tv
->tv_usec
+= 1000000;
103 time_adjust
= 0; /* stop active adjtime() */
104 time_status
|= STA_UNSYNC
;
105 time_maxerror
= NTP_PHASE_LIMIT
;
106 time_esterror
= NTP_PHASE_LIMIT
;
108 write_unlock_irq(&xtime_lock
);
112 do_gettimeofday (struct timeval
*tv
)
114 unsigned long flags
, usec
, sec
, old
;
116 read_lock_irqsave(&xtime_lock
, flags
);
118 usec
= gettimeoffset();
121 * Ensure time never goes backwards, even when ITC on different CPUs are
122 * not perfectly synchronized.
125 old
= last_time_offset
;
130 } while (cmpxchg(&last_time_offset
, old
, usec
) != old
);
133 usec
+= xtime
.tv_usec
;
135 read_unlock_irqrestore(&xtime_lock
, flags
);
137 while (usec
>= 1000000) {
147 timer_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
149 unsigned long new_itm
;
151 new_itm
= local_cpu_data
->itm_next
;
153 if (!time_after(ia64_get_itc(), new_itm
))
154 printk(KERN_ERR
"Oops: timer tick before it's due (itc=%lx,itm=%lx)\n",
155 ia64_get_itc(), new_itm
);
159 * Do kernel PC profiling here. We multiply the instruction number by
160 * four so that we can use a prof_shift of 2 to get instruction-level
161 * instead of just bundle-level accuracy.
163 if (!user_mode(regs
))
164 do_profile(regs
->cr_iip
+ 4*ia64_psr(regs
)->ri
);
169 new_itm
+= local_cpu_data
->itm_delta
;
171 if (smp_processor_id() == 0) {
173 * Here we are in the timer irq handler. We have irqs locally
174 * disabled, but we don't know if the timer_bh is running on
175 * another CPU. We need to avoid to SMP race by acquiring the
178 write_lock(&xtime_lock
);
180 local_cpu_data
->itm_next
= new_itm
;
181 write_unlock(&xtime_lock
);
183 local_cpu_data
->itm_next
= new_itm
;
185 if (time_after(new_itm
, ia64_get_itc()))
191 * If we're too close to the next clock tick for comfort, we increase the
192 * saftey margin by intentionally dropping the next tick(s). We do NOT update
193 * itm.next because that would force us to call do_timer() which in turn would
194 * let our clock run too fast (with the potentially devastating effect of
195 * losing monotony of time).
197 while (!time_after(new_itm
, ia64_get_itc() + local_cpu_data
->itm_delta
/2))
198 new_itm
+= local_cpu_data
->itm_delta
;
199 ia64_set_itm(new_itm
);
200 /* double check, in case we got hit by a (slow) PMI: */
201 } while (time_after_eq(ia64_get_itc(), new_itm
));
205 * Encapsulate access to the itm structure for SMP.
208 ia64_cpu_local_tick (void)
210 int cpu
= smp_processor_id();
211 unsigned long shift
= 0, delta
;
213 /* arrange for the cycle counter to generate a timer interrupt: */
214 ia64_set_itv(IA64_TIMER_VECTOR
);
216 delta
= local_cpu_data
->itm_delta
;
218 * Stagger the timer tick for each CPU so they don't occur all at (almost) the
222 unsigned long hi
= 1UL << ia64_fls(cpu
);
223 shift
= (2*(cpu
- hi
) + 1) * delta
/hi
/2;
225 local_cpu_data
->itm_next
= ia64_get_itc() + delta
+ shift
;
226 ia64_set_itm(local_cpu_data
->itm_next
);
232 unsigned long platform_base_freq
, itc_freq
, drift
;
233 struct pal_freq_ratio itc_ratio
, proc_ratio
;
237 * According to SAL v2.6, we need to use a SAL call to determine the platform base
238 * frequency and then a PAL call to determine the frequency ratio between the ITC
239 * and the base frequency.
241 status
= ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM
, &platform_base_freq
, &drift
);
243 printk(KERN_ERR
"SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status
));
245 status
= ia64_pal_freq_ratios(&proc_ratio
, 0, &itc_ratio
);
247 printk(KERN_ERR
"PAL_FREQ_RATIOS failed with status=%ld\n", status
);
250 /* invent "random" values */
252 "SAL/PAL failed to obtain frequency info---inventing reasonably values\n");
253 platform_base_freq
= 100000000;
257 if (platform_base_freq
< 40000000) {
258 printk(KERN_ERR
"Platform base frequency %lu bogus---resetting to 75MHz!\n",
260 platform_base_freq
= 75000000;
263 proc_ratio
.den
= 1; /* avoid division by zero */
265 itc_ratio
.den
= 1; /* avoid division by zero */
267 itc_freq
= (platform_base_freq
*itc_ratio
.num
)/itc_ratio
.den
;
268 local_cpu_data
->itm_delta
= (itc_freq
+ HZ
/2) / HZ
;
269 printk(KERN_INFO
"CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
270 "ITC freq=%lu.%03luMHz\n", smp_processor_id(),
271 platform_base_freq
/ 1000000, (platform_base_freq
/ 1000) % 1000,
272 itc_ratio
.num
, itc_ratio
.den
, itc_freq
/ 1000000, (itc_freq
/ 1000) % 1000);
274 local_cpu_data
->proc_freq
= (platform_base_freq
*proc_ratio
.num
)/proc_ratio
.den
;
275 local_cpu_data
->itc_freq
= itc_freq
;
276 local_cpu_data
->cyc_per_usec
= (itc_freq
+ 500000) / 1000000;
277 local_cpu_data
->usec_per_cyc
= ((1000000UL<<IA64_USEC_PER_CYC_SHIFT
)
278 + itc_freq
/2)/itc_freq
;
280 /* Setup the CPU local timer tick */
281 ia64_cpu_local_tick();
284 static struct irqaction timer_irqaction
= {
285 .handler
= timer_interrupt
,
286 .flags
= SA_INTERRUPT
,
293 register_percpu_irq(IA64_TIMER_VECTOR
, &timer_irqaction
);
294 efi_gettimeofday((struct timeval
*) &xtime
);