- /* Install default handlers. */
- for (i = 0; i < 256; i++)
- intr_register (i, 0, IF_OFF, intr_unexpected);
-
- /* Most exceptions require ring 0.
- Exceptions 3, 4, and 5 can be caused by ring 3 directly.
-
- Most exceptions can be handled with interrupts turned on.
- We need to disable interrupts for page faults because the
- fault address is stored in CR2 and needs to be preserved.
- */
-#if 0
- intr_register (0x00, 0, IF_ON, excp00_divide_error);
- intr_register (0x01, 0, IF_ON, excp01_debug);
- intr_register (0x02, 0, IF_ON, excp02_nmi);
- intr_register (0x03, 3, IF_ON, excp03_breakpoint);
- intr_register (0x04, 3, IF_ON, excp04_overflow);
- intr_register (0x05, 3, IF_ON, excp05_bound);
- intr_register (0x06, 0, IF_ON, excp06_invalid_opcode);
- intr_register (0x07, 0, IF_ON, excp07_device_not_available);
- intr_register (0x08, 0, IF_ON, excp08_double_fault);
- intr_register (0x09, 0, IF_ON, excp09_coprocessor_overrun);
- intr_register (0x0a, 0, IF_ON, excp0a_invalid_tss);
- intr_register (0x0b, 0, IF_ON, excp0b_segment_not_present);
- intr_register (0x0c, 0, IF_ON, excp0c_stack_fault);
- intr_register (0x0d, 0, IF_ON, excp0d_general_protection);
- intr_register (0x0e, 0, IF_OFF, excp0e_page_fault);
- intr_register (0x10, 0, IF_ON, excp10_fp_error);
- intr_register (0x11, 0, IF_ON, excp11_alignment);
- intr_register (0x12, 0, IF_ON, excp12_machine_check);
- intr_register (0x13, 0, IF_ON, excp13_simd_error);
-#endif
-
- idtr_operand = make_dtr_operand (sizeof idt - 1, idt);
- asm volatile ("lidt %0" :: "m" (idtr_operand));
+ /* Invoke the interrupt's handler. */
+ handler = intr_handlers[frame->vec_no];
+ if (handler != NULL)
+ handler (frame);
+ else if (frame->vec_no == 0x27 || frame->vec_no == 0x2f)
+ {
+ /* There is no handler, but this interrupt can trigger
+ spuriously due to a hardware fault or hardware race
+ condition. Ignore it. */
+ }
+ else
+ {
+ /* No handler and not spurious. Invoke the unexpected
+ interrupt handler. */
+ intr_dump_frame (frame);
+ PANIC ("Unexpected interrupt");
+ }
+
+ /* Complete the processing of an external interrupt. */
+ if (external)
+ {
+ ASSERT (intr_get_level () == INTR_OFF);
+ ASSERT (intr_context ());
+
+ in_external_intr = false;
+ pic_end_of_interrupt (frame->vec_no);
+
+ if (yield_on_return)
+ thread_yield ();
+ }