diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-07-23 18:52:24 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-07-23 18:52:24 +0200 |
| commit | cb87b4dd8e874d5d7b219487ca38f55756c205df (patch) | |
| tree | 708c018ecf05db1565433b17c69cc40dc4e96680 /kapi | |
| parent | 969c2018d2d3741022818e3bc326b57162748053 (diff) | |
| download | kernel-cb87b4dd8e874d5d7b219487ca38f55756c205df.tar.xz kernel-cb87b4dd8e874d5d7b219487ca38f55756c205df.zip | |
kapi: introduce driver and bus protocol
Diffstat (limited to 'kapi')
| -rw-r--r-- | kapi/kapi/devices.hpp | 3 | ||||
| -rw-r--r-- | kapi/kapi/devices/bus_protocol.hpp | 43 | ||||
| -rw-r--r-- | kapi/kapi/devices/driver.hpp | 80 | ||||
| -rw-r--r-- | kapi/kapi/devices/error.hpp | 36 |
4 files changed, 162 insertions, 0 deletions
diff --git a/kapi/kapi/devices.hpp b/kapi/kapi/devices.hpp index 5c3d1b63..d66afc96 100644 --- a/kapi/kapi/devices.hpp +++ b/kapi/kapi/devices.hpp @@ -3,9 +3,12 @@ #include <kapi/devices/block_device.hpp> // IWYU pragma: export #include <kapi/devices/bus.hpp> // IWYU pragma: export +#include <kapi/devices/bus_protocol.hpp> // IWYU pragma: export #include <kapi/devices/character_device.hpp> // IWYU pragma: export #include <kapi/devices/cpu.hpp> // IWYU pragma: export #include <kapi/devices/device.hpp> // IWYU pragma: export +#include <kapi/devices/driver.hpp> // IWYU pragma: export +#include <kapi/devices/error.hpp> // IWYU pragma: export #include <kapi/devices/interface.hpp> // IWYU pragma: export #include <kapi/devices/interface_registry.hpp> // IWYU pragma: export #include <kapi/devices/manager.hpp> // IWYU pragma: export diff --git a/kapi/kapi/devices/bus_protocol.hpp b/kapi/kapi/devices/bus_protocol.hpp new file mode 100644 index 00000000..2e4e6993 --- /dev/null +++ b/kapi/kapi/devices/bus_protocol.hpp @@ -0,0 +1,43 @@ +#ifndef TEACHOS_KAPI_DEVICES_BUS_PROTOCOL_HPP +#define TEACHOS_KAPI_DEVICES_BUS_PROTOCOL_HPP + +// IWYU pragma: private, include <kapi/devices.hpp> + +#include <kapi/devices/bus.hpp> +#include <kapi/devices/device.hpp> +#include <kapi/devices/driver.hpp> + +#include <kstd/result.hpp> + +#include <cstdint> + +namespace kapi::devices +{ + + //! Bus specific behavior. + //! + //! A bus protocol defines how a bus discovers its attached children, and how drivers are matched against devices. It + //! it a pure behavioral mixin. + struct bus_protocol + { + //! Allow safe destruction through base pointers. + virtual ~bus_protocol() = default; + + //! Discover the child devices, and busses, attached to the bus using this protocol. + //! + //! @param bus The bus to enumerate. + virtual auto enumerate(bus & bus) -> void = 0; + + //! Determine whether a given drivers is a candidate to bind a given device. + //! + //! @param device The device to test. + //! @param driver The driver to match against the device. + //! @return The match priority (higher == better match), of the device<->driver pairing, and error if the driver + //! doesn't match the device at all. + [[nodiscard]] virtual auto match(device const & device, driver const & driver) const + -> kstd::result<std::uint32_t> = 0; + }; + +} // namespace kapi::devices + +#endif
\ No newline at end of file diff --git a/kapi/kapi/devices/driver.hpp b/kapi/kapi/devices/driver.hpp new file mode 100644 index 00000000..fde5068c --- /dev/null +++ b/kapi/kapi/devices/driver.hpp @@ -0,0 +1,80 @@ +#ifndef TEACHOS_KAPI_DEVICES_DRIVER_HPP +#define TEACHOS_KAPI_DEVICES_DRIVER_HPP + +// IWYU pragma: private, include <kapi/devices.hpp> + +#include <kapi/devices/device.hpp> +#include <kapi/devices/interface.hpp> + +#include <kstd/result.hpp> + +#include <cstdint> +#include <optional> + +namespace kapi::devices +{ + + //! @addtogroup kapi-devices-kernel-defined + //! @{ + + //! The base type for all device drivers. + //! + //! Drivers model the behavior necessary to drive a device or bus. They are stateless logic and are thus never + //! attached to a bus or the device tree. + struct driver + { + //! Enable safe destruction through base pointers. + virtual ~driver() = default; + + //! Try to claim and initialize a device. + //! + //! This function must be called after a bus protocol has matched a device and selected this driver as the best + //! available one. + //! + //! @param device The device to probe. + //! @return Nothing on success, an error otherwise. If an error is returned, the device remains unbound. + [[nodiscard]] virtual auto probe(device & device) -> kstd::result<void> = 0; + + //! Release a device from this driver. + //! + //! This function must undo any initialization performed by a previous probe. It is intended to be called when a + //! device is removed from the device tree. Alternatively, unbinding may be requested by user-space, essentially + //! allowing a different driver to claim this device. + //! + //! @param device The device to release. + virtual auto unbind(device & device) -> void = 0; + + //! Retrieve this drivers implementation of a given capability interface. + //! + //! @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 static_cast<InterfaceType *>(query_interface(InterfaceType::id)); + } + + //! Check if this driver implements a given capability interface. + //! + //! @return true iff. this driver implements the requested capability interface, false otherwise. + template<typename InterfaceType> + [[nodiscard]] auto is_a() const noexcept -> bool + { + return query_interface(InterfaceType::id) != nullptr; + } + + //! Get the major number associated with this driver, if any. + //! + //! Drivers that want to claim an auto-populated device node in devfs must override this function. + [[nodiscard]] virtual auto claimed_major() const -> std::optional<std::uint8_t>; + + protected: + //! Return a pointer to the implementation of the given interface if this driver supports it. + virtual auto query_interface(interface interface) -> void *; + }; + + //! @} + +} // namespace kapi::devices + +#endif
\ No newline at end of file diff --git a/kapi/kapi/devices/error.hpp b/kapi/kapi/devices/error.hpp new file mode 100644 index 00000000..b4812550 --- /dev/null +++ b/kapi/kapi/devices/error.hpp @@ -0,0 +1,36 @@ +#ifndef TEACHOS_KAPI_DEVICES_ERROR_HPP +#define TEACHOS_KAPI_DEVICES_ERROR_HPP + +// IWYU pragma: private, include <kapi/devices.hpp> + +#include <kstd/system_error.hpp> + +#include <type_traits> + +namespace kapi::devices +{ + + enum struct driver_match_errc + { + //! The driver did not match on the given device. + no_match = 1, + }; + + [[nodiscard]] auto driver_match_category() noexcept -> kstd::error_category const &; + + [[nodiscard]] constexpr auto inline make_error_code(driver_match_errc error) noexcept -> kstd::error_code + { + return kstd::error_code{static_cast<int>(error), driver_match_category()}; + } + +} // namespace kapi::devices + +namespace kstd +{ + template<> + struct is_error_code_enum<kapi::devices::driver_match_errc> : std::true_type + { + }; +} // namespace kstd + +#endif
\ No newline at end of file |
