vserver 1.9.5.x5
[linux-2.6.git] / include / asm-i386 / mach-default / do_timer.h
1 /* defines for inline arch setup functions */
2
3 #include <asm/apic.h>
4
5 /**
6  * do_timer_interrupt_hook - hook into timer tick
7  * @regs:       standard registers from interrupt
8  *
9  * Description:
10  *      This hook is called immediately after the timer interrupt is ack'd.
11  *      It's primary purpose is to allow architectures that don't possess
12  *      individual per CPU clocks (like the CPU APICs supply) to broadcast the
13  *      timer interrupt as a means of triggering reschedules etc.
14  **/
15
16 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
17 {
18         do_timer(regs);
19 #ifndef CONFIG_SMP
20         update_process_times(user_mode(regs));
21 #endif
22 /*
23  * In the SMP case we use the local APIC timer interrupt to do the
24  * profiling, except when we simulate SMP mode on a uniprocessor
25  * system, in that case we have to call the local interrupt handler.
26  */
27 #ifndef CONFIG_X86_LOCAL_APIC
28         profile_tick(CPU_PROFILING, regs);
29 #else
30         if (!using_apic_timer)
31                 smp_local_timer_interrupt(regs);
32 #endif
33 }
34
35
36 /* you can safely undefine this if you don't have the Neptune chipset */
37
38 #define BUGGY_NEPTUN_TIMER
39
40 /**
41  * do_timer_overflow - process a detected timer overflow condition
42  * @count:      hardware timer interrupt count on overflow
43  *
44  * Description:
45  *      This call is invoked when the jiffies count has not incremented but
46  *      the hardware timer interrupt has.  It means that a timer tick interrupt
47  *      came along while the previous one was pending, thus a tick was missed
48  **/
49 static inline int do_timer_overflow(int count)
50 {
51         int i;
52
53         spin_lock(&i8259A_lock);
54         /*
55          * This is tricky when I/O APICs are used;
56          * see do_timer_interrupt().
57          */
58         i = inb(0x20);
59         spin_unlock(&i8259A_lock);
60         
61         /* assumption about timer being IRQ0 */
62         if (i & 0x01) {
63                 /*
64                  * We cannot detect lost timer interrupts ... 
65                  * well, that's why we call them lost, don't we? :)
66                  * [hmm, on the Pentium and Alpha we can ... sort of]
67                  */
68                 count -= LATCH;
69         } else {
70 #ifdef BUGGY_NEPTUN_TIMER
71                 /*
72                  * for the Neptun bug we know that the 'latch'
73                  * command doesn't latch the high and low value
74                  * of the counter atomically. Thus we have to 
75                  * substract 256 from the counter 
76                  * ... funny, isnt it? :)
77                  */
78                 
79                 count -= 256;
80 #else
81                 printk("do_slow_gettimeoffset(): hardware timer problem?\n");
82 #endif
83         }
84         return count;
85 }