#include #include #include #include #include #include #include #include #include #include namespace kapi::boot_modules { auto has_parameter(std::string_view cmdline, std::string_view key, std::string_view value) -> bool { for (auto token : std::views::split(cmdline, ' ')) { auto const text = std::string_view{token}; auto const equals = text.find('='); if (equals != std::string_view::npos && text.substr(0, equals) == key && text.substr(equals + 1) == value) { return true; } } return false; } boot_module_device::boot_module_device(std::size_t index, struct module const & module) : kapi::devices::device{kstd::format("boot_module{}", index)} , m_module(module) {} auto boot_module_device::command_line() const -> std::string_view { return m_module.name; } auto boot_module_device::module() const -> boot_modules::module const & { return m_module; } auto boot_module_device::query_interface(kapi::devices::interface interface) -> void * { if (interface == boot_module_identification::id) { return static_cast(this); } return kapi::devices::device::query_interface(interface); } boot_module_bus::boot_module_bus(registry const * registry) : kapi::devices::bus{"boot_modules"} , m_registry(registry) {} auto boot_module_bus::enumerate(kapi::devices::bus & self) -> void { std::size_t index = 0; for (auto const & module : *m_registry) { self.add_child(kstd::make_shared(index++, module)); } } auto boot_module_bus::match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const -> kstd::result { auto const * ident = dev.as(); auto const * claims = drv.as(); if (!ident || !claims) { return kstd::failure(kapi::devices::driver_match_errc::no_match); } auto const [key, value] = claims->claimed_parameter(); if (!has_parameter(ident->command_line(), key, value)) { return kstd::failure(kapi::devices::driver_match_errc::no_match); } return 0u; } auto boot_module_bus::protocol() -> kapi::devices::bus_protocol * { return this; } } // namespace kapi::boot_modules