aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-07-26 02:27:59 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-07-26 02:27:59 +0200
commit59f54d012c71e782966e9d083f1ee9459fd3fd70 (patch)
treefa1c34396c3b9e50c6128fa1b8e580abd4e44b3d
parentb486b794abaf35b0b2376662173eb07549252cfc (diff)
downloadkernel-59f54d012c71e782966e9d083f1ee9459fd3fd70.tar.xz
kernel-59f54d012c71e782966e9d083f1ee9459fd3fd70.zip
chore: replace "interface" with "facet"
-rw-r--r--arch/x86_64/arch/bus/isa.cpp15
-rw-r--r--arch/x86_64/arch/bus/isa.hpp15
-rw-r--r--arch/x86_64/arch/devices/pit.cpp6
-rw-r--r--arch/x86_64/arch/devices/pit.hpp2
-rw-r--r--arch/x86_64/arch/drivers/pit.cpp6
-rw-r--r--arch/x86_64/arch/drivers/pit.hpp2
-rw-r--r--kapi/kapi/boot_modules/device.hpp10
-rw-r--r--kapi/kapi/capabilities/facet_id.hpp36
-rw-r--r--kapi/kapi/capabilities/interface_id.hpp34
-rw-r--r--kapi/kapi/devices.hpp47
-rw-r--r--kapi/kapi/devices/bus.hpp14
-rw-r--r--kapi/kapi/devices/bus_protocol.hpp4
-rw-r--r--kapi/kapi/devices/device.hpp64
-rw-r--r--kapi/kapi/devices/driver.hpp40
-rw-r--r--kapi/kapi/devices/facet_registry.hpp305
-rw-r--r--kapi/kapi/devices/interface_id.hpp15
-rw-r--r--kapi/kapi/devices/interface_registry.hpp299
-rw-r--r--kapi/kapi/filesystem.hpp2
-rw-r--r--kapi/kapi/filesystem/block_special_file.hpp4
-rw-r--r--kapi/kapi/filesystem/character_special_file.hpp4
-rw-r--r--kapi/kapi/filesystem/interface_id.hpp15
-rw-r--r--kapi/kapi/test_support/devices.hpp2
-rw-r--r--kernel/CMakeLists.txt2
-rw-r--r--kernel/kapi/boot_modules/device.cpp6
-rw-r--r--kernel/kapi/devices.cpp4
-rw-r--r--kernel/kapi/devices/bus.cpp11
-rw-r--r--kernel/kapi/devices/device.cpp14
-rw-r--r--kernel/kapi/devices/driver.cpp2
-rw-r--r--kernel/kapi/devices/driver.tests.cpp78
-rw-r--r--kernel/kapi/devices/driver_registry.cpp2
-rw-r--r--kernel/kapi/devices/driver_registry.tests.cpp21
-rw-r--r--kernel/kapi/devices/facet_registry.cpp216
-rw-r--r--kernel/kapi/devices/facet_registry.tests.cpp (renamed from kernel/kapi/devices/interface_registry.tests.cpp)112
-rw-r--r--kernel/kapi/devices/interface_registry.cpp218
-rw-r--r--kernel/kernel/bus/boot_modules.cpp15
-rw-r--r--kernel/kernel/bus/boot_modules.hpp2
-rw-r--r--kernel/kernel/devices/storage.cpp2
-rw-r--r--kernel/kernel/devices/storage.tests.cpp2
-rw-r--r--kernel/kernel/drivers/storage/ram_disk.cpp20
-rw-r--r--kernel/kernel/drivers/storage/ram_disk.hpp2
-rw-r--r--kernel/kernel/filesystem/device_inode.cpp4
-rw-r--r--kernel/kernel/filesystem/device_inode.tests.cpp2
-rw-r--r--kernel/kernel/filesystem/device_number_registry.cpp37
-rw-r--r--kernel/kernel/filesystem/device_number_registry.hpp21
-rw-r--r--kernel/kernel/filesystem/device_number_registry.tests.cpp20
-rw-r--r--kernel/kernel/filesystem/file_type_bindings.hpp8
-rw-r--r--kernel/kernel/test_support/devices/block_device.cpp6
-rw-r--r--kernel/kernel/test_support/devices/block_device.hpp2
-rw-r--r--kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp5
49 files changed, 893 insertions, 882 deletions
diff --git a/arch/x86_64/arch/bus/isa.cpp b/arch/x86_64/arch/bus/isa.cpp
index ee195519..8e17c186 100644
--- a/arch/x86_64/arch/bus/isa.cpp
+++ b/arch/x86_64/arch/bus/isa.cpp
@@ -14,6 +14,8 @@ namespace arch::bus
{
struct isa_protocol final : kapi::devices::bus_protocol
{
+ constexpr auto static id = kapi::capabilities::facet_id{"isa_protocol"};
+
auto enumerate(kapi::devices::bus &) -> void override
{
// NOTE: ISA does not support enumeration, but we need to fulfill the interface.
@@ -22,8 +24,8 @@ namespace arch::bus
[[nodiscard]] auto match(kapi::devices::device const & device, kapi::devices::driver const & driver) const
-> kstd::result<std::uint32_t> override
{
- auto device_signature = device.as<isa_signature>();
- auto driver_claim = driver.as<isa_claim>();
+ auto device_signature = device.facet<isa_signature>();
+ auto driver_claim = driver.facet<isa_claim>();
if (!device_signature || !driver_claim)
{
@@ -44,9 +46,14 @@ namespace arch::bus
: kapi::devices::bus{"isa"}
{}
- auto isa::protocol() -> kapi::devices::bus_protocol *
+ auto isa::query_facet(kapi::capabilities::facet_id id) -> void *
{
- return &protocol_instance;
+ if (id == isa_protocol::id || id == kapi::devices::bus_protocol::id)
+ {
+ return &protocol_instance;
+ }
+
+ return bus::query_facet(id);
}
} // namespace arch::bus \ No newline at end of file
diff --git a/arch/x86_64/arch/bus/isa.hpp b/arch/x86_64/arch/bus/isa.hpp
index 87832c3c..db85f3f7 100644
--- a/arch/x86_64/arch/bus/isa.hpp
+++ b/arch/x86_64/arch/bus/isa.hpp
@@ -11,11 +11,11 @@
namespace arch::bus
{
- //! The signature interface used to identify ISA devices.
+ //! The signature facet used to identify ISA devices.
struct isa_signature
{
- //! The ID of this interface.
- constexpr auto static id = kapi::devices::interface_id{"isa_signature"};
+ //! The ID of this facet.
+ constexpr auto static id = kapi::capabilities::facet_id{"isa_signature"};
//! Allow for correct destruction through base pointers.
virtual ~isa_signature() = default;
@@ -24,11 +24,11 @@ namespace arch::bus
[[nodiscard]] virtual auto isa_name() const -> std::string_view = 0;
};
- //! The claim interface used to match ISA drivers.
+ //! The claim facet used to match ISA drivers.
struct isa_claim
{
- //! The ID of this interface
- constexpr auto static id = kapi::devices::interface_id{"isa_claim"};
+ //! The ID of this facet
+ constexpr auto static id = kapi::capabilities::facet_id{"isa_claim"};
//! Allow for correct destruction through base pointers.
virtual ~isa_claim() = default;
@@ -43,7 +43,8 @@ namespace arch::bus
//! Construct a default ISA bus.
isa();
- [[nodiscard]] auto protocol() -> kapi::devices::bus_protocol * override;
+ private:
+ auto query_facet(kapi::capabilities::facet_id id) -> void * override;
};
} // namespace arch::bus
diff --git a/arch/x86_64/arch/devices/pit.cpp b/arch/x86_64/arch/devices/pit.cpp
index 6a8e9974..bfd6e84b 100644
--- a/arch/x86_64/arch/devices/pit.cpp
+++ b/arch/x86_64/arch/devices/pit.cpp
@@ -18,14 +18,14 @@ namespace arch::devices
return "pit";
}
- auto pit::query_interface(kapi::devices::interface_id interface) -> void *
+ auto pit::query_facet(kapi::capabilities::facet_id facet) -> void *
{
- if (interface == arch::bus::isa_signature::id)
+ if (facet == arch::bus::isa_signature::id)
{
return static_cast<arch::bus::isa_signature *>(this);
}
- return kapi::devices::device::query_interface(interface);
+ return kapi::devices::device::query_facet(facet);
}
} // namespace arch::devices \ No newline at end of file
diff --git a/arch/x86_64/arch/devices/pit.hpp b/arch/x86_64/arch/devices/pit.hpp
index adb722ab..e2546d27 100644
--- a/arch/x86_64/arch/devices/pit.hpp
+++ b/arch/x86_64/arch/devices/pit.hpp
@@ -24,7 +24,7 @@ namespace arch::devices
[[nodiscard]] auto isa_name() const -> std::string_view override;
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override;
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
};
} // namespace arch::devices
diff --git a/arch/x86_64/arch/drivers/pit.cpp b/arch/x86_64/arch/drivers/pit.cpp
index ea053319..650c4245 100644
--- a/arch/x86_64/arch/drivers/pit.cpp
+++ b/arch/x86_64/arch/drivers/pit.cpp
@@ -92,14 +92,14 @@ namespace arch::drivers
return kapi::interrupts::status::handled;
}
- auto pit::query_interface(kapi::devices::interface_id interface) -> void *
+ auto pit::query_facet(kapi::capabilities::facet_id facet) -> void *
{
- if (interface == arch::bus::isa_claim::id)
+ if (facet == arch::bus::isa_claim::id)
{
return static_cast<arch::bus::isa_claim *>(this);
}
- return kapi::devices::driver::query_interface(interface);
+ return kapi::devices::driver::query_facet(facet);
}
} // namespace arch::drivers \ No newline at end of file
diff --git a/arch/x86_64/arch/drivers/pit.hpp b/arch/x86_64/arch/drivers/pit.hpp
index e99bdf81..32ad7573 100644
--- a/arch/x86_64/arch/drivers/pit.hpp
+++ b/arch/x86_64/arch/drivers/pit.hpp
@@ -32,7 +32,7 @@ namespace arch::drivers
[[nodiscard]] auto name() const noexcept -> std::string_view override;
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override;
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
private:
struct data
diff --git a/kapi/kapi/boot_modules/device.hpp b/kapi/kapi/boot_modules/device.hpp
index a6aba9b0..74152306 100644
--- a/kapi/kapi/boot_modules/device.hpp
+++ b/kapi/kapi/boot_modules/device.hpp
@@ -14,13 +14,13 @@ namespace kapi::boot_modules
//! @addtogroup kapi-boot_modules-kernel-defined
//! @{
- //! The signature interface of a boot module device.
+ //! The signature facet of a boot module device.
//!
//! Boot module devices are "virtual" devices that get attached to the boot module bus. The purpose is to allow them
//! to materialize as "real" devices, e.g. a ram disk, and have a driver bound to them.
struct boot_module_signature
{
- constexpr auto static id = kapi::devices::interface_id{"boot_module_signature"};
+ constexpr auto static id = kapi::capabilities::facet_id{"boot_module_signature"};
virtual ~boot_module_signature() = default;
@@ -31,10 +31,10 @@ namespace kapi::boot_modules
[[nodiscard]] auto virtual module() const -> kapi::boot_modules::module const & = 0;
};
- //! The claim interface of a boot module driver.
+ //! The claim facet of a boot module driver.
struct boot_module_claim
{
- constexpr auto static id = kapi::devices::interface_id{"boot_module_claim"};
+ constexpr auto static id = kapi::capabilities::facet_id{"boot_module_claim"};
virtual ~boot_module_claim() = default;
@@ -52,7 +52,7 @@ namespace kapi::boot_modules
[[nodiscard]] auto module() const -> struct module const & override;
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override;
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
private:
struct module m_module;
diff --git a/kapi/kapi/capabilities/facet_id.hpp b/kapi/kapi/capabilities/facet_id.hpp
new file mode 100644
index 00000000..0ceae747
--- /dev/null
+++ b/kapi/kapi/capabilities/facet_id.hpp
@@ -0,0 +1,36 @@
+#ifndef TEACHOS_KAPI_CAPABILITIES_FACET_ID_HPP
+#define TEACHOS_KAPI_CAPABILITIES_FACET_ID_HPP
+
+// IWYU pragma: private
+
+#include <string_view>
+
+namespace kapi::capabilities
+{
+
+ //! A tag to mark the presence of a given behavioral or data facet.
+ struct facet_id
+ {
+ //! Construct a new facet id.
+ //!
+ //! @param name The name of the facet.
+ constexpr explicit facet_id(std::string_view name)
+ : m_name{name}
+ {}
+
+ //! Get the name of this facet.
+ [[nodiscard]] constexpr auto name() const noexcept -> std::string_view const &
+ {
+ return m_name;
+ }
+
+ //! Check if this facet is equal to another one.
+ constexpr auto operator==(facet_id const &) const noexcept -> bool = default;
+
+ private:
+ std::string_view m_name;
+ };
+
+} // namespace kapi::capabilities
+
+#endif
diff --git a/kapi/kapi/capabilities/interface_id.hpp b/kapi/kapi/capabilities/interface_id.hpp
deleted file mode 100644
index 8e6870cc..00000000
--- a/kapi/kapi/capabilities/interface_id.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef TEACHOS_KAPI_CAPABILITIES_INTERFACE_ID_HPP
-#define TEACHOS_KAPI_CAPABILITIES_INTERFACE_ID_HPP
-
-// IWYU pragma: private
-
-#include <string_view>
-
-namespace kapi::capabilities
-{
-
- //! A tag to mark that a given devices provides a specific device capability interface.
- struct interface_id
- {
- //! Construct a new interface with a given name.
- constexpr explicit interface_id(std::string_view name)
- : m_name{name}
- {}
-
- //! Get the name of this interface.
- [[nodiscard]] constexpr auto name() const noexcept -> std::string_view const &
- {
- return m_name;
- }
-
- //! Check if this interface is equal to another one.
- constexpr auto operator==(interface_id const &) const noexcept -> bool = default;
-
- private:
- std::string_view m_name;
- };
-
-} // namespace kapi::capabilities
-
-#endif
diff --git a/kapi/kapi/devices.hpp b/kapi/kapi/devices.hpp
index 51f5129e..59fcc568 100644
--- a/kapi/kapi/devices.hpp
+++ b/kapi/kapi/devices.hpp
@@ -1,16 +1,16 @@
#ifndef TEACHOS_KAPI_DEVICES_HPP
#define TEACHOS_KAPI_DEVICES_HPP
-#include <kapi/devices/bus.hpp> // IWYU pragma: export
-#include <kapi/devices/bus_protocol.hpp> // IWYU pragma: export
-#include <kapi/devices/cpu.hpp> // IWYU pragma: export
-#include <kapi/devices/device.hpp> // IWYU pragma: export
-#include <kapi/devices/device_registry.hpp> // IWYU pragma: export
-#include <kapi/devices/driver.hpp> // IWYU pragma: export
-#include <kapi/devices/driver_registry.hpp> // IWYU pragma: export
-#include <kapi/devices/error.hpp> // IWYU pragma: export
-#include <kapi/devices/interface_id.hpp> // IWYU pragma: export
-#include <kapi/devices/interface_registry.hpp> // IWYU pragma: export
+#include <kapi/capabilities/facet_id.hpp> // IWYU pragma: export
+#include <kapi/devices/bus.hpp> // IWYU pragma: export
+#include <kapi/devices/bus_protocol.hpp> // IWYU pragma: export
+#include <kapi/devices/cpu.hpp> // IWYU pragma: export
+#include <kapi/devices/device.hpp> // IWYU pragma: export
+#include <kapi/devices/device_registry.hpp> // IWYU pragma: export
+#include <kapi/devices/driver.hpp> // IWYU pragma: export
+#include <kapi/devices/driver_registry.hpp> // IWYU pragma: export
+#include <kapi/devices/error.hpp> // IWYU pragma: export
+#include <kapi/devices/facet_registry.hpp> // IWYU pragma: export
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
@@ -34,28 +34,27 @@ namespace kapi::devices
//! @return a shared pointer to the root bus.
auto get_root_bus() -> kstd::shared_ptr<bus>;
- //! Publish the fact that a given device implements a given interface.
+ //! Publish the fact that a device supports a specific facet.
//!
- //! @tparam Interface The interface type implemented by the given device.
- //! @param device The device to publish the interface for.
+ //! @tparam Facet The facet type provided by the device.
+ //! @param device The device to publish the facet for.
//! @param name A stable name for the device.
- template<typename Interface>
- auto publish_interface(kstd::shared_ptr<device> device, kstd::string name) -> kstd::result<void>
+ template<typename Facet>
+ auto publish_facet(kstd::shared_ptr<device> device, kstd::string name) -> kstd::result<void>
{
- return interface_registry::get().publish<Interface>(device, std::move(name));
+ return facet_registry::get().publish<Facet>(device, std::move(name));
}
- //! Publish the fact that a given device implements a given interface.
+ //! Publish the fact that a given device provides a given facet.
//!
- //! @tparam Interface The interface type implemented by the given device.
- //! @param device The device to publish the interface for.
+ //! @tparam Facet The facet type provided by the given device.
+ //! @param device The device to publish the facet for.
//! @param name A stable name for the device.
- //! @param implementation The implementation of the interface for the device.
- template<typename Interface>
- auto publish_interface(kstd::shared_ptr<device> device, kstd::string name, Interface * implementation)
- -> kstd::result<void>
+ //! @param implementation The implementation of the facet for the device.
+ template<typename Facet>
+ auto publish_facet(kstd::shared_ptr<device> device, kstd::string name, Facet * implementation) -> kstd::result<void>
{
- return interface_registry::get().publish(device, std::move(name), implementation);
+ return facet_registry::get().publish(device, std::move(name), implementation);
}
//! @}
diff --git a/kapi/kapi/devices/bus.hpp b/kapi/kapi/devices/bus.hpp
index 2a306031..6c42d1de 100644
--- a/kapi/kapi/devices/bus.hpp
+++ b/kapi/kapi/devices/bus.hpp
@@ -3,8 +3,8 @@
// IWYU pragma: private, include <kapi/devices.hpp>
+#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices/device.hpp>
-#include <kapi/devices/interface_id.hpp>
#include <kstd/memory.hpp>
#include <kstd/print.hpp>
@@ -23,7 +23,7 @@ namespace kapi::devices
struct bus : device
{
//! The id of the bus facet.
- constexpr auto static id = interface_id{"bus"};
+ constexpr auto static id = kapi::capabilities::facet_id{"bus"};
//! Construct a bus with the given name.
//!
@@ -42,14 +42,14 @@ namespace kapi::devices
//! @return A vector of all children attached to this bus.
[[nodiscard]] auto children() const -> std::span<kstd::shared_ptr<device> const>;
- //! Get this bus's protocol facet, if present.
- //!
- //! @return this bus's protocol facet if it has one, nullptr otherwise.
- [[nodiscard]] virtual auto protocol() -> struct bus_protocol *;
+ // //! Get this bus's protocol facet, if present.
+ // //!
+ // //! @return this bus's protocol facet if it has one, nullptr otherwise.
+ // [[nodiscard]] virtual auto protocol() -> struct bus_protocol *;
protected:
//! All busses have the "bus" facet.
- auto query_interface(interface_id interface) -> void * override;
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
private:
kstd::vector<kstd::shared_ptr<device>> m_devices;
diff --git a/kapi/kapi/devices/bus_protocol.hpp b/kapi/kapi/devices/bus_protocol.hpp
index 2e4e6993..cc1f2e5b 100644
--- a/kapi/kapi/devices/bus_protocol.hpp
+++ b/kapi/kapi/devices/bus_protocol.hpp
@@ -3,6 +3,7 @@
// IWYU pragma: private, include <kapi/devices.hpp>
+#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices/bus.hpp>
#include <kapi/devices/device.hpp>
#include <kapi/devices/driver.hpp>
@@ -20,6 +21,9 @@ namespace kapi::devices
//! it a pure behavioral mixin.
struct bus_protocol
{
+ //! The id of the bus protocol facet.
+ constexpr auto static id = kapi::capabilities::facet_id{"bus_protocol"};
+
//! Allow safe destruction through base pointers.
virtual ~bus_protocol() = default;
diff --git a/kapi/kapi/devices/device.hpp b/kapi/kapi/devices/device.hpp
index 50fc10b6..71856279 100644
--- a/kapi/kapi/devices/device.hpp
+++ b/kapi/kapi/devices/device.hpp
@@ -3,8 +3,8 @@
// IWYU pragma: private, include <kapi/devices.hpp>
+#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices/driver.hpp>
-#include <kapi/devices/interface_id.hpp>
#include <kstd/memory.hpp>
#include <kstd/string.hpp>
@@ -46,52 +46,52 @@ namespace kapi::devices
//! Enable safe destruction through base pointers.
virtual ~device() = default;
- //! Get a given capability from this device, if it implements it.
+ //! Get a specific facet of this device, if it supports it.
//!
- //! @param interface The id of the desired interface.
- //! @return An opaque pointer to the interface implementation if this device supports it, nullptr otherwise.
- [[nodiscard]] auto as(interface_id interface) noexcept -> void *;
+ //! @param id The id of the desired facet.
+ //! @return An opaque pointer to the facet implementation if this device supports it, nullptr otherwise.
+ [[nodiscard]] auto facet(kapi::capabilities::facet_id id) noexcept -> void *;
- //! Get a given capability from this device, if it implements it.
+ //! Get a specific facet of this device, if it supports it.
//!
- //! @param interface The id of the desired interface.
- //! @return A opaque pointer to the interface implementation if this device supports it, nullptr otherwise.
- [[nodiscard]] auto as(interface_id interface) const noexcept -> void const *;
+ //! @param id The id of the desired facet.
+ //! @return A opaque pointer to the facet implementation if this device supports it, nullptr otherwise.
+ [[nodiscard]] auto facet(kapi::capabilities::facet_id id) const noexcept -> void const *;
- //! Get a given capability from this device, if it implements it.
+ //! Get a specific facet of this device, if it supports it.
//!
- //! @tparam Interface The id of the desired interface.
- //! @return A typed pointer to the interface implementation if this device supports it, nullptr otherwise.
- template<typename InterfaceType>
- [[nodiscard]] auto as() -> InterfaceType *
+ //! @tparam FacetType The type of the desired facet.
+ //! @return A typed pointer to the facet implementation if this device supports it, nullptr otherwise.
+ template<typename FacetType>
+ [[nodiscard]] auto facet() -> FacetType *
{
- return static_cast<InterfaceType *>(as(InterfaceType::id));
+ return static_cast<FacetType *>(facet(FacetType::id));
}
- //! Get a given capability from this device, if it implements it.
+ //! Get a specific facet of this device, if it supports it.
//!
- //! @tparam Interface The id of the desired interface.
- //! @return A typed pointer to the interface implementation if this device supports it, nullptr otherwise.
- template<typename InterfaceType>
- [[nodiscard]] auto as() const noexcept -> InterfaceType const *
+ //! @tparam FacetType The type of the desired facet.
+ //! @return A typed pointer to the facet implementation if this device supports it, nullptr otherwise.
+ template<typename FacetType>
+ [[nodiscard]] auto facet() const noexcept -> FacetType const *
{
- return static_cast<InterfaceType const *>(as(InterfaceType::id));
+ return static_cast<FacetType const *>(facet(FacetType::id));
}
- //! Check if this device implements a given capability interface.
+ //! Check if this device has a specific facet.
//!
- //! @param interface The id of the queried interface.
- //! @return true iff. this device implements the given interface, false otherwise.
- [[nodiscard]] auto is_a(interface_id interface) const noexcept -> bool;
+ //! @param id The id of the desired facet.
+ //! @return true iff. this device has the given facet, false otherwise.
+ [[nodiscard]] auto has_facet(kapi::capabilities::facet_id id) const noexcept -> bool;
- //! Check if this device implements a given capability interface.
+ //! Check if this device has a specific facet.
//!
- //! @tparam Interface The id of the queried interface.
- //! @return true iff. this device implements the given interface, false otherwise.
- template<typename InterfaceType>
- [[nodiscard]] auto is_a() const noexcept -> bool
+ //! @tparam FacetType The type of the desired facet.
+ //! @return true iff. this device has the given facet, false otherwise.
+ template<typename FacetType>
+ [[nodiscard]] auto has_facet() const noexcept -> bool
{
- return is_a(InterfaceType::id);
+ return has_facet(FacetType::id);
}
//! Get the name of the device.
@@ -125,7 +125,7 @@ namespace kapi::devices
auto set_driver_data(kstd::shared_ptr<void> data) -> void;
protected:
- auto virtual query_interface(interface_id interface) -> void *;
+ auto virtual query_facet(kapi::capabilities::facet_id facet) -> void *;
private:
//! Busses need to be able to register themselves as a device's parent.
diff --git a/kapi/kapi/devices/driver.hpp b/kapi/kapi/devices/driver.hpp
index a2c2e396..348e2841 100644
--- a/kapi/kapi/devices/driver.hpp
+++ b/kapi/kapi/devices/driver.hpp
@@ -3,7 +3,7 @@
// IWYU pragma: private, include <kapi/devices.hpp>
-#include <kapi/devices/interface_id.hpp>
+#include <kapi/capabilities/facet_id.hpp>
#include <kstd/result.hpp>
@@ -46,33 +46,33 @@ namespace kapi::devices
//! @param device The device to release.
virtual auto unbind(device & device) -> void = 0;
- //! Retrieve this drivers implementation of a given capability interface.
+ //! Retrieve this drivers implementation of a given capability facet.
//!
- //! @return A pointer to this drivers implementation of the requested interface, nullptr if this driver does not
- //! support the requested interface.
- template<typename InterfaceType>
- [[nodiscard]] auto as() -> InterfaceType *
+ //! @return A pointer to this drivers implementation of the requested facet, nullptr if this driver does not
+ //! support the requested facet.
+ template<typename FacetType>
+ [[nodiscard]] auto facet() -> FacetType *
{
- return static_cast<InterfaceType *>(query_interface(InterfaceType::id));
+ return static_cast<FacetType *>(query_facet(FacetType::id));
}
- //! Retrieve this drivers implementation of a given capability interface.
+ //! Retrieve this drivers implementation of a given capability facet.
//!
- //! @return A pointer to this drivers implementation of the requested interface, nullptr if this driver does not
- //! support the requested interface.
- template<typename InterfaceType>
- [[nodiscard]] auto as() const -> InterfaceType const *
+ //! @return A pointer to this drivers implementation of the requested facet, nullptr if this driver does not
+ //! support the requested facet.
+ template<typename FacetType>
+ [[nodiscard]] auto facet() const -> FacetType const *
{
- return static_cast<InterfaceType *>(const_cast<driver *>(this)->query_interface(InterfaceType::id));
+ return static_cast<FacetType *>(const_cast<driver *>(this)->query_facet(FacetType::id));
}
- //! Check if this driver implements a given capability interface.
+ //! Check if this driver implements a given capability facet.
//!
- //! @return true iff. this driver implements the requested capability interface, false otherwise.
- template<typename InterfaceType>
- [[nodiscard]] auto is_a() const noexcept -> bool
+ //! @return true iff. this driver implements the requested capability facet, false otherwise.
+ template<typename FacetType>
+ [[nodiscard]] auto has_facet() const noexcept -> bool
{
- return query_interface(InterfaceType::id) != nullptr;
+ return query_facet(FacetType::id) != nullptr;
}
//! Get the major number associated with this driver, if any.
@@ -86,8 +86,8 @@ namespace kapi::devices
[[nodiscard]] virtual auto name() const noexcept -> std::string_view = 0;
protected:
- //! Return a pointer to the implementation of the given interface if this driver supports it.
- virtual auto query_interface(interface_id interface) -> void *;
+ //! Return a pointer to the implementation of the given facet if this driver supports it.
+ virtual auto query_facet(kapi::capabilities::facet_id facet) -> void *;
};
//! @}
diff --git a/kapi/kapi/devices/facet_registry.hpp b/kapi/kapi/devices/facet_registry.hpp
new file mode 100644
index 00000000..82bb304b
--- /dev/null
+++ b/kapi/kapi/devices/facet_registry.hpp
@@ -0,0 +1,305 @@
+#ifndef TEACHOS_KAPI_DEVICES_FACET_REGISTRY_HPP
+#define TEACHOS_KAPI_DEVICES_FACET_REGISTRY_HPP
+
+// IWYU pragma: private, include <kapi/devices.hpp>
+
+#include <kapi/capabilities/facet_id.hpp>
+#include <kapi/devices/device.hpp>
+
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/string.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
+
+#include <string_view>
+#include <utility>
+
+namespace kapi::devices
+{
+
+ //! @addtogroup kapi-devices-kernel-defined
+ //! @{
+
+ struct facet_registry_observer;
+
+ //! The device facet registry.
+ //!
+ //! The purpose of the facet registry is to allow system components, for example drivers, to publish capabilities in
+ //! terms of facets for devices. An example for such a capability are block devices. A driver for a given type of
+ //! block devices may choose too publish a the "block" facet on a bound device. Other subsystems may then query if a
+ //! given device exposes the "block" facet or get all devices implementing that capability.
+ //!
+ //! @note The device registry holds only non-owning references to the published devices. If a device dies after
+ //! publishing, without being unpublished, the registry accessors will prevent a dead handle from being exported.
+ //!
+ //! @see kernel::drivers::storage::ram_disk
+ //! @see kernel::filesystem::device_inode
+ //! @see kernel::filesystem::device_number_registry
+ struct facet_registry
+ {
+ //! A registry entry.
+ //!
+ //! Registry entries are used to record published facets on devices.
+ struct entry
+ {
+ //! Create a new registry entry, associating a device with a name and facet
+ //!
+ //! @param device The device to record the published facet for.
+ //! @param name The stable name to associate with this facet record.
+ //! @param facet The id of the implemented facet.
+ //! @param implementation A pointer to the actual implementation of the facet for the given device.
+ constexpr entry(kstd::shared_ptr<struct device> device, kstd::string name, kapi::capabilities::facet_id facet,
+ void * implementation)
+ : m_device{device}
+ , m_name{name}
+ , m_id{facet}
+ , m_facet{implementation}
+ {}
+
+ //! Get a handle to the device of this entry.
+ //!
+ //! @return A non-null pointer to the device if it is still alive, a null
+ //! pointer otherwise.
+ [[nodiscard]] constexpr auto device() const noexcept -> kstd::shared_ptr<device>
+ {
+ return m_device.lock();
+ }
+
+ //! Get the name of this entry.
+ //!
+ //! @return The name associated with this entry.
+ [[nodiscard]] constexpr auto name() const noexcept -> kstd::string const &
+ {
+ return m_name;
+ }
+
+ //! Get the id of the facet of the device-facet-implementation tuple described by this entry.
+ //!
+ //! @return The facet id of this entry.
+ [[nodiscard]] constexpr auto id() const noexcept -> kapi::capabilities::facet_id
+ {
+ return m_id;
+ }
+
+ //! Get the facet of the device-facet-implementation tuple described by this entry.
+ //!
+ //! @return An untyped pointer to the facet implementation.
+ [[nodiscard]] constexpr auto untyped_facet() const noexcept -> void *
+ {
+ return m_facet;
+ }
+
+ //! Get the facet of the device-facet-implementation tuple described by this entry.
+ //!
+ //! @return A typed pointer to the facet if the facet id matches, nullptr otherwise.
+ template<typename FacetType>
+ [[nodiscard]] constexpr auto facet() noexcept -> FacetType *
+ {
+ if (m_id == FacetType::id)
+ {
+ return static_cast<FacetType *>(untyped_facet());
+ }
+ return nullptr;
+ }
+
+ //! Get the facet of the device-facet-implementation tuple described by this entry.
+ //!
+ //! @return A typed pointer to the facet if the facet id matches, nullptr otherwise.
+ template<typename FacetType>
+ [[nodiscard]] constexpr auto facet() const noexcept -> FacetType const *
+ {
+ if (m_id == FacetType::id)
+ {
+ return static_cast<FacetType const *>(untyped_facet());
+ }
+ return nullptr;
+ }
+
+ private:
+ kstd::weak_ptr<struct device> m_device;
+ kstd::string m_name;
+ kapi::capabilities::facet_id m_id;
+ void * m_facet;
+ };
+
+ //! Construct an empty facet registry.
+ facet_registry() = default;
+
+ //! Initialize the system global singleton.
+ //!
+ //! @warning This function will panic if the global singleton has already been
+ //! initialized.
+ auto static init() -> void;
+
+ //! Get the system global singleton.
+ //!
+ //! @warning This function will panic if the global singleton has not been
+ //! initialized.
+ auto static get() -> facet_registry &;
+
+ //! Publish the fact that a given device has a given facet.
+ //!
+ //! Each published device-facet tuple must be associated with a unique stable name, to allow unique lookup via the
+ //! stable name.
+ //!
+ //! This overload is designed for devices that know about the existence of the given facet on themselves.
+ //!
+ //! @tparam FacetType The facet type supported by the given device.
+ //! @param device The device to publish the facet for.
+ //! @param name A stable name for the device.
+ template<typename FacetType>
+ auto publish(kstd::shared_ptr<device> device, kstd::string name) -> kstd::result<void>
+ {
+ if (!device)
+ {
+ return kstd::failure(make_error_code(kstd::errc::invalid_argument));
+ }
+
+ return do_publish(device, std::move(name), FacetType::id, device->facet<FacetType>());
+ }
+
+ //! Publish the fact that a given device has a given facet.
+ //!
+ //! Each published device-facet tuple must be associated with a unique stable name, to allow unique lookup via the
+ //! stable name.
+ //!
+ //! This overload is designed to externally assign facets to a device.
+ //!
+ //! @tparam FacetType The facet type supported by the given device.
+ //! @param device The device to publish the facet for.
+ //! @param name A stable name for the device.
+ //! @param facet The implementation of the facet for the device.
+ template<typename FacetType>
+ auto publish(kstd::shared_ptr<device> device, kstd::string name, FacetType * facet) -> kstd::result<void>
+ {
+ return do_publish(device, std::move(name), FacetType::id, facet);
+ }
+
+ //! Withdraw a previously published facets for a device.
+ //!
+ //! @param device The device to withdraw the facet for.
+ //! @param id The id of the facet to withdraw for the device.
+ auto withdraw(device const & device, kapi::capabilities::facet_id id) -> void;
+
+ //! Withdraw every facet previously published for a device.
+ //!
+ //! @param device The device to withdraw all facets for.
+ auto withdraw_all_for(device const & device) -> void;
+
+ //! Get all devices supporting a given facet.
+ //!
+ //! @param id The id of the facet for which to get the devices supporting it.
+ [[nodiscard]] auto all(kapi::capabilities::facet_id id) const -> kstd::vector<entry>;
+
+ //! Attempt to resolve a facet for a device by name.
+ //!
+ //! @param id The id of the facet to look for.
+ //! @param name The stable name of the device.
+ [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *;
+
+ //! Attempt to resolve a facet for a device.
+ //!
+ //! @param id The id of the facet to look for.
+ //! @param device The device.
+ [[nodiscard]] auto resolve(kapi::capabilities::facet_id id, device & device) -> void *;
+
+ //! Attempt to resolve a facet for a device by name.
+ //!
+ //! @tparam FacetType The facet to look for.
+ //! @param name The stable name of the device.
+ template<typename FacetType>
+ [[nodiscard]] auto resolve(std::string_view name) -> FacetType *
+ {
+ return static_cast<FacetType *>(resolve(FacetType::id, name));
+ }
+
+ //! Attempt to resolve a facet for a device.
+ //!
+ //! @tparam FacetType The facet to look for.
+ //! @param device The device.
+ template<typename FacetType>
+ [[nodiscard]] auto resolve(device & device) -> FacetType *
+ {
+ return static_cast<FacetType *>(resolve(FacetType::id, device));
+ }
+
+ //! Subscribe to facet publish/withdraw notifications.
+ //!
+ //! Observers subscribed through this function are held through non-owning pointers. It is safe of an observer
+ //! subscribed through this function to be destroyed without being unsubscribed.
+ //!
+ //! @param observer The observer to subscribe.
+ auto subscribe(kstd::weak_ptr<facet_registry_observer> observer) -> void;
+
+ //! Subscribe to facet publish/withdraw notifications.
+ //!
+ //! @warning The registry has no way of detecting liveness of observers subscribed through this function. This
+ //! function is intended to be used solely with long-lived observers. If an observer subscribed through this
+ //! function is destroyed before being unregistered, the behavior of any triggered notifications becomes undefined.
+ //!
+ //! @param observer The observer to subscribe.
+ auto subscribe(facet_registry_observer & observer) -> void;
+
+ //! Cancel a subscription previously made for a given observer.
+ //!
+ //! @param observer The observer to unsubscribe.
+ auto unsubscribe(facet_registry_observer & observer) -> void;
+
+ private:
+ //! Publish the fact that a device has a specific facet
+ //!
+ //! @param device The device to publish the facet for.
+ //! @param name A stable name for the device.
+ //! @param id The id of the facet to be published for the device.
+ //! @param facet The facet of the device.
+ auto do_publish(kstd::shared_ptr<device> device, kstd::string name, kapi::capabilities::facet_id id, void * facet)
+ -> kstd::result<void>;
+
+ //! Notify all subscribed observers about a new facet having been published for a device.
+ //!
+ //! @param id The id of the published facet.
+ //! @param published The entry representing the published device-facet combination.
+ auto do_notify_published(kapi::capabilities::facet_id id, entry const & published) -> void;
+
+ //! Notify all subscribed observers that a facet was withdrawn for a device.
+ //!
+ //! @param id The id of the withdrawn device.
+ //! @param device The device.
+ auto do_notify_withdrawn(kapi::capabilities::facet_id id, device const & device) -> void;
+
+ kstd::vector<entry> m_entries;
+ kstd::vector<kstd::weak_ptr<facet_registry_observer>> m_observers;
+ kstd::vector<facet_registry_observer *> m_static_observers;
+ };
+
+ //! @}
+
+ //! @addtogroup kapi-devices
+ //! @{
+
+ //! The facet for types interested in observing facet transaction on an facet registry.
+ struct facet_registry_observer
+ {
+ //! Enable correct destruction through base pointers.
+ virtual ~facet_registry_observer() = default;
+
+ //! Called after an facet has been published for a device.
+ //!
+ //! @param facet The facet id of the published facet.
+ //! @param published The published entry.
+ virtual auto on_facet_published(kapi::capabilities::facet_id facet, facet_registry::entry const & published)
+ -> void = 0;
+
+ //! Called after an facet has been withdrawn.
+ //!
+ //! @param facet The facet that was withdrawn.
+ //! @param device The device for which the facet was withdrawn.
+ virtual auto on_facet_withdrawn(kapi::capabilities::facet_id facet, device & device) -> void = 0;
+ };
+
+ //! @}
+
+} // namespace kapi::devices
+
+#endif
diff --git a/kapi/kapi/devices/interface_id.hpp b/kapi/kapi/devices/interface_id.hpp
deleted file mode 100644
index 0698d2fd..00000000
--- a/kapi/kapi/devices/interface_id.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef TEACHOS_KAPI_DEVICES_INTERFACE_ID_HPP
-#define TEACHOS_KAPI_DEVICES_INTERFACE_ID_HPP
-
-// IWYU pragma: private
-
-#include <kapi/capabilities/interface_id.hpp>
-
-namespace kapi::devices
-{
-
- using interface_id = kapi::capabilities::interface_id;
-
-}
-
-#endif
diff --git a/kapi/kapi/devices/interface_registry.hpp b/kapi/kapi/devices/interface_registry.hpp
deleted file mode 100644
index e0e70654..00000000
--- a/kapi/kapi/devices/interface_registry.hpp
+++ /dev/null
@@ -1,299 +0,0 @@
-#ifndef TEACHOS_KAPI_DEVICES_INTERFACE_REGISTRY_HPP
-#define TEACHOS_KAPI_DEVICES_INTERFACE_REGISTRY_HPP
-
-// IWYU pragma: private, include <kapi/devices.hpp>
-
-#include <kapi/devices/device.hpp>
-#include <kapi/devices/interface_id.hpp>
-
-#include <kstd/memory.hpp>
-#include <kstd/result.hpp>
-#include <kstd/string.hpp>
-#include <kstd/system_error.hpp>
-#include <kstd/vector.hpp>
-
-#include <string_view>
-#include <utility>
-
-namespace kapi::devices
-{
-
- //! @addtogroup kapi-devices-kernel-defined
- //! @{
-
- struct interface_registry_observer;
-
- //! The device capability interface registry.
- //!
- //! The purpose of the interface registry is to allow system components, for
- //! example drivers, to plush interfaces/capabilities for devices. An example
- //! for such a capability are block devices. A driver for a given type of block
- //! devices may choose too publish a the "block" capability on a bound device.
- //! Other subsystems may then query if a given device exposes the "block"
- //! capability or get all devices implementing that capability.
- //!
- //! @note The device registry holds only non-owning references to the published
- //! devices. If a device dies after publishing, without being unpublished, the
- //! registry accessors will prevent a dead handle from being exported.
- //!
- //! @see kernel::drivers::storage::ram_disk
- //! @see kernel::filesystem::device_inode
- //! @see kernel::filesystem::device_number_registry
- struct interface_registry
- {
- //! A registry entry.
- //!
- //! Registry entries are used to record published interfaces on devices.
- struct entry
- {
- //! Create a new registry entry, associating a device with a name,
- //! interface, and interface implementation.
- //!
- //! @param device The device to record the published interface for.
- //! @param name The stable name to associate with this interface record.
- //! @param interface The id of the implemented interface.
- //! @param implementation A pointer to the actual implementation of the
- //! interface for the given device.
- constexpr entry(kstd::shared_ptr<struct device> device, kstd::string name, interface_id interface,
- void * implementation)
- : m_device{device}
- , m_name{name}
- , m_interface{interface}
- , m_implementation{implementation}
- {}
-
- //! Get a handle to the device of this entry.
- //!
- //! @return A non-null pointer to the device if it is still alive, a null
- //! pointer otherwise.
- [[nodiscard]] constexpr auto device() const noexcept -> kstd::shared_ptr<device>
- {
- return m_device.lock();
- }
-
- //! Get the name of this entry.
- //!
- //! @return The name associated with this entry.
- [[nodiscard]] constexpr auto name() const noexcept -> kstd::string const &
- {
- return m_name;
- }
-
- //! Get the interface id associated with this entry.
- //!
- //! @return The interface id of this entry.
- [[nodiscard]] constexpr auto interface() const noexcept -> interface_id
- {
- return m_interface;
- }
-
- //! Get the interface implementation associated with this entry.
- //!
- //! @return An untyped pointer to the interface implementation.
- [[nodiscard]] constexpr auto implementation() const noexcept -> void *
- {
- return m_implementation;
- }
-
- //! Get the interface implementation associated with this entry.
- //!
- //! @return A typed pointer to the implementation if the interface type
- //! matches, nullptr otherwise.
- template<typename Interface>
- [[nodiscard]] constexpr auto as() noexcept -> Interface *
- {
- if (m_interface == Interface::id)
- {
- return static_cast<Interface *>(m_implementation);
- }
- return nullptr;
- }
-
- //! Get the interface implementation associated with this entry.
- //!
- //! @return A typed pointer to the implementation if the interface type
- //! matches, nullptr otherwise.
- template<typename Interface>
- [[nodiscard]] constexpr auto as() const noexcept -> Interface const *
- {
- if (m_interface == Interface::id)
- {
- return static_cast<Interface const *>(m_implementation);
- }
- return nullptr;
- }
-
- private:
- kstd::weak_ptr<struct device> m_device;
- kstd::string m_name;
- interface_id m_interface;
- void * m_implementation;
- };
-
- //! Construct an empty interface registry.
- interface_registry() = default;
-
- //! Initialize the system global singleton.
- //!
- //! @warning This function will panic if the global singleton has already been
- //! initialized.
- auto static init() -> void;
-
- //! Get the system global singleton.
- //!
- //! @warning This function will panic if the global singleton has not been
- //! initialized.
- auto static get() -> interface_registry &;
-
- //! Publish the fact that a given device implements a given interface.
- //!
- //! @tparam Interface The interface type implemented by the given device.
- //! @param device The device to publish the interface for.
- //! @param name A stable name for the device.
- template<typename Interface>
- auto publish(kstd::shared_ptr<device> device, kstd::string name) -> kstd::result<void>
- {
- if (!device)
- {
- return kstd::failure(make_error_code(kstd::errc::invalid_argument));
- }
-
- return do_publish(device, std::move(name), Interface::id, device->as<Interface>());
- }
-
- //! Publish the fact that a given device implements a given interface.
- //!
- //! @tparam Interface The interface type implemented by the given device.
- //! @param device The device to publish the interface for.
- //! @param name A stable name for the device.
- //! @param implementation The implementation of the interface for the device.
- template<typename Interface>
- auto publish(kstd::shared_ptr<device> device, kstd::string name, Interface * implementation) -> kstd::result<void>
- {
- return do_publish(device, std::move(name), Interface::id, implementation);
- }
-
- //! Withdraw a previously published inteface for a given device.
- //!
- //! @param device The device to withdraw the interface for.
- //! @param interface The interface to withdraw for the given device.
- auto withdraw(device const & device, interface_id interface) -> void;
-
- //! Withdraw every interface previously published for a given device.
- //!
- //! @param device The device to withdraw all interfaces for.
- auto withdraw_all_for(device const & device) -> void;
-
- //! Get all devices implementing a given interface.
- //!
- //! @param interface The interface for which to get the implementing devices.
- [[nodiscard]] auto all(interface_id interface) const -> kstd::vector<entry>;
-
- //! Attempt to resolve a given device, by name, to a given interface
- //! implementation
- //!
- //! @param interface The interface to look for.
- //! @param name The stable name of the device to look for.
- [[nodiscard]] auto resolve(interface_id interface, std::string_view name) -> void *;
-
- //! Attempt to resolve a given device to a given interface implementation
- //!
- //! @param interface The interface to look for.
- //! @param device The device to look for.
- [[nodiscard]] auto resolve(interface_id interface, device & device) -> void *;
-
- //! Attempt to resolve a given device, by name, to a given interface
- //! implementation
- //!
- //! @tparam Interface The interface to look for.
- //! @param name The stable name of the device to look for.
- template<typename Interface>
- [[nodiscard]] auto resolve(std::string_view name) -> Interface *
- {
- return static_cast<Interface *>(resolve(Interface::id, name));
- }
-
- //! Attempt to resolve a given device to a given interface implementation
- //!
- //! @tparam Interface The interface to look for.
- //! @param device The device to look for.
- template<typename Interface>
- [[nodiscard]] auto resolve(device & device) -> Interface *
- {
- return static_cast<Interface *>(resolve(Interface::id, device));
- }
-
- //! Subscribe to interface publish/withdraw notifications.
- //!
- //! Observers subscribed through this function are held through non-owning
- //! pointers. It is safe of an observer subscribed through this function to be
- //! destroyed without being unsubscribed.
- //!
- //! @param observer The observer to subscribe.
- auto subscribe(kstd::weak_ptr<interface_registry_observer> observer) -> void;
-
- //! Subscribe to interface publish/withdraw notifications.
- //!
- //! @warning The registry has no way of detecting liveness of observers
- //! subscribed through this function. This function is intended to be used
- //! solely with long-lived observers. If an observer subscribed through this
- //! function is destroyed before being unregistered, the behavior of any
- //! triggered notifications becomes undefined.
- //!
- //! @param observer The observer to subscribe.
- auto subscribe(interface_registry_observer & observer) -> void;
-
- //! Cancel a subscription previously made for a given observer.
- //!
- //! @param observer The observer to unsubscribe.
- auto unsubscribe(interface_registry_observer & observer) -> void;
-
- private:
- //! Publish the fact that a given device implements a given interface.
- //!
- //! @param device The device to publish the interface for.
- //! @param name A stable name for the device.
- //! @param interface The capability interface to be published for the device.
- //! @param implementation The implementation of the interface for the device.
- auto do_publish(kstd::shared_ptr<device> device, kstd::string name, interface_id interface, void * implementation)
- -> kstd::result<void>;
-
- auto do_notify_published(interface_id interface, entry const & published) -> void;
-
- auto do_notify_withdrawn(interface_id interface, device const & device) -> void;
-
- kstd::vector<entry> m_entries;
- kstd::vector<kstd::weak_ptr<interface_registry_observer>> m_observers;
- kstd::vector<interface_registry_observer *> m_static_observers;
- };
-
- //! @}
-
- //! @addtogroup kapi-devices
- //! @{
-
- //! The interface for types interested in observing interface transaction on an interface registry.
- struct interface_registry_observer
- {
- //! Enable correct destruction through base pointers.
- virtual ~interface_registry_observer() = default;
-
- //! Called after an interface has been published for a device.
- //!
- //! @param interface The interface id of the published interface.
- //! @param published The published entry.
- virtual auto on_interface_published(interface_id interface, interface_registry::entry const & published)
- -> void = 0;
-
- //! Called after an interface has been withdrawn.
- //!
- //! @param interface The interface that was withdrawn.
- //! @param device The device for which the interface was withdrawn.
- virtual auto on_interface_withdrawn(interface_id interface, device & device) -> void = 0;
- };
-
- //! @}
-
-} // namespace kapi::devices
-
-#endif
diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp
index 52bc22bc..da72f523 100644
--- a/kapi/kapi/filesystem.hpp
+++ b/kapi/kapi/filesystem.hpp
@@ -1,12 +1,12 @@
#ifndef TEACHOS_KAPI_FILESYSTEM_HPP
#define TEACHOS_KAPI_FILESYSTEM_HPP
+#include <kapi/capabilities/facet_id.hpp> // IWYU pragma: export
#include <kapi/filesystem/block_special_file.hpp> // IWYU pragma: export
#include <kapi/filesystem/character_special_file.hpp> // IWYU pragma: export
#include <kapi/filesystem/device_number.hpp> // IWYU pragma: export
#include <kapi/filesystem/file_status.hpp> // IWYU pragma: export
#include <kapi/filesystem/file_type.hpp> // IWYU pragma: export
-#include <kapi/filesystem/interface_id.hpp> // IWYU pragma: export
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
diff --git a/kapi/kapi/filesystem/block_special_file.hpp b/kapi/kapi/filesystem/block_special_file.hpp
index c7f3ac51..0e44fe35 100644
--- a/kapi/kapi/filesystem/block_special_file.hpp
+++ b/kapi/kapi/filesystem/block_special_file.hpp
@@ -3,7 +3,7 @@
// IWYU pragma: private, include <kapi/filesystem.hpp>
-#include <kapi/filesystem/interface_id.hpp>
+#include <kapi/capabilities/facet_id.hpp>
#include <kstd/result.hpp>
#include <kstd/units.hpp>
@@ -15,7 +15,7 @@ namespace kapi::filesystem
struct block_special_file
{
- constexpr auto static id = interface_id{"block"};
+ constexpr auto static id = kapi::capabilities::facet_id{"block"};
//! Virtual destructor to enable clean deletes through base pointers.
virtual ~block_special_file() = default;
diff --git a/kapi/kapi/filesystem/character_special_file.hpp b/kapi/kapi/filesystem/character_special_file.hpp
index 7ce5fdaa..328bbef9 100644
--- a/kapi/kapi/filesystem/character_special_file.hpp
+++ b/kapi/kapi/filesystem/character_special_file.hpp
@@ -3,7 +3,7 @@
// IWYU pragma: private, include <kapi/filesystem.hpp>
-#include <kapi/filesystem/interface_id.hpp>
+#include <kapi/capabilities/facet_id.hpp>
#include <kstd/result.hpp>
#include <kstd/units.hpp>
@@ -16,7 +16,7 @@ namespace kapi::filesystem
struct character_special_file
{
- constexpr auto static id = interface_id{"char"};
+ constexpr auto static id = kapi::capabilities::facet_id{"char"};
//! Virtual destructor to enable clean deletes through base pointers.
virtual ~character_special_file() = default;
diff --git a/kapi/kapi/filesystem/interface_id.hpp b/kapi/kapi/filesystem/interface_id.hpp
deleted file mode 100644
index 18e0fbc4..00000000
--- a/kapi/kapi/filesystem/interface_id.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef TEACHOS_KAPI_FILESYSTEM_INTERFACE_ID_HPP
-#define TEACHOS_KAPI_FILESYSTEM_INTERFACE_ID_HPP
-
-// IWYU pragma: private
-
-#include <kapi/capabilities/interface_id.hpp>
-
-namespace kapi::filesystem
-{
-
- using interface_id = kapi::capabilities::interface_id;
-
-}
-
-#endif
diff --git a/kapi/kapi/test_support/devices.hpp b/kapi/kapi/test_support/devices.hpp
index 3cb1cd8b..623bb87a 100644
--- a/kapi/kapi/test_support/devices.hpp
+++ b/kapi/kapi/test_support/devices.hpp
@@ -4,7 +4,7 @@
namespace kapi::test_support::devices
{
auto deinit() -> void;
- auto deinit_interface_registry() -> void;
+ auto deinit_facet_registry() -> void;
auto deinit_driver_registry() -> void;
auto deinit_device_registry() -> void;
} // namespace kapi::test_support::devices
diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt
index 9bb2efd8..d22ad107 100644
--- a/kernel/CMakeLists.txt
+++ b/kernel/CMakeLists.txt
@@ -19,7 +19,7 @@ target_sources("kernel_lib" PRIVATE
"kapi/devices/driver.cpp"
"kapi/devices/driver_registry.cpp"
"kapi/devices/error.cpp"
- "kapi/devices/interface_registry.cpp"
+ "kapi/devices/facet_registry.cpp"
"kapi/filesystem.cpp"
"kapi/interrupts.cpp"
"kapi/memory.cpp"
diff --git a/kernel/kapi/boot_modules/device.cpp b/kernel/kapi/boot_modules/device.cpp
index 84a43c1c..b9262abf 100644
--- a/kernel/kapi/boot_modules/device.cpp
+++ b/kernel/kapi/boot_modules/device.cpp
@@ -26,14 +26,14 @@ namespace kapi::boot_modules
return m_module;
}
- auto device::query_interface(kapi::devices::interface_id interface) -> void *
+ auto device::query_facet(kapi::capabilities::facet_id facet) -> void *
{
- if (interface == boot_module_signature::id)
+ if (facet == boot_module_signature::id)
{
return static_cast<boot_module_signature *>(this);
}
- return kapi::devices::device::query_interface(interface);
+ return kapi::devices::device::query_facet(facet);
}
} // namespace kapi::boot_modules \ No newline at end of file
diff --git a/kernel/kapi/devices.cpp b/kernel/kapi/devices.cpp
index c3c9e595..2505779a 100644
--- a/kernel/kapi/devices.cpp
+++ b/kernel/kapi/devices.cpp
@@ -27,7 +27,7 @@ namespace kapi::devices
}
device_registry::init();
- interface_registry::init();
+ facet_registry::init();
root_bus = kstd::make_shared<kernel::bus::root>();
device_registry::get().add(root_bus);
@@ -49,7 +49,7 @@ namespace kapi::test_support::devices
auto deinit() -> void
{
deinit_driver_registry();
- deinit_interface_registry();
+ deinit_facet_registry();
deinit_device_registry();
kapi::devices::root_bus.reset();
diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp
index a9bba4fb..9eecced0 100644
--- a/kernel/kapi/devices/bus.cpp
+++ b/kernel/kapi/devices/bus.cpp
@@ -37,19 +37,14 @@ namespace kapi::devices
return {m_devices.data(), m_devices.size()};
}
- auto bus::protocol() -> struct bus_protocol *
+ auto bus::query_facet(kapi::capabilities::facet_id facet) -> void *
{
- return nullptr;
- }
-
- auto bus::query_interface(interface_id interface) -> void *
- {
- if (interface == bus::id)
+ if (facet == bus::id)
{
return this;
}
- return device::query_interface(interface);
+ return device::query_facet(facet);
}
} // namespace kapi::devices \ No newline at end of file
diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp
index 01096165..2628e4f4 100644
--- a/kernel/kapi/devices/device.cpp
+++ b/kernel/kapi/devices/device.cpp
@@ -12,19 +12,19 @@ namespace kapi::devices
: m_name(name)
{}
- auto device::as(interface_id interface) noexcept -> void *
+ auto device::facet(kapi::capabilities::facet_id facet) noexcept -> void *
{
- return query_interface(interface);
+ return query_facet(facet);
}
- auto device::as(interface_id interface) const noexcept -> void const *
+ auto device::facet(kapi::capabilities::facet_id facet) const noexcept -> void const *
{
- return const_cast<device *>(this)->query_interface(interface);
+ return const_cast<device *>(this)->query_facet(facet);
}
- auto device::is_a(interface_id interface) const noexcept -> bool
+ auto device::has_facet(kapi::capabilities::facet_id facet) const noexcept -> bool
{
- return const_cast<device *>(this)->query_interface(interface) != nullptr;
+ return const_cast<device *>(this)->query_facet(facet) != nullptr;
}
auto device::name() const -> kstd::string const &
@@ -67,7 +67,7 @@ namespace kapi::devices
m_driver_data = data;
}
- auto device::query_interface(interface_id) -> void *
+ auto device::query_facet(kapi::capabilities::facet_id) -> void *
{
return nullptr;
}
diff --git a/kernel/kapi/devices/driver.cpp b/kernel/kapi/devices/driver.cpp
index be2866f0..55b7507b 100644
--- a/kernel/kapi/devices/driver.cpp
+++ b/kernel/kapi/devices/driver.cpp
@@ -11,7 +11,7 @@ namespace kapi::devices
return std::nullopt;
}
- auto driver::query_interface(interface_id) -> void *
+ auto driver::query_facet(kapi::capabilities::facet_id) -> void *
{
return nullptr;
}
diff --git a/kernel/kapi/devices/driver.tests.cpp b/kernel/kapi/devices/driver.tests.cpp
index e65e48e0..560cc1bc 100644
--- a/kernel/kapi/devices/driver.tests.cpp
+++ b/kernel/kapi/devices/driver.tests.cpp
@@ -16,39 +16,49 @@ namespace
{
struct controller_identification
{
- constexpr auto static id = kapi::devices::interface_id{"stacking_test_controller_identification"};
+ constexpr auto static id = kapi::capabilities::facet_id{"stacking_test_controller_identification"};
virtual ~controller_identification() = default;
[[nodiscard]] virtual auto controller_name() const -> std::string_view = 0;
};
struct controller_driver_identification
{
- constexpr auto static id = kapi::devices::interface_id{"stacking_test_controller_driver_identification"};
+ constexpr auto static id = kapi::capabilities::facet_id{"stacking_test_controller_driver_identification"};
virtual ~controller_driver_identification() = default;
[[nodiscard]] virtual auto supported_names() const -> std::span<std::string_view const> = 0;
};
- struct controller_bus final : kapi::devices::bus, kapi::devices::bus_protocol
+ struct controller_protocol : kapi::devices::bus_protocol
{
- using kapi::devices::bus::bus;
+ constexpr auto static id = kapi::capabilities::facet_id{"stacking_test_controller_protocol"};
auto enumerate(kapi::devices::bus &) -> void override {}
[[nodiscard]] auto match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const
-> kstd::result<std::uint32_t> override
{
- auto const * ident = dev.as<controller_identification>();
- auto const * claims = drv.as<controller_driver_identification>();
+ auto const * ident = dev.facet<controller_identification>();
+ auto const * claims = drv.facet<controller_driver_identification>();
if (!ident || !claims || !std::ranges::contains(claims->supported_names(), ident->controller_name()))
{
return kstd::failure(kapi::devices::driver_match_errc::no_match);
}
return 0u;
}
+ } constinit controller_protocol_instance{};
+
+ struct controller_bus final : kapi::devices::bus
+ {
+ using kapi::devices::bus::bus;
- [[nodiscard]] auto protocol() -> kapi::devices::bus_protocol * override
+ [[nodiscard]] auto query_facet(kapi::capabilities::facet_id id) -> void * override
{
- return this;
+ if (id == controller_protocol::id || id == kapi::devices::bus_protocol::id)
+ {
+ return &controller_protocol_instance;
+ }
+
+ return kapi::devices::bus::query_facet(id);
}
};
@@ -64,26 +74,26 @@ namespace
}
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override
{
- if (interface == controller_identification::id)
+ if (facet == controller_identification::id)
{
return static_cast<controller_identification *>(this);
}
- return kapi::devices::bus::query_interface(interface);
+ return kapi::devices::bus::query_facet(facet);
}
};
struct leaf_identification
{
- constexpr auto static id = kapi::devices::interface_id{"stacking_test_leaf_identification"};
+ constexpr auto static id = kapi::capabilities::facet_id{"stacking_test_leaf_identification"};
virtual ~leaf_identification() = default;
[[nodiscard]] virtual auto leaf_name() const -> std::string_view = 0;
};
struct leaf_driver_identification
{
- constexpr auto static id = kapi::devices::interface_id{"stacking_test_leaf_driver_identification"};
+ constexpr auto static id = kapi::capabilities::facet_id{"stacking_test_leaf_driver_identification"};
virtual ~leaf_driver_identification() = default;
[[nodiscard]] virtual auto supported_names() const -> std::span<std::string_view const> = 0;
};
@@ -100,19 +110,19 @@ namespace
}
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override
{
- if (interface == leaf_identification::id)
+ if (facet == leaf_identification::id)
{
return static_cast<leaf_identification *>(this);
}
- return kapi::devices::device::query_interface(interface);
+ return kapi::devices::device::query_facet(facet);
}
};
- struct leaf_bus final : kapi::devices::bus, kapi::devices::bus_protocol
+ struct leaf_protocol final : kapi::devices::bus_protocol
{
- using kapi::devices::bus::bus;
+ constexpr auto static id = kapi::capabilities::facet_id{"stacking_test_leaf_protocol"};
auto enumerate(kapi::devices::bus & self) -> void override
{
@@ -122,18 +132,28 @@ namespace
[[nodiscard]] auto match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const
-> kstd::result<std::uint32_t> override
{
- auto const * ident = dev.as<leaf_identification>();
- auto const * claims = drv.as<leaf_driver_identification>();
+ auto const * ident = dev.facet<leaf_identification>();
+ auto const * claims = drv.facet<leaf_driver_identification>();
if (!ident || !claims || !std::ranges::contains(claims->supported_names(), ident->leaf_name()))
{
return kstd::failure(kapi::devices::driver_match_errc::no_match);
}
return 0u;
}
+ } constinit leaf_protocol_instance{};
+
+ struct leaf_bus final : kapi::devices::bus
+ {
+ using kapi::devices::bus::bus;
- [[nodiscard]] auto protocol() -> kapi::devices::bus_protocol * override
+ [[nodiscard]] auto query_facet(kapi::capabilities::facet_id id) -> void * override
{
- return this;
+ if (id == leaf_protocol::id || id == kapi::devices::bus_protocol::id)
+ {
+ return &leaf_protocol_instance;
+ }
+
+ return kapi::devices::bus::query_facet(id);
}
};
@@ -144,7 +164,7 @@ namespace
auto self_as_bus = kstd::static_pointer_cast<kapi::devices::bus>(dev.shared_from_this());
auto leaf = kstd::make_shared<leaf_bus>("stacking_test_leaf_bus");
self_as_bus->add_child(leaf);
- leaf->enumerate(*leaf);
+ leaf->facet<leaf_protocol>()->enumerate(*leaf);
return kstd::success();
}
@@ -163,14 +183,14 @@ namespace
}
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override
{
- if (interface == controller_driver_identification::id)
+ if (facet == controller_driver_identification::id)
{
return static_cast<controller_driver_identification *>(this);
}
- return kapi::devices::driver::query_interface(interface);
+ return kapi::devices::driver::query_facet(facet);
}
};
@@ -195,14 +215,14 @@ namespace
}
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override
{
- if (interface == leaf_driver_identification::id)
+ if (facet == leaf_driver_identification::id)
{
return static_cast<leaf_driver_identification *>(this);
}
- return kapi::devices::driver::query_interface(interface);
+ return kapi::devices::driver::query_facet(facet);
}
};
} // namespace
diff --git a/kernel/kapi/devices/driver_registry.cpp b/kernel/kapi/devices/driver_registry.cpp
index cb101d27..842dbc1d 100644
--- a/kernel/kapi/devices/driver_registry.cpp
+++ b/kernel/kapi/devices/driver_registry.cpp
@@ -79,7 +79,7 @@ namespace kapi::devices
}
auto parent = device->parent();
- auto protocol = parent ? parent->protocol() : nullptr;
+ auto protocol = parent ? parent->facet<kapi::devices::bus_protocol>() : nullptr;
if (!protocol)
{
return;
diff --git a/kernel/kapi/devices/driver_registry.tests.cpp b/kernel/kapi/devices/driver_registry.tests.cpp
index d4d8a174..c7d1744d 100644
--- a/kernel/kapi/devices/driver_registry.tests.cpp
+++ b/kernel/kapi/devices/driver_registry.tests.cpp
@@ -15,7 +15,7 @@ namespace
struct test_identification
{
- constexpr auto static id = kapi::devices::interface_id{"test_identification"};
+ constexpr auto static id = kapi::capabilities::facet_id{"test_identification"};
virtual ~test_identification() = default;
@@ -25,6 +25,8 @@ namespace
struct test_protocol final : kapi::devices::bus_protocol
{
+ constexpr auto static id = kapi::capabilities::facet_id{"test_protocol"};
+
explicit test_protocol(unsigned * match_calls)
: match_calls{match_calls}
{}
@@ -36,7 +38,7 @@ namespace
{
++*match_calls;
- auto const * identification = driver.as<test_identification>();
+ auto const * identification = driver.facet<test_identification>();
if (!identification)
{
return kstd::failure(kapi::devices::driver_match_errc::no_match);
@@ -52,9 +54,14 @@ namespace
{
using kapi::devices::bus::bus;
- [[nodiscard]] auto protocol() -> kapi::devices::bus_protocol * override
+ [[nodiscard]] auto query_facet(kapi::capabilities::facet_id id) -> void * override
{
- return &bus_protocol;
+ if (id == test_protocol::id || id == kapi::devices::bus_protocol::id)
+ {
+ return &bus_protocol;
+ }
+
+ return kapi::devices::bus::query_facet(id);
}
unsigned match_calls{};
@@ -106,14 +113,14 @@ namespace
mutable unsigned probe_calls;
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override
{
- if (interface == test_identification::id)
+ if (facet == test_identification::id)
{
return static_cast<test_identification *>(this);
}
- return kapi::devices::driver::query_interface(interface);
+ return kapi::devices::driver::query_facet(facet);
}
private:
diff --git a/kernel/kapi/devices/facet_registry.cpp b/kernel/kapi/devices/facet_registry.cpp
new file mode 100644
index 00000000..4aeebfc1
--- /dev/null
+++ b/kernel/kapi/devices/facet_registry.cpp
@@ -0,0 +1,216 @@
+#include <kapi/devices/facet_registry.hpp>
+
+#include <kapi/devices.hpp>
+#include <kapi/system.hpp>
+#include <kapi/test_support/devices.hpp>
+
+#include <kstd/memory.hpp>
+#include <kstd/result.hpp>
+#include <kstd/string.hpp>
+#include <kstd/system_error.hpp>
+#include <kstd/vector.hpp>
+
+#include <algorithm>
+#include <optional>
+#include <string_view>
+#include <utility>
+
+namespace kapi::devices
+{
+
+ namespace
+ {
+ constinit auto static registry = std::optional<facet_registry>{};
+ }
+
+ auto facet_registry::init() -> void
+ {
+ if (registry.has_value())
+ {
+ system::panic("[kernel] Device facet registry has already been initialized.");
+ }
+
+ registry.emplace();
+ }
+
+ auto facet_registry::get() -> facet_registry &
+ {
+ if (!registry)
+ {
+ system::panic("[kernel] Device facet registry has not been initialized.");
+ }
+
+ return *registry;
+ }
+
+ auto facet_registry::do_publish(kstd::shared_ptr<device> device, kstd::string name, kapi::capabilities::facet_id id,
+ void * facet) -> kstd::result<void>
+ {
+ // TODO: lock registry
+
+ erase_if(m_entries, [id](auto e) { return e.id() == id && !e.device(); });
+
+ if (!device || !facet || name.empty())
+ {
+ return kstd::failure(make_error_code(kstd::errc::invalid_argument));
+ }
+
+ auto already_published = std::ranges::any_of(
+ m_entries, [&](auto const & entry) { return entry.id() == id && entry.device().get() == device.get(); });
+
+ if (already_published)
+ {
+ return kstd::failure(make_error_code(kstd::errc::file_exists));
+ }
+
+ auto & published = m_entries.emplace_back(device, std::move(name), id, facet);
+
+ do_notify_published(id, published);
+
+ return kstd::success();
+ }
+
+ auto facet_registry::do_notify_published(kapi::capabilities::facet_id id, entry const & published) -> void
+ {
+ std::ranges::for_each(m_observers, [&](auto observer) {
+ if (auto locked_observer = observer.lock())
+ {
+ locked_observer->on_facet_published(id, published);
+ }
+ });
+
+ std::ranges::for_each(m_static_observers, [&](auto observer) { observer->on_facet_published(id, published); });
+ }
+
+ auto facet_registry::do_notify_withdrawn(kapi::capabilities::facet_id id, device const & device) -> void
+ {
+ std::ranges::for_each(m_observers, [&](auto observer) {
+ if (auto locked_observer = observer.lock())
+ {
+ locked_observer->on_facet_withdrawn(id, const_cast<devices::device &>(device));
+ }
+ });
+
+ std::ranges::for_each(m_static_observers, [&](auto observer) {
+ observer->on_facet_withdrawn(id, const_cast<devices::device &>(device));
+ });
+ }
+
+ auto facet_registry::withdraw(device const & device, kapi::capabilities::facet_id id) -> void
+ {
+ // TODO: lock registry
+
+ auto did_remove = erase_if(m_entries, [&](auto e) {
+ auto locked_device = e.device();
+ return e.id() == id && locked_device && locked_device.get() == &device;
+ }) != 0;
+
+ if (did_remove)
+ {
+ do_notify_withdrawn(id, device);
+ }
+ }
+
+ auto facet_registry::withdraw_all_for(device const & device) -> void
+ {
+ // TODO: lock registry
+
+ auto withdrawn_facets = kstd::vector<kapi::capabilities::facet_id>{};
+
+ erase_if(m_entries, [&](auto e) {
+ auto locked_device = e.device();
+ auto do_erase = locked_device && locked_device.get() == &device;
+ if (do_erase)
+ {
+ withdrawn_facets.push_back(e.id());
+ }
+ return do_erase;
+ });
+
+ std::ranges::for_each(withdrawn_facets, [&](auto facet) { do_notify_withdrawn(facet, device); });
+ }
+
+ auto facet_registry::all(kapi::capabilities::facet_id id) const -> kstd::vector<entry>
+ {
+ // TODO: lock registry
+
+ auto filtered = m_entries;
+ erase_if(filtered, [&](auto e) {
+ auto locked_device = e.device();
+ return !(e.id() == id && locked_device);
+ });
+ return filtered;
+ }
+
+ auto facet_registry::resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *
+ {
+ // TODO: lock registry
+
+ auto found = std::ranges::find_if(m_entries, [&](auto e) { return e.name() == name && e.device(); });
+
+ if (found == m_entries.cend())
+ {
+ return nullptr;
+ }
+ else if (auto device = found->device())
+ {
+ return resolve(id, *device);
+ }
+
+ return nullptr;
+ }
+
+ auto facet_registry::resolve(kapi::capabilities::facet_id id, device & device) -> void *
+ {
+ // TODO: lock registry
+
+ if (auto by_device = device.facet(id))
+ {
+ return by_device;
+ }
+
+ auto found = std::ranges::find_if(m_entries, [&](auto e) {
+ auto locked_device = e.device();
+ return e.id() == id && locked_device && locked_device.get() == &device;
+ });
+
+ if (found == m_entries.cend())
+ {
+ return nullptr;
+ }
+
+ return found->untyped_facet();
+ }
+
+ auto facet_registry::subscribe(kstd::weak_ptr<facet_registry_observer> observer) -> void
+ {
+ // TODO: lock registry
+
+ erase_if(m_observers, [](auto const & observer) { return observer.expired(); });
+ m_observers.push_back(observer);
+ }
+
+ auto facet_registry::subscribe(facet_registry_observer & observer) -> void
+ {
+ // TODO: lock registry
+
+ m_static_observers.push_back(&observer);
+ }
+
+ auto facet_registry::unsubscribe(facet_registry_observer & observer) -> void
+ {
+ // TODO: lock registry
+
+ erase_if(m_observers, [&](auto const & subscribed) { return subscribed.lock().get() == &observer; });
+ erase(m_static_observers, &observer);
+ }
+
+} // namespace kapi::devices
+
+namespace kapi::test_support::devices
+{
+ auto deinit_facet_registry() -> void
+ {
+ kapi::devices::registry.reset();
+ }
+} // namespace kapi::test_support::devices
diff --git a/kernel/kapi/devices/interface_registry.tests.cpp b/kernel/kapi/devices/facet_registry.tests.cpp
index 071b9a6d..4ad3f763 100644
--- a/kernel/kapi/devices/interface_registry.tests.cpp
+++ b/kernel/kapi/devices/facet_registry.tests.cpp
@@ -10,7 +10,7 @@ namespace
{
struct probe_device
{
- constexpr auto static id = kapi::devices::interface_id{"probe"};
+ constexpr auto static id = kapi::capabilities::facet_id{"probe"};
virtual ~probe_device() = default;
@@ -19,7 +19,7 @@ namespace
struct const_device
{
- constexpr auto static id = kapi::devices::interface_id{"flip"};
+ constexpr auto static id = kapi::capabilities::facet_id{"flip"};
virtual ~const_device() = default;
@@ -31,7 +31,7 @@ namespace
struct unimplemented_device
{
- constexpr auto static id = kapi::devices::interface_id{"unimplemented"};
+ constexpr auto static id = kapi::capabilities::facet_id{"unimplemented"};
virtual ~unimplemented_device() = default;
};
@@ -49,18 +49,18 @@ namespace
return m_value;
}
- auto query_interface(kapi::devices::interface_id interface) -> void * override
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override
{
- if (interface == probe_device::id)
+ if (facet == probe_device::id)
{
return static_cast<probe_device *>(this);
}
- if (interface == const_device::id)
+ if (facet == const_device::id)
{
return m_const_device;
}
- return kapi::devices::device::query_interface(interface);
+ return kapi::devices::device::query_facet(facet);
}
private:
@@ -68,15 +68,14 @@ namespace
const_device * m_const_device;
};
- struct counting_observer final : kapi::devices::interface_registry_observer
+ struct counting_observer final : kapi::devices::facet_registry_observer
{
- auto on_interface_published(kapi::devices::interface_id, kapi::devices::interface_registry::entry const &)
- -> void override
+ auto on_facet_published(kapi::capabilities::facet_id, kapi::devices::facet_registry::entry const &) -> void override
{
++published;
}
- auto on_interface_withdrawn(kapi::devices::interface_id, kapi::devices::device &) -> void override
+ auto on_facet_withdrawn(kapi::capabilities::facet_id, kapi::devices::device &) -> void override
{
++withdrawn;
}
@@ -85,19 +84,18 @@ namespace
std::size_t withdrawn{};
};
- struct evil_observer final : kapi::devices::interface_registry_observer
+ struct evil_observer final : kapi::devices::facet_registry_observer
{
explicit evil_observer(kstd::shared_ptr<counting_observer> & victim)
: m_victim{victim}
{}
- auto on_interface_published(kapi::devices::interface_id, kapi::devices::interface_registry::entry const &)
- -> void override
+ auto on_facet_published(kapi::capabilities::facet_id, kapi::devices::facet_registry::entry const &) -> void override
{
m_victim.reset();
}
- auto on_interface_withdrawn(kapi::devices::interface_id, kapi::devices::device &) -> void override
+ auto on_facet_withdrawn(kapi::capabilities::facet_id, kapi::devices::device &) -> void override
{
m_victim.reset();
}
@@ -108,46 +106,46 @@ namespace
} // namespace
-SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]")
+SCENARIO("Publishing and finding a device", "[kapi][devices][facet_registry]")
{
- GIVEN("An empty registry, a device, and an interface the device implements by inheritance")
+ GIVEN("An empty registry, a device, and a facet the device implements by inheritance")
{
- auto registry = kapi::devices::interface_registry{};
- auto free_standing_interface = const_device{};
- auto device = kstd::make_shared<test_device>(128, free_standing_interface);
+ auto registry = kapi::devices::facet_registry{};
+ auto free_standing_facet = const_device{};
+ auto device = kstd::make_shared<test_device>(128, free_standing_facet);
- THEN("Publishing an interface without a name fails")
+ THEN("Publishing an facet without a name fails")
{
REQUIRE_FALSE(registry.publish<probe_device>(device, ""));
}
- WHEN("publishing the interface for the device")
+ WHEN("publishing the facet for the device")
{
- CHECK(device->is_a<probe_device>());
- CHECK(device->is_a<const_device>());
- auto published = registry.publish(device, "probe0", device->as<probe_device>());
+ CHECK(device->has_facet<probe_device>());
+ CHECK(device->has_facet<const_device>());
+ auto published = registry.publish(device, "probe0", device->facet<probe_device>());
THEN("publishing is successful")
{
REQUIRE(published);
}
- THEN("publishing the same device and interface with a different name fails")
+ THEN("publishing the same device and facet with a different name fails")
{
- REQUIRE_FALSE(registry.publish(device, "probe1", device->as<probe_device>()));
+ REQUIRE_FALSE(registry.publish(device, "probe1", device->facet<probe_device>()));
}
- THEN("publishing a second interface for the same device succeeds")
+ THEN("publishing a second facet for the same device succeeds")
{
REQUIRE(registry.publish<const_device>(device, "probe0"));
}
- THEN("publishing a free standing second interface for the same device succeeds")
+ THEN("publishing a free standing second facet for the same device succeeds")
{
- REQUIRE(registry.publish(device, "probe0", &free_standing_interface));
+ REQUIRE(registry.publish(device, "probe0", &free_standing_facet));
}
- AND_WHEN("getting all devices implementing that interface")
+ AND_WHEN("getting all devices implementing that facet")
{
auto probeable_devices = registry.all(probe_device::id);
@@ -168,12 +166,12 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]
THEN("the returned implementation equals the result of device::as")
{
- REQUIRE(probeable_devices[0].implementation() == device->as<probe_device>());
+ REQUIRE(probeable_devices[0].untyped_facet() == device->facet<probe_device>());
}
- THEN("the interface provided function can be invoked")
+ THEN("the facet provided function can be invoked")
{
- auto implementation = probeable_devices[0].as<probe_device>();
+ auto implementation = probeable_devices[0].facet<probe_device>();
REQUIRE(implementation->get_value() == device->get_value());
}
}
@@ -198,7 +196,7 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]
REQUIRE_FALSE(registry.resolve<probe_device>("probe1"));
}
- THEN("withdrawing an interface for a device removes it from the registry")
+ THEN("withdrawing an facet for a device removes it from the registry")
{
registry.withdraw(*device, probe_device::id);
REQUIRE_FALSE(registry.resolve<probe_device>("probe0"));
@@ -207,7 +205,7 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]
WHEN("the device is destroyed without withdrawing it")
{
- CHECK(registry.publish(device, "probe0", device->as<probe_device>()));
+ CHECK(registry.publish(device, "probe0", device->facet<probe_device>()));
device.reset();
THEN("querying all does no longer report it")
@@ -224,7 +222,7 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]
GIVEN("no device has ever been published")
{
- auto registry = kapi::devices::interface_registry{};
+ auto registry = kapi::devices::facet_registry{};
THEN("all() returns an empty vector")
{
@@ -234,31 +232,31 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]
GIVEN("a null device")
{
- auto registry = kapi::devices::interface_registry{};
+ auto registry = kapi::devices::facet_registry{};
auto device = kstd::shared_ptr<kapi::devices::device>{};
- auto interface = const_device{};
+ auto facet = const_device{};
- THEN("publishing the interface for the device fails")
+ THEN("publishing the facet for the device fails")
{
- REQUIRE_FALSE(registry.publish(device, "probe0", &interface));
+ REQUIRE_FALSE(registry.publish(device, "probe0", &facet));
}
}
}
-SCENARIO("Interface registry notifies subscribers", "[kapi][devices][interface_registry]")
+SCENARIO("facet registry notifies subscribers", "[kapi][devices][facet_registry]")
{
GIVEN("a device and a subscribed observer")
{
- auto registry = kapi::devices::interface_registry{};
- auto free_standing_interface = const_device{};
- auto device = kstd::make_shared<test_device>(128, free_standing_interface);
+ auto registry = kapi::devices::facet_registry{};
+ auto free_standing_facet = const_device{};
+ auto device = kstd::make_shared<test_device>(128, free_standing_facet);
auto observer = kstd::make_shared<counting_observer>();
registry.subscribe(observer);
- WHEN("an interface is published for the device")
+ WHEN("an facet is published for the device")
{
- CHECK(registry.publish(device, "probe0", device->as<probe_device>()));
+ CHECK(registry.publish(device, "probe0", device->facet<probe_device>()));
THEN("the observer is notified exactly once")
{
@@ -267,9 +265,9 @@ SCENARIO("Interface registry notifies subscribers", "[kapi][devices][interface_r
}
}
- WHEN("an interface is published and then withdrawn")
+ WHEN("an facet is published and then withdrawn")
{
- CHECK(registry.publish(device, "probe0", device->as<probe_device>()));
+ CHECK(registry.publish(device, "probe0", device->facet<probe_device>()));
registry.withdraw(*device, probe_device::id);
THEN("the observer is notified of both exactly one")
@@ -285,7 +283,7 @@ SCENARIO("Interface registry notifies subscribers", "[kapi][devices][interface_r
THEN("publishing afterward does not crash")
{
- REQUIRE_NOTHROW(registry.publish(device, "probe0", device->as<probe_device>()));
+ REQUIRE_NOTHROW(registry.publish(device, "probe0", device->facet<probe_device>()));
}
}
@@ -295,12 +293,12 @@ SCENARIO("Interface registry notifies subscribers", "[kapi][devices][interface_r
THEN("publishing afterward does not crash")
{
- REQUIRE_NOTHROW(registry.publish(device, "probe0", device->as<probe_device>()));
+ REQUIRE_NOTHROW(registry.publish(device, "probe0", device->facet<probe_device>()));
}
THEN("the subscriber is not notified")
{
- REQUIRE_NOTHROW(registry.publish(device, "probe0", device->as<probe_device>()));
+ REQUIRE_NOTHROW(registry.publish(device, "probe0", device->facet<probe_device>()));
REQUIRE_NOTHROW(registry.withdraw(*device, probe_device::id));
REQUIRE(observer->published == 0);
REQUIRE(observer->withdrawn == 0);
@@ -310,9 +308,9 @@ SCENARIO("Interface registry notifies subscribers", "[kapi][devices][interface_r
GIVEN("two subscriber, the first destroying the second")
{
- auto registry = kapi::devices::interface_registry{};
- auto free_standing_interface = const_device{};
- auto device = kstd::make_shared<test_device>(128, free_standing_interface);
+ auto registry = kapi::devices::facet_registry{};
+ auto free_standing_facet = const_device{};
+ auto device = kstd::make_shared<test_device>(128, free_standing_facet);
auto second = kstd::make_shared<counting_observer>();
auto first = kstd::make_shared<evil_observer>(second);
@@ -320,9 +318,9 @@ SCENARIO("Interface registry notifies subscribers", "[kapi][devices][interface_r
registry.subscribe(first);
registry.subscribe(second);
- THEN("publishing an interface does not crash")
+ THEN("publishing an facet does not crash")
{
- REQUIRE_NOTHROW(registry.publish(device, "probe0", device->as<probe_device>()));
+ REQUIRE_NOTHROW(registry.publish(device, "probe0", device->facet<probe_device>()));
REQUIRE(second == nullptr);
}
}
diff --git a/kernel/kapi/devices/interface_registry.cpp b/kernel/kapi/devices/interface_registry.cpp
deleted file mode 100644
index 1d456b30..00000000
--- a/kernel/kapi/devices/interface_registry.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-#include <kapi/devices/interface_registry.hpp>
-
-#include <kapi/devices.hpp>
-#include <kapi/system.hpp>
-#include <kapi/test_support/devices.hpp>
-
-#include <kstd/memory.hpp>
-#include <kstd/result.hpp>
-#include <kstd/string.hpp>
-#include <kstd/system_error.hpp>
-#include <kstd/vector.hpp>
-
-#include <algorithm>
-#include <optional>
-#include <string_view>
-#include <utility>
-
-namespace kapi::devices
-{
-
- namespace
- {
- constinit auto static registry = std::optional<interface_registry>{};
- }
-
- auto interface_registry::init() -> void
- {
- if (registry.has_value())
- {
- system::panic("[kernel] Device interface registry has already been initialized.");
- }
-
- registry.emplace();
- }
-
- auto interface_registry::get() -> interface_registry &
- {
- if (!registry)
- {
- system::panic("[kernel] Device interface registry has not been initialized.");
- }
-
- return *registry;
- }
-
- auto interface_registry::do_publish(kstd::shared_ptr<device> device, kstd::string name, interface_id interface,
- void * implementation) -> kstd::result<void>
- {
- // TODO: lock registry
-
- erase_if(m_entries, [interface](auto e) { return e.interface() == interface && !e.device(); });
-
- if (!device || !implementation || name.empty())
- {
- return kstd::failure(make_error_code(kstd::errc::invalid_argument));
- }
-
- auto already_published = std::ranges::any_of(m_entries, [&](auto const & entry) {
- return entry.interface() == interface && entry.device().get() == device.get();
- });
-
- if (already_published)
- {
- return kstd::failure(make_error_code(kstd::errc::file_exists));
- }
-
- auto & published = m_entries.emplace_back(device, std::move(name), interface, implementation);
-
- do_notify_published(interface, published);
-
- return kstd::success();
- }
-
- auto interface_registry::do_notify_published(interface_id interface, entry const & published) -> void
- {
- std::ranges::for_each(m_observers, [&](auto observer) {
- if (auto locked_observer = observer.lock())
- {
- locked_observer->on_interface_published(interface, published);
- }
- });
-
- std::ranges::for_each(m_static_observers,
- [&](auto observer) { observer->on_interface_published(interface, published); });
- }
-
- auto interface_registry::do_notify_withdrawn(interface_id interface, device const & device) -> void
- {
- std::ranges::for_each(m_observers, [&](auto observer) {
- if (auto locked_observer = observer.lock())
- {
- locked_observer->on_interface_withdrawn(interface, const_cast<devices::device &>(device));
- }
- });
-
- std::ranges::for_each(m_static_observers, [&](auto observer) {
- observer->on_interface_withdrawn(interface, const_cast<devices::device &>(device));
- });
- }
-
- auto interface_registry::withdraw(device const & device, interface_id interface) -> void
- {
- // TODO: lock registry
-
- auto did_remove = erase_if(m_entries, [&](auto e) {
- auto locked_device = e.device();
- return e.interface() == interface && locked_device && locked_device.get() == &device;
- }) != 0;
-
- if (did_remove)
- {
- do_notify_withdrawn(interface, device);
- }
- }
-
- auto interface_registry::withdraw_all_for(device const & device) -> void
- {
- // TODO: lock registry
-
- auto withdrawn_interfaces = kstd::vector<interface_id>{};
-
- erase_if(m_entries, [&](auto e) {
- auto locked_device = e.device();
- auto do_erase = locked_device && locked_device.get() == &device;
- if (do_erase)
- {
- withdrawn_interfaces.push_back(e.interface());
- }
- return do_erase;
- });
-
- std::ranges::for_each(withdrawn_interfaces, [&](auto interface) { do_notify_withdrawn(interface, device); });
- }
-
- auto interface_registry::all(interface_id interface) const -> kstd::vector<entry>
- {
- // TODO: lock registry
-
- auto filtered = m_entries;
- erase_if(filtered, [&](auto e) {
- auto locked_device = e.device();
- return !(e.interface() == interface && locked_device);
- });
- return filtered;
- }
-
- auto interface_registry::resolve(interface_id interface, std::string_view name) -> void *
- {
- // TODO: lock registry
-
- auto found = std::ranges::find_if(m_entries, [&](auto e) { return e.name() == name && e.device(); });
-
- if (found == m_entries.cend())
- {
- return nullptr;
- }
- else if (auto device = found->device())
- {
- return resolve(interface, *device);
- }
-
- return nullptr;
- }
-
- auto interface_registry::resolve(interface_id interface, device & device) -> void *
- {
- // TODO: lock registry
-
- if (auto by_device = device.as(interface))
- {
- return by_device;
- }
-
- auto found = std::ranges::find_if(m_entries, [&](auto e) {
- auto locked_device = e.device();
- return e.interface() == interface && locked_device && locked_device.get() == &device;
- });
-
- if (found == m_entries.cend())
- {
- return nullptr;
- }
-
- return found->implementation();
- }
-
- auto interface_registry::subscribe(kstd::weak_ptr<interface_registry_observer> observer) -> void
- {
- // TODO: lock registry
-
- erase_if(m_observers, [](auto const & observer) { return observer.expired(); });
- m_observers.push_back(observer);
- }
-
- auto interface_registry::subscribe(interface_registry_observer & observer) -> void
- {
- // TODO: lock registry
-
- m_static_observers.push_back(&observer);
- }
-
- auto interface_registry::unsubscribe(interface_registry_observer & observer) -> void
- {
- // TODO: lock registry
-
- erase_if(m_observers, [&](auto const & subscribed) { return subscribed.lock().get() == &observer; });
- erase(m_static_observers, &observer);
- }
-
-} // namespace kapi::devices
-
-namespace kapi::test_support::devices
-{
- auto deinit_interface_registry() -> void
- {
- kapi::devices::registry.reset();
- }
-} // namespace kapi::test_support::devices
diff --git a/kernel/kernel/bus/boot_modules.cpp b/kernel/kernel/bus/boot_modules.cpp
index 069d414f..be507eb5 100644
--- a/kernel/kernel/bus/boot_modules.cpp
+++ b/kernel/kernel/bus/boot_modules.cpp
@@ -29,6 +29,8 @@ namespace kernel::bus
struct boot_modules_protocol : kapi::devices::bus_protocol
{
+ constexpr auto static id = kapi::capabilities::facet_id{"boot_modules_bus"};
+
auto enumerate(kapi::devices::bus &) -> void override
{
// The boot modules virtual bus does not support enumeration.
@@ -37,8 +39,8 @@ namespace kernel::bus
[[nodiscard]] auto match(kapi::devices::device const & dev, kapi::devices::driver const & drv) const
-> kstd::result<unsigned> override
{
- auto signature = dev.as<kapi::boot_modules::boot_module_signature>();
- auto claim = drv.as<kapi::boot_modules::boot_module_claim>();
+ auto signature = dev.facet<kapi::boot_modules::boot_module_signature>();
+ auto claim = drv.facet<kapi::boot_modules::boot_module_claim>();
if (!signature || !claim)
{
@@ -62,9 +64,14 @@ namespace kernel::bus
: kapi::devices::bus{"boot_modules"}
{}
- auto boot_modules::protocol() -> kapi::devices::bus_protocol *
+ auto boot_modules::query_facet(kapi::capabilities::facet_id id) -> void *
{
- return &protocol_instance;
+ if (id == boot_modules_protocol::id || id == kapi::devices::bus_protocol::id)
+ {
+ return static_cast<kapi::devices::bus_protocol *>(&protocol_instance);
+ }
+
+ return kapi::devices::bus::query_facet(id);
}
} // namespace kernel::bus
diff --git a/kernel/kernel/bus/boot_modules.hpp b/kernel/kernel/bus/boot_modules.hpp
index c73e0d74..011e2b2e 100644
--- a/kernel/kernel/bus/boot_modules.hpp
+++ b/kernel/kernel/bus/boot_modules.hpp
@@ -15,7 +15,7 @@ namespace kernel::bus
{
boot_modules();
- [[nodiscard]] auto protocol() -> kapi::devices::bus_protocol * override;
+ [[nodiscard]] auto query_facet(kapi::capabilities::facet_id id) -> void * override;
};
} // namespace kernel::bus
diff --git a/kernel/kernel/devices/storage.cpp b/kernel/kernel/devices/storage.cpp
index 4f5776d2..d54e7056 100644
--- a/kernel/kernel/devices/storage.cpp
+++ b/kernel/kernel/devices/storage.cpp
@@ -18,7 +18,7 @@ namespace kernel::devices::storage
auto determine_boot_device() -> kstd::shared_ptr<kapi::devices::device>
{
- auto block_devices = kapi::devices::interface_registry::get().all(kapi::filesystem::block_special_file::id);
+ auto block_devices = kapi::devices::facet_registry::get().all(kapi::filesystem::block_special_file::id);
if (block_devices.empty())
{
return nullptr;
diff --git a/kernel/kernel/devices/storage.tests.cpp b/kernel/kernel/devices/storage.tests.cpp
index 3cf21b01..46dfb5ab 100644
--- a/kernel/kernel/devices/storage.tests.cpp
+++ b/kernel/kernel/devices/storage.tests.cpp
@@ -29,7 +29,7 @@ TEST_CASE("Storage devices attached with init() are reachable from the root bus"
bus->add_child(device);
- auto block_devices = kapi::devices::interface_registry::get().all(kapi::filesystem::block_special_file::id);
+ auto block_devices = kapi::devices::facet_registry::get().all(kapi::filesystem::block_special_file::id);
REQUIRE(block_devices.size() == 1);
CHECK(block_devices[0].name() == "ram0");
diff --git a/kernel/kernel/drivers/storage/ram_disk.cpp b/kernel/kernel/drivers/storage/ram_disk.cpp
index 97a6443b..987f4bbc 100644
--- a/kernel/kernel/drivers/storage/ram_disk.cpp
+++ b/kernel/kernel/drivers/storage/ram_disk.cpp
@@ -96,13 +96,13 @@ namespace kernel::drivers::storage
auto ram_disk::probe(kapi::devices::device & device) -> kstd::result<void>
{
- auto interface = device.as<kapi::boot_modules::boot_module_signature>();
- if (!interface)
+ auto facet = device.facet<kapi::boot_modules::boot_module_signature>();
+ if (!facet)
{
return kstd::failure(make_error_code(kstd::errc::invalid_argument));
}
- auto const & module = interface->module();
+ auto const & module = facet->module();
if (module.start_address.raw() == 0 || module.size == 0)
{
return kstd::failure(make_error_code(kstd::errc::invalid_argument));
@@ -111,15 +111,15 @@ namespace kernel::drivers::storage
auto implementation = kstd::make_shared<struct block_node>(module);
auto next_index =
- std::ranges::count_if(kapi::devices::interface_registry::get().all(kapi::filesystem::block_special_file::id),
+ std::ranges::count_if(kapi::devices::facet_registry::get().all(kapi::filesystem::block_special_file::id),
[this](auto const & published) {
auto published_device = published.device();
return published_device && published_device->bound_driver() == this;
});
auto name = kstd::format("ram{}", next_index);
- auto published = kapi::devices::publish_interface<kapi::filesystem::block_special_file>(device.shared_from_this(),
- name, implementation.get());
+ auto published = kapi::devices::publish_facet<kapi::filesystem::block_special_file>(device.shared_from_this(), name,
+ implementation.get());
if (!published)
{
return published;
@@ -132,7 +132,7 @@ namespace kernel::drivers::storage
auto ram_disk::unbind(kapi::devices::device & device) -> void
{
- kapi::devices::interface_registry::get().withdraw(device, kapi::filesystem::block_special_file::id);
+ kapi::devices::facet_registry::get().withdraw(device, kapi::filesystem::block_special_file::id);
device.set_driver_data(nullptr);
}
@@ -151,14 +151,14 @@ namespace kernel::drivers::storage
return "Generic RAM Disk";
}
- auto ram_disk::query_interface(kapi::devices::interface_id interface) -> void *
+ auto ram_disk::query_facet(kapi::capabilities::facet_id facet) -> void *
{
- if (interface == kapi::boot_modules::boot_module_claim::id)
+ if (facet == kapi::boot_modules::boot_module_claim::id)
{
return static_cast<kapi::boot_modules::boot_module_claim *>(this);
}
- return kapi::devices::driver::query_interface(interface);
+ return kapi::devices::driver::query_facet(facet);
}
} // namespace kernel::drivers::storage \ No newline at end of file
diff --git a/kernel/kernel/drivers/storage/ram_disk.hpp b/kernel/kernel/drivers/storage/ram_disk.hpp
index 2805466f..d5d54551 100644
--- a/kernel/kernel/drivers/storage/ram_disk.hpp
+++ b/kernel/kernel/drivers/storage/ram_disk.hpp
@@ -27,7 +27,7 @@ namespace kernel::drivers::storage
[[nodiscard]] auto name() const noexcept -> std::string_view override;
protected:
- auto query_interface(kapi::devices::interface_id interface) -> void * override;
+ auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
};
} // namespace kernel::drivers::storage
diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp
index ce0ad3fe..4dcff4a1 100644
--- a/kernel/kernel/filesystem/device_inode.cpp
+++ b/kernel/kernel/filesystem/device_inode.cpp
@@ -42,7 +42,7 @@ namespace kernel::filesystem
-> kstd::result<kstd::units::bytes>
{
if (auto block_device =
- kapi::devices::interface_registry::get().resolve<kapi::filesystem::block_special_file>(*m_device))
+ kapi::devices::facet_registry::get().resolve<kapi::filesystem::block_special_file>(*m_device))
{
return devices::block_device_utils::read(*block_device, buffer, offset, size);
}
@@ -54,7 +54,7 @@ namespace kernel::filesystem
-> kstd::result<kstd::units::bytes>
{
if (auto block_device =
- kapi::devices::interface_registry::get().resolve<kapi::filesystem::block_special_file>(*m_device))
+ kapi::devices::facet_registry::get().resolve<kapi::filesystem::block_special_file>(*m_device))
{
return devices::block_device_utils::write(*block_device, buffer, offset, size);
}
diff --git a/kernel/kernel/filesystem/device_inode.tests.cpp b/kernel/kernel/filesystem/device_inode.tests.cpp
index 5f409a79..59800531 100644
--- a/kernel/kernel/filesystem/device_inode.tests.cpp
+++ b/kernel/kernel/filesystem/device_inode.tests.cpp
@@ -172,7 +172,7 @@ SCENARIO("Device inode raw_device()", "[filesystem][device-inode]")
CHECK(kernel::tests::devices::bind(*device, std::uint8_t{1}));
- REQUIRE(kapi::devices::interface_registry::get().publish<kapi::filesystem::block_special_file>(device, "ram0"));
+ REQUIRE(kapi::devices::facet_registry::get().publish<kapi::filesystem::block_special_file>(device, "ram0"));
auto inode = kernel::filesystem::device_inode{device};
diff --git a/kernel/kernel/filesystem/device_number_registry.cpp b/kernel/kernel/filesystem/device_number_registry.cpp
index aca0c64c..d51a343a 100644
--- a/kernel/kernel/filesystem/device_number_registry.cpp
+++ b/kernel/kernel/filesystem/device_number_registry.cpp
@@ -29,28 +29,28 @@ namespace kernel::filesystem
{
if (!instance)
{
- instance.emplace(kapi::devices::interface_registry::get());
+ instance.emplace(kapi::devices::facet_registry::get());
}
return *instance;
}
- device_number_registry::device_number_registry(kapi::devices::interface_registry & interface_registry)
- : m_interface_registry{&interface_registry}
+ device_number_registry::device_number_registry(kapi::devices::facet_registry & facet_registry)
+ : m_facet_registry{&facet_registry}
{
for (auto const & binding : file_type_bindings)
{
- for (auto const & published : interface_registry.all(binding.interface))
+ for (auto const & published : facet_registry.all(binding.facet))
{
- try_number(binding.interface, published);
+ try_number(binding.facet, published);
}
}
- m_interface_registry->subscribe(*this);
+ m_facet_registry->subscribe(*this);
}
device_number_registry::~device_number_registry()
{
- m_interface_registry->unsubscribe(*this);
+ m_facet_registry->unsubscribe(*this);
}
auto device_number_registry::resolve(kapi::filesystem::device_number number, file_type type) const
@@ -114,19 +114,18 @@ namespace kernel::filesystem
m_observers.push_back(std::move(observer));
}
- auto device_number_registry::on_interface_published(kapi::devices::interface_id interface,
- kapi::devices::interface_registry::entry const & published)
- -> void
+ auto device_number_registry::on_facet_published(kapi::capabilities::facet_id facet,
+ kapi::devices::facet_registry::entry const & published) -> void
{
- try_number(interface, published);
+ try_number(facet, published);
}
- auto device_number_registry::on_interface_withdrawn(kapi::devices::interface_id interface,
- kapi::devices::device & device) -> void
+ auto device_number_registry::on_facet_withdrawn(kapi::capabilities::facet_id facet, kapi::devices::device & device)
+ -> void
{
- // Check if there even is a binding defined for the given interface.
+ // Check if there even is a binding defined for the given facet.
auto binding =
- std::ranges::find_if(file_type_bindings, [&](auto const & binding) { return binding.interface == interface; });
+ std::ranges::find_if(file_type_bindings, [&](auto const & binding) { return binding.facet == facet; });
if (binding == std::ranges::cend(file_type_bindings))
{
return;
@@ -158,12 +157,12 @@ namespace kernel::filesystem
});
}
- auto device_number_registry::try_number(kapi::devices::interface_id interface,
- kapi::devices::interface_registry::entry const & published) -> void
+ auto device_number_registry::try_number(kapi::capabilities::facet_id facet,
+ kapi::devices::facet_registry::entry const & published) -> void
{
- // Check if there even is a binding defined for the given interface.
+ // Check if there even is a binding defined for the given facet.
auto binding =
- std::ranges::find_if(file_type_bindings, [&](auto const & binding) { return binding.interface == interface; });
+ std::ranges::find_if(file_type_bindings, [&](auto const & binding) { return binding.facet == facet; });
if (binding == std::ranges::cend(file_type_bindings))
{
return;
diff --git a/kernel/kernel/filesystem/device_number_registry.hpp b/kernel/kernel/filesystem/device_number_registry.hpp
index 20a26c22..8ace3727 100644
--- a/kernel/kernel/filesystem/device_number_registry.hpp
+++ b/kernel/kernel/filesystem/device_number_registry.hpp
@@ -20,7 +20,7 @@ namespace kernel::filesystem
struct device_number_registry_observer;
//! A registry to assign stable device numbers to published devices.
- struct device_number_registry final : kapi::devices::interface_registry_observer
+ struct device_number_registry final : kapi::devices::facet_registry_observer
{
//! A single numbered device.
//!
@@ -33,10 +33,10 @@ namespace kernel::filesystem
kstd::weak_ptr<kapi::devices::device> device;
};
- //! Construct a new device number registry, subscribing to the given interface registry.
+ //! Construct a new device number registry, subscribing to the given facet registry.
//!
- //! @param interface_registry The interface registry to back this device number registry.
- explicit device_number_registry(kapi::devices::interface_registry & interface_registry);
+ //! @param facet_registry The facet registry to back this device number registry.
+ explicit device_number_registry(kapi::devices::facet_registry & facet_registry);
//! Destroy this registry.
~device_number_registry() override;
@@ -78,21 +78,20 @@ namespace kernel::filesystem
auto subscribe(kstd::weak_ptr<device_number_registry_observer> observer) -> void;
private:
- auto on_interface_published(kapi::devices::interface_id interface,
- kapi::devices::interface_registry::entry const & entry) -> void override;
+ auto on_facet_published(kapi::capabilities::facet_id facet, kapi::devices::facet_registry::entry const & entry)
+ -> void override;
- auto on_interface_withdrawn(kapi::devices::interface_id interface, kapi::devices::device & device) -> void override;
+ auto on_facet_withdrawn(kapi::capabilities::facet_id facet, kapi::devices::device & device) -> void override;
- auto try_number(kapi::devices::interface_id interface, kapi::devices::interface_registry::entry const & published)
- -> void;
+ auto try_number(kapi::capabilities::facet_id facet, kapi::devices::facet_registry::entry const & published) -> void;
- kstd::observer_ptr<kapi::devices::interface_registry> m_interface_registry;
+ kstd::observer_ptr<kapi::devices::facet_registry> m_facet_registry;
mutable kstd::vector<entry> m_entries{};
kstd::flat_map<kapi::devices::driver const *, std::uint8_t> m_next_minor;
kstd::vector<kstd::weak_ptr<device_number_registry_observer>> m_observers{};
};
- //! The interface for types interested in observing numbering transactions on a device number registry.
+ //! The facet for types interested in observing numbering transactions on a device number registry.
struct device_number_registry_observer
{
//! Enable correct destruction through base pointers.
diff --git a/kernel/kernel/filesystem/device_number_registry.tests.cpp b/kernel/kernel/filesystem/device_number_registry.tests.cpp
index 3791a16e..865a6de9 100644
--- a/kernel/kernel/filesystem/device_number_registry.tests.cpp
+++ b/kernel/kernel/filesystem/device_number_registry.tests.cpp
@@ -22,13 +22,13 @@ using namespace kstd::units_literals;
namespace
{
- auto make_bound_block_device(kapi::devices::interface_registry & interfaces, kstd::string const & name,
+ auto make_bound_block_device(kapi::devices::facet_registry & facets, kstd::string const & name,
kstd::units::bytes block_size, std::optional<std::uint8_t> major)
-> kstd::shared_ptr<kernel::tests::devices::block_device>
{
auto device = kstd::make_shared<kernel::tests::devices::block_device>(name, block_size);
[[maybe_unused]] auto driver = kernel::tests::devices::bind(*device, major);
- if (!interfaces.publish<kapi::filesystem::block_special_file>(device, name))
+ if (!facets.publish<kapi::filesystem::block_special_file>(device, name))
{
throw std::runtime_error{"failed to publish block device!"};
}
@@ -39,8 +39,8 @@ namespace
SCENARIO("Device number registry resolves and numbers published block devices",
"[kernel][filesystem][device_number_registry]")
{
- auto interfaces = kapi::devices::interface_registry{};
- auto registry = kernel::filesystem::device_number_registry{interfaces};
+ auto facets = kapi::devices::facet_registry{};
+ auto registry = kernel::filesystem::device_number_registry{facets};
GIVEN("No devices have been published")
{
@@ -52,7 +52,7 @@ SCENARIO("Device number registry resolves and numbers published block devices",
GIVEN("A single block device has been published, bound to a driver claiming major 1")
{
- auto device = make_bound_block_device(interfaces, "ram0", 512_B, std::uint8_t{1});
+ auto device = make_bound_block_device(facets, "ram0", 512_B, std::uint8_t{1});
THEN("all() returns a vector with one element")
{
@@ -96,7 +96,7 @@ SCENARIO("Device number registry resolves and numbers published block devices",
GIVEN("A device was published")
{
- auto device = make_bound_block_device(interfaces, "ram0", 512_B, std::uint8_t{1});
+ auto device = make_bound_block_device(facets, "ram0", 512_B, std::uint8_t{1});
auto number = registry.number_of(*device);
WHEN("destroying it with no further owner")
@@ -112,8 +112,8 @@ SCENARIO("Device number registry resolves and numbers published block devices",
GIVEN("Two block-capable drivers claiming different majors")
{
- [[maybe_unused]] auto device_a = make_bound_block_device(interfaces, "ramA0", 512_B, std::uint8_t{1});
- [[maybe_unused]] auto device_b = make_bound_block_device(interfaces, "ramB0", 512_B, std::uint8_t{2});
+ [[maybe_unused]] auto device_a = make_bound_block_device(facets, "ramA0", 512_B, std::uint8_t{1});
+ [[maybe_unused]] auto device_b = make_bound_block_device(facets, "ramB0", 512_B, std::uint8_t{2});
THEN("their minors are numbered independently, starting at 0 for each driver")
{
@@ -134,7 +134,7 @@ SCENARIO("Device number registry resolves and numbers published block devices",
GIVEN("A driver that never overrides claimed_major()")
{
- make_bound_block_device(interfaces, "unnumbered0", 512_B, std::nullopt);
+ make_bound_block_device(facets, "unnumbered0", 512_B, std::nullopt);
THEN("it is never numbered, regardless of what it publishes")
{
@@ -145,7 +145,7 @@ SCENARIO("Device number registry resolves and numbers published block devices",
GIVEN("A published device with no bound driver at all")
{
auto device = kstd::make_shared<kernel::tests::devices::block_device>("unbound0", 512_B);
- CHECK(interfaces.publish<kapi::filesystem::block_special_file>(device, "unbound0"));
+ CHECK(facets.publish<kapi::filesystem::block_special_file>(device, "unbound0"));
THEN("it is never numbered")
{
diff --git a/kernel/kernel/filesystem/file_type_bindings.hpp b/kernel/kernel/filesystem/file_type_bindings.hpp
index d771f49c..ea52972b 100644
--- a/kernel/kernel/filesystem/file_type_bindings.hpp
+++ b/kernel/kernel/filesystem/file_type_bindings.hpp
@@ -11,16 +11,16 @@
namespace kernel::filesystem
{
- //! A binding between an interface, a posix special file type
+ //! A binding between a facet, a posix special file type
struct file_type_binding // NOLINT(cppcoreguidelines-pro-type-member-init)
{
- kapi::filesystem::interface_id interface;
+ kapi::capabilities::facet_id facet;
file_type posix_type;
};
- //! Predefined bindings for interface + file type
+ //! Predefined bindings for facet + file type
//!
- //! This array associates published interfaces with files types.
+ //! This array associates published facets with files types.
constexpr auto inline file_type_bindings = std::array{
file_type_binding{kapi::filesystem::block_special_file::id, file_type::block},
};
diff --git a/kernel/kernel/test_support/devices/block_device.cpp b/kernel/kernel/test_support/devices/block_device.cpp
index 2cde621c..a92b095b 100644
--- a/kernel/kernel/test_support/devices/block_device.cpp
+++ b/kernel/kernel/test_support/devices/block_device.cpp
@@ -68,13 +68,13 @@ namespace kernel::tests::devices
return kstd::units::bytes{data.size()};
}
- auto block_device::query_interface(kapi::devices::interface_id interface) -> void *
+ auto block_device::query_facet(kapi::capabilities::facet_id facet) -> void *
{
- if (interface == kapi::filesystem::block_special_file::id)
+ if (facet == kapi::filesystem::block_special_file::id)
{
return static_cast<kapi::filesystem::block_special_file *>(this);
}
- return kapi::devices::device::query_interface(interface);
+ return kapi::devices::device::query_facet(facet);
}
} // namespace kernel::tests::devices \ No newline at end of file
diff --git a/kernel/kernel/test_support/devices/block_device.hpp b/kernel/kernel/test_support/devices/block_device.hpp
index 9546b0cc..94201da1 100644
--- a/kernel/kernel/test_support/devices/block_device.hpp
+++ b/kernel/kernel/test_support/devices/block_device.hpp
@@ -28,7 +28,7 @@ namespace kernel::tests::devices
kstd::vector<uint8_t> data{};
private:
- [[nodiscard]] auto query_interface(kapi::devices::interface_id interface) -> void * override;
+ [[nodiscard]] auto query_facet(kapi::capabilities::facet_id facet) -> void * override;
kstd::units::bytes m_block_size{};
};
diff --git a/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp b/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp
index 3464c6e8..d5068565 100644
--- a/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp
+++ b/kernel/kernel/test_support/filesystem/storage_boot_module_fixture.cpp
@@ -104,8 +104,7 @@ namespace kernel::tests::filesystem
m_boot_module_bus->add_child(kstd::make_shared<kapi::boot_modules::device>(i, module));
}
- if (module_count > 0 &&
- kapi::devices::interface_registry::get().all(kapi::filesystem::block_special_file::id).empty())
+ if (module_count > 0 && kapi::devices::facet_registry::get().all(kapi::filesystem::block_special_file::id).empty())
{
throw std::runtime_error{"No RAM disk driver bound to any of the test fixture's boot modules."};
}
@@ -128,7 +127,7 @@ namespace kernel::tests::filesystem
}
if (!module_names.empty() &&
- kapi::devices::interface_registry::get().all(kapi::filesystem::block_special_file::id).empty())
+ kapi::devices::facet_registry::get().all(kapi::filesystem::block_special_file::id).empty())
{
throw std::runtime_error{"No RAM disk driver bound to any of the test fixture's boot modules."};
}