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