SimpleKernel 1.17.0
Loading...
Searching...
No Matches
virtio::MmioTransport Class Referencefinal

Virtio MMIO 传输层 More...

#include <mmio.hpp>

Inheritance diagram for virtio::MmioTransport:
Inheritance graph
Collaboration diagram for virtio::MmioTransport:
Collaboration graph

Public Types

enum class  MmioReg : size_t {
  kMagicValue = 0x000 , kVersion = 0x004 , kDeviceId = 0x008 , kVendorId = 0x00C ,
  kDeviceFeatures = 0x010 , kDeviceFeaturesSel = 0x014 , kDriverFeatures = 0x020 , kDriverFeaturesSel = 0x024 ,
  kQueueSel = 0x030 , kQueueNumMax = 0x034 , kQueueNum = 0x038 , kQueueReady = 0x044 ,
  kQueueNotify = 0x050 , kInterruptStatus = 0x060 , kInterruptAck = 0x064 , kStatus = 0x070 ,
  kQueueDescLow = 0x080 , kQueueDescHigh = 0x084 , kQueueDriverLow = 0x090 , kQueueDriverHigh = 0x094 ,
  kQueueDeviceLow = 0x0A0 , kQueueDeviceHigh = 0x0A4 , kShmSel = 0x0AC , kShmLenLow = 0x0B0 ,
  kShmLenHigh = 0x0B4 , kShmBaseLow = 0x0B8 , kShmBaseHigh = 0x0BC , kQueueReset = 0x0C0 ,
  kConfigGeneration = 0x0FC , kConfig = 0x100
}
 MMIO 寄存器偏移量 More...
 
- Public Types inherited from virtio::Transport
enum class  DeviceStatus : uint32_t {
  kReset = 0 , kAcknowledge = 1 , kDriver = 2 , kDriverOk = 4 ,
  kFeaturesOk = 8 , kDeviceNeedsReset = 64 , kFailed = 128
}
 设备状态位定义 More...
 

Public Member Functions

 MmioTransport (uint64_t base)
 构造函数
 
auto IsValid () const -> bool
 检查设备是否成功初始化
 
auto GetDeviceId () const -> uint32_t
 
auto GetVendorId () const -> uint32_t
 
auto GetStatus () const -> uint32_t
 
auto SetStatus (uint32_t status) -> void
 
auto GetDeviceFeatures () -> uint64_t
 读取 64 位设备特性
 
auto SetDriverFeatures (uint64_t features) -> void
 写入 64 位驱动特性
 
auto GetQueueNumMax (uint32_t queue_idx) -> uint32_t
 获取队列最大容量
 
auto SetQueueNum (uint32_t queue_idx, uint32_t num) -> void
 
auto SetQueueDesc (uint32_t queue_idx, uint64_t addr) -> void
 设置描述符表物理地址
 
auto SetQueueAvail (uint32_t queue_idx, uint64_t addr) -> void
 设置 Available Ring 物理地址
 
auto SetQueueUsed (uint32_t queue_idx, uint64_t addr) -> void
 设置 Used Ring 物理地址
 
auto GetQueueReady (uint32_t queue_idx) -> bool
 
auto SetQueueReady (uint32_t queue_idx, bool ready) -> void
 
auto NotifyQueue (uint32_t queue_idx) -> void
 通知设备有新的可用缓冲区
 
auto GetInterruptStatus () const -> uint32_t
 
auto AckInterrupt (uint32_t ack_bits) -> void
 
auto ReadConfigU8 (uint32_t offset) const -> uint8_t
 读取配置空间 8 位值
 
auto ReadConfigU16 (uint32_t offset) const -> uint16_t
 读取配置空间 16 位值
 
auto ReadConfigU32 (uint32_t offset) const -> uint32_t
 读取配置空间 32 位值
 
auto ReadConfigU64 (uint32_t offset) const -> uint64_t
 读取配置空间 64 位值
 
auto GetConfigGeneration () const -> uint32_t
 
构造/析构函数
 MmioTransport (MmioTransport &&other) noexcept
 
auto operator= (MmioTransport &&) noexcept -> MmioTransport &=delete
 
 MmioTransport (const MmioTransport &)=delete
 
auto operator= (const MmioTransport &) -> MmioTransport &=delete
 
- Public Member Functions inherited from virtio::Transport
auto Reset (this auto &&self) -> void
 重置设备
 
auto NeedsReset (this auto const &self) -> bool
 检查设备是否需要重置
 
auto IsActive (this auto const &self) -> bool
 检查设备是否已激活(DRIVER_OK 已设置)
 
