From e7abfb7bf87ac605b2168891973d7e04a84d627e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 31 Mar 2026 21:56:37 +0200 Subject: kapi/devices: introduce basic bus abstraction --- kapi/include/kapi/devices/bus.hpp | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 kapi/include/kapi/devices/bus.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp new file mode 100644 index 0000000..cf8d090 --- /dev/null +++ b/kapi/include/kapi/devices/bus.hpp @@ -0,0 +1,40 @@ +#ifndef TEACHOS_KAPI_DEVICES_BUS_HPP +#define TEACHOS_KAPI_DEVICES_BUS_HPP + +#include "kapi/devices/device.hpp" + +#include +#include +#include + +#include + +namespace kapi::devices +{ + //! A bus device that represents a logical/physical tree of devices and busses. + struct bus : device + { + //! Construct a bus with the given major number, minor number, and name. + //! + //! @param major The major number of the bus. + //! @param minor The minor number of the bus. + //! @param name The name of the bus. + bus(std::size_t major, std::size_t minor, kstd::string const & name) + : device(major, minor, name) + {} + + //! Attach a child device to this bus. + //! + //! Whenever a device is attached to a bus, the bus takes sole ownership of the device. + //! + //! @param child The child device to attach. + virtual auto add_child(kstd::unique_ptr child) -> void = 0; + + //! Get a list of all child devices attached to this bus. + //! + //! @return A reference to list of child devices of this bus. + [[nodiscard]] virtual auto children() const -> kstd::vector const & = 0; + }; +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From 77473afe9d5acb9450443b07b56d3dbc2f0639a6 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 31 Mar 2026 22:22:25 +0200 Subject: kstd: introduce observer_ptr --- kapi/include/kapi/devices/bus.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index cf8d090..0b25ac1 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -4,6 +4,7 @@ #include "kapi/devices/device.hpp" #include +#include #include #include @@ -33,7 +34,7 @@ namespace kapi::devices //! Get a list of all child devices attached to this bus. //! //! @return A reference to list of child devices of this bus. - [[nodiscard]] virtual auto children() const -> kstd::vector const & = 0; + [[nodiscard]] virtual auto children() const -> kstd::vector> const & = 0; }; } // namespace kapi::devices -- cgit v1.2.3 From a2ff4ace21699fe2be2e0401af78790c01f78d85 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 11:45:55 +0200 Subject: kstd: move observer_ptr to bits --- kapi/include/kapi/devices/bus.hpp | 1 - 1 file changed, 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index 0b25ac1..a8d7df8 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -4,7 +4,6 @@ #include "kapi/devices/device.hpp" #include -#include #include #include -- cgit v1.2.3 From d0c532af74d8d486d734904fd330d5dae7f49754 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 13:36:01 +0200 Subject: kapi: add basic device subsystem --- kapi/include/kapi/devices.hpp | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 kapi/include/kapi/devices.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp new file mode 100644 index 0000000..60a39bd --- /dev/null +++ b/kapi/include/kapi/devices.hpp @@ -0,0 +1,46 @@ +#ifndef TEACHOS_KAPI_DEVICES_HPP +#define TEACHOS_KAPI_DEVICES_HPP + +#include "kapi/devices/bus.hpp" // IWYU pragma: export +#include "kapi/devices/device.hpp" // IWYU pragma: export + +#include + +namespace kapi::devices +{ + + //! @addtogroup kernel-defined + //! @{ + + //! Initialize the kernel's device management subsystem. + auto init() -> void; + + //! Get the virtual system root bus. + //! + //! @warning This function will panic if the root bus has not been initialized. + //! + //! @return a reference to the root bus. + auto get_root_bus() -> bus &; + + //! Ask the kernel to allocate a new major number. + //! + //! @return a new, unused major number. + auto allocate_major_number() -> std::size_t; + + //! Register a new device with the kernel's device manager. + //! + //! @param device The device to register. + //! @return true if the device was registered successfully, false otherwise. + auto register_device(device & device) -> bool; + + //! Unregister a device from the kernel's device manager. + //! + //! @param device The device to unregister. + //! @return true if the device was unregistered successfully, false otherwise. + auto unregister_device(device & device) -> bool; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From b84c4c9d8c90f3d3fd5a60de282278912fad2f04 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 13:59:27 +0200 Subject: x86_64/devices: implement ISA bus stub --- kapi/include/kapi/devices.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index 60a39bd..2028a64 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -41,6 +41,14 @@ namespace kapi::devices //! @} + //! @addtogroup platform-defined + //! @{ + + //! Initialize the platform's device tree. + auto init_platform_devices() -> void; + + //! @} + } // namespace kapi::devices #endif \ No newline at end of file -- cgit v1.2.3 From 66ffd2ad8c793c4eea1527848fe4772e42595718 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 14:24:52 +0200 Subject: kapi: extract common bus code --- kapi/include/kapi/devices/bus.hpp | 61 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index a8d7df8..ccaf0f2 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -2,12 +2,17 @@ #define TEACHOS_KAPI_DEVICES_BUS_HPP #include "kapi/devices/device.hpp" +#include "kapi/system.hpp" #include +#include #include #include +#include +#include #include +#include namespace kapi::devices { @@ -23,17 +28,65 @@ namespace kapi::devices : device(major, minor, name) {} + //! Initialize the bus and all of its children. + //! + //! @return true iff. the bus and all of its children are healthy, false otherwise. + auto init() -> bool final + { + if (m_initialized.test_and_set()) + { + return true; + } + + if (!probe()) + { + return false; + } + + return std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { + kstd::println("[kAPI:BUS] Initializing child device {}@{}", child->name(), name()); + return acc && child->init(); + }); + } + //! Attach a child device to this bus. //! //! Whenever a device is attached to a bus, the bus takes sole ownership of the device. //! //! @param child The child device to attach. - virtual auto add_child(kstd::unique_ptr child) -> void = 0; + auto add_child(kstd::unique_ptr child) -> void + { + auto observer = m_observers.emplace_back(child.get()); + m_devices.push_back(std::move(child)); - //! Get a list of all child devices attached to this bus. + if (m_initialized.test()) + { + kstd::println("[kAPI:BUS] Initializing child device {}@{}", observer->name(), name()); + if (!observer->init()) + { + kapi::system::panic("[kAPI:BUS] Failed to initialize child device"); + } + } + } + + [[nodiscard]] auto children() const -> kstd::vector> const & + { + return m_observers; + } + + protected: + //! Probe the bus hardware state. //! - //! @return A reference to list of child devices of this bus. - [[nodiscard]] virtual auto children() const -> kstd::vector> const & = 0; + //! @return true iff. the bus hardware is healthy, false otherwise. + auto virtual probe() -> bool + { + return true; + } + + private: + kstd::vector> m_devices; + kstd::vector> m_observers; + std::atomic_flag m_initialized{}; }; } // namespace kapi::devices -- cgit v1.2.3 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 --- kapi/include/kapi/devices.hpp | 24 +++-------------------- kapi/include/kapi/devices/bus.hpp | 2 ++ kapi/include/kapi/devices/manager.hpp | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 kapi/include/kapi/devices/manager.hpp (limited to 'kapi') diff --git a/kapi/include/kapi/devices.hpp b/kapi/include/kapi/devices.hpp index 2028a64..5c01b2f 100644 --- a/kapi/include/kapi/devices.hpp +++ b/kapi/include/kapi/devices.hpp @@ -1,10 +1,9 @@ #ifndef TEACHOS_KAPI_DEVICES_HPP #define TEACHOS_KAPI_DEVICES_HPP -#include "kapi/devices/bus.hpp" // IWYU pragma: export -#include "kapi/devices/device.hpp" // IWYU pragma: export - -#include +#include "kapi/devices/bus.hpp" // IWYU pragma: export +#include "kapi/devices/device.hpp" // IWYU pragma: export +#include "kapi/devices/manager.hpp" // IWYU pragma: export namespace kapi::devices { @@ -22,23 +21,6 @@ namespace kapi::devices //! @return a reference to the root bus. auto get_root_bus() -> bus &; - //! Ask the kernel to allocate a new major number. - //! - //! @return a new, unused major number. - auto allocate_major_number() -> std::size_t; - - //! Register a new device with the kernel's device manager. - //! - //! @param device The device to register. - //! @return true if the device was registered successfully, false otherwise. - auto register_device(device & device) -> bool; - - //! Unregister a device from the kernel's device manager. - //! - //! @param device The device to unregister. - //! @return true if the device was unregistered successfully, false otherwise. - auto unregister_device(device & device) -> bool; - //! @} //! @addtogroup platform-defined diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index ccaf0f2..a5457e1 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -2,6 +2,7 @@ #define TEACHOS_KAPI_DEVICES_BUS_HPP #include "kapi/devices/device.hpp" +#include "kapi/devices/manager.hpp" #include "kapi/system.hpp" #include @@ -58,6 +59,7 @@ namespace kapi::devices { auto observer = m_observers.emplace_back(child.get()); m_devices.push_back(std::move(child)); + kapi::devices::register_device(*observer); if (m_initialized.test()) { diff --git a/kapi/include/kapi/devices/manager.hpp b/kapi/include/kapi/devices/manager.hpp new file mode 100644 index 0000000..56cd678 --- /dev/null +++ b/kapi/include/kapi/devices/manager.hpp @@ -0,0 +1,37 @@ +#ifndef TEACHOS_KAPI_DEVICES_MANAGER_HPP +#define TEACHOS_KAPI_DEVICES_MANAGER_HPP + +// IWYU pragma: private, include "kapi/devices.hpp" + +#include "kapi/devices/device.hpp" + +#include + +namespace kapi::devices +{ + + //! @addtogroup kernel-defined + //! @{ + + //! Ask the kernel to allocate a new major number. + //! + //! @return a new, unused major number. + auto allocate_major_number() -> std::size_t; + + //! Register a new device with the kernel's device manager. + //! + //! @param device The device to register. + //! @return true if the device was registered successfully, false otherwise. + auto register_device(device & device) -> bool; + + //! Unregister a device from the kernel's device manager. + //! + //! @param device The device to unregister. + //! @return true if the device was unregistered successfully, false otherwise. + auto unregister_device(device & device) -> bool; + + //! @} + +} // namespace kapi::devices + +#endif \ No newline at end of file -- cgit v1.2.3 From 3e80b6baa8f9666a9dd3cd4531bc68a3de4fee92 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:18:05 +0200 Subject: kapi: allow for device searches --- kapi/include/kapi/devices/manager.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/manager.hpp b/kapi/include/kapi/devices/manager.hpp index 56cd678..7817fbc 100644 --- a/kapi/include/kapi/devices/manager.hpp +++ b/kapi/include/kapi/devices/manager.hpp @@ -5,7 +5,10 @@ #include "kapi/devices/device.hpp" +#include + #include +#include namespace kapi::devices { @@ -30,6 +33,19 @@ namespace kapi::devices //! @return true if the device was unregistered successfully, false otherwise. auto unregister_device(device & device) -> bool; + //! Find a device by its major and minor numbers. + //! + //! @param major the major number of the device. + //! @param minor the minor number of the device. + //! @return a pointer to the device iff. the device was found, nullptr otherwise. + auto find_device(std::size_t major, std::size_t minor) -> kstd::observer_ptr; + + //! Find a device by its name. + //! + //! @param name the name of the device. + //! @return a pointer to the device iff. the device was found, nullptr otherwise. + auto find_device(std::string_view name) -> kstd::observer_ptr; + //! @} } // namespace kapi::devices -- cgit v1.2.3 From 33b43603936ed0108d67853727a17d6b3740b445 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 2 Apr 2026 15:43:34 +0200 Subject: kapi/bus: ensure all devices get initialized --- kapi/include/kapi/devices/bus.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kapi') diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp index a5457e1..ee774b7 100644 --- a/kapi/include/kapi/devices/bus.hpp +++ b/kapi/include/kapi/devices/bus.hpp @@ -46,7 +46,7 @@ namespace kapi::devices return std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { kstd::println("[kAPI:BUS] Initializing child device {}@{}", child->name(), name()); - return acc && child->init(); + return child->init() && acc; }); } -- cgit v1.2.3