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