ia64/xen-unstable

view xen/arch/x86/i8259.c @ 18806:ed8524f4a044

x86: Re-initialise HPET on resume from S3

Signed-off-by: Guanqun Lu <guanqun.lu@intel.com>
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Nov 18 15:55:14 2008 +0000 (2008-11-18)
parents 51a05fb4c601
children 6468257e9e62
line source
1 /******************************************************************************
2 * i8259.c
3 *
4 * Well, this is required for SMP systems as well, as it build interrupt
5 * tables for IO APICS as well as uniprocessor 8259-alikes.
6 */
8 #include <xen/config.h>
9 #include <xen/init.h>
10 #include <xen/types.h>
11 #include <asm/regs.h>
12 #include <xen/errno.h>
13 #include <xen/sched.h>
14 #include <xen/irq.h>
15 #include <asm/atomic.h>
16 #include <asm/system.h>
17 #include <asm/io.h>
18 #include <asm/desc.h>
19 #include <asm/bitops.h>
20 #include <xen/delay.h>
21 #include <asm/apic.h>
22 #include <asm/asm_defns.h>
23 #include <io_ports.h>
25 /*
26 * Common place to define all x86 IRQ vectors
27 *
28 * This builds up the IRQ handler stubs using some ugly macros in irq.h
29 *
30 * These macros create the low-level assembly IRQ routines that save
31 * register context and call do_IRQ(). do_IRQ() then does all the
32 * operations that are needed to keep the AT (or SMP IOAPIC)
33 * interrupt-controller happy.
34 */
36 BUILD_COMMON_IRQ()
38 #define BI(x,y) \
39 BUILD_IRQ(x##y)
41 #define BUILD_16_IRQS(x) \
42 BI(x,0) BI(x,1) BI(x,2) BI(x,3) \
43 BI(x,4) BI(x,5) BI(x,6) BI(x,7) \
44 BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
45 BI(x,c) BI(x,d) BI(x,e) BI(x,f)
47 BUILD_16_IRQS(0x0) BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
48 BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
49 BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
50 BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf)
52 #undef BUILD_16_IRQS
53 #undef BI
56 /*
57 * The following vectors are part of the Linux architecture, there
58 * is no hardware IRQ pin equivalent for them, they are triggered
59 * through the ICC by us (IPIs)
60 */
61 BUILD_SMP_INTERRUPT(event_check_interrupt,EVENT_CHECK_VECTOR)
62 BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
63 BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
65 /*
66 * Every pentium local APIC has two 'local interrupts', with a
67 * soft-definable vector attached to both interrupts, one of
68 * which is a timer interrupt, the other one is error counter
69 * overflow. Linux uses the local APIC timer interrupt to get
70 * a much simpler SMP time architecture:
71 */
72 BUILD_SMP_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
73 BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
74 BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
75 BUILD_SMP_INTERRUPT(pmu_apic_interrupt,PMU_APIC_VECTOR)
76 BUILD_SMP_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
78 #define IRQ(x,y) \
79 IRQ##x##y##_interrupt
81 #define IRQLIST_16(x) \
82 IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
83 IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
84 IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
85 IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
87 static void (*interrupt[])(void) = {
88 IRQLIST_16(0x0), IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
89 IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
90 IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
91 IRQLIST_16(0xc), IRQLIST_16(0xd), IRQLIST_16(0xe), IRQLIST_16(0xf)
92 };
94 #undef IRQ
95 #undef IRQLIST_16
97 /*
98 * This is the 'legacy' 8259A Programmable Interrupt Controller,
99 * present in the majority of PC/AT boxes.
100 * plus some generic x86 specific things if generic specifics makes
101 * any sense at all.
102 * this file should become arch/i386/kernel/irq.c when the old irq.c
103 * moves to arch independent land
104 */
106 static DEFINE_SPINLOCK(i8259A_lock);
108 static void disable_8259A_vector(unsigned int vector)
109 {
110 disable_8259A_irq(LEGACY_IRQ_FROM_VECTOR(vector));
111 }
113 static void enable_8259A_vector(unsigned int vector)
114 {
115 enable_8259A_irq(LEGACY_IRQ_FROM_VECTOR(vector));
116 }
118 static void mask_and_ack_8259A_vector(unsigned int);
120 static void end_8259A_vector(unsigned int vector)
121 {
122 if (!(irq_desc[vector].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
123 enable_8259A_vector(vector);
124 }
126 static unsigned int startup_8259A_vector(unsigned int vector)
127 {
128 enable_8259A_vector(vector);
129 return 0; /* never anything pending */
130 }
132 static struct hw_interrupt_type i8259A_irq_type = {
133 .typename = "XT-PIC",
134 .startup = startup_8259A_vector,
135 .shutdown = disable_8259A_vector,
136 .enable = enable_8259A_vector,
137 .disable = disable_8259A_vector,
138 .ack = mask_and_ack_8259A_vector,
139 .end = end_8259A_vector
140 };
142 /*
143 * 8259A PIC functions to handle ISA devices:
144 */
146 /*
147 * This contains the irq mask for both 8259A irq controllers,
148 */
149 static unsigned int cached_irq_mask = 0xffff;
151 #define __byte(x,y) (((unsigned char *)&(y))[x])
152 #define cached_21 (__byte(0,cached_irq_mask))
153 #define cached_A1 (__byte(1,cached_irq_mask))
155 /*
156 * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
157 * boards the timer interrupt is not really connected to any IO-APIC pin,
158 * it's fed to the master 8259A's IR0 line only.
159 *
160 * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
161 * this 'mixed mode' IRQ handling costs nothing because it's only used
162 * at IRQ setup time.
163 */
164 unsigned long io_apic_irqs;
166 void disable_8259A_irq(unsigned int irq)
167 {
168 unsigned int mask = 1 << irq;
169 unsigned long flags;
171 spin_lock_irqsave(&i8259A_lock, flags);
172 cached_irq_mask |= mask;
173 if (irq & 8)
174 outb(cached_A1,0xA1);
175 else
176 outb(cached_21,0x21);
177 spin_unlock_irqrestore(&i8259A_lock, flags);
178 }
180 void enable_8259A_irq(unsigned int irq)
181 {
182 unsigned int mask = ~(1 << irq);
183 unsigned long flags;
185 spin_lock_irqsave(&i8259A_lock, flags);
186 cached_irq_mask &= mask;
187 if (irq & 8)
188 outb(cached_A1,0xA1);
189 else
190 outb(cached_21,0x21);
191 spin_unlock_irqrestore(&i8259A_lock, flags);
192 }
194 int i8259A_irq_pending(unsigned int irq)
195 {
196 unsigned int mask = 1<<irq;
197 unsigned long flags;
198 int ret;
200 spin_lock_irqsave(&i8259A_lock, flags);
201 if (irq < 8)
202 ret = inb(0x20) & mask;
203 else
204 ret = inb(0xA0) & (mask >> 8);
205 spin_unlock_irqrestore(&i8259A_lock, flags);
207 return ret;
208 }
210 /*
211 * This function assumes to be called rarely. Switching between
212 * 8259A registers is slow.
213 * This has to be protected by the irq controller spinlock
214 * before being called.
215 */
216 static inline int i8259A_irq_real(unsigned int irq)
217 {
218 int value;
219 int irqmask = 1<<irq;
221 if (irq < 8) {
222 outb(0x0B,0x20); /* ISR register */
223 value = inb(0x20) & irqmask;
224 outb(0x0A,0x20); /* back to the IRR register */
225 return value;
226 }
227 outb(0x0B,0xA0); /* ISR register */
228 value = inb(0xA0) & (irqmask >> 8);
229 outb(0x0A,0xA0); /* back to the IRR register */
230 return value;
231 }
233 /*
234 * Careful! The 8259A is a fragile beast, it pretty
235 * much _has_ to be done exactly like this (mask it
236 * first, _then_ send the EOI, and the order of EOI
237 * to the two 8259s is important!
238 */
239 static void mask_and_ack_8259A_vector(unsigned int vector)
240 {
241 unsigned int irq = LEGACY_IRQ_FROM_VECTOR(vector);
242 unsigned int irqmask = 1 << irq;
243 unsigned long flags;
245 spin_lock_irqsave(&i8259A_lock, flags);
246 /*
247 * Lightweight spurious IRQ detection. We do not want
248 * to overdo spurious IRQ handling - it's usually a sign
249 * of hardware problems, so we only do the checks we can
250 * do without slowing down good hardware unnecesserily.
251 *
252 * Note that IRQ7 and IRQ15 (the two spurious IRQs
253 * usually resulting from the 8259A-1|2 PICs) occur
254 * even if the IRQ is masked in the 8259A. Thus we
255 * can check spurious 8259A IRQs without doing the
256 * quite slow i8259A_irq_real() call for every IRQ.
257 * This does not cover 100% of spurious interrupts,
258 * but should be enough to warn the user that there
259 * is something bad going on ...
260 */
261 if (cached_irq_mask & irqmask)
262 goto spurious_8259A_irq;
263 cached_irq_mask |= irqmask;
265 handle_real_irq:
266 if (irq & 8) {
267 inb(0xA1); /* DUMMY - (do we need this?) */
268 outb(cached_A1,0xA1);
269 outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */
270 outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */
271 } else {
272 inb(0x21); /* DUMMY - (do we need this?) */
273 outb(cached_21,0x21);
274 outb(0x60+irq,0x20); /* 'Specific EOI' to master */
275 }
276 spin_unlock_irqrestore(&i8259A_lock, flags);
277 return;
279 spurious_8259A_irq:
280 /*
281 * this is the slow path - should happen rarely.
282 */
283 if (i8259A_irq_real(irq))
284 /*
285 * oops, the IRQ _is_ in service according to the
286 * 8259A - not spurious, go handle it.
287 */
288 goto handle_real_irq;
290 {
291 static int spurious_irq_mask;
292 /*
293 * At this point we can be sure the IRQ is spurious,
294 * lets ACK and report it. [once per IRQ]
295 */
296 if (!(spurious_irq_mask & irqmask)) {
297 printk("spurious 8259A interrupt: IRQ%d.\n", irq);
298 spurious_irq_mask |= irqmask;
299 }
300 atomic_inc(&irq_err_count);
301 /*
302 * Theoretically we do not have to handle this IRQ,
303 * but in Linux this does not cause problems and is
304 * simpler for us.
305 */
306 goto handle_real_irq;
307 }
308 }
310 static char irq_trigger[2];
311 /**
312 * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
313 */
314 static void restore_ELCR(char *trigger)
315 {
316 outb(trigger[0], 0x4d0);
317 outb(trigger[1], 0x4d1);
318 }
320 static void save_ELCR(char *trigger)
321 {
322 /* IRQ 0,1,2,8,13 are marked as reserved */
323 trigger[0] = inb(0x4d0) & 0xF8;
324 trigger[1] = inb(0x4d1) & 0xDE;
325 }
327 int i8259A_resume(void)
328 {
329 init_8259A(0);
330 restore_ELCR(irq_trigger);
331 return 0;
332 }
334 int i8259A_suspend(void)
335 {
336 save_ELCR(irq_trigger);
337 return 0;
338 }
340 void __devinit init_8259A(int auto_eoi)
341 {
342 unsigned long flags;
344 spin_lock_irqsave(&i8259A_lock, flags);
346 outb(0xff, 0x21); /* mask all of 8259A-1 */
347 outb(0xff, 0xA1); /* mask all of 8259A-2 */
349 /*
350 * outb_p - this has to work on a wide range of PC hardware.
351 */
352 outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */
353 outb_p(FIRST_LEGACY_VECTOR + 0, 0x21); /* ICW2: 8259A-1 IR0-7 */
354 outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */
355 if (auto_eoi)
356 outb_p(0x03, 0x21); /* master does Auto EOI */
357 else
358 outb_p(0x01, 0x21); /* master expects normal EOI */
360 outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */
361 outb_p(FIRST_LEGACY_VECTOR + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 */
362 outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */
363 outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode
364 is to be investigated) */
366 if (auto_eoi)
367 /*
368 * in AEOI mode we just have to mask the interrupt
369 * when acking.
370 */
371 i8259A_irq_type.ack = disable_8259A_vector;
372 else
373 i8259A_irq_type.ack = mask_and_ack_8259A_vector;
375 udelay(100); /* wait for 8259A to initialize */
377 outb(cached_21, 0x21); /* restore master IRQ mask */
378 outb(cached_A1, 0xA1); /* restore slave IRQ mask */
380 spin_unlock_irqrestore(&i8259A_lock, flags);
381 }
383 static struct irqaction cascade = { no_action, "cascade", NULL};
385 void __init init_IRQ(void)
386 {
387 int i;
389 init_bsp_APIC();
391 init_8259A(0);
393 for ( i = 0; i < NR_IRQS; i++ )
394 {
395 irq_desc[i].status = IRQ_DISABLED;
396 irq_desc[i].handler = &no_irq_type;
397 irq_desc[i].action = NULL;
398 irq_desc[i].depth = 1;
399 spin_lock_init(&irq_desc[i].lock);
400 cpus_setall(irq_desc[i].affinity);
401 if ( i >= 0x20 )
402 set_intr_gate(i, interrupt[i]);
403 }
405 for ( i = 0; i < 16; i++ )
406 {
407 vector_irq[LEGACY_VECTOR(i)] = i;
408 irq_desc[LEGACY_VECTOR(i)].handler = &i8259A_irq_type;
409 }
411 /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
412 vector_irq[HYPERCALL_VECTOR] = NEVER_ASSIGN;
413 vector_irq[0x80] = NEVER_ASSIGN;
415 apic_intr_init();
417 /* Set the clock to HZ Hz */
418 #define CLOCK_TICK_RATE 1193182 /* crystal freq (Hz) */
419 #define LATCH (((CLOCK_TICK_RATE)+(HZ/2))/HZ)
420 outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
421 outb_p(LATCH & 0xff, PIT_CH0); /* LSB */
422 outb(LATCH >> 8, PIT_CH0); /* MSB */
424 setup_irq(2, &cascade);
425 }