aboutsummaryrefslogtreecommitdiff
path: root/kernel/kapi/devices
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-07-24 17:50:16 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-24 17:50:16 +0200
commite99eb52d9923606dd325862a5f2e649eee0b2d3e (patch)
treee3a15138bfec8a630d02f0f858bb9f000c6da3f8 /kernel/kapi/devices
parentaa25bfac399e32efda039eb833b2c4d74f1edba0 (diff)
downloadkernel-e99eb52d9923606dd325862a5f2e649eee0b2d3e.tar.xz
kernel-e99eb52d9923606dd325862a5f2e649eee0b2d3e.zip
kapi: formally extract device registry
Diffstat (limited to 'kernel/kapi/devices')
-rw-r--r--kernel/kapi/devices/bus.cpp2
-rw-r--r--kernel/kapi/devices/device_registry.cpp106
-rw-r--r--kernel/kapi/devices/driver.tests.cpp4
-rw-r--r--kernel/kapi/devices/driver_registry.cpp4
-rw-r--r--kernel/kapi/devices/driver_registry.tests.cpp8
5 files changed, 115 insertions, 9 deletions
diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp
index db693eac..1b3ad4bf 100644
--- a/kernel/kapi/devices/bus.cpp
+++ b/kernel/kapi/devices/bus.cpp
@@ -21,7 +21,7 @@ namespace kapi::devices
{
child->set_parent(kstd::static_pointer_cast<bus>(shared_from_this()));
- if (!kapi::devices::register_device(child))
+ if (!kapi::devices::device_registry::get().add(child))
{
kapi::system::panic("[OS:DEV] Failed to register child device {}", child->name());
}
diff --git a/kernel/kapi/devices/device_registry.cpp b/kernel/kapi/devices/device_registry.cpp
new file mode 100644
index 00000000..aca0e7fe
--- /dev/null
+++ b/kernel/kapi/devices/device_registry.cpp
@@ -0,0 +1,106 @@
+#include <kapi/devices/device_registry.hpp>
+
+#include <kapi/devices/device.hpp>
+#include <kapi/system.hpp>
+
+#include <kstd/memory.hpp>
+#include <kstd/print.hpp>
+#include <kstd/string.hpp>
+#include <kstd/vector.hpp>
+
+#include <optional>
+#include <string_view>
+#include <utility>
+
+namespace kapi::devices
+{
+
+ namespace
+ {
+ auto constinit instance = std::optional<device_registry>{};
+ }
+
+ auto device_registry::init() -> void
+ {
+ if (instance)
+ {
+ system::panic("[OS:DEV] Device registry has already been initialized");
+ }
+
+ instance = device_registry{};
+ }
+
+ auto device_registry::get() -> device_registry &
+ {
+ if (!instance)
+ {
+ system::panic("[OS:DEV] Device registry has not been initialized");
+ }
+
+ return *instance;
+ }
+
+ auto device_registry::add(kstd::shared_ptr<device> device) -> bool
+ {
+ if (!device)
+ {
+ return false;
+ }
+
+ kstd::println("[OS:DEV] Registering device {}", device->name());
+
+ auto found = m_devices.find(device->name());
+ if (found != m_devices.end())
+ {
+ if (!found->second.expired())
+ {
+ return false;
+ }
+
+ found->second = device;
+ return true;
+ }
+
+ return m_devices.emplace(device->name(), device).second;
+ }
+
+ auto device_registry::remove(device &) -> bool
+ {
+ kstd::println("[OS:DEV] TODO: implement device deregistration");
+ return false;
+ }
+
+ auto device_registry::find(std::string_view name) const -> kstd::shared_ptr<device>
+ {
+ auto found = m_devices.find(kstd::string{name});
+ if (found == m_devices.end())
+ {
+ return nullptr;
+ }
+
+ return found->second.lock();
+ }
+
+ auto device_registry::all() const -> kstd::vector<kstd::shared_ptr<device>>
+ {
+ auto result = kstd::vector<kstd::shared_ptr<device>>{};
+
+ for (auto const & [name, weak_device] : m_devices)
+ {
+ if (auto device = weak_device.lock())
+ {
+ result.push_back(std::move(device));
+ }
+ }
+
+ return result;
+ }
+} // namespace kapi::devices
+
+namespace kapi::test_support::devices
+{
+ auto deinit_device_registry() -> void
+ {
+ kapi::devices::instance.reset();
+ }
+} // namespace kapi::test_support::devices \ No newline at end of file
diff --git a/kernel/kapi/devices/driver.tests.cpp b/kernel/kapi/devices/driver.tests.cpp
index abce92d2..53c569dd 100644
--- a/kernel/kapi/devices/driver.tests.cpp
+++ b/kernel/kapi/devices/driver.tests.cpp
@@ -213,14 +213,14 @@ SCENARIO("a bound controller driver can attach a further, independently-typed bu
THEN("the controller device bound the controller driver")
{
- auto controller = kapi::devices::find_device("stacking_test_controller");
+ auto controller = kapi::devices::device_registry::get().find("stacking_test_controller");
REQUIRE(controller != nullptr);
REQUIRE(controller->state() == kapi::devices::state::bound);
}
THEN("the leaf device the controller driver attached is reachable and bound to the leaf driver")
{
- auto leaf = kapi::devices::find_device("stacking_test_leaf");
+ auto leaf = kapi::devices::device_registry::get().find("stacking_test_leaf");
REQUIRE(leaf != nullptr);
REQUIRE(leaf->state() == kapi::devices::state::bound);
REQUIRE(leaf->bound_driver() != nullptr);
diff --git a/kernel/kapi/devices/driver_registry.cpp b/kernel/kapi/devices/driver_registry.cpp
index 67da9877..5784694a 100644
--- a/kernel/kapi/devices/driver_registry.cpp
+++ b/kernel/kapi/devices/driver_registry.cpp
@@ -3,8 +3,8 @@
#include <kapi/devices/bus.hpp>
#include <kapi/devices/bus_protocol.hpp>
#include <kapi/devices/device.hpp>
+#include <kapi/devices/device_registry.hpp>
#include <kapi/devices/driver.hpp>
-#include <kapi/devices/manager.hpp>
#include <kapi/system.hpp>
#include <kapi/test_support/devices.hpp>
@@ -57,7 +57,7 @@ namespace kapi::devices
{
m_drivers.emplace_back(std::move(driver));
- for (auto const & device : kapi::devices::all())
+ for (auto const & device : kapi::devices::device_registry::get().all())
{
if (device->state() != state::bound)
{
diff --git a/kernel/kapi/devices/driver_registry.tests.cpp b/kernel/kapi/devices/driver_registry.tests.cpp
index 52f320f4..bf87fb47 100644
--- a/kernel/kapi/devices/driver_registry.tests.cpp
+++ b/kernel/kapi/devices/driver_registry.tests.cpp
@@ -131,7 +131,7 @@ SCENARIO("Driver registry binds devices and drivers regardless of arrival order"
THEN("the device binds")
{
- auto dev = kapi::devices::find_device("driver_registry_test_device_1");
+ auto dev = kapi::devices::device_registry::get().find("driver_registry_test_device_1");
REQUIRE(dev);
REQUIRE(dev->state() == kapi::devices::state::bound);
}
@@ -144,7 +144,7 @@ SCENARIO("Driver registry binds devices and drivers regardless of arrival order"
THEN("the device binds")
{
- auto dev = kapi::devices::find_device("driver_registry_test_device_2");
+ auto dev = kapi::devices::device_registry::get().find("driver_registry_test_device_2");
REQUIRE(dev);
REQUIRE(dev->state() == kapi::devices::state::bound);
}
@@ -169,7 +169,7 @@ SCENARIO("driver_registry picks the highest-priority match", "[devices][driver_r
THEN("it binds to the higher-priority driver")
{
- auto dev = kapi::devices::find_device("driver_registry_priority_device");
+ auto dev = kapi::devices::device_registry::get().find("driver_registry_priority_device");
REQUIRE(dev != nullptr);
REQUIRE(dev->bound_driver() == high_priority.get());
}
@@ -194,7 +194,7 @@ SCENARIO("driver_registry breaks ties by registration order", "[devices][driver_
THEN("the first-registered driver wins the tie")
{
- auto dev = kapi::devices::find_device("driver_registry_tie_device");
+ auto dev = kapi::devices::device_registry::get().find("driver_registry_tie_device");
REQUIRE(dev != nullptr);
REQUIRE(dev->bound_driver() == registered_first.get());
}