From ab4c59912c526d515e6e72188c08a7f92e5573e8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:07:54 +0200 Subject: x86_64: implement legacy PIT driver --- arch/x86_64/src/devices/legacy_pit.cpp | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 arch/x86_64/src/devices/legacy_pit.cpp (limited to 'arch/x86_64/src/devices/legacy_pit.cpp') diff --git a/arch/x86_64/src/devices/legacy_pit.cpp b/arch/x86_64/src/devices/legacy_pit.cpp new file mode 100644 index 0000000..f2fb70e --- /dev/null +++ b/arch/x86_64/src/devices/legacy_pit.cpp @@ -0,0 +1,54 @@ +#include "arch/devices/legacy_pit.hpp" + +#include "kapi/devices.hpp" +#include "kapi/devices/device.hpp" +#include "kapi/interrupts.hpp" + +#include "arch/device_io/port_io.hpp" + +#include + +namespace arch::devices +{ + + namespace + { + using command_port = io::port<0x43, std::uint8_t, io::port_write>; + using channel_0_port = io::port<0x40, std::uint8_t, io::port_write>; + using channel_1_port = io::port<0x41, std::uint8_t, io::port_write>; + using channel_2_port = io::port<0x42, std::uint8_t, io::port_write>; + } // namespace + + legacy_pit::legacy_pit(std::uint32_t frequency_in_hz) + : kapi::devices::device{kapi::devices::allocate_major_number(), 0, "legacy_pit"} + , m_irq_number{0} + , m_frequency_in_hz{frequency_in_hz} + {} + + auto legacy_pit::init() -> bool + { + constexpr auto base_frequency = 1'193'182u; + auto divisor = static_cast(base_frequency / m_frequency_in_hz); + + kapi::interrupts::register_handler(m_irq_number, *this); + + command_port::write(0x36); // NOLINT + channel_0_port::write(divisor & 0xff); // NOLINT + channel_0_port::write(divisor >> 8 & 0xff); // NOLINT + + return true; + } + + auto legacy_pit::handle_interrupt(std::uint32_t irq_number) -> kapi::interrupts::status + { + if (irq_number != m_irq_number) + { + return kapi::interrupts::status::unhandled; + } + + ++m_ticks; + + return kapi::interrupts::status::handled; + } + +} // namespace arch::devices \ No newline at end of file -- cgit v1.2.3 From 21489576381d827871e7cdf060929c5d7f3d4e9f Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:49:14 +0200 Subject: devices: don't automatically allocate major numbers in ctors --- arch/x86_64/src/devices/legacy_pit.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/src/devices/legacy_pit.cpp') diff --git a/arch/x86_64/src/devices/legacy_pit.cpp b/arch/x86_64/src/devices/legacy_pit.cpp index f2fb70e..970f538 100644 --- a/arch/x86_64/src/devices/legacy_pit.cpp +++ b/arch/x86_64/src/devices/legacy_pit.cpp @@ -6,6 +6,7 @@ #include "arch/device_io/port_io.hpp" +#include #include namespace arch::devices @@ -19,8 +20,8 @@ namespace arch::devices using channel_2_port = io::port<0x42, std::uint8_t, io::port_write>; } // namespace - legacy_pit::legacy_pit(std::uint32_t frequency_in_hz) - : kapi::devices::device{kapi::devices::allocate_major_number(), 0, "legacy_pit"} + legacy_pit::legacy_pit(std::size_t major, std::uint32_t frequency_in_hz) + : kapi::devices::device{major, 0, "legacy_pit"} , m_irq_number{0} , m_frequency_in_hz{frequency_in_hz} {} -- cgit v1.2.3 From c5afb5c1ce1c084c840dbb58d73af6fe2b235ec7 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:55:47 +0200 Subject: x86_64: ensure PIT is not overwhelmed on config --- arch/x86_64/src/devices/legacy_pit.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'arch/x86_64/src/devices/legacy_pit.cpp') diff --git a/arch/x86_64/src/devices/legacy_pit.cpp b/arch/x86_64/src/devices/legacy_pit.cpp index 970f538..a8df3c3 100644 --- a/arch/x86_64/src/devices/legacy_pit.cpp +++ b/arch/x86_64/src/devices/legacy_pit.cpp @@ -18,6 +18,9 @@ namespace arch::devices using channel_0_port = io::port<0x40, std::uint8_t, io::port_write>; using channel_1_port = io::port<0x41, std::uint8_t, io::port_write>; using channel_2_port = io::port<0x42, std::uint8_t, io::port_write>; + + constexpr auto base_frequency = 1'193'182u; + constexpr auto square_wave_mode = 0x36; } // namespace legacy_pit::legacy_pit(std::size_t major, std::uint32_t frequency_in_hz) @@ -28,14 +31,16 @@ namespace arch::devices auto legacy_pit::init() -> bool { - constexpr auto base_frequency = 1'193'182u; auto divisor = static_cast(base_frequency / m_frequency_in_hz); kapi::interrupts::register_handler(m_irq_number, *this); - command_port::write(0x36); // NOLINT - channel_0_port::write(divisor & 0xff); // NOLINT - channel_0_port::write(divisor >> 8 & 0xff); // NOLINT + command_port::write(square_wave_mode); + io::wait(); + channel_0_port::write(divisor & 0xff); + io::wait(); + channel_0_port::write(divisor >> 8 & 0xff); + io::wait(); return true; } -- cgit v1.2.3