aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/kapi/interrupts.cpp
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-03-26 16:35:32 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-03-27 07:02:35 +0100
commit00a77644192642e06462c11479a5c0e9bd859e9a (patch)
treed86cee8a0d7f4d2894ced16614fcd4554e10c327 /arch/x86_64/kapi/interrupts.cpp
parent2521d58e7a5c16595e401e1af7becb572ad35f53 (diff)
downloadteachos-00a77644192642e06462c11479a5c0e9bd859e9a.tar.xz
teachos-00a77644192642e06462c11479a5c0e9bd859e9a.zip
kapi: extract interrupts API
Diffstat (limited to 'arch/x86_64/kapi/interrupts.cpp')
-rw-r--r--arch/x86_64/kapi/interrupts.cpp68
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