fastcall void irq_handler(pt_regs_t *regs) { assert(!critical_inside(CRITICAL_IRQ_LOCK)); critical_enter(CRITICAL_IRQ_HANDLER); { int irq = regs->trapno - 0x20; ipl_enable(); irq_dispatch(irq); /* next lines ordered this way thats why. * On eoi current irq unmasked and may occur again right there, * on irq stack. It may repeat till stack exhaustion. * Disabling ipl first prevents irq handling of same or lower * level till switched to lower critical level. */ ipl_disable(); irqctrl_eoi(irq); } critical_leave(CRITICAL_IRQ_HANDLER); critical_dispatch_pending(); }
void __attribute__ ((noreturn)) arch_shutdown(arch_shutdown_mode_t mode) { switch (mode) { case ARCH_SHUTDOWN_MODE_HALT: acpi_shutdown(); break; case ARCH_SHUTDOWN_MODE_REBOOT: /* * There are several ways to reboot a computer. Unfortunately, none of * them will work on all machines. We try to use three methods: * 1. using ACPI; * 2. via the keyboard controller; * 3. generating a triple fault. * You can read more at * http://mjg59.dreamwidth.org/3561.html */ acpi_reset(); arch_reset_kbd(); cpu_triple_reset(); break; case ARCH_SHUTDOWN_MODE_ABORT: break; } ipl_disable(); while (1) {} }
void interrupt_handle(void) { unsigned int irq = REG_LOAD(GICC_IAR); if (irq == SPURIOUS_IRQ) return; /* TODO check if IRQ number is correct */ assert(!critical_inside(CRITICAL_IRQ_LOCK)); irqctrl_disable(irq); irqctrl_eoi(irq); critical_enter(CRITICAL_IRQ_HANDLER); { ipl_enable(); irq_dispatch(irq); ipl_disable(); } irqctrl_enable(irq); critical_leave(CRITICAL_IRQ_HANDLER); critical_dispatch_pending(); }