SimpleKernel 1.17.0
Loading...
Searching...
No Matches
device_initializer.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <utility>
8
9#include "expected.hpp"
10#include "kernel_log.hpp"
12
13namespace virtio {
14
45template <TransportConcept TransportImpl>
47 public:
65 [[nodiscard]] auto Init(uint64_t driver_features) -> Expected<uint64_t> {
66 if (!transport_.IsValid()) {
67 return std::unexpected(Error{ErrorCode::kTransportNotInitialized});
68 }
69
70 transport_.Reset();
71
72 transport_.SetStatus(
73 std::to_underlying(Transport::DeviceStatus::kAcknowledge));
74
75 transport_.SetStatus(
76 std::to_underlying(Transport::DeviceStatus::kAcknowledge) |
77 std::to_underlying(Transport::DeviceStatus::kDriver));
78
79 uint64_t device_features = transport_.GetDeviceFeatures();
80 uint64_t negotiated_features = device_features & driver_features;
81
82 transport_.SetDriverFeatures(negotiated_features);
83
84 transport_.SetStatus(
85 std::to_underlying(Transport::DeviceStatus::kAcknowledge) |
86 std::to_underlying(Transport::DeviceStatus::kDriver) |
87 std::to_underlying(Transport::DeviceStatus::kFeaturesOk));
88
89 uint32_t status = transport_.GetStatus();
90 if ((status & std::to_underlying(Transport::DeviceStatus::kFeaturesOk)) ==
91 0) {
92 transport_.SetStatus(
93 status | std::to_underlying(Transport::DeviceStatus::kFailed));
94 return std::unexpected(Error{ErrorCode::kFeatureNegotiationFailed});
95 }
96
97 return negotiated_features;
98 }
99
116 [[nodiscard]] auto SetupQueue(uint32_t queue_idx, uint64_t desc_phys,
117 uint64_t avail_phys, uint64_t used_phys,
118 uint32_t queue_size) -> Expected<void> {
119 if (!transport_.IsValid()) {
120 return std::unexpected(Error{ErrorCode::kTransportNotInitialized});
121 }
122
123 uint32_t max_size = transport_.GetQueueNumMax(queue_idx);
124 if (max_size == 0) {
125 return std::unexpected(Error{ErrorCode::kQueueNotAvailable});
126 }
127 if (queue_size > max_size) {
128 return std::unexpected(Error{ErrorCode::kQueueTooLarge});
129 }
130
131 transport_.SetQueueNum(queue_idx, queue_size);
132 transport_.SetQueueDesc(queue_idx, desc_phys);
133 transport_.SetQueueAvail(queue_idx, avail_phys);
134 transport_.SetQueueUsed(queue_idx, used_phys);
135 transport_.SetQueueReady(queue_idx, true);
136
137 return {};
138 }
139
153 [[nodiscard]] auto Activate() -> Expected<void> {
154 if (!transport_.IsValid()) {
155 return std::unexpected(Error{ErrorCode::kTransportNotInitialized});
156 }
157
158 uint32_t current_status = transport_.GetStatus();
159 transport_.SetStatus(
160 current_status |
161 std::to_underlying(Transport::DeviceStatus::kDriverOk));
162
163 uint32_t new_status = transport_.GetStatus();
164 if ((new_status &
165 std::to_underlying(Transport::DeviceStatus::kDeviceNeedsReset)) != 0) {
166 return std::unexpected(Error{ErrorCode::kDeviceError});
167 }
168
169 return {};
170 }
171
179 [[nodiscard]] auto transport() -> TransportImpl& { return transport_; }
180
181 [[nodiscard]] auto transport() const -> const TransportImpl& {
182 return transport_;
183 }
184
187
193 explicit DeviceInitializer(TransportImpl& transport)
202
203 private:
205 TransportImpl& transport_;
206};
207
208} // namespace virtio
Virtio 设备初始化器
auto operator=(DeviceInitializer &&) -> DeviceInitializer &=delete
DeviceInitializer(TransportImpl &transport)
构造函数
auto Activate() -> Expected< void >
激活设备,开始正常运行
auto SetupQueue(uint32_t queue_idx, uint64_t desc_phys, uint64_t avail_phys, uint64_t used_phys, uint32_t queue_size) -> Expected< void >
配置并激活指定的 virtqueue
auto transport() const -> const TransportImpl &
auto transport() -> TransportImpl &
获取底层传输层引用
DeviceInitializer(const DeviceInitializer &)=delete
auto Init(uint64_t driver_features) -> Expected< uint64_t >
执行 virtio 设备初始化序列
TransportImpl & transport_
底层传输层引用
auto operator=(const DeviceInitializer &) -> DeviceInitializer &=delete
DeviceInitializer(DeviceInitializer &&)=delete
@ kDriver
表示客户操作系统知道如何驱动该设备
@ kDriverOk
表示驱动程序已准备好驱动设备(特性协商完成)
@ kDeviceNeedsReset
表示设备需要重置
@ kFeaturesOk
表示驱动程序已确认设备提供的所有功能
@ kAcknowledge
表示客户操作系统已找到设备并识别为有效的 virtio 设备
@ kFailed
表示在客户机中出现问题,已放弃该设备
@ kTransportNotInitialized
传输层未正确初始化
@ kQueueTooLarge
请求的队列大小超过设备支持的最大值
@ kFeatureNegotiationFailed
特性协商失败
@ kDeviceError
通用设备报告错误
@ kQueueNotAvailable
队列不可用(queue_num_max == 0)
std::expected< T, Error > Expected
std::expected 别名模板
Definition expected.hpp:365
Definition defs.h:9
错误类型,用于 std::expected
Definition expected.hpp:343