]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/x86/isa/atpic.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / x86 / isa / atpic.c
1 /*-
2  * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the author nor the names of any co-contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 /*
31  * PIC driver for the 8259A Master and Slave PICs in PC/AT machines.
32  */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_auto_eoi.h"
38 #include "opt_isa.h"
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/bus.h>
43 #include <sys/interrupt.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/module.h>
47
48 #include <machine/cpufunc.h>
49 #include <machine/frame.h>
50 #include <machine/intr_machdep.h>
51 #include <machine/md_var.h>
52 #include <machine/resource.h>
53 #include <machine/segments.h>
54
55 #include <dev/ic/i8259.h>
56 #include <x86/isa/icu.h>
57 #ifdef PC98
58 #include <pc98/cbus/cbus.h>
59 #else
60 #include <x86/isa/isa.h>
61 #endif
62 #include <isa/isavar.h>
63
64 #ifdef __amd64__
65 #define SDT_ATPIC       SDT_SYSIGT
66 #define GSEL_ATPIC      0
67 #else
68 #define SDT_ATPIC       SDT_SYS386IGT
69 #define GSEL_ATPIC      GSEL(GCODE_SEL, SEL_KPL)
70 #endif
71
72 #define MASTER  0
73 #define SLAVE   1
74
75 #define NUM_ISA_IRQS            16
76
77 static void     atpic_init(void *dummy);
78
79 unsigned int imen;      /* XXX */
80
81 inthand_t
82         IDTVEC(atpic_intr0), IDTVEC(atpic_intr1), IDTVEC(atpic_intr2),
83         IDTVEC(atpic_intr3), IDTVEC(atpic_intr4), IDTVEC(atpic_intr5),
84         IDTVEC(atpic_intr6), IDTVEC(atpic_intr7), IDTVEC(atpic_intr8),
85         IDTVEC(atpic_intr9), IDTVEC(atpic_intr10), IDTVEC(atpic_intr11),
86         IDTVEC(atpic_intr12), IDTVEC(atpic_intr13), IDTVEC(atpic_intr14),
87         IDTVEC(atpic_intr15);
88
89 #define IRQ(ap, ai)     ((ap)->at_irqbase + (ai)->at_irq)
90
91 #define ATPIC(io, base, eoi, imenptr)                                   \
92         { { atpic_enable_source, atpic_disable_source, (eoi),           \
93             atpic_enable_intr, atpic_disable_intr, atpic_vector,        \
94             atpic_source_pending, NULL, atpic_resume, atpic_config_intr,\
95             atpic_assign_cpu }, (io), (base), IDT_IO_INTS + (base),     \
96             (imenptr) }
97
98 #define INTSRC(irq)                                                     \
99         { { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ),    \
100             (irq) % 8 }
101
102 struct atpic {
103         struct pic at_pic;
104         int     at_ioaddr;
105         int     at_irqbase;
106         uint8_t at_intbase;
107         uint8_t *at_imen;
108 };
109
110 struct atpic_intsrc {
111         struct intsrc at_intsrc;
112         inthand_t *at_intr;
113         int     at_irq;                 /* Relative to PIC base. */
114         enum intr_trigger at_trigger;
115         u_long  at_count;
116         u_long  at_straycount;
117 };
118
119 static void atpic_enable_source(struct intsrc *isrc);
120 static void atpic_disable_source(struct intsrc *isrc, int eoi);
121 static void atpic_eoi_master(struct intsrc *isrc);
122 static void atpic_eoi_slave(struct intsrc *isrc);
123 static void atpic_enable_intr(struct intsrc *isrc);
124 static void atpic_disable_intr(struct intsrc *isrc);
125 static int atpic_vector(struct intsrc *isrc);
126 static void atpic_resume(struct pic *pic, bool suspend_cancelled);
127 static int atpic_source_pending(struct intsrc *isrc);
128 static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
129     enum intr_polarity pol);
130 static int atpic_assign_cpu(struct intsrc *isrc, u_int apic_id);
131 static void i8259_init(struct atpic *pic, int slave);
132
133 static struct atpic atpics[] = {
134         ATPIC(IO_ICU1, 0, atpic_eoi_master, (uint8_t *)&imen),
135         ATPIC(IO_ICU2, 8, atpic_eoi_slave, ((uint8_t *)&imen) + 1)
136 };
137
138 static struct atpic_intsrc atintrs[] = {
139         INTSRC(0),
140         INTSRC(1),
141         INTSRC(2),
142         INTSRC(3),
143         INTSRC(4),
144         INTSRC(5),
145         INTSRC(6),
146         INTSRC(7),
147         INTSRC(8),
148         INTSRC(9),
149         INTSRC(10),
150         INTSRC(11),
151         INTSRC(12),
152         INTSRC(13),
153         INTSRC(14),
154         INTSRC(15),
155 };
156
157 CTASSERT(sizeof(atintrs) / sizeof(atintrs[0]) == NUM_ISA_IRQS);
158
159 static __inline void
160 _atpic_eoi_master(struct intsrc *isrc)
161 {
162
163         KASSERT(isrc->is_pic == &atpics[MASTER].at_pic,
164             ("%s: mismatched pic", __func__));
165 #ifndef AUTO_EOI_1
166         outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
167 #endif
168 }
169
170 /*
171  * The data sheet says no auto-EOI on slave, but it sometimes works.
172  * So, if AUTO_EOI_2 is enabled, we use it.
173  */
174 static __inline void
175 _atpic_eoi_slave(struct intsrc *isrc)
176 {
177
178         KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic,
179             ("%s: mismatched pic", __func__));
180 #ifndef AUTO_EOI_2
181         outb(atpics[SLAVE].at_ioaddr, OCW2_EOI);
182 #ifndef AUTO_EOI_1
183         outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
184 #endif
185 #endif
186 }
187
188 static void
189 atpic_enable_source(struct intsrc *isrc)
190 {
191         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
192         struct atpic *ap = (struct atpic *)isrc->is_pic;
193
194         spinlock_enter();
195         if (*ap->at_imen & IMEN_MASK(ai)) {
196                 *ap->at_imen &= ~IMEN_MASK(ai);
197                 outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
198         }
199         spinlock_exit();
200 }
201
202 static void
203 atpic_disable_source(struct intsrc *isrc, int eoi)
204 {
205         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
206         struct atpic *ap = (struct atpic *)isrc->is_pic;
207
208         spinlock_enter();
209         if (ai->at_trigger != INTR_TRIGGER_EDGE) {
210                 *ap->at_imen |= IMEN_MASK(ai);
211                 outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen);
212         }
213
214         /*
215          * Take care to call these functions directly instead of through
216          * a function pointer.  All of the referenced variables should
217          * still be hot in the cache.
218          */
219         if (eoi == PIC_EOI) {
220                 if (isrc->is_pic == &atpics[MASTER].at_pic)
221                         _atpic_eoi_master(isrc);
222                 else
223                         _atpic_eoi_slave(isrc);
224         }
225
226         spinlock_exit();
227 }
228
229 static void
230 atpic_eoi_master(struct intsrc *isrc)
231 {
232 #ifndef AUTO_EOI_1
233         spinlock_enter();
234         _atpic_eoi_master(isrc);
235         spinlock_exit();
236 #endif
237 }
238
239 static void
240 atpic_eoi_slave(struct intsrc *isrc)
241 {
242 #ifndef AUTO_EOI_2
243         spinlock_enter();
244         _atpic_eoi_slave(isrc);
245         spinlock_exit();
246 #endif
247 }
248
249 static void
250 atpic_enable_intr(struct intsrc *isrc)
251 {
252 }
253
254 static void
255 atpic_disable_intr(struct intsrc *isrc)
256 {
257 }
258
259
260 static int
261 atpic_vector(struct intsrc *isrc)
262 {
263         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
264         struct atpic *ap = (struct atpic *)isrc->is_pic;
265
266         return (IRQ(ap, ai));
267 }
268
269 static int
270 atpic_source_pending(struct intsrc *isrc)
271 {
272         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
273         struct atpic *ap = (struct atpic *)isrc->is_pic;
274
275         return (inb(ap->at_ioaddr) & IMEN_MASK(ai));
276 }
277
278 static void
279 atpic_resume(struct pic *pic, bool suspend_cancelled)
280 {
281         struct atpic *ap = (struct atpic *)pic;
282
283         i8259_init(ap, ap == &atpics[SLAVE]);
284 #ifndef PC98
285         if (ap == &atpics[SLAVE] && elcr_found)
286                 elcr_resume();
287 #endif
288 }
289
290 static int
291 atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
292     enum intr_polarity pol)
293 {
294         struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
295         u_int vector;
296
297         /* Map conforming values to edge/hi and sanity check the values. */
298         if (trig == INTR_TRIGGER_CONFORM)
299                 trig = INTR_TRIGGER_EDGE;
300         if (pol == INTR_POLARITY_CONFORM)
301                 pol = INTR_POLARITY_HIGH;
302         vector = atpic_vector(isrc);
303         if ((trig == INTR_TRIGGER_EDGE && pol == INTR_POLARITY_LOW) ||
304             (trig == INTR_TRIGGER_LEVEL && pol == INTR_POLARITY_HIGH)) {
305                 printf(
306                 "atpic: Mismatched config for IRQ%u: trigger %s, polarity %s\n",
307                     vector, trig == INTR_TRIGGER_EDGE ? "edge" : "level",
308                     pol == INTR_POLARITY_HIGH ? "high" : "low");
309                 return (EINVAL);
310         }
311
312         /* If there is no change, just return. */
313         if (ai->at_trigger == trig)
314                 return (0);
315
316 #ifdef PC98
317         if ((vector == 0 || vector == 1 || vector == 7 || vector == 8) &&
318             trig == INTR_TRIGGER_LEVEL) {
319                 if (bootverbose)
320                         printf(
321                 "atpic: Ignoring invalid level/low configuration for IRQ%u\n",
322                             vector);
323                 return (EINVAL);
324         }
325         return (ENXIO);
326 #else
327         /*
328          * Certain IRQs can never be level/lo, so don't try to set them
329          * that way if asked.  At least some ELCR registers ignore setting
330          * these bits as well.
331          */
332         if ((vector == 0 || vector == 1 || vector == 2 || vector == 13) &&
333             trig == INTR_TRIGGER_LEVEL) {
334                 if (bootverbose)
335                         printf(
336                 "atpic: Ignoring invalid level/low configuration for IRQ%u\n",
337                             vector);
338                 return (EINVAL);
339         }
340         if (!elcr_found) {
341                 if (bootverbose)
342                         printf("atpic: No ELCR to configure IRQ%u as %s\n",
343                             vector, trig == INTR_TRIGGER_EDGE ? "edge/high" :
344                             "level/low");
345                 return (ENXIO);
346         }
347         if (bootverbose)
348                 printf("atpic: Programming IRQ%u as %s\n", vector,
349                     trig == INTR_TRIGGER_EDGE ? "edge/high" : "level/low");
350         spinlock_enter();
351         elcr_write_trigger(atpic_vector(isrc), trig);
352         ai->at_trigger = trig;
353         spinlock_exit();
354         return (0);
355 #endif /* PC98 */
356 }
357
358 static int
359 atpic_assign_cpu(struct intsrc *isrc, u_int apic_id)
360 {
361
362         /*
363          * 8259A's are only used in UP in which case all interrupts always
364          * go to the sole CPU and this function shouldn't even be called.
365          */
366         panic("%s: bad cookie", __func__);
367 }
368
369 static void
370 i8259_init(struct atpic *pic, int slave)
371 {
372         int imr_addr;
373
374         /* Reset the PIC and program with next four bytes. */
375         spinlock_enter();
376 #ifdef DEV_MCA
377         /* MCA uses level triggered interrupts. */
378         if (MCA_system)
379                 outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4 | ICW1_LTIM);
380         else
381 #endif
382                 outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4);
383         imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET;
384
385         /* Start vector. */
386         outb(imr_addr, pic->at_intbase);
387
388         /*
389          * Setup slave links.  For the master pic, indicate what line
390          * the slave is configured on.  For the slave indicate
391          * which line on the master we are connected to.
392          */
393         if (slave)
394                 outb(imr_addr, ICU_SLAVEID);
395         else
396                 outb(imr_addr, IRQ_MASK(ICU_SLAVEID));
397
398         /* Set mode. */
399         if (slave)
400                 outb(imr_addr, SLAVE_MODE);
401         else
402                 outb(imr_addr, MASTER_MODE);
403
404         /* Set interrupt enable mask. */
405         outb(imr_addr, *pic->at_imen);
406
407         /* Reset is finished, default to IRR on read. */
408         outb(pic->at_ioaddr, OCW3_SEL | OCW3_RR);
409
410 #ifndef PC98
411         /* OCW2_L1 sets priority order to 3-7, 0-2 (com2 first). */
412         if (!slave)
413                 outb(pic->at_ioaddr, OCW2_R | OCW2_SL | OCW2_L1);
414 #endif
415         spinlock_exit();
416 }
417
418 void
419 atpic_startup(void)
420 {
421         struct atpic_intsrc *ai;
422         int i;
423
424         /* Start off with all interrupts disabled. */
425         imen = 0xffff;
426         i8259_init(&atpics[MASTER], 0);
427         i8259_init(&atpics[SLAVE], 1);
428         atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
429
430         /* Install low-level interrupt handlers for all of our IRQs. */
431         for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
432                 if (i == ICU_SLAVEID)
433                         continue;
434                 ai->at_intsrc.is_count = &ai->at_count;
435                 ai->at_intsrc.is_straycount = &ai->at_straycount;
436                 setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase +
437                     ai->at_irq, ai->at_intr, SDT_ATPIC, SEL_KPL, GSEL_ATPIC);
438         }
439
440 #ifdef DEV_MCA
441         /* For MCA systems, all interrupts are level triggered. */
442         if (MCA_system)
443                 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
444                         ai->at_trigger = INTR_TRIGGER_LEVEL;
445         else
446 #endif
447
448 #ifdef PC98
449         for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
450                 switch (i) {
451                 case 0:
452                 case 1:
453                 case 7:
454                 case 8:
455                         ai->at_trigger = INTR_TRIGGER_EDGE;
456                         break;
457                 default:
458                         ai->at_trigger = INTR_TRIGGER_LEVEL;
459                         break;
460                 }
461 #else
462         /*
463          * Look for an ELCR.  If we find one, update the trigger modes.
464          * If we don't find one, assume that IRQs 0, 1, 2, and 13 are
465          * edge triggered and that everything else is level triggered.
466          * We only use the trigger information to reprogram the ELCR if
467          * we have one and as an optimization to avoid masking edge
468          * triggered interrupts.  For the case that we don't have an ELCR,
469          * it doesn't hurt to mask an edge triggered interrupt, so we
470          * assume level trigger for any interrupt that we aren't sure is
471          * edge triggered.
472          */
473         if (elcr_found) {
474                 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
475                         ai->at_trigger = elcr_read_trigger(i);
476         } else {
477                 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
478                         switch (i) {
479                         case 0:
480                         case 1:
481                         case 2:
482                         case 8:
483                         case 13:
484                                 ai->at_trigger = INTR_TRIGGER_EDGE;
485                                 break;
486                         default:
487                                 ai->at_trigger = INTR_TRIGGER_LEVEL;
488                                 break;
489                         }
490         }
491 #endif /* PC98 */
492 }
493
494 static void
495 atpic_init(void *dummy __unused)
496 {
497         struct atpic_intsrc *ai;
498         int i;
499
500         /*
501          * Register our PICs, even if we aren't going to use any of their
502          * pins so that they are suspended and resumed.
503          */
504         if (intr_register_pic(&atpics[0].at_pic) != 0 ||
505             intr_register_pic(&atpics[1].at_pic) != 0)
506                 panic("Unable to register ATPICs");
507
508         /*
509          * If any of the ISA IRQs have an interrupt source already, then
510          * assume that the APICs are being used and don't register any
511          * of our interrupt sources.  This makes sure we don't accidentally
512          * use mixed mode.  The "accidental" use could otherwise occur on
513          * machines that route the ACPI SCI interrupt to a different ISA
514          * IRQ (at least one machines routes it to IRQ 13) thus disabling
515          * that APIC ISA routing and allowing the ATPIC source for that IRQ
516          * to leak through.  We used to depend on this feature for routing
517          * IRQ0 via mixed mode, but now we don't use mixed mode at all.
518          */
519         for (i = 0; i < NUM_ISA_IRQS; i++)
520                 if (intr_lookup_source(i) != NULL)
521                         return;
522
523         /* Loop through all interrupt sources and add them. */
524         for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
525                 if (i == ICU_SLAVEID)
526                         continue;
527                 intr_register_source(&ai->at_intsrc);
528         }
529 }
530 SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL);
531
532 void
533 atpic_handle_intr(u_int vector, struct trapframe *frame)
534 {
535         struct intsrc *isrc;
536
537         KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector));
538         isrc = &atintrs[vector].at_intsrc;
539
540         /*
541          * If we don't have an event, see if this is a spurious
542          * interrupt.
543          */
544         if (isrc->is_event == NULL && (vector == 7 || vector == 15)) {
545                 int port, isr;
546
547                 /*
548                  * Read the ISR register to see if IRQ 7/15 is really
549                  * pending.  Reset read register back to IRR when done.
550                  */
551                 port = ((struct atpic *)isrc->is_pic)->at_ioaddr;
552                 spinlock_enter();
553                 outb(port, OCW3_SEL | OCW3_RR | OCW3_RIS);
554                 isr = inb(port);
555                 outb(port, OCW3_SEL | OCW3_RR);
556                 spinlock_exit();
557                 if ((isr & IRQ_MASK(7)) == 0)
558                         return;
559         }
560         intr_execute_handlers(isrc, frame);
561 }
562
563 #ifdef DEV_ISA
564 /*
565  * Bus attachment for the ISA PIC.
566  */
567 static struct isa_pnp_id atpic_ids[] = {
568         { 0x0000d041 /* PNP0000 */, "AT interrupt controller" },
569         { 0 }
570 };
571
572 static int
573 atpic_probe(device_t dev)
574 {
575         int result;
576         
577         result = ISA_PNP_PROBE(device_get_parent(dev), dev, atpic_ids);
578         if (result <= 0)
579                 device_quiet(dev);
580         return (result);
581 }
582
583 /*
584  * We might be granted IRQ 2, as this is typically consumed by chaining
585  * between the two PIC components.  If we're using the APIC, however,
586  * this may not be the case, and as such we should free the resource.
587  * (XXX untested)
588  *
589  * The generic ISA attachment code will handle allocating any other resources
590  * that we don't explicitly claim here.
591  */
592 static int
593 atpic_attach(device_t dev)
594 {
595         struct resource *res;
596         int rid;
597
598         /* Try to allocate our IRQ and then free it. */
599         rid = 0;
600         res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0);
601         if (res != NULL)
602                 bus_release_resource(dev, SYS_RES_IRQ, rid, res);
603         return (0);
604 }
605
606 static device_method_t atpic_methods[] = {
607         /* Device interface */
608         DEVMETHOD(device_probe,         atpic_probe),
609         DEVMETHOD(device_attach,        atpic_attach),
610         DEVMETHOD(device_detach,        bus_generic_detach),
611         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
612         DEVMETHOD(device_suspend,       bus_generic_suspend),
613         DEVMETHOD(device_resume,        bus_generic_resume),
614         { 0, 0 }
615 };
616
617 static driver_t atpic_driver = {
618         "atpic",
619         atpic_methods,
620         1,              /* no softc */
621 };
622
623 static devclass_t atpic_devclass;
624
625 DRIVER_MODULE(atpic, isa, atpic_driver, atpic_devclass, 0, 0);
626 #ifndef PC98
627 DRIVER_MODULE(atpic, acpi, atpic_driver, atpic_devclass, 0, 0);
628 #endif
629
630 /*
631  * Return a bitmap of the current interrupt requests.  This is 8259-specific
632  * and is only suitable for use at probe time.
633  */
634 intrmask_t
635 isa_irq_pending(void)
636 {
637         u_char irr1;
638         u_char irr2;
639
640         irr1 = inb(IO_ICU1);
641         irr2 = inb(IO_ICU2);
642         return ((irr2 << 8) | irr1);
643 }
644 #endif /* DEV_ISA */