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