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