2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * PIC driver for the 8259A Master and Slave PICs in PC/AT machines.
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
35 #include "opt_auto_eoi.h"
38 #include <sys/param.h>
39 #include <sys/systm.h>
42 #include <sys/interrupt.h>
43 #include <sys/kernel.h>
45 #include <sys/module.h>
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>
55 #include <dev/ic/i8259.h>
56 #include <x86/isa/icu.h>
57 #include <isa/isareg.h>
58 #include <isa/isavar.h>
61 #define SDT_ATPIC SDT_SYSIGT
64 #define SDT_ATPIC SDT_SYS386IGT
65 #define GSEL_ATPIC GSEL(GCODE_SEL, SEL_KPL)
71 #define IMEN_MASK(ai) (IRQ_MASK((ai)->at_irq))
73 #define NUM_ISA_IRQS 16
75 static void atpic_init(void *dummy);
78 IDTVEC(atpic_intr0), IDTVEC(atpic_intr1), IDTVEC(atpic_intr2),
79 IDTVEC(atpic_intr3), IDTVEC(atpic_intr4), IDTVEC(atpic_intr5),
80 IDTVEC(atpic_intr6), IDTVEC(atpic_intr7), IDTVEC(atpic_intr8),
81 IDTVEC(atpic_intr9), IDTVEC(atpic_intr10), IDTVEC(atpic_intr11),
82 IDTVEC(atpic_intr12), IDTVEC(atpic_intr13), IDTVEC(atpic_intr14),
84 /* XXXKIB i386 uses stubs until pti comes */
86 IDTVEC(atpic_intr0_pti), IDTVEC(atpic_intr1_pti),
87 IDTVEC(atpic_intr2_pti), IDTVEC(atpic_intr3_pti),
88 IDTVEC(atpic_intr4_pti), IDTVEC(atpic_intr5_pti),
89 IDTVEC(atpic_intr6_pti), IDTVEC(atpic_intr7_pti),
90 IDTVEC(atpic_intr8_pti), IDTVEC(atpic_intr9_pti),
91 IDTVEC(atpic_intr10_pti), IDTVEC(atpic_intr11_pti),
92 IDTVEC(atpic_intr12_pti), IDTVEC(atpic_intr13_pti),
93 IDTVEC(atpic_intr14_pti), IDTVEC(atpic_intr15_pti);
95 #define IRQ(ap, ai) ((ap)->at_irqbase + (ai)->at_irq)
97 #define ATPIC(io, base, eoi) { \
99 .pic_register_sources = atpic_register_sources, \
100 .pic_enable_source = atpic_enable_source, \
101 .pic_disable_source = atpic_disable_source, \
102 .pic_eoi_source = (eoi), \
103 .pic_enable_intr = atpic_enable_intr, \
104 .pic_disable_intr = atpic_disable_intr, \
105 .pic_vector = atpic_vector, \
106 .pic_source_pending = atpic_source_pending, \
107 .pic_resume = atpic_resume, \
108 .pic_config_intr = atpic_config_intr, \
109 .pic_assign_cpu = atpic_assign_cpu \
112 .at_irqbase = (base), \
113 .at_intbase = IDT_IO_INTS + (base), \
117 #define INTSRC(irq) \
118 { { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ), \
119 IDTVEC(atpic_intr ## irq ## _pti), (irq) % 8 }
129 struct atpic_intsrc {
130 struct intsrc at_intsrc;
131 inthand_t *at_intr, *at_intr_pti;
132 int at_irq; /* Relative to PIC base. */
133 enum intr_trigger at_trigger;
135 u_long at_straycount;
138 static void atpic_register_sources(struct pic *pic);
139 static void atpic_enable_source(struct intsrc *isrc);
140 static void atpic_disable_source(struct intsrc *isrc, int eoi);
141 static void atpic_eoi_master(struct intsrc *isrc);
142 static void atpic_eoi_slave(struct intsrc *isrc);
143 static void atpic_enable_intr(struct intsrc *isrc);
144 static void atpic_disable_intr(struct intsrc *isrc);
145 static int atpic_vector(struct intsrc *isrc);
146 static void atpic_resume(struct pic *pic, bool suspend_cancelled);
147 static int atpic_source_pending(struct intsrc *isrc);
148 static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
149 enum intr_polarity pol);
150 static int atpic_assign_cpu(struct intsrc *isrc, u_int apic_id);
151 static void i8259_init(struct atpic *pic, int slave);
153 static struct atpic atpics[] = {
154 ATPIC(IO_ICU1, 0, atpic_eoi_master),
155 ATPIC(IO_ICU2, 8, atpic_eoi_slave)
158 static struct atpic_intsrc atintrs[] = {
177 CTASSERT(nitems(atintrs) == NUM_ISA_IRQS);
180 _atpic_eoi_master(struct intsrc *isrc)
183 KASSERT(isrc->is_pic == &atpics[MASTER].at_pic,
184 ("%s: mismatched pic", __func__));
186 outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
191 * The data sheet says no auto-EOI on slave, but it sometimes works.
192 * So, if AUTO_EOI_2 is enabled, we use it.
195 _atpic_eoi_slave(struct intsrc *isrc)
198 KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic,
199 ("%s: mismatched pic", __func__));
201 outb(atpics[SLAVE].at_ioaddr, OCW2_EOI);
203 outb(atpics[MASTER].at_ioaddr, OCW2_EOI);
209 atpic_register_sources(struct pic *pic)
211 struct atpic *ap = (struct atpic *)pic;
212 struct atpic_intsrc *ai;
216 * If any of the ISA IRQs have an interrupt source already, then
217 * assume that the I/O APICs are being used and don't register any
218 * of our interrupt sources. This makes sure we don't accidentally
219 * use mixed mode. The "accidental" use could otherwise occur on
220 * machines that route the ACPI SCI interrupt to a different ISA
221 * IRQ (at least one machine routes it to IRQ 13) thus disabling
222 * that APIC ISA routing and allowing the ATPIC source for that IRQ
223 * to leak through. We used to depend on this feature for routing
224 * IRQ0 via mixed mode, but now we don't use mixed mode at all.
226 * To avoid the slave not register sources after the master
227 * registers its sources, register all IRQs when this function is
228 * called on the master.
230 if (ap != &atpics[MASTER])
232 for (i = 0; i < NUM_ISA_IRQS; i++)
233 if (intr_lookup_source(i) != NULL)
236 /* Loop through all interrupt sources and add them. */
237 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
238 if (i == ICU_SLAVEID)
240 intr_register_source(&ai->at_intsrc);
245 atpic_enable_source(struct intsrc *isrc)
247 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
248 struct atpic *ap = (struct atpic *)isrc->is_pic;
251 if (ap->at_imen & IMEN_MASK(ai)) {
252 ap->at_imen &= ~IMEN_MASK(ai);
253 outb(ap->at_ioaddr + ICU_IMR_OFFSET, ap->at_imen);
259 atpic_disable_source(struct intsrc *isrc, int eoi)
261 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
262 struct atpic *ap = (struct atpic *)isrc->is_pic;
265 if (ai->at_trigger != INTR_TRIGGER_EDGE) {
266 ap->at_imen |= IMEN_MASK(ai);
267 outb(ap->at_ioaddr + ICU_IMR_OFFSET, ap->at_imen);
271 * Take care to call these functions directly instead of through
272 * a function pointer. All of the referenced variables should
273 * still be hot in the cache.
275 if (eoi == PIC_EOI) {
276 if (isrc->is_pic == &atpics[MASTER].at_pic)
277 _atpic_eoi_master(isrc);
279 _atpic_eoi_slave(isrc);
286 atpic_eoi_master(struct intsrc *isrc)
290 _atpic_eoi_master(isrc);
296 atpic_eoi_slave(struct intsrc *isrc)
300 _atpic_eoi_slave(isrc);
306 atpic_enable_intr(struct intsrc *isrc)
311 atpic_disable_intr(struct intsrc *isrc)
316 atpic_vector(struct intsrc *isrc)
318 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
319 struct atpic *ap = (struct atpic *)isrc->is_pic;
321 return (IRQ(ap, ai));
325 atpic_source_pending(struct intsrc *isrc)
327 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
328 struct atpic *ap = (struct atpic *)isrc->is_pic;
330 return (inb(ap->at_ioaddr) & IMEN_MASK(ai));
334 atpic_resume(struct pic *pic, bool suspend_cancelled)
336 struct atpic *ap = (struct atpic *)pic;
338 i8259_init(ap, ap == &atpics[SLAVE]);
339 if (ap == &atpics[SLAVE] && elcr_found)
344 atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
345 enum intr_polarity pol)
347 struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
350 /* Map conforming values to edge/hi and sanity check the values. */
351 if (trig == INTR_TRIGGER_CONFORM)
352 trig = INTR_TRIGGER_EDGE;
353 if (pol == INTR_POLARITY_CONFORM)
354 pol = INTR_POLARITY_HIGH;
355 vector = atpic_vector(isrc);
356 if ((trig == INTR_TRIGGER_EDGE && pol == INTR_POLARITY_LOW) ||
357 (trig == INTR_TRIGGER_LEVEL && pol == INTR_POLARITY_HIGH)) {
359 "atpic: Mismatched config for IRQ%u: trigger %s, polarity %s\n",
360 vector, trig == INTR_TRIGGER_EDGE ? "edge" : "level",
361 pol == INTR_POLARITY_HIGH ? "high" : "low");
365 /* If there is no change, just return. */
366 if (ai->at_trigger == trig)
370 * Certain IRQs can never be level/lo, so don't try to set them
371 * that way if asked. At least some ELCR registers ignore setting
372 * these bits as well.
374 if ((vector == 0 || vector == 1 || vector == 2 || vector == 13) &&
375 trig == INTR_TRIGGER_LEVEL) {
378 "atpic: Ignoring invalid level/low configuration for IRQ%u\n",
384 printf("atpic: No ELCR to configure IRQ%u as %s\n",
385 vector, trig == INTR_TRIGGER_EDGE ? "edge/high" :
390 printf("atpic: Programming IRQ%u as %s\n", vector,
391 trig == INTR_TRIGGER_EDGE ? "edge/high" : "level/low");
393 elcr_write_trigger(atpic_vector(isrc), trig);
394 ai->at_trigger = trig;
400 atpic_assign_cpu(struct intsrc *isrc, u_int apic_id)
404 * 8259A's are only used in UP in which case all interrupts always
405 * go to the sole CPU and this function shouldn't even be called.
407 panic("%s: bad cookie", __func__);
411 i8259_init(struct atpic *pic, int slave)
415 /* Reset the PIC and program with next four bytes. */
417 outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4);
418 imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET;
421 outb(imr_addr, pic->at_intbase);
424 * Setup slave links. For the master pic, indicate what line
425 * the slave is configured on. For the slave indicate
426 * which line on the master we are connected to.
429 outb(imr_addr, ICU_SLAVEID);
431 outb(imr_addr, IRQ_MASK(ICU_SLAVEID));
435 outb(imr_addr, SLAVE_MODE);
437 outb(imr_addr, MASTER_MODE);
439 /* Set interrupt enable mask. */
440 outb(imr_addr, pic->at_imen);
442 /* Reset is finished, default to IRR on read. */
443 outb(pic->at_ioaddr, OCW3_SEL | OCW3_RR);
445 /* OCW2_L1 sets priority order to 3-7, 0-2 (com2 first). */
447 outb(pic->at_ioaddr, OCW2_R | OCW2_SL | OCW2_L1);
455 struct atpic_intsrc *ai;
458 /* Start off with all interrupts disabled. */
459 i8259_init(&atpics[MASTER], 0);
460 i8259_init(&atpics[SLAVE], 1);
461 atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
463 /* Install low-level interrupt handlers for all of our IRQs. */
464 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
465 if (i == ICU_SLAVEID)
467 ai->at_intsrc.is_count = &ai->at_count;
468 ai->at_intsrc.is_straycount = &ai->at_straycount;
469 setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase +
470 ai->at_irq, pti ? ai->at_intr_pti : ai->at_intr, SDT_ATPIC,
471 SEL_KPL, GSEL_ATPIC);
475 * Look for an ELCR. If we find one, update the trigger modes.
476 * If we don't find one, assume that IRQs 0, 1, 2, and 13 are
477 * edge triggered and that everything else is level triggered.
478 * We only use the trigger information to reprogram the ELCR if
479 * we have one and as an optimization to avoid masking edge
480 * triggered interrupts. For the case that we don't have an ELCR,
481 * it doesn't hurt to mask an edge triggered interrupt, so we
482 * assume level trigger for any interrupt that we aren't sure is
486 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
487 ai->at_trigger = elcr_read_trigger(i);
489 for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
496 ai->at_trigger = INTR_TRIGGER_EDGE;
499 ai->at_trigger = INTR_TRIGGER_LEVEL;
506 atpic_init(void *dummy __unused)
510 * Register our PICs, even if we aren't going to use any of their
511 * pins so that they are suspended and resumed.
513 if (intr_register_pic(&atpics[0].at_pic) != 0 ||
514 intr_register_pic(&atpics[1].at_pic) != 0)
515 panic("Unable to register ATPICs");
517 if (num_io_irqs == 0)
518 num_io_irqs = NUM_ISA_IRQS;
520 SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_FOURTH, atpic_init, NULL);
523 atpic_handle_intr(u_int vector, struct trapframe *frame)
527 kasan_mark(frame, sizeof(*frame), sizeof(*frame), 0);
528 kmsan_mark(frame, sizeof(*frame), KMSAN_STATE_INITED);
531 KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector));
532 isrc = &atintrs[vector].at_intsrc;
535 * If we don't have an event, see if this is a spurious
538 if (isrc->is_event == NULL && (vector == 7 || vector == 15)) {
542 * Read the ISR register to see if IRQ 7/15 is really
543 * pending. Reset read register back to IRR when done.
545 port = ((struct atpic *)isrc->is_pic)->at_ioaddr;
547 outb(port, OCW3_SEL | OCW3_RR | OCW3_RIS);
549 outb(port, OCW3_SEL | OCW3_RR);
551 if ((isr & IRQ_MASK(7)) == 0)
554 intr_execute_handlers(isrc, frame);
559 * Bus attachment for the ISA PIC.
561 static struct isa_pnp_id atpic_ids[] = {
562 { 0x0000d041 /* PNP0000 */, "AT interrupt controller" },
567 atpic_probe(device_t dev)
571 result = ISA_PNP_PROBE(device_get_parent(dev), dev, atpic_ids);
578 * We might be granted IRQ 2, as this is typically consumed by chaining
579 * between the two PIC components. If we're using the APIC, however,
580 * this may not be the case, and as such we should free the resource.
583 * The generic ISA attachment code will handle allocating any other resources
584 * that we don't explicitly claim here.
587 atpic_attach(device_t dev)
589 struct resource *res;
592 /* Try to allocate our IRQ and then free it. */
594 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0);
596 bus_release_resource(dev, SYS_RES_IRQ, rid, res);
600 static device_method_t atpic_methods[] = {
601 /* Device interface */
602 DEVMETHOD(device_probe, atpic_probe),
603 DEVMETHOD(device_attach, atpic_attach),
604 DEVMETHOD(device_detach, bus_generic_detach),
605 DEVMETHOD(device_shutdown, bus_generic_shutdown),
606 DEVMETHOD(device_suspend, bus_generic_suspend),
607 DEVMETHOD(device_resume, bus_generic_resume),
611 static driver_t atpic_driver = {
617 DRIVER_MODULE(atpic, isa, atpic_driver, 0, 0);
618 DRIVER_MODULE(atpic, acpi, atpic_driver, 0, 0);
619 ISA_PNP_INFO(atpic_ids);