1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include <kapi/boot_modules/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(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<boot_module_identification *>(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<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
|