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