From dd2dc3ef9a5318a0f7c7c35be59759ab08adc3dc Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 20 Mar 2026 21:48:30 +0100 Subject: x86_64/cpu: implement basic interrupt handling --- arch/x86_64/src/cpu/initialization.cpp | 51 +++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'arch/x86_64/src/cpu/initialization.cpp') diff --git a/arch/x86_64/src/cpu/initialization.cpp b/arch/x86_64/src/cpu/initialization.cpp index aae4f1f..214687c 100644 --- a/arch/x86_64/src/cpu/initialization.cpp +++ b/arch/x86_64/src/cpu/initialization.cpp @@ -1,6 +1,7 @@ #include "arch/cpu/initialization.hpp" #include "arch/cpu/global_descriptor_table.hpp" +#include "arch/cpu/interrupts.hpp" #include "arch/cpu/segment_descriptor.hpp" #include "arch/cpu/task_state_segment.hpp" @@ -83,30 +84,38 @@ namespace arch::cpu .granularity = segment_granularity::page, .base_high = 0, }; + + constexpr auto make_tss_descriptor(task_state_segment const * tss_ptr) -> system_segment_descriptor + { + auto const address = std::bit_cast(tss_ptr); + auto const limit = sizeof(task_state_segment) - 1; + + return system_segment_descriptor{ + { + .limit_low = limit & 0xffff, // NOLINT(readability-magic-numbers) + .base_low = address & 0xffffff, // NOLINT(readability-magic-numbers) + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = false, + .type = segment_type::system, + .privilege_level = 0, + .present = true, + .limit_high = (limit >> 16) & 0xf, // NOLINT(readability-magic-numbers) + .long_mode = false, + .protected_mode = false, + .granularity = segment_granularity::byte, + .base_high = (address >> 24) & 0xff, // NOLINT(readability-magic-numbers) + }, + (address >> 32) & 0xffff'ffff, // NOLINT(readability-magic-numbers) + }; + } } // namespace auto initialize_descriptors() -> void { auto static tss = task_state_segment{}; - auto static tss_descriptor = system_segment_descriptor{ - { - .limit_low = (sizeof(tss) - 1) & 0xffff, // NOLINT(readability-magic-numbers) - .base_low = std::bit_cast(&tss) & 0xffffff, // NOLINT(readability-magic-numbers) - .accessed = false, - .read_write = false, - .direction_or_conforming = false, - .executable = false, - .type = segment_type::system, - .privilege_level = 0, - .present = true, - .limit_high = ((sizeof(tss) - 1) >> 16) & 0xf, // NOLINT(readability-magic-numbers) - .long_mode = false, - .protected_mode = false, - .granularity = segment_granularity::byte, - .base_high = (std::bit_cast(&tss) >> 24) & 0xff, // NOLINT(readability-magic-numbers) - }, - (std::bit_cast(&tss) >> 32) & 0xffff'ffff, // NOLINT(readability-magic-numbers) - }; + auto static tss_descriptor = make_tss_descriptor(&tss); auto static gdt = global_descriptor_table{ gdt_null_descriptor, gdt_kernel_code_descriptor, gdt_kernel_data_descriptor, @@ -116,7 +125,9 @@ namespace arch::cpu kstd::println("[x86_64:SYS] Reloading Global Descriptor Table."); gdt.load(1, 2); - kstd::println("[x86_64:SYS] TODO: initialize Interrupt Descriptor Table."); + kstd::println("[x86_64:SYS] Initializing Interrupt Descriptor Table."); + auto static idt = interrupt_descriptor_table{}; + idt.load(); } } // namespace arch::cpu -- cgit v1.2.3 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/src/cpu/initialization.cpp | 37 ++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'arch/x86_64/src/cpu/initialization.cpp') 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 -- cgit v1.2.3 From 6a392e8e40f163470d7fb12e0846f2ec7bdee61a Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 21 Mar 2026 09:02:12 +0100 Subject: x86_64/cpu: ignore 8259 interrupts --- arch/x86_64/src/cpu/initialization.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'arch/x86_64/src/cpu/initialization.cpp') diff --git a/arch/x86_64/src/cpu/initialization.cpp b/arch/x86_64/src/cpu/initialization.cpp index 85da38d..5f4703d 100644 --- a/arch/x86_64/src/cpu/initialization.cpp +++ b/arch/x86_64/src/cpu/initialization.cpp @@ -144,9 +144,8 @@ namespace arch::cpu 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}; + constexpr auto pic_master_mask = std::uint8_t{0x00}; + constexpr auto pic_slave_mask = std::uint8_t{0x00}; pic_master_control_port::write(pic_init_command); pic_slave_control_port::write(pic_init_command); @@ -162,9 +161,6 @@ namespace arch::cpu 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 -- cgit v1.2.3