auto AcknowledgeInterrupt (this auto &&self) -> void
 确认并清除设备中断
 

Private Attributes

MmioAccessor mmio_
 MMIO 寄存器访问器
 
bool is_valid_
 设备是否成功初始化
 
uint32_t device_id_
 设备 ID(缓存以避免重复读取)
 
uint32_t vendor_id_
 供应商 ID(缓存以避免重复读取)
 

Additional Inherited Members

- Protected Member Functions inherited from virtio::Transport
 Transport ()=default
 
 ~Transport ()=default
 
 Transport (Transport &&) noexcept=default
 
auto operator= (Transport &&) noexcept -> Transport &=default
 
 Transport (const Transport &)=delete
 
auto operator= (const Transport &) -> Transport &=delete
 

Detailed Description

Virtio MMIO 传输层

MMIO virtio 设备通过一组内存映射的控制寄存器和设备特定配置空间进行访问。 所有寄存器值采用小端格式组织。

仅支持 Modern VirtIO (v2, virtio 1.0+)。

寄存器布局包括:

  • 魔数(MagicValue): 0x74726976
  • 版本号(Version): 0x2(modern)
  • 设备/供应商 ID
  • 特性位配置
  • 队列配置
  • 中断状态与确认
  • 设备状态
  • 共享内存区域(可选,需要相应特性支持)
  • 队列重置(可选,需要 VIRTIO_F_RING_RESET 特性)
  • 设备特定配置空间(从 0x100 开始)
See also
virtio-v1.2#4.2 Virtio Over MMIO

Definition at line 61 of file mmio.hpp.

Member Enumeration Documentation

◆ MmioReg

enum class virtio::MmioTransport::MmioReg : size_t
strong

MMIO 寄存器偏移量

See also
virtio-v1.2#4.2.2 MMIO Device Register Layout
Enumerator
kMagicValue 
kVersion 
kDeviceId 
kVendorId 
kDeviceFeatures 
kDeviceFeaturesSel 
kDriverFeatures 
kDriverFeaturesSel 
kQueueSel 
kQueueNumMax 
kQueueNum 
kQueueReady 
kQueueNotify 
kInterruptStatus 
kInterruptAck 
kStatus 
kQueueDescLow 
kQueueDescHigh 
kQueueDriverLow 
kQueueDriverHigh 
kQueueDeviceLow 
kQueueDeviceHigh 
kShmSel 
kShmLenLow 
kShmLenHigh 
kShmBaseLow 
kShmBaseHigh 
kQueueReset 
kConfigGeneration 
kConfig 

Definition at line 67 of file mmio.hpp.

67 : size_t {
68 kMagicValue = 0x000,
69 kVersion = 0x004,
70 kDeviceId = 0x008,
71 kVendorId = 0x00C,
72 kDeviceFeatures = 0x010,
73 kDeviceFeaturesSel = 0x014,
74 // 0x018 ~ 0x01F: reserved
75 kDriverFeatures = 0x020,
76 kDriverFeaturesSel = 0x024,
77 // 0x028 ~ 0x02F: reserved
78 kQueueSel = 0x030,
79 kQueueNumMax = 0x034,
80 kQueueNum = 0x038,
81 // 0x03C ~ 0x03F: reserved
82 // 0x040 ~ 0x043: reserved
83 kQueueReady = 0x044,
84 // 0x048 ~ 0x04F: reserved
85 kQueueNotify = 0x050,
86 // 0x054 ~ 0x05F: reserved
87 kInterruptStatus = 0x060,
88 kInterruptAck = 0x064,
89 // 0x068 ~ 0x06F: reserved
90 kStatus = 0x070,
91 // 0x074 ~ 0x07F: reserved
92 kQueueDescLow = 0x080,
93 kQueueDescHigh = 0x084,
94 // 0x088 ~ 0x08F: reserved
95 kQueueDriverLow = 0x090,
96 kQueueDriverHigh = 0x094,
97 // 0x098 ~ 0x09F: reserved
98 kQueueDeviceLow = 0x0A0,
99 kQueueDeviceHigh = 0x0A4,
100 // 0x0A8 ~ 0x0AB: reserved
101 kShmSel = 0x0AC,
102 kShmLenLow = 0x0B0,
103 kShmLenHigh = 0x0B4,
104 kShmBaseLow = 0x0B8,
105 kShmBaseHigh = 0x0BC,
106 kQueueReset = 0x0C0,
107 // 0x0C4 ~ 0x0FB: reserved
108 kConfigGeneration = 0x0FC,
109 kConfig = 0x100,
110 };

