#include "kapi/devices.hpp" #include "kapi/system.hpp" #include "kernel/devices/root_bus.hpp" #include #include #include #include #include #include #include #include namespace kapi::devices { namespace { auto constinit next_major_number = std::atomic_size_t{1}; auto constinit root_bus = std::optional{}; auto constinit device_tree = kstd::flat_map, kstd::observer_ptr>{}; } // namespace auto init() -> void { auto static is_initialized = std::atomic_flag{}; if (is_initialized.test_and_set()) { return; } auto & bus = root_bus.emplace(); register_device(bus); bus.init(); } auto get_root_bus() -> bus & { if (!root_bus.has_value()) { kapi::system::panic("[OS:DEV] Root bus not initialized!"); } return *root_bus; } auto allocate_major_number() -> std::size_t { return next_major_number++; } auto register_device(device & device) -> bool { kstd::println("[OS:DEV] Registering device {}@{}:{}", device.name(), device.major(), device.minor()); return device_tree.emplace(std::pair{device.major(), device.minor()}, &device).second; } auto unregister_device(device &) -> bool { kstd::println("[OS:DEV] TODO: implement device deregistration"); return false; } auto find_device(std::size_t major, std::size_t minor) -> kstd::observer_ptr { if (device_tree.contains(std::pair{major, minor})) { return device_tree.at(std::pair{major, minor}); } return nullptr; } auto find_device(std::string_view name) -> kstd::observer_ptr { for (auto const & [key, value] : device_tree) { if (value->name() == name) { return value; } } return nullptr; } } // namespace kapi::devices