#include #include #include #include #include #include #include #include #include #include #include #include namespace kapi::devices { namespace { auto constinit root_bus = kstd::shared_ptr{}; auto constinit device_tree = kstd::flat_map>{}; } // namespace auto init() -> void { if (root_bus) { kapi::system::panic("[OS:DEV] The device subsystem has already been initialized"); } interface_registry::init(); kernel::drivers::init(); root_bus = kstd::make_shared(); register_device(root_bus); } auto get_root_bus() -> kstd::shared_ptr { if (!root_bus) { kapi::system::panic("[OS:DEV] Root bus not initialized!"); } return root_bus; } auto register_device(kstd::shared_ptr device) -> bool { if (!device) { return false; } kstd::println("[OS:DEV] Registering device {}", device->name()); auto found = device_tree.find(device->name()); if (found != device_tree.end()) { if (!found->second.expired()) { return false; } found->second = device; return true; } return device_tree.emplace(device->name(), device).second; } auto unregister_device(device &) -> bool { kstd::println("[OS:DEV] TODO: implement device deregistration"); return false; } auto find_device(std::string_view name) -> kstd::shared_ptr { auto found = device_tree.find(kstd::string{name}); if (found == device_tree.end()) { return nullptr; } return found->second.lock(); } auto all() -> kstd::vector> { auto result = kstd::vector>{}; for (auto const & [name, weak_device] : device_tree) { if (auto device = weak_device.lock()) { result.push_back(std::move(device)); } } return result; } } // namespace kapi::devices namespace kapi::test_support::devices { auto deinit() -> void { deinit_interface_registry(); deinit_driver_registry(); kapi::devices::root_bus.reset(); } } // namespace kapi::test_support::devices