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  */
7 
8 #include <xen/init.h>
9 #include <xen/types.h>
10 #include <asm/regs.h>
11 #include <xen/errno.h>
12 #include <xen/sched.h>
13 #include <xen/irq.h>
14 #include <asm/atomic.h>
15 #include <asm/system.h>
16 #include <asm/io.h>
17 #include <asm/desc.h>
18 #include <xen/bitops.h>
19 #include <xen/delay.h>
20 #include <asm/apic.h>
21 #include <asm/asm_defns.h>
22 #include <io_ports.h>
23 #include <irq_vectors.h>
24 
25 /*
26  * This is the 'legacy' 8259A Programmable Interrupt Controller,
27  * present in the majority of PC/AT boxes.
28  * plus some generic x86 specific things if generic specifics makes
29  * any sense at all.
30  * this file should become arch/i386/kernel/irq.c when the old irq.c
31  * moves to arch independent land
32  */
33 
34 static DEFINE_SPINLOCK(i8259A_lock);
35 
36 static bool _mask_and_ack_8259A_irq(unsigned int irq);
37 
bogus_8259A_irq(unsigned int irq)38 bool bogus_8259A_irq(unsigned int irq)
39 {
40     return _mask_and_ack_8259A_irq(irq);
41 }
42 
mask_and_ack_8259A_irq(struct irq_desc * desc)43 static void mask_and_ack_8259A_irq(struct irq_desc *desc)
44 {
45     _mask_and_ack_8259A_irq(desc->irq);
46 }
47 
startup_8259A_irq(struct irq_desc * desc)48 static unsigned int startup_8259A_irq(struct irq_desc *desc)
49 {
50     enable_8259A_irq(desc);
51     return 0; /* never anything pending */
52 }
53 
end_8259A_irq(struct irq_desc * desc,u8 vector)54 static void end_8259A_irq(struct irq_desc *desc, u8 vector)
55 {
56     if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
57         enable_8259A_irq(desc);
58 }
59 
60 static struct hw_interrupt_type __read_mostly i8259A_irq_type = {
61     .typename = "XT-PIC",
62     .startup  = startup_8259A_irq,
63     .shutdown = disable_8259A_irq,
64     .enable   = enable_8259A_irq,
65     .disable  = disable_8259A_irq,
66     .ack      = mask_and_ack_8259A_irq,
67     .end      = end_8259A_irq
68 };
69 
70 /*
71  * 8259A PIC functions to handle ISA devices:
72  */
73 
74 #define aeoi_mode (i8259A_irq_type.ack == disable_8259A_irq)
75 
76 /*
77  * This contains the irq mask for both 8259A irq controllers,
78  */
79 static unsigned int cached_irq_mask = 0xffff;
80 
81 #define __byte(x,y) (((unsigned char *)&(y))[x])
82 #define cached_21   (__byte(0,cached_irq_mask))
83 #define cached_A1   (__byte(1,cached_irq_mask))
84 
85 /*
86  * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
87  * boards the timer interrupt is not really connected to any IO-APIC pin,
88  * it's fed to the master 8259A's IR0 line only.
89  *
90  * Any '1' bit in this mask means the IRQ is routed through the IO-APIC.
91  * this 'mixed mode' IRQ handling costs nothing because it's only used
92  * at IRQ setup time.
93  */
94 unsigned int __read_mostly io_apic_irqs;
95 
_disable_8259A_irq(unsigned int irq)96 static void _disable_8259A_irq(unsigned int irq)
97 {
98     unsigned int mask = 1 << irq;
99     unsigned long flags;
100 
101     spin_lock_irqsave(&i8259A_lock, flags);
102     cached_irq_mask |= mask;
103     if (irq & 8)
104         outb(cached_A1,0xA1);
105     else
106         outb(cached_21,0x21);
107     per_cpu(vector_irq, 0)[LEGACY_VECTOR(irq)] = ~irq;
108     spin_unlock_irqrestore(&i8259A_lock, flags);
109 }
110 
disable_8259A_irq(struct irq_desc * desc)111 void disable_8259A_irq(struct irq_desc *desc)
112 {
113     _disable_8259A_irq(desc->irq);
114 }
115 
enable_8259A_irq(struct irq_desc * desc)116 void enable_8259A_irq(struct irq_desc *desc)
117 {
118     unsigned int mask = ~(1 << desc->irq);
119     unsigned long flags;
120 
121     spin_lock_irqsave(&i8259A_lock, flags);
122     cached_irq_mask &= mask;
123     per_cpu(vector_irq, 0)[LEGACY_VECTOR(desc->irq)] = desc->irq;
124     if (desc->irq & 8)
125         outb(cached_A1,0xA1);
126     else
127         outb(cached_21,0x21);
128     spin_unlock_irqrestore(&i8259A_lock, flags);
129 }
130 
i8259A_irq_pending(unsigned int irq)131 int i8259A_irq_pending(unsigned int irq)
132 {
133     unsigned int mask = 1<<irq;
134     unsigned long flags;
135     int ret;
136 
137     spin_lock_irqsave(&i8259A_lock, flags);
138     if (irq < 8)
139         ret = inb(0x20) & mask;
140     else
141         ret = inb(0xA0) & (mask >> 8);
142     spin_unlock_irqrestore(&i8259A_lock, flags);
143 
144     return ret;
145 }
146 
mask_8259A(void)147 void mask_8259A(void)
148 {
149     unsigned long flags;
150 
151     spin_lock_irqsave(&i8259A_lock, flags);
152     outb(0xff, 0xA1);
153     outb(0xff, 0x21);
154     spin_unlock_irqrestore(&i8259A_lock, flags);
155 }
156 
unmask_8259A(void)157 void unmask_8259A(void)
158 {
159     unsigned long flags;
160 
161     spin_lock_irqsave(&i8259A_lock, flags);
162     outb(cached_A1, 0xA1);
163     outb(cached_21, 0x21);
164     spin_unlock_irqrestore(&i8259A_lock, flags);
165 }
166 
167 /*
168  * This function assumes to be called rarely. Switching between
169  * 8259A registers is slow.
170  * This has to be protected by the irq controller spinlock
171  * before being called.
172  */
i8259A_irq_real(unsigned int irq)173 static inline int i8259A_irq_real(unsigned int irq)
174 {
175     int value;
176     int irqmask = 1<<irq;
177 
178     if (irq < 8) {
179         outb(0x0B,0x20);                /* ISR register */
180         value = inb(0x20) & irqmask;
181         outb(0x0A,0x20);                /* back to the IRR register */
182         return value;
183     }
184     outb(0x0B,0xA0);                    /* ISR register */
185     value = inb(0xA0) & (irqmask >> 8);
186     outb(0x0A,0xA0);                    /* back to the IRR register */
187     return value;
188 }
189 
190 /*
191  * Careful! The 8259A is a fragile beast, it pretty
192  * much _has_ to be done exactly like this (mask it
193  * first, _then_ send the EOI, and the order of EOI
194  * to the two 8259s is important!  Return a boolean
195  * indicating whether the irq was genuine or spurious.
196  */
_mask_and_ack_8259A_irq(unsigned int irq)197 static bool _mask_and_ack_8259A_irq(unsigned int irq)
198 {
199     unsigned int irqmask = 1 << irq;
200     unsigned long flags;
201     bool is_real_irq = true; /* Assume real unless spurious */
202 
203     spin_lock_irqsave(&i8259A_lock, flags);
204 
205     /*
206      * Lightweight spurious IRQ detection. We do not want
207      * to overdo spurious IRQ handling - it's usually a sign
208      * of hardware problems, so we only do the checks we can
209      * do without slowing down good hardware unnecesserily.
210      *
211      * Note that IRQ7 and IRQ15 (the two spurious IRQs
212      * usually resulting from the 8259A-1|2 PICs) occur
213      * even if the IRQ is masked in the 8259A. Thus we
214      * can check spurious 8259A IRQs without doing the
215      * quite slow i8259A_irq_real() call for every IRQ.
216      * This does not cover 100% of spurious interrupts,
217      * but should be enough to warn the user that there
218      * is something bad going on ...
219      */
220     if ((cached_irq_mask & irqmask) && !i8259A_irq_real(irq)) {
221         static int spurious_irq_mask;
222         is_real_irq = false;
223         /* Report spurious IRQ, once per IRQ line. */
224         if (!(spurious_irq_mask & irqmask)) {
225             printk("spurious 8259A interrupt: IRQ%d.\n", irq);
226             spurious_irq_mask |= irqmask;
227         }
228         /*
229          * Theoretically we do not have to handle this IRQ,
230          * but in Linux this does not cause problems and is
231          * simpler for us.
232          */
233     }
234 
235     cached_irq_mask |= irqmask;
236 
237     if (irq & 8) {
238         inb(0xA1);              /* DUMMY - (do we need this?) */
239         outb(cached_A1,0xA1);
240         if (!aeoi_mode) {
241             outb(0x60 + (irq & 7), 0xA0);/* 'Specific EOI' to slave */
242             outb(0x62,0x20);        /* 'Specific EOI' to master-IRQ2 */
243         }
244     } else {
245         inb(0x21);              /* DUMMY - (do we need this?) */
246         outb(cached_21,0x21);
247         if (!aeoi_mode)
248             outb(0x60 + irq, 0x20);/* 'Specific EOI' to master */
249     }
250 
251     spin_unlock_irqrestore(&i8259A_lock, flags);
252 
253     return is_real_irq;
254 }
255 
256 static char irq_trigger[2];
257 /**
258  * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
259  */
restore_ELCR(char * trigger)260 static void restore_ELCR(char *trigger)
261 {
262     outb(trigger[0], 0x4d0);
263     outb(trigger[1], 0x4d1);
264 }
265 
save_ELCR(char * trigger)266 static void save_ELCR(char *trigger)
267 {
268     /* IRQ 0,1,2,8,13 are marked as reserved */
269     trigger[0] = inb(0x4d0) & 0xF8;
270     trigger[1] = inb(0x4d1) & 0xDE;
271 }
272 
i8259A_resume(void)273 int i8259A_resume(void)
274 {
275     init_8259A(aeoi_mode);
276     restore_ELCR(irq_trigger);
277     return 0;
278 }
279 
i8259A_suspend(void)280 int i8259A_suspend(void)
281 {
282     save_ELCR(irq_trigger);
283     return 0;
284 }
285 
init_8259A(int auto_eoi)286 void init_8259A(int auto_eoi)
287 {
288     unsigned long flags;
289 
290     spin_lock_irqsave(&i8259A_lock, flags);
291 
292     outb(0xff, 0x21);   /* mask all of 8259A-1 */
293     outb(0xff, 0xA1);   /* mask all of 8259A-2 */
294 
295     /*
296      * outb_p - this has to work on a wide range of PC hardware.
297      */
298     outb_p(0x11, 0x20);     /* ICW1: select 8259A-1 init */
299     outb_p(FIRST_LEGACY_VECTOR + 0, 0x21); /* ICW2: 8259A-1 IR0-7 */
300     outb_p(0x04, 0x21);     /* 8259A-1 (the master) has a slave on IR2 */
301     if (auto_eoi)
302         outb_p(0x03, 0x21); /* master does Auto EOI */
303     else
304         outb_p(0x01, 0x21); /* master expects normal EOI */
305 
306     outb_p(0x11, 0xA0);     /* ICW1: select 8259A-2 init */
307     outb_p(FIRST_LEGACY_VECTOR + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 */
308     outb_p(0x02, 0xA1);     /* 8259A-2 is a slave on master's IR2 */
309     outb_p(0x01, 0xA1);     /* (slave's support for AEOI in flat mode
310                                is to be investigated) */
311 
312     if (auto_eoi)
313         /*
314          * in AEOI mode we just have to mask the interrupt
315          * when acking.
316          */
317         i8259A_irq_type.ack = disable_8259A_irq;
318     else
319         i8259A_irq_type.ack = mask_and_ack_8259A_irq;
320 
321     udelay(100);            /* wait for 8259A to initialize */
322 
323     outb(cached_21, 0x21);  /* restore master IRQ mask */
324     outb(cached_A1, 0xA1);  /* restore slave IRQ mask */
325 
326     spin_unlock_irqrestore(&i8259A_lock, flags);
327 }
328 
make_8259A_irq(unsigned int irq)329 void __init make_8259A_irq(unsigned int irq)
330 {
331     io_apic_irqs &= ~(1 << irq);
332     irq_to_desc(irq)->handler = &i8259A_irq_type;
333 }
334 
335 static struct irqaction __read_mostly cascade = { no_action, "cascade", NULL};
336 
init_IRQ(void)337 void __init init_IRQ(void)
338 {
339     int irq, cpu = smp_processor_id();
340 
341     init_bsp_APIC();
342 
343     init_8259A(0);
344 
345     for (irq = 0; platform_legacy_irq(irq); irq++) {
346         struct irq_desc *desc = irq_to_desc(irq);
347 
348         if ( irq == 2 ) /* IRQ2 doesn't exist */
349             continue;
350         desc->handler = &i8259A_irq_type;
351         per_cpu(vector_irq, cpu)[LEGACY_VECTOR(irq)] = irq;
352         cpumask_copy(desc->arch.cpu_mask, cpumask_of(cpu));
353         desc->arch.vector = LEGACY_VECTOR(irq);
354     }
355 
356     per_cpu(vector_irq, cpu)[IRQ0_VECTOR] = 0;
357 
358     apic_intr_init();
359 
360     setup_irq(2, 0, &cascade);
361 }
362 
363