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