SimpleKernel 1.17.0
Loading...
Searching...
No Matches
driver_registry.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <etl/delegate.h>
8#include <etl/flat_map.h>
9#include <etl/span.h>
10#include <etl/vector.h>
11
12#include <cassert>
13#include <cstddef>
14#include <cstdint>
15
16#include "device_node.hpp"
17#include "expected.hpp"
18#include "kernel.h"
19#include "kernel_log.hpp"
20#include "kstd_cstring"
21#include "spinlock.hpp"
22#include "virtual_memory.hpp"
23
25struct MatchEntry {
29 const char* compatible{nullptr};
30};
31
38 const char* name{nullptr};
39 etl::span<const MatchEntry> match_table{};
41 etl::delegate<bool(DeviceNode&)> match{};
43 etl::delegate<Expected<void>(DeviceNode&)> probe{};
45 etl::delegate<Expected<void>(DeviceNode&)> remove{};
46};
47
49struct CStrLess {
50 auto operator()(const char* a, const char* b) const -> bool {
51 return kstd::strcmp(a, b) < 0;
52 }
53};
54
63 public:
70 [[nodiscard]] auto Register(const DriverEntry& entry) -> Expected<void> {
71 LockGuard guard(lock_);
72 if (drivers_.full()) {
73 return std::unexpected(Error(ErrorCode::kOutOfMemory));
74 }
75 const size_t idx = drivers_.size();
76 for (const auto& me : entry.match_table) {
77 if (compat_map_.full()) {
78 return std::unexpected(Error(ErrorCode::kOutOfMemory));
79 }
80 // 重复键时 insert() 为空操作 — 先注册的驱动优先。
81 compat_map_.insert({me.compatible, idx});
82 }
83 drivers_.push_back(entry);
84 return {};
85 }
86
93 [[nodiscard]] auto FindDriver(const DeviceNode& node) -> const DriverEntry* {
94 // 遍历节点的 compatible 字符串列表,对每个字符串执行 flat_map 查找。
95 const char* p = node.compatible;
96 const char* end = node.compatible + node.compatible_len;
97 while (p < end) {
98 const auto it = compat_map_.find(p);
99 if (it != compat_map_.end()) {
100 auto& entry = drivers_[it->second];
101 if (entry.match(const_cast<DeviceNode&>(node))) {
102 return &entry;
103 }
104 }
105 p += kstd::strlen(p) + 1;
106 }
107 return nullptr;
108 }
109
112 DriverRegistry() = default;
113 ~DriverRegistry() = default;
116 auto operator=(const DriverRegistry&) -> DriverRegistry& = delete;
119
120 private:
121 static constexpr size_t kMaxDrivers = 32;
123 static constexpr size_t kMaxCompatEntries = 96;
124
125 etl::vector<DriverEntry, kMaxDrivers> drivers_;
126 etl::flat_map<const char*, size_t, kMaxCompatEntries, CStrLess> compat_map_;
127 SpinLock lock_{"driver_registry"};
128};
129
130namespace mmio_helper {
131
134 uint64_t base{0};
135 size_t size{0};
136};
137
148[[nodiscard]] inline auto Prepare(const DeviceNode& node, size_t default_size)
150 assert(
151 node.mmio_base != 0 &&
152 "mmio_helper::Prepare: node has no MMIO base; driver matched wrong node");
153
154 size_t size = node.mmio_size > 0 ? node.mmio_size : default_size;
155 auto map_result =
156 VirtualMemorySingleton::instance().MapMMIO(node.mmio_base, size);
157 if (!map_result.has_value()) {
158 return std::unexpected(map_result.error());
159 }
160
161 return ProbeContext{node.mmio_base, size};
162}
163
164} // namespace mmio_helper
void * end[]
内核结束
驱动注册表 — 以 ETL vector 存储 DriverEntry,并附带 flat_map 兼容索引。
DriverRegistry()=default
DriverRegistry(const DriverRegistry &)=delete
DriverRegistry(DriverRegistry &&)=delete
auto FindDriver(const DeviceNode &node) -> const DriverEntry *
查找 match_table 中含有 node.compatible 字符串的第一个驱动 (flat_map 查找,O(Cn · log T))。
auto Register(const DriverEntry &entry) -> Expected< void >
注册一个驱动条目。
static constexpr size_t kMaxDrivers
etl::flat_map< const char *, size_t, kMaxCompatEntries, CStrLess > compat_map_
~DriverRegistry()=default
auto operator=(DriverRegistry &&) -> DriverRegistry &=delete
static constexpr size_t kMaxCompatEntries
所有驱动 MatchEntry 行数上限(32 个驱动 × 约 3 条 compatible 字符串)
auto operator=(const DriverRegistry &) -> DriverRegistry &=delete
etl::vector< DriverEntry, kMaxDrivers > drivers_
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
自旋锁
Definition spinlock.hpp:27
BusType
总线类型标识 — 为将来扩展 PCI/ACPI 总线预留的扩展点
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
auto Prepare(const DeviceNode &node, size_t default_size) -> Expected< ProbeContext >
从节点提取 MMIO base/size 并通过 VirtualMemory 映射该区域。
flat_map 中 const char* 键的比较器(使用 kstd::strcmp)。
auto operator()(const char *a, const char *b) const -> bool
单个设备的硬件资源描述。
类型擦除的驱动条目 — 每个已注册驱动对应一条。
etl::delegate< Expected< void >(DeviceNode &)> probe
驱动初始化
etl::delegate< bool(DeviceNode &)> match
硬件检测
etl::span< const MatchEntry > match_table
const char * name
etl::delegate< Expected< void >(DeviceNode &)> remove
驱动卸载
错误类型,用于 std::expected
Definition expected.hpp:343
驱动静态匹配表中的一条记录
const char * compatible
映射完成后的 MMIO 区域信息