From f4dc64976049761a6f56dd55d9d0b651f1e9475f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 16:47:41 +0100 Subject: kapi: move interrupt handling to kernel --- kernel/kapi/interrupts.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 kernel/kapi/interrupts.cpp (limited to 'kernel/kapi/interrupts.cpp') diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp new file mode 100644 index 0000000..e79453a --- /dev/null +++ b/kernel/kapi/interrupts.cpp @@ -0,0 +1,45 @@ +#include "kapi/interrupts.hpp" + +#include +#include + +#include +#include + +namespace kapi::interrupts +{ + + namespace + { + auto constinit handlers = std::array, 256>{}; + } // namespace + + auto register_handler(std::uint32_t irq_number, handler & handler) -> void + { + auto & handler_list = handlers.at(irq_number); + handler_list.push_back(&handler); + } + + auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void + { + static_cast(irq_number); + static_cast(handler); + kstd::println("[OS:interrupts] TODO: support erasure from vector."); + } + + auto dispatch(std::uint32_t irq_number) -> status + { + auto & handler_list = handlers.at(irq_number); + + for (auto handler : handler_list) + { + if (handler && handler->handle_interrupt(irq_number) == status::handled) + { + return status::handled; + } + } + + return status::unhandled; + } + +} // namespace kapi::interrupts \ No newline at end of file -- cgit v1.2.3 From aa68f53d2502e0ea81c8e9c95e37d9847cb6cb16 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 17:15:26 +0100 Subject: arch/cpu: fix interrupt dispatch --- kernel/kapi/interrupts.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'kernel/kapi/interrupts.cpp') diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp index e79453a..27427bb 100644 --- a/kernel/kapi/interrupts.cpp +++ b/kernel/kapi/interrupts.cpp @@ -31,6 +31,12 @@ namespace kapi::interrupts { auto & handler_list = handlers.at(irq_number); + if (handler_list.empty()) + { + kstd::println(kstd::print_sink::stderr, "[OS:interrupts] No handler for IRQ{}", irq_number); + return status::unhandled; + } + for (auto handler : handler_list) { if (handler && handler->handle_interrupt(irq_number) == status::handled) -- cgit v1.2.3 From 11c6d57e013832983bcd9bb965d470bf4c282ab6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 26 Mar 2026 18:40:39 +0100 Subject: kstd/vector: implement range erase --- kernel/kapi/interrupts.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'kernel/kapi/interrupts.cpp') diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp index 27427bb..e172e70 100644 --- a/kernel/kapi/interrupts.cpp +++ b/kernel/kapi/interrupts.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -22,9 +23,9 @@ namespace kapi::interrupts auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void { - static_cast(irq_number); - static_cast(handler); - kstd::println("[OS:interrupts] TODO: support erasure from vector."); + auto & handler_list = handlers.at(irq_number); + auto [first, last] = std::ranges::remove(handler_list, &handler); + handler_list.erase(first, last); } auto dispatch(std::uint32_t irq_number) -> status -- cgit v1.2.3 From 3070bb45b9741165d786b2c5a018ee55c1a82db8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 27 Mar 2026 07:05:05 +0100 Subject: kernel/interrupts: switch to flat_map for dispatch --- kernel/kapi/interrupts.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'kernel/kapi/interrupts.cpp') diff --git a/kernel/kapi/interrupts.cpp b/kernel/kapi/interrupts.cpp index e172e70..0e37bc3 100644 --- a/kernel/kapi/interrupts.cpp +++ b/kernel/kapi/interrupts.cpp @@ -1,10 +1,10 @@ #include "kapi/interrupts.hpp" +#include #include #include #include -#include #include namespace kapi::interrupts @@ -12,13 +12,20 @@ namespace kapi::interrupts namespace { - auto constinit handlers = std::array, 256>{}; + auto constinit handlers = kstd::flat_map>{}; } // namespace auto register_handler(std::uint32_t irq_number, handler & handler) -> void { - auto & handler_list = handlers.at(irq_number); - handler_list.push_back(&handler); + if (handlers.contains(irq_number)) + { + auto & handler_list = handlers.at(irq_number); + handler_list.push_back(&handler); + } + else + { + handlers.emplace(irq_number, kstd::vector{&handler}); + } } auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void @@ -30,6 +37,12 @@ namespace kapi::interrupts auto dispatch(std::uint32_t irq_number) -> status { + if (!handlers.contains(irq_number)) + { + kstd::println(kstd::print_sink::stderr, "[OS:interrupts] No handler for IRQ{}", irq_number); + return status::unhandled; + } + auto & handler_list = handlers.at(irq_number); if (handler_list.empty()) -- cgit v1.2.3