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