aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/CMakeLists.txt1
-rw-r--r--kernel/kapi/devices.cpp65
-rw-r--r--kernel/kapi/devices.tests.cpp10
-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
8 files changed, 125 insertions, 75 deletions
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 082cb7be..f4d0d3b3 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -16,6 +16,7 @@ target_sources("kernel_lib" PRIVATE
"kapi/devices/bus.cpp"
"kapi/devices/cpu.cpp"
"kapi/devices/device.cpp"
+ "kapi/devices/device_registry.cpp"
"kapi/devices/driver.cpp"
"kapi/devices/driver_registry.cpp"
"kapi/devices/error.cpp"
diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp
index 64e549f3..b0f384ab 100644
--- a/kernel/kapi/devices.cpp
+++ b/kernel/kapi/devices.cpp
@@ -8,12 +8,9 @@
#include <kstd/flat_map.hpp>
#include <kstd/memory.hpp>
-#include <kstd/print.hpp>
#include <kstd/string.hpp>
-#include <kstd/vector.hpp>
#include <string_view>
-#include <utility>
namespace kapi::devices
{
@@ -30,11 +27,12 @@ namespace kapi::devices
kapi::system::panic("[OS:DEV] The device subsystem has already been initialized");
}
+ device_registry::init();
interface_registry::init();
kernel::drivers::init();
root_bus = kstd::make_shared<kernel::devices::root_bus>();
- register_device(root_bus);
+ device_registry::get().add(root_bus);
}
auto get_root_bus() -> kstd::shared_ptr<bus>
@@ -46,70 +44,15 @@ namespace kapi::devices
return root_bus;
}
- auto register_device(kstd::shared_ptr<device> device) -> bool
- {
- if (!device)
- {
- return false;
- }
-
- kstd::println("[OS:DEV] Registering device {}", device->name());
-
- auto found = device_tree.find(device->name());
- if (found != device_tree.end())
- {
- if (!found->second.expired())
- {
- return false;
- }
-
- found->second = device;
- return true;
- }
-
- 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::shared_ptr<device>
- {
- auto found = device_tree.find(kstd::string{name});
- if (found == device_tree.end())
- {
- return nullptr;
- }
-
- return found->second.lock();
- }
-
- auto all() -> kstd::vector<kstd::shared_ptr<device>>
- {
- auto result = kstd::vector<kstd::shared_ptr<device>>{};
-
- for (auto const & [name, weak_device] : device_tree)
- {
- if (auto device = weak_device.lock())
- {
- result.push_back(std::move(device));
- }
- }
-
- return result;
- }
-
} // namespace kapi::devices
namespace kapi::test_support::devices
{
auto deinit() -> void
{
- deinit_interface_registry();
deinit_driver_registry();
+ deinit_interface_registry();
+ deinit_device_registry();
kapi::devices::root_bus.reset();
}
diff --git a/kernel/kapi/devices.tests.cpp b/kernel/kapi/devices.tests.cpp
index 627c5ce0..1064c000 100644
--- a/kernel/kapi/devices.tests.cpp
+++ b/kernel/kapi/devices.tests.cpp
@@ -28,14 +28,14 @@ SCENARIO("the device registry holds devices weakly and prunes stale entries lazi
THEN("it is discoverable via find_devices")
{
- auto found = kapi::devices::find_device("registry_test_device");
+ auto found = kapi::devices::device_registry::get().find("registry_test_device");
REQUIRE(found);
REQUIRE(found->name() == "registry_test_device");
}
THEN("find_device reports no match for an uknown name")
{
- REQUIRE_FALSE(kapi::devices::find_device("does_not_exist"));
+ REQUIRE_FALSE(kapi::devices::device_registry::get().find("does_not_exist"));
}
WHEN("every strong reference to the device is dropped")
@@ -44,7 +44,7 @@ SCENARIO("the device registry holds devices weakly and prunes stale entries lazi
THEN("find_device no longer resolves it")
{
- REQUIRE_FALSE(kapi::devices::find_device("registry_test_device"));
+ REQUIRE_FALSE(kapi::devices::device_registry::get().find("registry_test_device"));
}
}
}
@@ -59,12 +59,12 @@ SCENARIO("the device registry holds devices weakly and prunes stale entries lazi
WHEN("a new device is registered under the very same name")
{
auto new_device = kstd::make_shared<test_device>("registry_reuse_device");
- auto registered = kapi::devices::register_device(new_device);
+ auto registered = kapi::devices::device_registry::get().add(new_device);
THEN("registration succeeds")
{
REQUIRE(registered);
- REQUIRE(kapi::devices::find_device("registry_reuse_device") == new_device);
+ REQUIRE(kapi::devices::device_registry::get().find("registry_reuse_device") == new_device);
}
}
}
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());
}