1351290Sdim/*-
2351290Sdim * Copyright (c) 2003 John Baldwin <jhb@FreeBSD.org>
3351290Sdim * All rights reserved.
4351290Sdim *
5351290Sdim * Redistribution and use in source and binary forms, with or without
6351290Sdim * modification, are permitted provided that the following conditions
7351290Sdim * are met:
8351290Sdim * 1. Redistributions of source code must retain the above copyright
9351290Sdim *    notice, this list of conditions and the following disclaimer.
10351290Sdim * 2. Redistributions in binary form must reproduce the above copyright
11351290Sdim *    notice, this list of conditions and the following disclaimer in the
12351290Sdim *    documentation and/or other materials provided with the distribution.
13351290Sdim *
14351290Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15351290Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16351290Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17351290Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18351290Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19351290Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20351290Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21351290Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22351290Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23351290Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24351290Sdim * SUCH DAMAGE.
25351290Sdim */
26351290Sdim
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#ifdef PC98
55#include <pc98/cbus/cbus.h>
56#else
57#include <x86/isa/isa.h>
58#endif
59#include <isa/isavar.h>
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
74static void	atpic_init(void *dummy);
75
76unsigned int imen;	/* XXX */
77
78inthand_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
99struct 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
107struct 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
116static void atpic_enable_source(struct intsrc *isrc);
117static void atpic_disable_source(struct intsrc *isrc, int eoi);
118static void atpic_eoi_master(struct intsrc *isrc);
119static void atpic_eoi_slave(struct intsrc *isrc);
120static void atpic_enable_intr(struct intsrc *isrc);
121static void atpic_disable_intr(struct intsrc *isrc);
122static int atpic_vector(struct intsrc *isrc);
123static void atpic_resume(struct pic *pic);
124static int atpic_source_pending(struct intsrc *isrc);
125static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
126    enum intr_polarity pol);
127static int atpic_assign_cpu(struct intsrc *isrc, u_int apic_id);
128static void i8259_init(struct atpic *pic, int slave);
129
130static 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
135static 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
154CTASSERT(sizeof(atintrs) / sizeof(atintrs[0]) == NUM_ISA_IRQS);
155
156static __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 */
171static __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
185static void
186atpic_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
199static void
200atpic_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
226static void
227atpic_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
236static void
237atpic_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
246static void
247atpic_enable_intr(struct intsrc *isrc)
248{
249}
250
251static void
252atpic_disable_intr(struct intsrc *isrc)
253{
254}
255
256
257static int
258atpic_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
266static int
267atpic_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
275static void
276atpic_resume(struct pic *pic)
277{
278	struct atpic *ap = (struct atpic *)pic;
279
280	i8259_init(ap, ap == &atpics[SLAVE]);
281#ifndef PC98
282	if (ap == &atpics[SLAVE] && elcr_found)
283		elcr_resume();
284#endif
285}
286
287static int
288atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
289    enum intr_polarity pol)
290{
291	struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc;
292	u_int vector;
293
294	/* Map conforming values to edge/hi and sanity check the values. */
295	if (trig == INTR_TRIGGER_CONFORM)
296		trig = INTR_TRIGGER_EDGE;
297	if (pol == INTR_POLARITY_CONFORM)
298		pol = INTR_POLARITY_HIGH;
299	vector = atpic_vector(isrc);
300	if ((trig == INTR_TRIGGER_EDGE && pol == INTR_POLARITY_LOW) ||
301	    (trig == INTR_TRIGGER_LEVEL && pol == INTR_POLARITY_HIGH)) {
302		printf(
303		"atpic: Mismatched config for IRQ%u: trigger %s, polarity %s\n",
304		    vector, trig == INTR_TRIGGER_EDGE ? "edge" : "level",
305		    pol == INTR_POLARITY_HIGH ? "high" : "low");
306		return (EINVAL);
307	}
308
309	/* If there is no change, just return. */
310	if (ai->at_trigger == trig)
311		return (0);
312
313#ifdef PC98
314	if ((vector == 0 || vector == 1 || vector == 7 || vector == 8) &&
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	return (ENXIO);
323#else
324	/*
325	 * Certain IRQs can never be level/lo, so don't try to set them
326	 * that way if asked.  At least some ELCR registers ignore setting
327	 * these bits as well.
328	 */
329	if ((vector == 0 || vector == 1 || vector == 2 || vector == 13) &&
330	    trig == INTR_TRIGGER_LEVEL) {
331		if (bootverbose)
332			printf(
333		"atpic: Ignoring invalid level/low configuration for IRQ%u\n",
334			    vector);
335		return (EINVAL);
336	}
337	if (!elcr_found) {
338		if (bootverbose)
339			printf("atpic: No ELCR to configure IRQ%u as %s\n",
340			    vector, trig == INTR_TRIGGER_EDGE ? "edge/high" :
341			    "level/low");
342		return (ENXIO);
343	}
344	if (bootverbose)
345		printf("atpic: Programming IRQ%u as %s\n", vector,
346		    trig == INTR_TRIGGER_EDGE ? "edge/high" : "level/low");
347	spinlock_enter();
348	elcr_write_trigger(atpic_vector(isrc), trig);
349	ai->at_trigger = trig;
350	spinlock_exit();
351	return (0);
352#endif /* PC98 */
353}
354
355static int
356atpic_assign_cpu(struct intsrc *isrc, u_int apic_id)
357{
358
359	/*
360	 * 8259A's are only used in UP in which case all interrupts always
361	 * go to the sole CPU and this function shouldn't even be called.
362	 */
363	panic("%s: bad cookie", __func__);
364}
365
366static void
367i8259_init(struct atpic *pic, int slave)
368{
369	int imr_addr;
370
371	/* Reset the PIC and program with next four bytes. */
372	spinlock_enter();
373#ifdef DEV_MCA
374	/* MCA uses level triggered interrupts. */
375	if (MCA_system)
376		outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4 | ICW1_LTIM);
377	else
378#endif
379		outb(pic->at_ioaddr, ICW1_RESET | ICW1_IC4);
380	imr_addr = pic->at_ioaddr + ICU_IMR_OFFSET;
381
382	/* Start vector. */
383	outb(imr_addr, pic->at_intbase);
384
385	/*
386	 * Setup slave links.  For the master pic, indicate what line
387	 * the slave is configured on.  For the slave indicate
388	 * which line on the master we are connected to.
389	 */
390	if (slave)
391		outb(imr_addr, ICU_SLAVEID);
392	else
393		outb(imr_addr, IRQ_MASK(ICU_SLAVEID));
394
395	/* Set mode. */
396	if (slave)
397		outb(imr_addr, SLAVE_MODE);
398	else
399		outb(imr_addr, MASTER_MODE);
400
401	/* Set interrupt enable mask. */
402	outb(imr_addr, *pic->at_imen);
403
404	/* Reset is finished, default to IRR on read. */
405	outb(pic->at_ioaddr, OCW3_SEL | OCW3_RR);
406
407#ifndef PC98
408	/* OCW2_L1 sets priority order to 3-7, 0-2 (com2 first). */
409	if (!slave)
410		outb(pic->at_ioaddr, OCW2_R | OCW2_SL | OCW2_L1);
411#endif
412	spinlock_exit();
413}
414
415void
416atpic_startup(void)
417{
418	struct atpic_intsrc *ai;
419	int i;
420
421	/* Start off with all interrupts disabled. */
422	imen = 0xffff;
423	i8259_init(&atpics[MASTER], 0);
424	i8259_init(&atpics[SLAVE], 1);
425	atpic_enable_source((struct intsrc *)&atintrs[ICU_SLAVEID]);
426
427	/* Install low-level interrupt handlers for all of our IRQs. */
428	for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
429		if (i == ICU_SLAVEID)
430			continue;
431		ai->at_intsrc.is_count = &ai->at_count;
432		ai->at_intsrc.is_straycount = &ai->at_straycount;
433		setidt(((struct atpic *)ai->at_intsrc.is_pic)->at_intbase +
434		    ai->at_irq, ai->at_intr, SDT_ATPIC, SEL_KPL, GSEL_ATPIC);
435	}
436
437#ifdef DEV_MCA
438	/* For MCA systems, all interrupts are level triggered. */
439	if (MCA_system)
440		for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
441			ai->at_trigger = INTR_TRIGGER_LEVEL;
442	else
443#endif
444
445#ifdef PC98
446	for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
447		switch (i) {
448		case 0:
449		case 1:
450		case 7:
451		case 8:
452			ai->at_trigger = INTR_TRIGGER_EDGE;
453			break;
454		default:
455			ai->at_trigger = INTR_TRIGGER_LEVEL;
456			break;
457		}
458#else
459	/*
460	 * Look for an ELCR.  If we find one, update the trigger modes.
461	 * If we don't find one, assume that IRQs 0, 1, 2, and 13 are
462	 * edge triggered and that everything else is level triggered.
463	 * We only use the trigger information to reprogram the ELCR if
464	 * we have one and as an optimization to avoid masking edge
465	 * triggered interrupts.  For the case that we don't have an ELCR,
466	 * it doesn't hurt to mask an edge triggered interrupt, so we
467	 * assume level trigger for any interrupt that we aren't sure is
468	 * edge triggered.
469	 */
470	if (elcr_found) {
471		for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
472			ai->at_trigger = elcr_read_trigger(i);
473	} else {
474		for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++)
475			switch (i) {
476			case 0:
477			case 1:
478			case 2:
479			case 8:
480			case 13:
481				ai->at_trigger = INTR_TRIGGER_EDGE;
482				break;
483			default:
484				ai->at_trigger = INTR_TRIGGER_LEVEL;
485				break;
486			}
487	}
488#endif /* PC98 */
489}
490
491static void
492atpic_init(void *dummy __unused)
493{
494	struct atpic_intsrc *ai;
495	int i;
496
497	/*
498	 * Register our PICs, even if we aren't going to use any of their
499	 * pins so that they are suspended and resumed.
500	 */
501	if (intr_register_pic(&atpics[0].at_pic) != 0 ||
502	    intr_register_pic(&atpics[1].at_pic) != 0)
503		panic("Unable to register ATPICs");
504
505	/*
506	 * If any of the ISA IRQs have an interrupt source already, then
507	 * assume that the APICs are being used and don't register any
508	 * of our interrupt sources.  This makes sure we don't accidentally
509	 * use mixed mode.  The "accidental" use could otherwise occur on
510	 * machines that route the ACPI SCI interrupt to a different ISA
511	 * IRQ (at least one machines routes it to IRQ 13) thus disabling
512	 * that APIC ISA routing and allowing the ATPIC source for that IRQ
513	 * to leak through.  We used to depend on this feature for routing
514	 * IRQ0 via mixed mode, but now we don't use mixed mode at all.
515	 */
516	for (i = 0; i < NUM_ISA_IRQS; i++)
517		if (intr_lookup_source(i) != NULL)
518			return;
519
520	/* Loop through all interrupt sources and add them. */
521	for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
522		if (i == ICU_SLAVEID)
523			continue;
524		intr_register_source(&ai->at_intsrc);
525	}
526}
527SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL);
528
529void
530atpic_handle_intr(u_int vector, struct trapframe *frame)
531{
532	struct intsrc *isrc;
533
534	KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector));
535	isrc = &atintrs[vector].at_intsrc;
536
537	/*
538	 * If we don't have an event, see if this is a spurious
539	 * interrupt.
540	 */
541	if (isrc->is_event == NULL && (vector == 7 || vector == 15)) {
542		int port, isr;
543
544		/*
545		 * Read the ISR register to see if IRQ 7/15 is really
546		 * pending.  Reset read register back to IRR when done.
547		 */
548		port = ((struct atpic *)isrc->is_pic)->at_ioaddr;
549		spinlock_enter();
550		outb(port, OCW3_SEL | OCW3_RR | OCW3_RIS);
551		isr = inb(port);
552		outb(port, OCW3_SEL | OCW3_RR);
553		spinlock_exit();
554		if ((isr & IRQ_MASK(7)) == 0)
555			return;
556	}
557	intr_execute_handlers(isrc, frame);
558}
559
560#ifdef DEV_ISA
561/*
562 * Bus attachment for the ISA PIC.
563 */
564static struct isa_pnp_id atpic_ids[] = {
565	{ 0x0000d041 /* PNP0000 */, "AT interrupt controller" },
566	{ 0 }
567};
568
569static int
570atpic_probe(device_t dev)
571{
572	int result;
573
574	result = ISA_PNP_PROBE(device_get_parent(dev), dev, atpic_ids);
575	if (result <= 0)
576		device_quiet(dev);
577	return (result);
578}
579
580/*
581 * We might be granted IRQ 2, as this is typically consumed by chaining
582 * between the two PIC components.  If we're using the APIC, however,
583 * this may not be the case, and as such we should free the resource.
584 * (XXX untested)
585 *
586 * The generic ISA attachment code will handle allocating any other resources
587 * that we don't explicitly claim here.
588 */
589static int
590atpic_attach(device_t dev)
591{
592	struct resource *res;
593	int rid;
594
595	/* Try to allocate our IRQ and then free it. */
596	rid = 0;
597	res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0);
598	if (res != NULL)
599		bus_release_resource(dev, SYS_RES_IRQ, rid, res);
600	return (0);
601}
602
603static device_method_t atpic_methods[] = {
604	/* Device interface */
605	DEVMETHOD(device_probe,		atpic_probe),
606	DEVMETHOD(device_attach,	atpic_attach),
607	DEVMETHOD(device_detach,	bus_generic_detach),
608	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
609	DEVMETHOD(device_suspend,	bus_generic_suspend),
610	DEVMETHOD(device_resume,	bus_generic_resume),
611	{ 0, 0 }
612};
613
614static driver_t atpic_driver = {
615	"atpic",
616	atpic_methods,
617	1,		/* no softc */
618};
619
620static devclass_t atpic_devclass;
621
622DRIVER_MODULE(atpic, isa, atpic_driver, atpic_devclass, 0, 0);
623#ifndef PC98
624DRIVER_MODULE(atpic, acpi, atpic_driver, atpic_devclass, 0, 0);
625#endif
626
627/*
628 * Return a bitmap of the current interrupt requests.  This is 8259-specific
629 * and is only suitable for use at probe time.
630 */
631intrmask_t
632isa_irq_pending(void)
633{
634	u_char irr1;
635	u_char irr2;
636
637	irr1 = inb(IO_ICU1);
638	irr2 = inb(IO_ICU2);
639	return ((irr2 << 8) | irr1);
640}
641#endif /* DEV_ISA */
642