1 /* 2 * Macintosh interrupts 3 * 4 * General design: 5 * In contrary to the Amiga and Atari platforms, the Mac hardware seems to 6 * exclusively use the autovector interrupts (the 'generic level0-level7' 7 * interrupts with exception vectors 0x19-0x1f). The following interrupt levels 8 * are used: 9 * 1 - VIA1 10 * - slot 0: one second interrupt (CA2) 11 * - slot 1: VBlank (CA1) 12 * - slot 2: ADB data ready (SR full) 13 * - slot 3: ADB data (CB2) 14 * - slot 4: ADB clock (CB1) 15 * - slot 5: timer 2 16 * - slot 6: timer 1 17 * - slot 7: status of IRQ; signals 'any enabled int.' 18 * 19 * 2 - VIA2 or RBV 20 * - slot 0: SCSI DRQ (CA2) 21 * - slot 1: NUBUS IRQ (CA1) need to read port A to find which 22 * - slot 2: /EXP IRQ (only on IIci) 23 * - slot 3: SCSI IRQ (CB2) 24 * - slot 4: ASC IRQ (CB1) 25 * - slot 5: timer 2 (not on IIci) 26 * - slot 6: timer 1 (not on IIci) 27 * - slot 7: status of IRQ; signals 'any enabled int.' 28 * 29 * 2 - OSS (IIfx only?) 30 * - slot 0: SCSI interrupt 31 * - slot 1: Sound interrupt 32 * 33 * Levels 3-6 vary by machine type. For VIA or RBV Macintoshes: 34 * 35 * 3 - unused (?) 36 * 37 * 4 - SCC 38 * 39 * 5 - unused (?) 40 * [serial errors or special conditions seem to raise level 6 41 * interrupts on some models (LC4xx?)] 42 * 43 * 6 - off switch (?) 44 * 45 * Machines with Quadra-like VIA hardware, except PSC and PMU machines, support 46 * an alternate interrupt mapping, as used by A/UX. It spreads ethernet and 47 * sound out to their own autovector IRQs and gives VIA1 a higher priority: 48 * 49 * 1 - unused (?) 50 * 51 * 3 - on-board SONIC 52 * 53 * 5 - Apple Sound Chip (ASC) 54 * 55 * 6 - VIA1 56 * 57 * For OSS Macintoshes (IIfx only at this point): 58 * 59 * 3 - Nubus interrupt 60 * - slot 0: Slot $9 61 * - slot 1: Slot $A 62 * - slot 2: Slot $B 63 * - slot 3: Slot $C 64 * - slot 4: Slot $D 65 * - slot 5: Slot $E 66 * 67 * 4 - SCC IOP 68 * 69 * 5 - ISM IOP (ADB?) 70 * 71 * 6 - unused 72 * 73 * For PSC Macintoshes (660AV, 840AV): 74 * 75 * 3 - PSC level 3 76 * - slot 0: MACE 77 * 78 * 4 - PSC level 4 79 * - slot 1: SCC channel A interrupt 80 * - slot 2: SCC channel B interrupt 81 * - slot 3: MACE DMA 82 * 83 * 5 - PSC level 5 84 * 85 * 6 - PSC level 6 86 * 87 * Finally we have good 'ole level 7, the non-maskable interrupt: 88 * 89 * 7 - NMI (programmer's switch on the back of some Macs) 90 * Also RAM parity error on models which support it (IIc, IIfx?) 91 * 92 * The current interrupt logic looks something like this: 93 * 94 * - We install dispatchers for the autovector interrupts (1-7). These 95 * dispatchers are responsible for querying the hardware (the 96 * VIA/RBV/OSS/PSC chips) to determine the actual interrupt source. Using 97 * this information a machspec interrupt number is generated by placing the 98 * index of the interrupt hardware into the low three bits and the original 99 * autovector interrupt number in the upper 5 bits. The handlers for the 100 * resulting machspec interrupt are then called. 101 * 102 * - Nubus is a special case because its interrupts are hidden behind two 103 * layers of hardware. Nubus interrupts come in as index 1 on VIA #2, 104 * which translates to IRQ number 17. In this spot we install _another_ 105 * dispatcher. This dispatcher finds the interrupting slot number (9-F) and 106 * then forms a new machspec interrupt number as above with the slot number 107 * minus 9 in the low three bits and the pseudo-level 7 in the upper five 108 * bits. The handlers for this new machspec interrupt number are then 109 * called. This puts Nubus interrupts into the range 56-62. 110 * 111 * - The Baboon interrupts (used on some PowerBooks) are an even more special 112 * case. They're hidden behind the Nubus slot $C interrupt thus adding a 113 * third layer of indirection. Why oh why did the Apple engineers do that? 114 * 115 * - We support "fast" and "slow" handlers, just like the Amiga port. The 116 * fast handlers are called first and with all interrupts disabled. They 117 * are expected to execute quickly (hence the name). The slow handlers are 118 * called last with interrupts enabled and the interrupt level restored. 119 * They must therefore be reentrant. 120 * 121 * TODO: 122 * 123 */ 124 125 #include <linux/types.h> 126 #include <linux/kernel.h> 127 #include <linux/sched.h> 128 #include <linux/interrupt.h> 129 #include <linux/irq.h> 130 #include <linux/delay.h> 131 132 #include <asm/irq.h> 133 #include <asm/macintosh.h> 134 #include <asm/macints.h> 135 #include <asm/mac_via.h> 136 #include <asm/mac_psc.h> 137 #include <asm/mac_oss.h> 138 #include <asm/mac_iop.h> 139 #include <asm/mac_baboon.h> 140 #include <asm/hwtest.h> 141 #include <asm/irq_regs.h> 142 143 #define SHUTUP_SONIC 144 145 /* 146 * console_loglevel determines NMI handler function 147 */ 148 149 irqreturn_t mac_nmi_handler(int, void *); 150 irqreturn_t mac_debug_handler(int, void *); 151 152 /* #define DEBUG_MACINTS */ 153 154 static struct irq_chip mac_irq_chip = { 155 .name = "mac", 156 .irq_enable = mac_irq_enable, 157 .irq_disable = mac_irq_disable, 158 }; 159 160 void __init mac_init_IRQ(void) 161 { 162 #ifdef DEBUG_MACINTS 163 printk("mac_init_IRQ(): Setting things up...\n"); 164 #endif 165 m68k_setup_irq_controller(&mac_irq_chip, handle_simple_irq, IRQ_USER, 166 NUM_MAC_SOURCES - IRQ_USER); 167 /* Make sure the SONIC interrupt is cleared or things get ugly */ 168 #ifdef SHUTUP_SONIC 169 printk("Killing onboard sonic... "); 170 /* This address should hopefully be mapped already */ 171 if (hwreg_present((void*)(0x50f0a000))) { 172 *(long *)(0x50f0a014) = 0x7fffL; 173 *(long *)(0x50f0a010) = 0L; 174 } 175 printk("Done.\n"); 176 #endif /* SHUTUP_SONIC */ 177 178 /* 179 * Now register the handlers for the master IRQ handlers 180 * at levels 1-7. Most of the work is done elsewhere. 181 */ 182 183 if (oss_present) 184 oss_register_interrupts(); 185 else 186 via_register_interrupts(); 187 if (psc_present) 188 psc_register_interrupts(); 189 if (baboon_present) 190 baboon_register_interrupts(); 191 iop_register_interrupts(); 192 if (request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI", 193 mac_nmi_handler)) 194 pr_err("Couldn't register NMI\n"); 195 #ifdef DEBUG_MACINTS 196 printk("mac_init_IRQ(): Done!\n"); 197 #endif 198 } 199 200 /* 201 * mac_irq_enable - enable an interrupt source 202 * mac_irq_disable - disable an interrupt source 203 * 204 * These routines are just dispatchers to the VIA/OSS/PSC routines. 205 */ 206 207 void mac_irq_enable(struct irq_data *data) 208 { 209 int irq = data->irq; 210 int irq_src = IRQ_SRC(irq); 211 212 switch(irq_src) { 213 case 1: 214 via_irq_enable(irq); 215 break; 216 case 2: 217 case 7: 218 if (oss_present) 219 oss_irq_enable(irq); 220 else 221 via_irq_enable(irq); 222 break; 223 case 3: 224 case 5: 225 case 6: 226 if (psc_present) 227 psc_irq_enable(irq); 228 else if (oss_present) 229 oss_irq_enable(irq); 230 break; 231 case 4: 232 if (psc_present) 233 psc_irq_enable(irq); 234 break; 235 case 8: 236 if (baboon_present) 237 baboon_irq_enable(irq); 238 break; 239 } 240 } 241 242 void mac_irq_disable(struct irq_data *data) 243 { 244 int irq = data->irq; 245 int irq_src = IRQ_SRC(irq); 246 247 switch(irq_src) { 248 case 1: 249 via_irq_disable(irq); 250 break; 251 case 2: 252 case 7: 253 if (oss_present) 254 oss_irq_disable(irq); 255 else 256 via_irq_disable(irq); 257 break; 258 case 3: 259 case 5: 260 case 6: 261 if (psc_present) 262 psc_irq_disable(irq); 263 else if (oss_present) 264 oss_irq_disable(irq); 265 break; 266 case 4: 267 if (psc_present) 268 psc_irq_disable(irq); 269 break; 270 case 8: 271 if (baboon_present) 272 baboon_irq_disable(irq); 273 break; 274 } 275 } 276 277 static int num_debug[8]; 278 279 irqreturn_t mac_debug_handler(int irq, void *dev_id) 280 { 281 if (num_debug[irq] < 10) { 282 printk("DEBUG: Unexpected IRQ %d\n", irq); 283 num_debug[irq]++; 284 } 285 return IRQ_HANDLED; 286 } 287 288 static int in_nmi; 289 static volatile int nmi_hold; 290 291 irqreturn_t mac_nmi_handler(int irq, void *dev_id) 292 { 293 int i; 294 /* 295 * generate debug output on NMI switch if 'debug' kernel option given 296 * (only works with Penguin!) 297 */ 298 299 in_nmi++; 300 for (i=0; i<100; i++) 301 udelay(1000); 302 303 if (in_nmi == 1) { 304 nmi_hold = 1; 305 printk("... pausing, press NMI to resume ..."); 306 } else { 307 printk(" ok!\n"); 308 nmi_hold = 0; 309 } 310 311 barrier(); 312 313 while (nmi_hold == 1) 314 udelay(1000); 315 316 if (console_loglevel >= 8) { 317 #if 0 318 struct pt_regs *fp = get_irq_regs(); 319 show_state(); 320 printk("PC: %08lx\nSR: %04x SP: %p\n", fp->pc, fp->sr, fp); 321 printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n", 322 fp->d0, fp->d1, fp->d2, fp->d3); 323 printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", 324 fp->d4, fp->d5, fp->a0, fp->a1); 325 326 if (STACK_MAGIC != *(unsigned long *)current->kernel_stack_page) 327 printk("Corrupted stack page\n"); 328 printk("Process %s (pid: %d, stackpage=%08lx)\n", 329 current->comm, current->pid, current->kernel_stack_page); 330 if (intr_count == 1) 331 dump_stack((struct frame *)fp); 332 #else 333 /* printk("NMI "); */ 334 #endif 335 } 336 in_nmi--; 337 return IRQ_HANDLED; 338 } 339