Constructor & Destructor Documentation

◆ MmioTransport() [1/3]

virtio::MmioTransport::MmioTransport ( uint64_t  base)
inlineexplicit

构造函数

在构造时完成以下初始化:

  1. 验证 MMIO 魔数和版本号
  2. 检查设备是否存在(Device ID != 0)
  3. 执行设备重置
  4. 缓存设备 ID 和 Vendor ID
Parameters
baseMMIO 寄存器基地址
Postcondition
构造完成后应调用 IsValid() 检查初始化是否成功
See also
virtio-v1.2#4.2.2 MMIO Device Register Layout

Definition at line 126 of file mmio.hpp.

127 : mmio_(base), is_valid_(false), device_id_(0), vendor_id_(0) {
128 if (base == 0) {
129 return;
130 }
131
132 auto magic = mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kMagicValue));
133 if (magic != kMmioMagicValue) {
134 return;
135 }
136
137 auto version = mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kVersion));
138 if (version != kMmioVersionModern) {
139 return;
140 }
141
142 device_id_ = mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kDeviceId));
143 if (device_id_ == 0) {
144 return;
145 }
146
147 vendor_id_ = mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kVendorId));
148 this->Reset();
149 is_valid_ = true;
150 }
uint32_t device_id_
设备 ID(缓存以避免重复读取)
Definition mmio.hpp:382
bool is_valid_
设备是否成功初始化
Definition mmio.hpp:379
uint32_t vendor_id_
供应商 ID(缓存以避免重复读取)
Definition mmio.hpp:385
MmioAccessor mmio_
MMIO 寄存器访问器
Definition mmio.hpp:376
auto Reset(this auto &&self) -> void
重置设备
static constexpr uint32_t kMmioMagicValue
MMIO 魔数: little-endian "virt" = 0x74726976.
Definition mmio.hpp:31
static constexpr uint32_t kMmioVersionModern
Modern VirtIO MMIO 版本号(VirtIO 1.0+)
Definition mmio.hpp:37
auto Read(size_t offset) const -> T
Read from MMIO register.
Here is the call graph for this function:

◆ MmioTransport() [2/3]

virtio::MmioTransport::MmioTransport ( MmioTransport &&  other)
inlinenoexcept

Definition at line 159 of file mmio.hpp.

160 : Transport(std::move(other)),
161 mmio_(other.mmio_),
162 is_valid_(other.is_valid_),
163 device_id_(other.device_id_),
164 vendor_id_(other.vendor_id_) {
165 other.is_valid_ = false;
166 }
Transport()=default

◆ MmioTransport() [3/3]

virtio::MmioTransport::MmioTransport ( const MmioTransport )
delete

Member Function Documentation

◆ AckInterrupt()

auto virtio::MmioTransport::AckInterrupt ( uint32_t  ack_bits) -> void
inline

Definition at line 302 of file mmio.hpp.

302 {
303 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kInterruptAck), ack_bits);
304 }
auto Write(size_t offset, T val) const -> void
Write to MMIO register.
Here is the call graph for this function:

◆ GetConfigGeneration()

auto virtio::MmioTransport::GetConfigGeneration ( ) const -> uint32_t
inline

Definition at line 370 of file mmio.hpp.

370 {
371 return mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kConfigGeneration));
372 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetDeviceFeatures()

auto virtio::MmioTransport::GetDeviceFeatures ( ) -> uint64_t
inline

读取 64 位设备特性

需要分两次 32 位读取(低 32 位和高 32 位)。 涉及硬件寄存器写入,因此不能声明为 const。

Returns
设备支持的 64 位特性位
See also
virtio-v1.2#4.2.2.1

Definition at line 193 of file mmio.hpp.

193 {
194 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kDeviceFeaturesSel), 0);
195 uint64_t lo =
196 mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kDeviceFeatures));
197
198 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kDeviceFeaturesSel), 1);
199 uint64_t hi =
200 mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kDeviceFeatures));
201
202 return (hi << 32) | lo;
203 }
Here is the call graph for this function:

◆ GetDeviceId()

auto virtio::MmioTransport::GetDeviceId ( ) const -> uint32_t
inline

Definition at line 172 of file mmio.hpp.

172{ return device_id_; }

◆ GetInterruptStatus()

auto virtio::MmioTransport::GetInterruptStatus ( ) const -> uint32_t
inline

Definition at line 298 of file mmio.hpp.

298 {
299 return mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kInterruptStatus));
300 }
Here is the call graph for this function:

◆ GetQueueNumMax()

