From eb8074e9003034ef2186b62fc66b1073455be5de Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 21 Mar 2026 08:48:26 +0100 Subject: x86_64/cpu: fixup 8259 interrupts --- arch/x86_64/include/arch/cpu/initialization.hpp | 3 ++ arch/x86_64/include/arch/cpu/interrupts.hpp | 3 ++ arch/x86_64/kapi/system.cpp | 3 ++ arch/x86_64/src/cpu/initialization.cpp | 37 +++++++++++++++++++++++++ arch/x86_64/src/cpu/interrupts.cpp | 10 +++++++ 5 files changed, 56 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/include/arch/cpu/initialization.hpp b/arch/x86_64/include/arch/cpu/initialization.hpp index b2ce864..71186d4 100644 --- a/arch/x86_64/include/arch/cpu/initialization.hpp +++ b/arch/x86_64/include/arch/cpu/initialization.hpp @@ -3,4 +3,7 @@ namespace arch::cpu { auto initialize_descriptors() -> void; + + auto initialize_legacy_interrupts() -> void; + } // namespace arch::cpu diff --git a/arch/x86_64/include/arch/cpu/interrupts.hpp b/arch/x86_64/include/arch/cpu/interrupts.hpp index 19358ac..8f156a4 100644 --- a/arch/x86_64/include/arch/cpu/interrupts.hpp +++ b/arch/x86_64/include/arch/cpu/interrupts.hpp @@ -109,6 +109,9 @@ namespace arch::cpu auto static read() -> interrupt_descriptor_table_register; }; + auto enable_interrupts() -> void; + auto disable_interrupts() -> void; + } // namespace arch::cpu #endif \ No newline at end of file diff --git a/arch/x86_64/kapi/system.cpp b/arch/x86_64/kapi/system.cpp index ffb6a46..301169f 100644 --- a/arch/x86_64/kapi/system.cpp +++ b/arch/x86_64/kapi/system.cpp @@ -1,6 +1,7 @@ #include "kapi/system.hpp" #include "arch/cpu/initialization.hpp" +#include "arch/cpu/interrupts.hpp" namespace kapi::system { @@ -8,6 +9,8 @@ namespace kapi::system auto memory_initialized() -> void { arch::cpu::initialize_descriptors(); + arch::cpu::initialize_legacy_interrupts(); + arch::cpu::enable_interrupts(); } } // namespace kapi::system \ 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 214687c..85da38d 100644 --- a/arch/x86_64/src/cpu/initialization.cpp +++ b/arch/x86_64/src/cpu/initialization.cpp @@ -4,6 +4,7 @@ #include "arch/cpu/interrupts.hpp" #include "arch/cpu/segment_descriptor.hpp" #include "arch/cpu/task_state_segment.hpp" +#include "arch/device_io/port_io.hpp" #include @@ -130,4 +131,40 @@ namespace arch::cpu idt.load(); } + 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{0xfb}; + constexpr auto pic_slave_mask = std::uint8_t{0xff}; + constexpr auto pic_timer_mask = std::uint8_t{0x01}; + + pic_master_control_port::write(pic_init_command); + pic_slave_control_port::write(pic_init_command); + + pic_master_data_port::write(pic_master_offset); + pic_slave_data_port::write(pic_slave_offset); + + pic_master_data_port::write(pic_cascade_address); + pic_slave_data_port::write(pic_cascade_slave_identity); + + pic_master_data_port::write(pic_use_8086_mode); + pic_slave_data_port::write(pic_use_8086_mode); + + pic_master_data_port::write(pic_master_mask); + pic_slave_data_port::write(pic_slave_mask); + + auto const current_master_mask = pic_master_data_port::read(); + pic_master_data_port::write(current_master_mask | pic_timer_mask); + } + } // namespace arch::cpu diff --git a/arch/x86_64/src/cpu/interrupts.cpp b/arch/x86_64/src/cpu/interrupts.cpp index 08469c0..19cf6f4 100644 --- a/arch/x86_64/src/cpu/interrupts.cpp +++ b/arch/x86_64/src/cpu/interrupts.cpp @@ -91,4 +91,14 @@ namespace arch::cpu return idtr; } + auto enable_interrupts() -> void + { + asm volatile("sti"); + } + + auto disable_interrupts() -> void + { + asm volatile("cli"); + } + } // namespace arch::cpu \ No newline at end of file -- cgit v1.2.3