1 #include <linux/linkage.h> 2 #include <linux/errno.h> 3 #include <linux/signal.h> 4 #include <linux/sched.h> 5 #include <linux/ioport.h> 6 #include <linux/interrupt.h> 7 #include <linux/timex.h> 8 #include <linux/slab.h> 9 #include <linux/random.h> 10 #include <linux/kprobes.h> 11 #include <linux/init.h> 12 #include <linux/kernel_stat.h> 13 #include <linux/sysdev.h> 14 #include <linux/bitops.h> 15 #include <linux/acpi.h> 16 #include <linux/io.h> 17 #include <linux/delay.h> 18 19 #include <asm/atomic.h> 20 #include <asm/system.h> 21 #include <asm/timer.h> 22 #include <asm/hw_irq.h> 23 #include <asm/pgtable.h> 24 #include <asm/desc.h> 25 #include <asm/apic.h> 26 #include <asm/setup.h> 27 #include <asm/i8259.h> 28 #include <asm/traps.h> 29 30 /* 31 * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: 32 * (these are usually mapped to vectors 0x30-0x3f) 33 */ 34 35 /* 36 * The IO-APIC gives us many more interrupt sources. Most of these 37 * are unused but an SMP system is supposed to have enough memory ... 38 * sometimes (mostly wrt. hw bugs) we get corrupted vectors all 39 * across the spectrum, so we really want to be prepared to get all 40 * of these. Plus, more powerful systems might have more than 64 41 * IO-APIC registers. 42 * 43 * (these are usually mapped into the 0x30-0xff vector range) 44 */ 45 46 #ifdef CONFIG_X86_32 47 /* 48 * Note that on a 486, we don't want to do a SIGFPE on an irq13 49 * as the irq is unreliable, and exception 16 works correctly 50 * (ie as explained in the intel literature). On a 386, you 51 * can't use exception 16 due to bad IBM design, so we have to 52 * rely on the less exact irq13. 53 * 54 * Careful.. Not only is IRQ13 unreliable, but it is also 55 * leads to races. IBM designers who came up with it should 56 * be shot. 57 */ 58 59 static irqreturn_t math_error_irq(int cpl, void *dev_id) 60 { 61 outb(0, 0xF0); 62 if (ignore_fpu_irq || !boot_cpu_data.hard_math) 63 return IRQ_NONE; 64 math_error((void __user *)get_irq_regs()->ip); 65 return IRQ_HANDLED; 66 } 67 68 /* 69 * New motherboards sometimes make IRQ 13 be a PCI interrupt, 70 * so allow interrupt sharing. 71 */ 72 static struct irqaction fpu_irq = { 73 .handler = math_error_irq, 74 .name = "fpu", 75 }; 76 #endif 77 78 /* 79 * IRQ2 is cascade interrupt to second interrupt controller 80 */ 81 static struct irqaction irq2 = { 82 .handler = no_action, 83 .name = "cascade", 84 }; 85 86 DEFINE_PER_CPU(vector_irq_t, vector_irq) = { 87 [0 ... IRQ0_VECTOR - 1] = -1, 88 [IRQ0_VECTOR] = 0, 89 [IRQ1_VECTOR] = 1, 90 [IRQ2_VECTOR] = 2, 91 [IRQ3_VECTOR] = 3, 92 [IRQ4_VECTOR] = 4, 93 [IRQ5_VECTOR] = 5, 94 [IRQ6_VECTOR] = 6, 95 [IRQ7_VECTOR] = 7, 96 [IRQ8_VECTOR] = 8, 97 [IRQ9_VECTOR] = 9, 98 [IRQ10_VECTOR] = 10, 99 [IRQ11_VECTOR] = 11, 100 [IRQ12_VECTOR] = 12, 101 [IRQ13_VECTOR] = 13, 102 [IRQ14_VECTOR] = 14, 103 [IRQ15_VECTOR] = 15, 104 [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1 105 }; 106 107 int vector_used_by_percpu_irq(unsigned int vector) 108 { 109 int cpu; 110 111 for_each_online_cpu(cpu) { 112 if (per_cpu(vector_irq, cpu)[vector] != -1) 113 return 1; 114 } 115 116 return 0; 117 } 118 119 void __init init_ISA_irqs(void) 120 { 121 int i; 122 123 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC) 124 init_bsp_APIC(); 125 #endif 126 init_8259A(0); 127 128 /* 129 * 16 old-style INTA-cycle interrupts: 130 */ 131 for (i = 0; i < NR_IRQS_LEGACY; i++) { 132 struct irq_desc *desc = irq_to_desc(i); 133 134 desc->status = IRQ_DISABLED; 135 desc->action = NULL; 136 desc->depth = 1; 137 138 set_irq_chip_and_handler_name(i, &i8259A_chip, 139 handle_level_irq, "XT"); 140 } 141 } 142 143 void __init init_IRQ(void) 144 { 145 x86_init.irqs.intr_init(); 146 } 147 148 static void __init smp_intr_init(void) 149 { 150 #ifdef CONFIG_SMP 151 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC) 152 /* 153 * The reschedule interrupt is a CPU-to-CPU reschedule-helper 154 * IPI, driven by wakeup. 155 */ 156 alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); 157 158 /* IPIs for invalidation */ 159 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); 160 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); 161 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); 162 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); 163 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); 164 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); 165 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); 166 alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); 167 168 /* IPI for generic function call */ 169 alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); 170 171 /* IPI for generic single function call */ 172 alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, 173 call_function_single_interrupt); 174 175 /* Low priority IPI to cleanup after moving an irq */ 176 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); 177 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); 178 179 /* IPI used for rebooting/stopping */ 180 alloc_intr_gate(REBOOT_VECTOR, reboot_interrupt); 181 #endif 182 #endif /* CONFIG_SMP */ 183 } 184 185 static void __init apic_intr_init(void) 186 { 187 smp_intr_init(); 188 189 #ifdef CONFIG_X86_THERMAL_VECTOR 190 alloc_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); 191 #endif 192 #ifdef CONFIG_X86_MCE_THRESHOLD 193 alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); 194 #endif 195 #if defined(CONFIG_X86_MCE) && defined(CONFIG_X86_LOCAL_APIC) 196 alloc_intr_gate(MCE_SELF_VECTOR, mce_self_interrupt); 197 #endif 198 199 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC) 200 /* self generated IPI for local APIC timer */ 201 alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); 202 203 /* generic IPI for platform specific use */ 204 alloc_intr_gate(GENERIC_INTERRUPT_VECTOR, generic_interrupt); 205 206 /* IPI vectors for APIC spurious and error interrupts */ 207 alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); 208 alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt); 209 210 /* Performance monitoring interrupts: */ 211 # ifdef CONFIG_PERF_COUNTERS 212 alloc_intr_gate(LOCAL_PENDING_VECTOR, perf_pending_interrupt); 213 # endif 214 215 #endif 216 } 217 218 void __init native_init_IRQ(void) 219 { 220 int i; 221 222 /* Execute any quirks before the call gates are initialised: */ 223 x86_init.irqs.pre_vector_init(); 224 225 apic_intr_init(); 226 227 /* 228 * Cover the whole vector space, no vector can escape 229 * us. (some of these will be overridden and become 230 * 'special' SMP interrupts) 231 */ 232 for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { 233 /* IA32_SYSCALL_VECTOR could be used in trap_init already. */ 234 if (!test_bit(i, used_vectors)) 235 set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]); 236 } 237 238 if (!acpi_ioapic) 239 setup_irq(2, &irq2); 240 241 #ifdef CONFIG_X86_32 242 /* 243 * External FPU? Set up irq13 if so, for 244 * original braindamaged IBM FERR coupling. 245 */ 246 if (boot_cpu_data.hard_math && !cpu_has_fpu) 247 setup_irq(FPU_IRQ, &fpu_irq); 248 249 irq_ctx_init(smp_processor_id()); 250 #endif 251 } 252