auto virtio::MmioTransport::GetQueueNumMax ( uint32_t  queue_idx) -> uint32_t
inline

获取队列最大容量

涉及硬件寄存器写入,因此不能声明为 const。

Parameters
queue_idx队列索引
Returns
队列最大大小
See also
virtio-v1.2#4.2.3.2

Definition at line 230 of file mmio.hpp.

230 {
231 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueSel), queue_idx);
232 return mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kQueueNumMax));
233 }
Here is the call graph for this function:

◆ GetQueueReady()

auto virtio::MmioTransport::GetQueueReady ( uint32_t  queue_idx) -> bool
inline

Definition at line 282 of file mmio.hpp.

282 {
283 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueSel), queue_idx);
284 return mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kQueueReady)) != 0;
285 }
Here is the call graph for this function:

◆ GetStatus()

auto virtio::MmioTransport::GetStatus ( ) const -> uint32_t
inline

Definition at line 176 of file mmio.hpp.

176 {
177 return mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kStatus));
178 }
Here is the call graph for this function:

◆ GetVendorId()

auto virtio::MmioTransport::GetVendorId ( ) const -> uint32_t
inline

Definition at line 174 of file mmio.hpp.

174{ return vendor_id_; }

◆ IsValid()

auto virtio::MmioTransport::IsValid ( ) const -> bool
inline

检查设备是否成功初始化

Definition at line 155 of file mmio.hpp.

155{ return is_valid_; }

◆ NotifyQueue()

auto virtio::MmioTransport::NotifyQueue ( uint32_t  queue_idx) -> void
inline

通知设备有新的可用缓冲区

Definition at line 294 of file mmio.hpp.

294 {
295 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueNotify), queue_idx);
296 }
Here is the call graph for this function:

◆ operator=() [1/2]

auto virtio::MmioTransport::operator= ( const MmioTransport ) -> MmioTransport &=delete
delete

◆ operator=() [2/2]

auto virtio::MmioTransport::operator= ( MmioTransport &&  ) -> MmioTransport &=delete
deletenoexcept

◆ ReadConfigU16()

auto virtio::MmioTransport::ReadConfigU16 ( uint32_t  offset) const -> uint16_t
inline

读取配置空间 16 位值

Parameters
offset相对于配置空间起始的偏移量

Definition at line 321 of file mmio.hpp.

321 {
322 return mmio_.Read<uint16_t>(std::to_underlying(MmioReg::kConfig) + offset);
323 }
Here is the call graph for this function:

◆ ReadConfigU32()

auto virtio::MmioTransport::ReadConfigU32 ( uint32_t  offset) const -> uint32_t
inline

读取配置空间 32 位值

Parameters
offset相对于配置空间起始的偏移量

Definition at line 330 of file mmio.hpp.

330 {
331 return mmio_.Read<uint32_t>(std::to_underlying(MmioReg::kConfig) + offset);
332 }
Here is the call graph for this function:

◆ ReadConfigU64()

auto virtio::MmioTransport::ReadConfigU64 ( uint32_t  offset) const -> uint64_t
inline

读取配置空间 64 位值

使用 generation counter 机制保证读取的 64 位配置数据一致性:

  1. 读取 ConfigGeneration
  2. 读取配置数据
  3. 再次读取 ConfigGeneration
  4. 如果两次 generation 不同,说明配置在读取过程中被修改,需要重试
Parameters
offset相对于配置空间起始的偏移量
Returns
64 位配置值(保证一致性)
See also
virtio-v1.2#2.5.1 Driver Requirements: Device Configuration Space
virtio-v1.2#4.2.2 MMIO Device Register Layout (ConfigGeneration)

Definition at line 348 of file mmio.hpp.

348 {
349 uint32_t gen1;
350 uint32_t gen2;
351 uint64_t value;
352
353 static constexpr uint32_t kMaxConfigRetries = 1000;
354 uint32_t retries = 0;
355 do {
356 gen1 = GetConfigGeneration();
357
358 auto* ptr = reinterpret_cast<volatile uint32_t*>(
359 mmio_.base + std::to_underlying(MmioReg::kConfig) + offset);
360 uint64_t lo = ptr[0];
361 uint64_t hi = ptr[1];
362 value = (hi << 32) | lo;
363
364 gen2 = GetConfigGeneration();
365 } while (gen1 != gen2 && ++retries < kMaxConfigRetries);
366
367 return value;
368 }
auto GetConfigGeneration() const -> uint32_t
Definition mmio.hpp:370
Here is the call graph for this function:

◆ ReadConfigU8()

