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