#include "interrupts/Interrupts.h" #include "trace/StackTracer.h" #include "utils/Registers.h" void Interrupts::disable() { asm volatile("cli"); } void Interrupts::enable() { asm volatile("sti"); } extern int _asm_interrupt_exit; bool Interrupts::is_in_handler() { return stack_trace_contains((uintptr_t)&_asm_interrupt_exit); } void Interrupts::return_from_handler(Context* context) { asm volatile("mov %0, %%rsp\n" "jmp _asm_interrupt_exit" : : "r"(context)); } bool Interrupts::are_enabled() { return (read_rflags() & 0x200) > 0; } static bool saved_interrupt_state; void Interrupts::push_and_disable() { saved_interrupt_state = are_enabled(); disable(); } void Interrupts::push_and_enable() { saved_interrupt_state = are_enabled(); enable(); } void Interrupts::pop() { if (saved_interrupt_state && !are_enabled()) enable(); else if (!saved_interrupt_state && are_enabled()) disable(); } bool Interrupts::were_enabled() { return saved_interrupt_state; }