xref: /dflybsd-src/sys/platform/pc64/icu/icu.c (revision 2c64e990ea2bb1213bd0758af732469466873ba6)
11b505979SSepherosa Ziehau /*-
21b505979SSepherosa Ziehau  * Copyright (c) 1991 The Regents of the University of California.
31b505979SSepherosa Ziehau  * All rights reserved.
41b505979SSepherosa Ziehau  *
51b505979SSepherosa Ziehau  * This code is derived from software contributed to Berkeley by
61b505979SSepherosa Ziehau  * William Jolitz.
71b505979SSepherosa Ziehau  *
81b505979SSepherosa Ziehau  * Redistribution and use in source and binary forms, with or without
91b505979SSepherosa Ziehau  * modification, are permitted provided that the following conditions
101b505979SSepherosa Ziehau  * are met:
111b505979SSepherosa Ziehau  * 1. Redistributions of source code must retain the above copyright
121b505979SSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer.
131b505979SSepherosa Ziehau  * 2. Redistributions in binary form must reproduce the above copyright
141b505979SSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer in the
151b505979SSepherosa Ziehau  *    documentation and/or other materials provided with the distribution.
16*2c64e990Szrj  * 3. Neither the name of the University nor the names of its contributors
171b505979SSepherosa Ziehau  *    may be used to endorse or promote products derived from this software
181b505979SSepherosa Ziehau  *    without specific prior written permission.
191b505979SSepherosa Ziehau  *
201b505979SSepherosa Ziehau  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
211b505979SSepherosa Ziehau  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
221b505979SSepherosa Ziehau  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
231b505979SSepherosa Ziehau  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
241b505979SSepherosa Ziehau  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
251b505979SSepherosa Ziehau  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
261b505979SSepherosa Ziehau  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
271b505979SSepherosa Ziehau  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
281b505979SSepherosa Ziehau  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
291b505979SSepherosa Ziehau  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
301b505979SSepherosa Ziehau  * SUCH DAMAGE.
311b505979SSepherosa Ziehau  *
321b505979SSepherosa Ziehau  *	from: @(#)isa.c	7.2 (Berkeley) 5/13/91
331b505979SSepherosa Ziehau  * $FreeBSD: src/sys/i386/isa/intr_machdep.c,v 1.29.2.5 2001/10/14 06:54:27 luigi Exp $
341b505979SSepherosa Ziehau  * $DragonFly: src/sys/platform/pc32/isa/intr_machdep.c,v 1.48 2008/08/02 01:14:43 dillon Exp $
351b505979SSepherosa Ziehau  */
361b505979SSepherosa Ziehau /*
371b505979SSepherosa Ziehau  * This file contains an aggregated module marked:
381b505979SSepherosa Ziehau  * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
391b505979SSepherosa Ziehau  * All rights reserved.
401b505979SSepherosa Ziehau  * See the notice for details.
411b505979SSepherosa Ziehau  */
421b505979SSepherosa Ziehau 
431b505979SSepherosa Ziehau #include "opt_auto_eoi.h"
441b505979SSepherosa Ziehau 
451b505979SSepherosa Ziehau #include <sys/param.h>
461b505979SSepherosa Ziehau #include <sys/systm.h>
471b505979SSepherosa Ziehau #include <sys/machintr.h>
481b505979SSepherosa Ziehau #include <sys/interrupt.h>
493566408bSSepherosa Ziehau #include <sys/thread2.h>
50e10f5746SSepherosa Ziehau 
511b505979SSepherosa Ziehau #include <bus/isa/isareg.h>
521b505979SSepherosa Ziehau #include <cpu/cpufunc.h>
53e10f5746SSepherosa Ziehau 
5457a9c56bSSepherosa Ziehau #include <machine/intr_machdep.h>
551b505979SSepherosa Ziehau #include <machine_base/icu/icu.h>
561b505979SSepherosa Ziehau #include <machine_base/icu/icu_var.h>
57ed4d621dSSepherosa Ziehau #include <machine_base/apic/ioapic.h>
581b505979SSepherosa Ziehau 
591b505979SSepherosa Ziehau static void	icu_init(void);
601b505979SSepherosa Ziehau 
611b505979SSepherosa Ziehau static void
icu_init(void)621b505979SSepherosa Ziehau icu_init(void)
631b505979SSepherosa Ziehau {
641b505979SSepherosa Ziehau #ifdef AUTO_EOI_1
651b505979SSepherosa Ziehau 	int auto_eoi = 2;		/* auto EOI, 8086 mode */
661b505979SSepherosa Ziehau #else
671b505979SSepherosa Ziehau 	int auto_eoi = 0;		/* 8086 mode */
681b505979SSepherosa Ziehau #endif
691b505979SSepherosa Ziehau 
70f45bfca0SSepherosa Ziehau 	if (ioapic_enable)
711b505979SSepherosa Ziehau 		auto_eoi = 2;		/* auto EOI, 8086 mode */
721b505979SSepherosa Ziehau 
731b505979SSepherosa Ziehau 	/*
741b505979SSepherosa Ziehau 	 * Program master
751b505979SSepherosa Ziehau 	 */
761b505979SSepherosa Ziehau 	outb(IO_ICU1, 0x11);		/* reset; program device, four bytes */
771b505979SSepherosa Ziehau 	outb(IO_ICU1 + ICU_IMR_OFFSET, IDT_OFFSET);
781b505979SSepherosa Ziehau 					/* starting at this vector index */
791b505979SSepherosa Ziehau 	outb(IO_ICU1 + ICU_IMR_OFFSET, 1 << ICU_IRQ_SLAVE);
801b505979SSepherosa Ziehau 					/* slave on line 2 */
811b505979SSepherosa Ziehau 	outb(IO_ICU1 + ICU_IMR_OFFSET, auto_eoi | 1); /* 8086 mode */
821b505979SSepherosa Ziehau 
831b505979SSepherosa Ziehau 	outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff); /* leave interrupts masked */
841b505979SSepherosa Ziehau 	outb(IO_ICU1, 0x0a);		/* default to IRR on read */
851b505979SSepherosa Ziehau 	outb(IO_ICU1, 0xc0 | (3 - 1));	/* pri order 3-7, 0-2 (com2 first) */
861b505979SSepherosa Ziehau 
871b505979SSepherosa Ziehau 	/*
881b505979SSepherosa Ziehau 	 * Program slave
891b505979SSepherosa Ziehau 	 */
901b505979SSepherosa Ziehau 	outb(IO_ICU2, 0x11);		/* reset; program device, four bytes */
911b505979SSepherosa Ziehau 	outb(IO_ICU2 + ICU_IMR_OFFSET, IDT_OFFSET + 8);
921b505979SSepherosa Ziehau 					/* staring at this vector index */
931b505979SSepherosa Ziehau 	outb(IO_ICU2 + ICU_IMR_OFFSET, ICU_IRQ_SLAVE);
941b505979SSepherosa Ziehau #ifdef AUTO_EOI_2
951b505979SSepherosa Ziehau 	outb(IO_ICU2 + ICU_IMR_OFFSET, 2 | 1); /* auto EOI, 8086 mode */
961b505979SSepherosa Ziehau #else
971b505979SSepherosa Ziehau 	outb(IO_ICU2 + ICU_IMR_OFFSET, 1); /* 8086 mode */
981b505979SSepherosa Ziehau #endif
991b505979SSepherosa Ziehau 
1001b505979SSepherosa Ziehau 	outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff); /* leave interrupts masked */
1011b505979SSepherosa Ziehau 	outb(IO_ICU2, 0x0a);		/* default to IRR on read */
1021b505979SSepherosa Ziehau }
1031b505979SSepherosa Ziehau 
1041b505979SSepherosa Ziehau void
icu_definit(void)1051b505979SSepherosa Ziehau icu_definit(void)
1061b505979SSepherosa Ziehau {
1071b505979SSepherosa Ziehau 	register_t ef;
1081b505979SSepherosa Ziehau 
1091b505979SSepherosa Ziehau 	KKASSERT(MachIntrABI.type == MACHINTR_ICU);
1101b505979SSepherosa Ziehau 
1111b505979SSepherosa Ziehau 	ef = read_rflags();
1121b505979SSepherosa Ziehau 	cpu_disable_intr();
1131b505979SSepherosa Ziehau 
1141b505979SSepherosa Ziehau 	/* Leave interrupts masked */
1151b505979SSepherosa Ziehau 	outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff);
1161b505979SSepherosa Ziehau 	outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff);
1171b505979SSepherosa Ziehau 
1181b505979SSepherosa Ziehau 	MachIntrABI.setdefault();
1191b505979SSepherosa Ziehau 	icu_init();
1201b505979SSepherosa Ziehau 
1211b505979SSepherosa Ziehau 	write_rflags(ef);
1221b505979SSepherosa Ziehau }
1231b505979SSepherosa Ziehau 
1241b505979SSepherosa Ziehau /*
1251b505979SSepherosa Ziehau  *  ICU reinitialize when ICU configuration has lost.
1261b505979SSepherosa Ziehau  */
1271b505979SSepherosa Ziehau void
icu_reinit(void)1281b505979SSepherosa Ziehau icu_reinit(void)
1291b505979SSepherosa Ziehau {
1302675301dSSepherosa Ziehau #ifdef foo
1311b505979SSepherosa Ziehau 	int i;
1321b505979SSepherosa Ziehau 
1331b505979SSepherosa Ziehau 	icu_init();
1341b505979SSepherosa Ziehau 	for (i = 0; i < MAX_HARDINTS; ++i) {
1351b505979SSepherosa Ziehau 		if (count_registered_ints(i))
13635b2edcbSSepherosa Ziehau 			machintr_intr_enable(i);
1371b505979SSepherosa Ziehau 	}
1382675301dSSepherosa Ziehau #else
1392675301dSSepherosa Ziehau 	icu_init();
1402675301dSSepherosa Ziehau #endif
1411b505979SSepherosa Ziehau }
1421b505979SSepherosa Ziehau 
1431b505979SSepherosa Ziehau /*
1441b505979SSepherosa Ziehau  * Return a bitmap of the current interrupt requests.  This is 8259-specific
1451b505979SSepherosa Ziehau  * and is only suitable for use at probe time.
1461b505979SSepherosa Ziehau  */
1471b505979SSepherosa Ziehau intrmask_t
icu_irq_pending(void)1481b505979SSepherosa Ziehau icu_irq_pending(void)
1491b505979SSepherosa Ziehau {
1501b505979SSepherosa Ziehau 	u_char irr1;
1511b505979SSepherosa Ziehau 	u_char irr2;
1521b505979SSepherosa Ziehau 
1531b505979SSepherosa Ziehau 	irr1 = inb(IO_ICU1);
1541b505979SSepherosa Ziehau 	irr2 = inb(IO_ICU2);
1551b505979SSepherosa Ziehau 	return ((irr2 << 8) | irr1);
1561b505979SSepherosa Ziehau }
1576b809ec7SSepherosa Ziehau 
1586b809ec7SSepherosa Ziehau int
icu_ioapic_extint(int irq,int vec)1596b809ec7SSepherosa Ziehau icu_ioapic_extint(int irq, int vec)
1606b809ec7SSepherosa Ziehau {
1616b809ec7SSepherosa Ziehau 	uint8_t mask;
1626b809ec7SSepherosa Ziehau 
1636b809ec7SSepherosa Ziehau 	/*
1646b809ec7SSepherosa Ziehau 	 * Only first 8 interrupt is supported.
1656b809ec7SSepherosa Ziehau 	 * Don't allow setup for the slave link.
1666b809ec7SSepherosa Ziehau 	 */
1676b809ec7SSepherosa Ziehau 	if (irq >= 8 || irq == 2)
1686b809ec7SSepherosa Ziehau 		return EOPNOTSUPP;
1696b809ec7SSepherosa Ziehau 
1706b809ec7SSepherosa Ziehau 	mask = ~(1 << irq);
1716b809ec7SSepherosa Ziehau 
1726b809ec7SSepherosa Ziehau 	/*
1736b809ec7SSepherosa Ziehau 	 * Re-initialize master 8259:
1746b809ec7SSepherosa Ziehau 	 *   reset; prog 4 bytes, single ICU, edge triggered
1756b809ec7SSepherosa Ziehau 	 */
1766b809ec7SSepherosa Ziehau 	outb(IO_ICU1, 0x13);
1776b809ec7SSepherosa Ziehau 	outb(IO_ICU1 + 1, vec);		/* start vector (unused) */
1786b809ec7SSepherosa Ziehau 	outb(IO_ICU1 + 1, 0x00);	/* ignore slave */
1796b809ec7SSepherosa Ziehau 	outb(IO_ICU1 + 1, 0x03);	/* auto EOI, 8086 */
1806b809ec7SSepherosa Ziehau 	outb(IO_ICU1 + 1, mask);
1816b809ec7SSepherosa Ziehau 
1826b809ec7SSepherosa Ziehau 	return 0;
1836b809ec7SSepherosa Ziehau }
1843566408bSSepherosa Ziehau 
1853566408bSSepherosa Ziehau void
icu_reinit_noioapic(void)1863566408bSSepherosa Ziehau icu_reinit_noioapic(void)
1873566408bSSepherosa Ziehau {
1883566408bSSepherosa Ziehau 	register_t ef;
1893566408bSSepherosa Ziehau 
1903566408bSSepherosa Ziehau 	KKASSERT(MachIntrABI.type == MACHINTR_ICU);
191f45bfca0SSepherosa Ziehau 	KKASSERT(ioapic_enable == 0);
1923566408bSSepherosa Ziehau 
1933566408bSSepherosa Ziehau 	crit_enter();
1943566408bSSepherosa Ziehau 	ef = read_rflags();
1953566408bSSepherosa Ziehau 	cpu_disable_intr();
1963566408bSSepherosa Ziehau 
1973566408bSSepherosa Ziehau 	/* Leave interrupts masked */
1983566408bSSepherosa Ziehau 	outb(IO_ICU1 + ICU_IMR_OFFSET, 0xff);
1993566408bSSepherosa Ziehau 	outb(IO_ICU2 + ICU_IMR_OFFSET, 0xff);
2003566408bSSepherosa Ziehau 
2013566408bSSepherosa Ziehau 	icu_init();
2023566408bSSepherosa Ziehau 	MachIntrABI.stabilize();
2033566408bSSepherosa Ziehau 
2043566408bSSepherosa Ziehau 	write_rflags(ef);
2053566408bSSepherosa Ziehau 
2063566408bSSepherosa Ziehau 	MachIntrABI.cleanup();
2073566408bSSepherosa Ziehau 	crit_exit();
2083566408bSSepherosa Ziehau }
209