auto virtio::MmioTransport::ReadConfigU8 ( uint32_t  offset) const -> uint8_t
inline

读取配置空间 8 位值

Parameters
offset相对于配置空间起始的偏移量
See also
virtio-v1.2#4.2.2.2

Definition at line 312 of file mmio.hpp.

312 {
313 return mmio_.Read<uint8_t>(std::to_underlying(MmioReg::kConfig) + offset);
314 }
Here is the call graph for this function:

◆ SetDriverFeatures()

auto virtio::MmioTransport::SetDriverFeatures ( uint64_t  features) -> void
inline

写入 64 位驱动特性

Parameters
features驱动程序接受的特性位
See also
virtio-v1.2#4.2.2.1

Definition at line 211 of file mmio.hpp.

211 {
212 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kDriverFeaturesSel), 0);
213 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kDriverFeatures),
214 static_cast<uint32_t>(features));
215
216 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kDriverFeaturesSel), 1);
217 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kDriverFeatures),
218 static_cast<uint32_t>(features >> 32));
219 }
Here is the call graph for this function:

◆ SetQueueAvail()

auto virtio::MmioTransport::SetQueueAvail ( uint32_t  queue_idx,
uint64_t  addr 
) -> void
inline

设置 Available Ring 物理地址

Parameters
queue_idx队列索引
addrAvailable Ring 的 64 位物理地址

Definition at line 260 of file mmio.hpp.

260 {
261 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueSel), queue_idx);
262 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueDriverLow),
263 static_cast<uint32_t>(addr));
264 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueDriverHigh),
265 static_cast<uint32_t>(addr >> 32));
266 }
Here is the call graph for this function:

◆ SetQueueDesc()

auto virtio::MmioTransport::SetQueueDesc ( uint32_t  queue_idx,
uint64_t  addr 
) -> void
inline

设置描述符表物理地址

Parameters
queue_idx队列索引
addr描述符表的 64 位物理地址

Definition at line 246 of file mmio.hpp.

246 {
247 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueSel), queue_idx);
248 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueDescLow),
249 static_cast<uint32_t>(addr));
250 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueDescHigh),
251 static_cast<uint32_t>(addr >> 32));
252 }
Here is the call graph for this function:

◆ SetQueueNum()

auto virtio::MmioTransport::SetQueueNum ( uint32_t  queue_idx,
uint32_t  num 
) -> void
inline

Definition at line 235 of file mmio.hpp.

235 {
236 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueSel), queue_idx);
237 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueNum), num);
238 }
Here is the call graph for this function:

◆ SetQueueReady()

auto virtio::MmioTransport::SetQueueReady ( uint32_t  queue_idx,
bool  ready 
) -> void
inline

Definition at line 287 of file mmio.hpp.

287 {
288 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueSel), queue_idx);
289 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueReady),
290 ready ? 1 : 0);
291 }
Here is the call graph for this function:

◆ SetQueueUsed()

auto virtio::MmioTransport::SetQueueUsed ( uint32_t  queue_idx,
uint64_t  addr 
) -> void
inline

设置 Used Ring 物理地址

Parameters
queue_idx队列索引
addrUsed Ring 的 64 位物理地址

Definition at line 274 of file mmio.hpp.

274 {
275 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueSel), queue_idx);
276 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueDeviceLow),
277 static_cast<uint32_t>(addr));
278 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kQueueDeviceHigh),
279 static_cast<uint32_t>(addr >> 32));
280 }
Here is the call graph for this function:

◆ SetStatus()

auto virtio::MmioTransport::SetStatus ( uint32_t  status) -> void
inline

Definition at line 180 of file mmio.hpp.

180 {
181 mmio_.Write<uint32_t>(std::to_underlying(MmioReg::kStatus), status);
182 }
Here is the call graph for this function:

Member Data Documentation

◆ device_id_

uint32_t virtio::MmioTransport::device_id_
private

设备 ID(缓存以避免重复读取)

Definition at line 382 of file mmio.hpp.

◆ is_valid_

bool virtio::MmioTransport::is_valid_
private

设备是否成功初始化

Definition at line 379 of file mmio.hpp.

◆ mmio_

MmioAccessor virtio::MmioTransport::mmio_
private

MMIO 寄存器访问器

Definition at line 376 of file mmio.hpp.

◆ vendor_id_

uint32_t virtio::MmioTransport::vendor_id_
private

供应商 ID(缓存以避免重复读取)

Definition at line 385 of file mmio.hpp.


The documentation for this class was generated from the following file: