default:
break;
}
+
+ /*
+ * Issue the EOI before invoking the scheduler since it might reschedule
+ * tasks, and the remainder of the function would not be executed until
+ * this task gets scheduled again. Since the interrupt controller (whether
+ * it be the i8259 or the APIC) will not issue further interrupts until
+ * an EOI is issued, the next task would effectively not get preempted
+ * until it makes a syscall or causes an exception (or an NMI or IPI
+ * occurs).
+ *
+ * TLDR: Issue the EOI first to avoid deadlocks.
+ */
+
+#if CONFIG_APIC == 1
+ /* FIXME: Make sure this is NOT done for NMI, SMI, INIT, ExtInt,
+ * SIPI or INIT-deassert mode interrupts */
+ _apic_eoi(ctx.intn);
+#else
+ _i8259_eoi(ctx.intn);
+#endif /* CONFIG_APIC */
+
/*
if(ctx.intn == 32) {
unsigned *apic_esr;
break;
}
- #if CONFIG_APIC == 1
- /* FIXME: Make sure this is NOT done for NMI, SMI, INIT, ExtInt,
- * SIPI or INIT-deassert mode interrupts */
- _apic_eoi(ctx.intn);
- #else
- _i8259_eoi(ctx.intn);
- #endif /* CONFIG_APIC */
-
return(0);
}