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