diff --git a/kernel/include/kernel/InterruptController.h b/kernel/include/kernel/InterruptController.h index 56dc6b2564..7283b97526 100644 --- a/kernel/include/kernel/InterruptController.h +++ b/kernel/include/kernel/InterruptController.h @@ -5,9 +5,6 @@ #include -#define DISABLE_INTERRUPTS() asm volatile("cli") -#define ENABLE_INTERRUPTS() asm volatile("sti") - namespace Kernel { @@ -51,11 +48,4 @@ namespace Kernel bool m_using_apic { false }; }; - inline bool interrupts_enabled() - { - uintptr_t flags; - asm volatile("pushf; pop %0" : "=r"(flags) :: "memory"); - return flags & (1 << 9); - } - } diff --git a/kernel/include/kernel/Interrupts.h b/kernel/include/kernel/Interrupts.h new file mode 100644 index 0000000000..c5285ef528 --- /dev/null +++ b/kernel/include/kernel/Interrupts.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace Kernel +{ + + enum class InterruptState + { + Disabled, + Enabled, + }; + +#if ARCH(x86_64) || ARCH(i386) + + inline void set_interrupt_state(InterruptState state) + { + if (state == InterruptState::Enabled) + asm volatile("sti"); + else + asm volatile("cli"); + } + + inline InterruptState get_interrupt_state() + { + uintptr_t flags; + asm volatile("pushf; pop %0" : "=rm"(flags)); + if (flags & (1 << 9)) + return InterruptState::Enabled; + return InterruptState::Disabled; + } + +#else +#error "Unknown architecure" +#endif + +} diff --git a/kernel/include/kernel/Lock/SpinLock.h b/kernel/include/kernel/Lock/SpinLock.h index 9606f763bb..f7ce17215a 100644 --- a/kernel/include/kernel/Lock/SpinLock.h +++ b/kernel/include/kernel/Lock/SpinLock.h @@ -2,14 +2,13 @@ #include #include +#include #include namespace Kernel { - using InterruptState = bool; - class SpinLock { BAN_NON_COPYABLE(SpinLock); diff --git a/kernel/kernel/Lock/SpinLock.cpp b/kernel/kernel/Lock/SpinLock.cpp index 771e330dbc..aaf12742f9 100644 --- a/kernel/kernel/Lock/SpinLock.cpp +++ b/kernel/kernel/Lock/SpinLock.cpp @@ -12,8 +12,8 @@ namespace Kernel auto tid = Scheduler::current_tid(); ASSERT_NEQ(m_locker.load(), tid); - InterruptState state = interrupts_enabled(); - DISABLE_INTERRUPTS(); + auto state = get_interrupt_state(); + set_interrupt_state(InterruptState::Disabled); if (!m_locker.compare_exchange(-1, tid)) ASSERT_NOT_REACHED(); @@ -25,16 +25,15 @@ namespace Kernel { ASSERT_EQ(m_locker.load(), Scheduler::current_tid()); m_locker.store(-1); - if (state) - ENABLE_INTERRUPTS(); + set_interrupt_state(state); } InterruptState RecursiveSpinLock::lock() { auto tid = Scheduler::current_tid(); - InterruptState state = interrupts_enabled(); - DISABLE_INTERRUPTS(); + auto state = get_interrupt_state(); + set_interrupt_state(InterruptState::Disabled); if (tid == m_locker) ASSERT_GT(m_lock_depth, 0); @@ -57,8 +56,7 @@ namespace Kernel ASSERT_GT(m_lock_depth, 0); if (--m_lock_depth == 0) m_locker = -1; - if (state) - ENABLE_INTERRUPTS(); + set_interrupt_state(state); } } diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 6266714a66..3ef798ce7d 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -220,7 +220,7 @@ namespace Kernel void Process::on_thread_exit(Thread& thread) { - ASSERT(!interrupts_enabled()); + ASSERT(get_interrupt_state() == InterruptState::Disabled); ASSERT(m_threads.size() > 0); diff --git a/kernel/kernel/Scheduler.cpp b/kernel/kernel/Scheduler.cpp index 93ec9805b1..52d31cf946 100644 --- a/kernel/kernel/Scheduler.cpp +++ b/kernel/kernel/Scheduler.cpp @@ -11,8 +11,8 @@ #define SCHEDULER_VERIFY_INTERRUPT_STATE 1 #if SCHEDULER_VERIFY_INTERRUPT_STATE - #define VERIFY_STI() ASSERT(interrupts_enabled()) - #define VERIFY_CLI() ASSERT(!interrupts_enabled()) + #define VERIFY_STI() ASSERT(get_interrupt_state() == InterruptState::Enabled) + #define VERIFY_CLI() ASSERT(get_interrupt_state() == InterruptState::Disabled) #else #define VERIFY_STI() #define VERIFY_CLI() @@ -84,13 +84,10 @@ namespace Kernel void Scheduler::reschedule() { - DISABLE_INTERRUPTS(); + set_interrupt_state(InterruptState::Disabled); if (save_current_thread()) - { - ENABLE_INTERRUPTS(); - return; - } + return set_interrupt_state(InterruptState::Enabled); advance_current_thread(); execute_current_thread(); ASSERT_NOT_REACHED(); @@ -190,7 +187,7 @@ namespace Kernel void Scheduler::delete_current_process_and_thread() { - DISABLE_INTERRUPTS(); + set_interrupt_state(InterruptState::Disabled); load_temp_stack(); PageTable::kernel().load(); @@ -285,7 +282,7 @@ namespace Kernel if (save_current_thread()) { - ENABLE_INTERRUPTS(); + set_interrupt_state(InterruptState::Enabled); return; } @@ -311,7 +308,7 @@ namespace Kernel void Scheduler::set_current_thread_sleeping(uint64_t wake_time) { VERIFY_STI(); - DISABLE_INTERRUPTS(); + set_interrupt_state(InterruptState::Disabled); ASSERT(m_current_thread); @@ -322,7 +319,7 @@ namespace Kernel void Scheduler::block_current_thread(Semaphore* semaphore, uint64_t wake_time) { VERIFY_STI(); - DISABLE_INTERRUPTS(); + set_interrupt_state(InterruptState::Disabled); ASSERT(m_current_thread); diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index dda33d3e6f..11c44c6538 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -82,7 +82,7 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info) { using namespace Kernel; - DISABLE_INTERRUPTS(); + set_interrupt_state(InterruptState::Disabled); if (!validate_boot_magic(boot_magic)) {