diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-04-02 14:24:52 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-04-02 14:24:52 +0200 |
| commit | 66ffd2ad8c793c4eea1527848fe4772e42595718 (patch) | |
| tree | 9d86601b57270172d76d5e617218507864ee4f54 /kapi/include | |
| parent | b84c4c9d8c90f3d3fd5a60de282278912fad2f04 (diff) | |
| download | teachos-66ffd2ad8c793c4eea1527848fe4772e42595718.tar.xz teachos-66ffd2ad8c793c4eea1527848fe4772e42595718.zip | |
kapi: extract common bus code
Diffstat (limited to 'kapi/include')
| -rw-r--r-- | kapi/include/kapi/devices/bus.hpp | 61 |
1 files changed, 57 insertions, 4 deletions
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 <kstd/memory> +#include <kstd/print> #include <kstd/string> #include <kstd/vector> +#include <algorithm> +#include <atomic> #include <cstddef> +#include <utility> 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<device> child) -> void = 0; + auto add_child(kstd::unique_ptr<device> 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<kstd::observer_ptr<device>> 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<kstd::observer_ptr<device>> const & = 0; + //! @return true iff. the bus hardware is healthy, false otherwise. + auto virtual probe() -> bool + { + return true; + } + + private: + kstd::vector<kstd::unique_ptr<device>> m_devices; + kstd::vector<kstd::observer_ptr<device>> m_observers; + std::atomic_flag m_initialized{}; }; } // namespace kapi::devices |
