#include #include #include #include #include #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>{}; } // namespace auto init() -> void { if (root_bus.has_value()) { kapi::system::panic("[OS:DEV] The device subsystem has already been initialized"); } interface_registry::init(); 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.fetch_add(1, std::memory_order::relaxed); } auto register_device(device & device) -> bool { kstd::println("[OS:DEV] Registering device {}", device.name()); 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::observer_ptr { for (auto const & [key, value] : device_tree) { if (value->name() == name) { return value; } } return nullptr; } } // namespace kapi::devices namespace kapi::test_support::devices { auto deinit() -> void { deinit_interface_registry(); kapi::devices::root_bus.reset(); kapi::devices::next_major_number = 1; } } // namespace kapi::test_support::devices