diff options
Diffstat (limited to 'arch/x86_64/kapi/interrupts.cpp')
| -rw-r--r-- | arch/x86_64/kapi/interrupts.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/arch/x86_64/kapi/interrupts.cpp b/arch/x86_64/kapi/interrupts.cpp new file mode 100644 index 0000000..babc926 --- /dev/null +++ b/arch/x86_64/kapi/interrupts.cpp @@ -0,0 +1,68 @@ +#include "kapi/interrupts.hpp" + +#include "kapi/system.hpp" + +#include <kstd/print> +#include <kstd/vector> + +#include <array> +#include <cstdint> + +namespace kapi::interrupts +{ + + namespace + { + constexpr auto irq_offset = 32uz; + auto constinit handlers = std::array<kstd::vector<handler *>, 256 - irq_offset>{}; + } // namespace + + auto enable() -> void + { + asm volatile("sti"); + } + + auto disable() -> void + { + asm volatile("cli"); + } + + auto register_handler(std::uint32_t irq_number, handler & handler) -> void + { + if (irq_number < irq_offset) + { + system::panic("[x86_64:CPU] IRQ number must be in range [32, 255]."); + } + + handlers[irq_number - irq_offset].push_back(&handler); + } + + auto unregister_handler(std::uint32_t irq_number, [[maybe_unused]] handler & handler) -> void + { + if (irq_number < irq_offset) + { + system::panic("[x86_64:CPU] IRQ number must be in range [32, 255]."); + } + + kstd::println("[x86_64:CPU] TODO: support erasure from vector."); + } + + auto dispatch(std::uint32_t irq_number) -> status + { + if (irq_number < irq_offset) + { + return status::unhandled; + } + + for (auto handler : handlers[irq_number - irq_offset]) + { + if (handler && handler->handle_interrupt(irq_number) == status::handled) + { + return status::handled; + } + } + + return status::unhandled; + } + +} // namespace kapi::interrupts
\ No newline at end of file |
