Allow use of {suspend,resume}_interrupts() from within an ISR

Move functions from hulk.cpu to hulk.him.
This commit is contained in:
Josh Holtrop 2023-12-01 07:54:37 -05:00
parent 73f4d6b728
commit 44a305721e
2 changed files with 42 additions and 31 deletions

View File

@ -135,37 +135,6 @@ enum uint CPUID_1_ECX_RDRND = 0x4000_0000u;
enum uint CPUID_1_ECX_HYPERVISOR = 0x8000_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() void cli()
{ {
__asm("cli", ""); __asm("cli", "");

View File

@ -102,6 +102,46 @@ mixin(`private static __gshared extern(C) void function()[N_ISRS] isrs = [`,
isrs_list(), 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 struct Him
{ {
/** /**
@ -235,6 +275,7 @@ struct Him
*/ */
public extern(C) ulong * isr(ulong vector, ulong * stack_frame) public extern(C) ulong * isr(ulong vector, ulong * stack_frame)
{ {
interrupt_level++;
Thread.current_thread.stack_pointer = stack_frame; Thread.current_thread.stack_pointer = stack_frame;
if ((vector >= INT_APIC_BASE) && (vector < (INT_APIC_BASE + INT_APIC_COUNT))) 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; Thread.current_thread = Thread.current_thread.list_next;
interrupt_level--;
return Thread.current_thread.stack_pointer; return Thread.current_thread.stack_pointer;
} }