diff --git a/src/hulk/cpu.d b/src/hulk/cpu.d index 0edd8dd..aa3af81 100644 --- a/src/hulk/cpu.d +++ b/src/hulk/cpu.d @@ -135,37 +135,6 @@ enum uint CPUID_1_ECX_RDRND = 0x4000_0000u; enum uint CPUID_1_ECX_HYPERVISOR = 0x8000_0000u; /** @} */ -/** Interrupt suspend level (0 when interrupts are enabled). */ -private __gshared size_t intr_suspend_level; - -/** - * Suspend interrupts. - * - * This function disables interrupts. Calls can be nested and interrupts will - * be enabled only when the outermost pair of - * suspend_interrupts()/resume_interrupts() is complete. - */ -void suspend_interrupts() -{ - cli(); - intr_suspend_level++; -} - -/** - * Resume interrupts. - * - * Calls can be nested and interrupts will be enabled only when the outermost - * pair of suspend_interrupts()/resume_interrupts() is complete. - */ -void resume_interrupts() -{ - intr_suspend_level--; - if (intr_suspend_level == 0) - { - sti(); - } -} - void cli() { __asm("cli", ""); diff --git a/src/hulk/him.d b/src/hulk/him.d index 2609afc..23ad3d2 100644 --- a/src/hulk/him.d +++ b/src/hulk/him.d @@ -102,6 +102,46 @@ mixin(`private static __gshared extern(C) void function()[N_ISRS] isrs = [`, isrs_list(), `];`); +/** Interrupt suspend level (0 when interrupts are enabled). */ +private __gshared size_t interrupt_suspend_level; + +/** Interrupt nest level (0 when not in an interrupt handler). */ +private __gshared size_t interrupt_level; + +/** + * Suspend interrupts. + * + * This function disables interrupts. Calls can be nested and interrupts will + * be enabled only when the outermost pair of + * suspend_interrupts()/resume_interrupts() is complete. + */ +void suspend_interrupts() +{ + if (interrupt_level == 0) + { + cli(); + interrupt_suspend_level++; + } +} + +/** + * Resume interrupts. + * + * Calls can be nested and interrupts will be enabled only when the outermost + * pair of suspend_interrupts()/resume_interrupts() is complete. + */ +void resume_interrupts() +{ + if (interrupt_level == 0) + { + interrupt_suspend_level--; + if (interrupt_suspend_level == 0) + { + sti(); + } + } +} + struct Him { /** @@ -235,6 +275,7 @@ struct Him */ public extern(C) ulong * isr(ulong vector, ulong * stack_frame) { + interrupt_level++; Thread.current_thread.stack_pointer = stack_frame; if ((vector >= INT_APIC_BASE) && (vector < (INT_APIC_BASE + INT_APIC_COUNT))) { @@ -268,5 +309,6 @@ public extern(C) ulong * isr(ulong vector, ulong * stack_frame) } } Thread.current_thread = Thread.current_thread.list_next; + interrupt_level--; return Thread.current_thread.stack_pointer; }