aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-03-21 10:13:17 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-03-21 10:16:21 +0100
commitc9ce8625dd80f701e280f90cb30c30f8663473e9 (patch)
tree08eb79b8e775fcd4ee8c334cd019caca8d6f61f3 /arch/x86_64
parentfcf0cd73b0978c2db3e719542cf81d7d2c0fe24e (diff)
downloadteachos-c9ce8625dd80f701e280f90cb30c30f8663473e9.tar.xz
teachos-c9ce8625dd80f701e280f90cb30c30f8663473e9.zip
x86_64/cpu: fixup 8259 interrupt handling
We now mask the timer interrupt and ensure we are informing the PIC about us having handled the interrupt.
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/include/arch/cpu/legacy_pic.hpp19
-rw-r--r--arch/x86_64/src/cpu/initialization.cpp12
-rw-r--r--arch/x86_64/src/cpu/interrupts.cpp4
3 files changed, 28 insertions, 7 deletions
diff --git a/arch/x86_64/include/arch/cpu/legacy_pic.hpp b/arch/x86_64/include/arch/cpu/legacy_pic.hpp
new file mode 100644
index 0000000..9f53d86
--- /dev/null
+++ b/arch/x86_64/include/arch/cpu/legacy_pic.hpp
@@ -0,0 +1,19 @@
+#ifndef TEACHOS_X86_64_CPU_LEGACY_PIC_HPP
+#define TEACHOS_X86_64_CPU_LEGACY_PIC_HPP
+
+#include "arch/device_io/port_io.hpp"
+
+#include <cstdint>
+
+namespace arch::cpu
+{
+ using pic_master_control_port = io::port<0x20, std::uint8_t, io::port_read, io::port_write>;
+ using pic_master_data_port = io::port<0x21, std::uint8_t, io::port_read, io::port_write>;
+ using pic_slave_control_port = io::port<0xa0, std::uint8_t, io::port_read, io::port_write>;
+ using pic_slave_data_port = io::port<0xa1, std::uint8_t, io::port_read, io::port_write>;
+
+ constexpr auto pic_end_of_interrupt = std::uint8_t{0x20};
+
+} // namespace arch::cpu
+
+#endif \ No newline at end of file
diff --git a/arch/x86_64/src/cpu/initialization.cpp b/arch/x86_64/src/cpu/initialization.cpp
index 5f4703d..878fa07 100644
--- a/arch/x86_64/src/cpu/initialization.cpp
+++ b/arch/x86_64/src/cpu/initialization.cpp
@@ -2,9 +2,9 @@
#include "arch/cpu/global_descriptor_table.hpp"
#include "arch/cpu/interrupts.hpp"
+#include "arch/cpu/legacy_pic.hpp"
#include "arch/cpu/segment_descriptor.hpp"
#include "arch/cpu/task_state_segment.hpp"
-#include "arch/device_io/port_io.hpp"
#include <kstd/print>
@@ -133,18 +133,13 @@ namespace arch::cpu
auto initialize_legacy_interrupts() -> void
{
- using pic_master_control_port = io::port<0x20, std::uint8_t, io::port_read, io::port_write>;
- using pic_master_data_port = io::port<0x21, std::uint8_t, io::port_read, io::port_write>;
- using pic_slave_control_port = io::port<0xa0, std::uint8_t, io::port_read, io::port_write>;
- using pic_slave_data_port = io::port<0xa1, std::uint8_t, io::port_read, io::port_write>;
-
constexpr auto pic_init_command = std::uint8_t{0x11};
constexpr auto pic_master_offset = std::uint8_t{0x20};
constexpr auto pic_slave_offset = std::uint8_t{0x28};
constexpr auto pic_cascade_address = std::uint8_t{0x04};
constexpr auto pic_cascade_slave_identity = std::uint8_t{0x02};
constexpr auto pic_use_8086_mode = std::uint8_t{0x01};
- constexpr auto pic_master_mask = std::uint8_t{0x00};
+ constexpr auto pic_master_mask = std::uint8_t{0x01};
constexpr auto pic_slave_mask = std::uint8_t{0x00};
pic_master_control_port::write(pic_init_command);
@@ -161,6 +156,9 @@ namespace arch::cpu
pic_master_data_port::write(pic_master_mask);
pic_slave_data_port::write(pic_slave_mask);
+
+ pic_master_data_port::write(pic_master_mask);
+ pic_slave_data_port::write(pic_slave_mask);
}
} // namespace arch::cpu
diff --git a/arch/x86_64/src/cpu/interrupts.cpp b/arch/x86_64/src/cpu/interrupts.cpp
index 466389d..048c461 100644
--- a/arch/x86_64/src/cpu/interrupts.cpp
+++ b/arch/x86_64/src/cpu/interrupts.cpp
@@ -2,6 +2,7 @@
#include "kapi/cpu.hpp"
+#include "arch/cpu/legacy_pic.hpp"
#include "arch/cpu/segment_selector.hpp"
#include <kstd/print>
@@ -42,6 +43,9 @@ namespace arch::cpu
auto handle_legacy_interrupt(interrupt_frame * frame) -> void
{
kstd::println("[x86_64:SYS] Ignoring 8259 legacy interrupt {:#04x}", frame->interrupt.number);
+
+ pic_master_control_port::write(pic_end_of_interrupt);
+ pic_slave_control_port::write(pic_end_of_interrupt);
}
} // namespace