| Commit | Line | Data |
|---|---|---|
| 984263bc MD |
1 | /*- |
| 2 | * Copyright (c) 1991 The Regents of the University of California. | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * This code is derived from software contributed to Berkeley by | |
| 6 | * William Jolitz. | |
| 7 | * | |
| 8 | * Redistribution and use in source and binary forms, with or without | |
| 9 | * modification, are permitted provided that the following conditions | |
| 10 | * are met: | |
| 11 | * 1. Redistributions of source code must retain the above copyright | |
| 12 | * notice, this list of conditions and the following disclaimer. | |
| 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 14 | * notice, this list of conditions and the following disclaimer in the | |
| 15 | * documentation and/or other materials provided with the distribution. | |
| 16 | * 3. All advertising materials mentioning features or use of this software | |
| 17 | * must display the following acknowledgement: | |
| 18 | * This product includes software developed by the University of | |
| 19 | * California, Berkeley and its contributors. | |
| 20 | * 4. Neither the name of the University nor the names of its contributors | |
| 21 | * may be used to endorse or promote products derived from this software | |
| 22 | * without specific prior written permission. | |
| 23 | * | |
| 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
| 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
| 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 34 | * SUCH DAMAGE. | |
| 35 | * | |
| 36 | * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 | |
| 37 | * $FreeBSD: src/sys/i386/isa/intr_machdep.c,v 1.29.2.5 2001/10/14 06:54:27 luigi Exp $ | |
| 21ce0dfa | 38 | * $DragonFly: src/sys/platform/pc32/isa/intr_machdep.c,v 1.48 2008/08/02 01:14:43 dillon Exp $ |
| 984263bc MD |
39 | */ |
| 40 | /* | |
| 41 | * This file contains an aggregated module marked: | |
| 42 | * Copyright (c) 1997, Stefan Esser <se@freebsd.org> | |
| 43 | * All rights reserved. | |
| 44 | * See the notice for details. | |
| 45 | */ | |
| 46 | ||
| 1f2de5d4 | 47 | #include "use_isa.h" |
| 984263bc MD |
48 | #include "opt_auto_eoi.h" |
| 49 | ||
| 984263bc MD |
50 | #include <sys/param.h> |
| 51 | #ifndef SMP | |
| 52 | #include <machine/lock.h> | |
| 53 | #endif | |
| 54 | #include <sys/systm.h> | |
| 55 | #include <sys/syslog.h> | |
| 56 | #include <sys/malloc.h> | |
| 57 | #include <sys/errno.h> | |
| 58 | #include <sys/interrupt.h> | |
| 59 | #include <machine/ipl.h> | |
| 60 | #include <machine/md_var.h> | |
| 61 | #include <machine/segments.h> | |
| 62 | #include <sys/bus.h> | |
| ef0fdad1 MD |
63 | #include <machine/globaldata.h> |
| 64 | #include <sys/proc.h> | |
| 65 | #include <sys/thread2.h> | |
| 37e7efec | 66 | #include <sys/machintr.h> |
| 984263bc | 67 | |
| 96728c05 | 68 | #include <machine/smp.h> |
| 21ce0dfa | 69 | #include <bus/isa/isa.h> |
| a9295349 | 70 | #include <machine_base/icu/icu.h> |
| 984263bc MD |
71 | |
| 72 | #if NISA > 0 | |
| 1f2de5d4 | 73 | #include <bus/isa/isavar.h> |
| 984263bc | 74 | #endif |
| a9295349 | 75 | #include <machine_base/isa/intr_machdep.h> |
| 984263bc | 76 | #include <sys/interrupt.h> |
| 984263bc | 77 | #include <machine/clock.h> |
| cb973d15 | 78 | #include <machine/cpu.h> |
| 984263bc | 79 | |
| 984263bc | 80 | /* XXX should be in suitable include files */ |
| 984263bc | 81 | #define ICU_IMR_OFFSET 1 /* IO_ICU{1,2} + 1 */ |
| 984263bc | 82 | |
| bf3e6b54 | 83 | static void init_i8259(void); |
| 385b2dc2 | 84 | |
| 984263bc MD |
85 | #define NMI_PARITY (1 << 7) |
| 86 | #define NMI_IOCHAN (1 << 6) | |
| 87 | #define ENMI_WATCHDOG (1 << 7) | |
| 88 | #define ENMI_BUSTIMER (1 << 6) | |
| 89 | #define ENMI_IOSTATUS (1 << 5) | |
| 984263bc MD |
90 | |
| 91 | /* | |
| 92 | * Handle a NMI, possibly a machine check. | |
| 93 | * return true to panic system, false to ignore. | |
| 94 | */ | |
| 95 | int | |
| 09e6e929 | 96 | isa_nmi(int cd) |
| 984263bc MD |
97 | { |
| 98 | int retval = 0; | |
| 984263bc MD |
99 | int isa_port = inb(0x61); |
| 100 | int eisa_port = inb(0x461); | |
| 101 | ||
| 102 | log(LOG_CRIT, "NMI ISA %x, EISA %x\n", isa_port, eisa_port); | |
| 984263bc MD |
103 | |
| 104 | if (isa_port & NMI_PARITY) { | |
| 105 | log(LOG_CRIT, "RAM parity error, likely hardware failure."); | |
| 106 | retval = 1; | |
| 107 | } | |
| 108 | ||
| 109 | if (isa_port & NMI_IOCHAN) { | |
| 110 | log(LOG_CRIT, "I/O channel check, likely hardware failure."); | |
| 111 | retval = 1; | |
| 112 | } | |
| 113 | ||
| 114 | /* | |
| 115 | * On a real EISA machine, this will never happen. However it can | |
| 116 | * happen on ISA machines which implement XT style floating point | |
| 117 | * error handling (very rare). Save them from a meaningless panic. | |
| 118 | */ | |
| 119 | if (eisa_port == 0xff) | |
| 120 | return(retval); | |
| 121 | ||
| 122 | if (eisa_port & ENMI_WATCHDOG) { | |
| 123 | log(LOG_CRIT, "EISA watchdog timer expired, likely hardware failure."); | |
| 124 | retval = 1; | |
| 125 | } | |
| 126 | ||
| 127 | if (eisa_port & ENMI_BUSTIMER) { | |
| 128 | log(LOG_CRIT, "EISA bus timeout, likely hardware failure."); | |
| 129 | retval = 1; | |
| 130 | } | |
| 131 | ||
| 132 | if (eisa_port & ENMI_IOSTATUS) { | |
| 133 | log(LOG_CRIT, "EISA I/O port status error."); | |
| 134 | retval = 1; | |
| 135 | } | |
| 984263bc MD |
136 | return(retval); |
| 137 | } | |
| 138 | ||
| 139 | /* | |
| bf3e6b54 DR |
140 | * ICU reinitialize when ICU configuration has lost. |
| 141 | */ | |
| 142 | void | |
| 09e6e929 | 143 | icu_reinit(void) |
| bf3e6b54 | 144 | { |
| 477d3c1c | 145 | int i; |
| bf3e6b54 | 146 | |
| 477d3c1c | 147 | init_i8259(); |
| 5f456c40 | 148 | for (i = 0; i < MAX_HARDINTS; ++i) { |
| 477d3c1c | 149 | if (count_registered_ints(i)) |
| 37e7efec | 150 | machintr_intren(i); |
| 477d3c1c | 151 | } |
| bf3e6b54 DR |
152 | } |
| 153 | ||
| bf3e6b54 | 154 | /* |
| b46d0159 | 155 | * Fill in default interrupt table (in case of spurious interrupt |
| 984263bc MD |
156 | * during configuration of kernel, setup interrupt control unit |
| 157 | */ | |
| 158 | void | |
| 09e6e929 | 159 | isa_defaultirq(void) |
| 984263bc MD |
160 | { |
| 161 | int i; | |
| 162 | ||
| 163 | /* icu vectors */ | |
| 5f456c40 | 164 | for (i = 0; i < MAX_HARDINTS; i++) |
| 35408d22 | 165 | machintr_vector_setdefault(i); |
| bf3e6b54 DR |
166 | init_i8259(); |
| 167 | } | |
| 168 | ||
| 169 | static void | |
| 170 | init_i8259(void) | |
| 171 | { | |
| 984263bc MD |
172 | |
| 173 | /* initialize 8259's */ | |
| af90f33e | 174 | outb(IO_ICU1, 0x11); /* reset; program device, four bytes */ |
| 97359a5b | 175 | outb(IO_ICU1+ICU_IMR_OFFSET, IDT_OFFSET); /* starting at this vector index */ |
| 59843dd6 | 176 | outb(IO_ICU1+ICU_IMR_OFFSET, 1 << ICU_IRQ_SLAVE); /* slave on line 2 */ |
| 984263bc | 177 | #ifdef AUTO_EOI_1 |
| 79b62055 | 178 | int auto_eoi = 2; /* auto EOI, 8086 mode */ |
| 984263bc | 179 | #else |
| 79b62055 MN |
180 | int auto_eoi = 0; /* 8086 mode */ |
| 181 | #endif | |
| 182 | #ifdef SMP | |
| 183 | if (apic_io_enable) | |
| 184 | auto_eoi = 2; /* auto EOI, 8086 mode */ | |
| 984263bc | 185 | #endif |
| 79b62055 MN |
186 | outb(IO_ICU1+ICU_IMR_OFFSET, auto_eoi | 1); |
| 187 | ||
| 984263bc MD |
188 | outb(IO_ICU1+ICU_IMR_OFFSET, 0xff); /* leave interrupts masked */ |
| 189 | outb(IO_ICU1, 0x0a); /* default to IRR on read */ | |
| 984263bc | 190 | outb(IO_ICU1, 0xc0 | (3 - 1)); /* pri order 3-7, 0-2 (com2 first) */ |
| af90f33e | 191 | outb(IO_ICU2, 0x11); /* reset; program device, four bytes */ |
| 97359a5b | 192 | outb(IO_ICU2+ICU_IMR_OFFSET, IDT_OFFSET+8); /* staring at this vector index */ |
| 10ff1029 | 193 | outb(IO_ICU2+ICU_IMR_OFFSET, ICU_IRQ_SLAVE); |
| 984263bc MD |
194 | #ifdef AUTO_EOI_2 |
| 195 | outb(IO_ICU2+ICU_IMR_OFFSET, 2 | 1); /* auto EOI, 8086 mode */ | |
| 196 | #else | |
| 197 | outb(IO_ICU2+ICU_IMR_OFFSET,1); /* 8086 mode */ | |
| 198 | #endif | |
| 984263bc MD |
199 | outb(IO_ICU2+ICU_IMR_OFFSET, 0xff); /* leave interrupts masked */ |
| 200 | outb(IO_ICU2, 0x0a); /* default to IRR on read */ | |
| 201 | } | |
| 202 | ||
| 984263bc MD |
203 | #if NISA > 0 |
| 204 | /* | |
| 205 | * Return a bitmap of the current interrupt requests. This is 8259-specific | |
| 206 | * and is only suitable for use at probe time. | |
| 207 | */ | |
| 208 | intrmask_t | |
| f15db79e | 209 | isa_irq_pending(void) |
| 984263bc MD |
210 | { |
| 211 | u_char irr1; | |
| 212 | u_char irr2; | |
| 213 | ||
| 214 | irr1 = inb(IO_ICU1); | |
| 215 | irr2 = inb(IO_ICU2); | |
| 216 | return ((irr2 << 8) | irr1); | |
| 217 | } | |
| 59843dd6 | 218 | |
| 984263bc MD |
219 | #endif |
| 220 | ||
| 984263bc MD |
221 | /* The following notice applies beyond this point in the file */ |
| 222 | ||
| 223 | /* | |
| 224 | * Copyright (c) 1997, Stefan Esser <se@freebsd.org> | |
| 225 | * All rights reserved. | |
| 226 | * | |
| 227 | * Redistribution and use in source and binary forms, with or without | |
| 228 | * modification, are permitted provided that the following conditions | |
| 229 | * are met: | |
| 230 | * 1. Redistributions of source code must retain the above copyright | |
| 231 | * notice unmodified, this list of conditions, and the following | |
| 232 | * disclaimer. | |
| 233 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 234 | * notice, this list of conditions and the following disclaimer in the | |
| 235 | * documentation and/or other materials provided with the distribution. | |
| 236 | * | |
| 237 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
| 238 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
| 239 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
| 240 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 241 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
| 242 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 243 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 244 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 245 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 246 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 247 | * | |
| 248 | * $FreeBSD: src/sys/i386/isa/intr_machdep.c,v 1.29.2.5 2001/10/14 06:54:27 luigi Exp $ | |
| 249 | * | |
| 250 | */ | |
| 251 | ||
| 545a1cd3 MD |
252 | #ifdef SMP |
| 253 | /* | |
| 254 | * forward_fast_remote() | |
| 255 | * | |
| 256 | * This function is called from the receiving end of an IPIQ when a | |
| 257 | * remote cpu wishes to forward a fast interrupt to us. All we have to | |
| 258 | * do is set the interrupt pending and let the IPI's doreti deal with it. | |
| 259 | */ | |
| 260 | void | |
| 261 | forward_fastint_remote(void *arg) | |
| 262 | { | |
| 263 | int irq = (int)arg; | |
| 264 | struct mdglobaldata *gd = mdcpu; | |
| 265 | ||
| 266 | atomic_set_int_nonlocked(&gd->gd_fpending, 1 << irq); | |
| 235957ed | 267 | atomic_set_int_nonlocked(&gd->mi.gd_reqflags, RQF_INTPEND); |
| 545a1cd3 MD |
268 | } |
| 269 | ||
| 270 | #endif |