diff options
Diffstat (limited to 'kernel/kapi')
| -rw-r--r-- | kernel/kapi/boot_module/bus.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/kernel/kapi/boot_module/bus.cpp b/kernel/kapi/boot_module/bus.cpp new file mode 100644 index 00000000..b917866c --- /dev/null +++ b/kernel/kapi/boot_module/bus.cpp @@ -0,0 +1,102 @@ +#include <kapi/boot_module/bus.hpp> + +#include <kapi/boot_modules.hpp> +#include <kapi/devices.hpp> + +#include <kstd/format.hpp> +#include <kstd/memory.hpp> +#include <kstd/result.hpp> +#include <kstd/string.hpp> + +#include <cstddef> +#include <ranges> +#include <string_view> + +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(equals) == key && text.substr(equals + 1) == value) + { + return true; + } + } + return false; + } + + boot_module_device::boot_module_device(std::size_t index, boot_module const & module) + : kapi::devices::device{kstd::format("boot_module{}", index)} + , m_module(module) + {} + + auto boot_module_device::init() -> bool + { + return true; + } + + auto boot_module_device::command_line() const -> std::string_view + { + return m_module.name; + } + + auto boot_module_device::module() const -> boot_modules::boot_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<boot_module_identification *>(this); + } + + return kapi::devices::device::query_interface(interface); + } + + boot_module_bus::boot_module_bus(boot_module_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<boot_module_device>(index++, module)); + } + } + + auto boot_module_bus::match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const + -> kstd::result<unsigned> + { + auto const * ident = dev.as<boot_module_identification>(); + auto const * claims = drv.as<boot_module_driver_identification>(); + + 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 |
