1 #include <lwk/kernel.h>
3 #include <lwk/kallsyms.h>
8 #include <arch/idt_vectors.h>
10 #include <arch/xcall.h>
11 #include <arch/i387.h>
13 idtvec_handler_t idtvec_table[NUM_IDT_ENTRIES];
14 static DEFINE_SPINLOCK(idtvec_table_lock);
16 extern void asm_idtvec_table(void);
19 do_unhandled_idt_vector(struct pt_regs *regs, unsigned int vector)
21 if ((vector >= IRQ0_VECTOR) && (vector <= IRQ15_VECTOR)) {
23 "Unhandled Interrupt! (vector=%u, isa_irq=%u)\n",
24 vector, vector - IRQ0_VECTOR);
27 "Unhandled Interrupt! (vector=%u)\n", vector);
32 do_divide_error(struct pt_regs *regs, unsigned int vector)
34 printk("Divide Error Exception\n");
40 do_nmi(struct pt_regs *regs, unsigned int vector)
42 printk("NMI Exception\n");
48 do_int3(struct pt_regs *regs, unsigned int vector)
50 printk("INT3 Exception\n");
56 do_overflow(struct pt_regs *regs, unsigned int vector)
58 printk("Overflow Exception\n");
64 do_bounds(struct pt_regs *regs, unsigned int vector)
66 printk("Bounds Exception\n");
72 do_invalid_op(struct pt_regs *regs, unsigned int vector)
74 printk("Invalid Op Exception\n");
80 do_device_not_available(struct pt_regs *regs, unsigned int vector)
82 BUG_ON(current->arch.flags & TF_USED_FPU);
83 current->arch.flags |= TF_USED_FPU;
85 fpu_restore_state(current);
89 do_double_fault(struct pt_regs *regs, unsigned int vector)
91 printk("Double Fault Exception\n");
97 do_coproc_segment_overrun(struct pt_regs *regs, unsigned int vector)
99 printk("Coprocessor Segment Exception\n");
100 show_registers(regs);
105 do_invalid_tss(struct pt_regs *regs, unsigned int vector)
107 printk("Invalid TSS Exception)\n");
108 show_registers(regs);
113 do_segment_not_present(struct pt_regs *regs, unsigned int vector)
115 printk("Segment Not Present Exception\n");
116 show_registers(regs);
121 do_stack_segment(struct pt_regs *regs, unsigned int vector)
123 printk("Stack Segment Exception\n");
124 show_registers(regs);
129 do_general_protection(struct pt_regs *regs, unsigned int vector)
131 printk("General Protection Exception\n");
132 show_registers(regs);
137 do_page_fault(struct pt_regs *regs, unsigned int vector)
139 printk("Page Fault Exception\n");
140 show_registers(regs);
145 do_spurious_interrupt_bug(struct pt_regs *regs, unsigned int vector)
147 printk("Spurious Interrupt Exception\n");
148 show_registers(regs);
153 do_coprocessor_error(struct pt_regs *regs, unsigned int vector)
155 printk("Coprocessor Error Exception\n");
156 show_registers(regs);
161 do_alignment_check(struct pt_regs *regs, unsigned int vector)
163 printk("Alignment Check Exception\n");
164 show_registers(regs);
169 do_machine_check(struct pt_regs *regs, unsigned int vector)
171 printk("Machine Check Exception\n");
172 show_registers(regs);
177 do_simd_coprocessor_error(struct pt_regs *regs, unsigned int vector)
179 printk("SIMD Coprocessor Error Exception\n");
180 show_registers(regs);
185 do_apic_timer(struct pt_regs *regs, unsigned int vector)
191 do_apic_perf_counter(struct pt_regs *regs, unsigned int vector)
193 printk("APIC Perf. Counter Interrupt, vector=%u\n", vector);
194 show_registers(regs);
199 do_apic_thermal(struct pt_regs *regs, unsigned int vector)
201 printk("APIC Thermal Interrupt, vector=%u\n", vector);
202 show_registers(regs);
207 do_apic_error(struct pt_regs *regs, unsigned int vector)
209 printk("APIC Error Interrupt, vector=%u\n", vector);
210 show_registers(regs);
215 do_apic_spurious(struct pt_regs *regs, unsigned int vector)
217 printk("APIC Spurious Interrupt, vector=%u\n", vector);
218 show_registers(regs);
223 set_idtvec_handler(unsigned int vector, idtvec_handler_t handler)
225 char namebuf[KSYM_NAME_LEN+1];
226 unsigned long symsize, offset;
227 unsigned long irqstate;
229 ASSERT(vector < NUM_IDT_ENTRIES);
231 if (handler != &do_unhandled_idt_vector) {
232 printk(KERN_DEBUG "IDT Vector %3u -> %s()\n",
233 vector, kallsyms_lookup( (unsigned long)handler,
234 &symsize, &offset, namebuf )
238 spin_lock_irqsave(&idtvec_table_lock, irqstate);
239 idtvec_table[vector] = handler;
240 spin_unlock_irqrestore(&idtvec_table_lock, irqstate);
244 do_interrupt(struct pt_regs *regs, unsigned int vector)
246 idtvec_table[vector](regs, vector);
247 if (vector >= FIRST_EXTERNAL_VECTOR)
248 lapic_ack_interrupt();
252 interrupts_init(void)
257 * Initialize the Interrupt Descriptor Table (IDT).
259 for (vector = 0; vector < NUM_IDT_ENTRIES; vector++) {
260 void *asm_handler = (void *) (
261 (unsigned long)(&asm_idtvec_table) + (vector * 16)
263 set_intr_gate(vector, asm_handler);
264 set_idtvec_handler(vector, &do_unhandled_idt_vector);
268 * Register handlers for the standard x86_64 interrupts & exceptions.
270 set_idtvec_handler( DIVIDE_ERROR_VECTOR, &do_divide_error );
271 set_idtvec_handler( NMI_VECTOR, &do_nmi );
272 set_idtvec_handler( INT3_VECTOR, &do_int3 );
273 set_idtvec_handler( OVERFLOW_VECTOR, &do_overflow );
274 set_idtvec_handler( BOUNDS_VECTOR, &do_bounds );
275 set_idtvec_handler( INVALID_OP_VECTOR, &do_invalid_op );
276 set_idtvec_handler( DEVICE_NOT_AVAILABLE_VECTOR, &do_device_not_available );
277 set_idtvec_handler( DOUBLE_FAULT_VECTOR, &do_double_fault );
278 set_idtvec_handler( COPROC_SEGMENT_OVERRUN_VECTOR, &do_coproc_segment_overrun );
279 set_idtvec_handler( INVALID_TSS_VECTOR, &do_invalid_tss );
280 set_idtvec_handler( SEGMENT_NOT_PRESENT_VECTOR, &do_segment_not_present );
281 set_idtvec_handler( STACK_SEGMENT_VECTOR, &do_stack_segment );
282 set_idtvec_handler( GENERAL_PROTECTION_VECTOR, &do_general_protection );
283 set_idtvec_handler( PAGE_FAULT_VECTOR, &do_page_fault );
284 set_idtvec_handler( SPURIOUS_INTERRUPT_BUG_VECTOR, &do_spurious_interrupt_bug );
285 set_idtvec_handler( COPROCESSOR_ERROR_VECTOR, &do_coprocessor_error );
286 set_idtvec_handler( ALIGNMENT_CHECK_VECTOR, &do_alignment_check );
287 set_idtvec_handler( MACHINE_CHECK_VECTOR, &do_machine_check );
288 set_idtvec_handler( SIMD_COPROCESSOR_ERROR_VECTOR, &do_simd_coprocessor_error );
291 * Register handlers for all of the local APIC vectors.
293 set_idtvec_handler( APIC_TIMER_VECTOR, &do_apic_timer );
294 set_idtvec_handler( APIC_PERF_COUNTER_VECTOR, &do_apic_perf_counter );
295 set_idtvec_handler( APIC_THERMAL_VECTOR, &do_apic_thermal );
296 set_idtvec_handler( APIC_ERROR_VECTOR, &do_apic_error );
297 set_idtvec_handler( APIC_SPURIOUS_VECTOR, &do_apic_spurious );
300 * Register handlers for inter-CPU interrupts (cross calls).
302 set_idtvec_handler( XCALL_FUNCTION_VECTOR, &arch_xcall_function_interrupt );
303 set_idtvec_handler( XCALL_RESCHEDULE_VECTOR, &arch_xcall_reschedule_interrupt );