21 if (node.mmio_size == 0) {
22 klog::Err(
"VirtioDriver: FDT reg property missing size for node '{}'",
28 return std::unexpected(ctx.error());
31 etl::io_port_ro<uint32_t> magic_reg{
reinterpret_cast<void*
>(ctx->base)};
37 etl::io_port_ro<uint32_t> device_id_reg{
reinterpret_cast<void*
>(
40 const auto device_id =
static_cast<DeviceId>(device_id_reg.read());
43 case DeviceId::kBlock: {
44 if (blk_device_count_ >= kMaxBlkDevices) {
46 "VirtioDriver: blk device pool full, device at {:#x} skipped",
50 const size_t idx = blk_device_count_;
53 dma_buffers_[idx] = kstd::make_unique<IoBuffer>(kMinDmaBufferSize);
54 if (!dma_buffers_[idx] || !dma_buffers_[idx]->IsValid() ||
55 dma_buffers_[idx]->GetBuffer().size() < kMinDmaBufferSize) {
56 klog::Err(
"VirtioDriver: failed to allocate DMA buffer at {:#x}",
62 auto [slot_size, slot_align] =
64 slot_buffers_[idx] = kstd::make_unique<IoBuffer>(slot_size, slot_align);
65 if (!slot_buffers_[idx] || !slot_buffers_[idx]->IsValid()) {
66 klog::Err(
"VirtioDriver: failed to allocate slot DMA buffer at {:#x}",
68 dma_buffers_[idx].reset();
72 uint64_t extra_features =
79 auto vq_dma = dma_buffers_[idx]->ToDmaRegion();
80 auto slot_dma = slot_buffers_[idx]->ToDmaRegion();
84 kDefaultQueueSize, extra_features);
85 if (!result.has_value()) {
86 klog::Err(
"VirtioDriver: VirtioBlk Create failed at {:#x}", ctx->base);
87 dma_buffers_[idx].reset();
88 slot_buffers_[idx].reset();
89 return std::unexpected(
Error(result.error().code));
92 blk_devices_[idx].emplace(std::move(*result));
94 irqs_[idx] = node.irq;
97 if (blk_adapter_count_ < kMaxBlkDevices) {
98 const auto adapter_idx =
static_cast<uint32_t
>(blk_adapter_count_);
99 blk_adapters_[blk_adapter_count_].emplace(&blk_devices_[idx].value(),
101 node.block_device = &blk_adapters_[blk_adapter_count_].value();
102 ++blk_adapter_count_;
105 "VirtioDriver: blk adapter pool full, device at {:#x} skipped",
111 "VirtioDriver: block device at {:#x}, capacity={} sectors, irq={}",
112 ctx->base, blk_devices_[idx].value().GetCapacity(), irqs_[idx]);
static auto Create(uint64_t mmio_base, const DmaRegion &vq_dma, const DmaRegion &slot_dma, VirtToPhysFunc virt_to_phys=IdentityVirtToPhys, uint16_t queue_count=1, uint32_t queue_size=128, uint64_t driver_features=0) -> Expected< VirtioBlk >
创建并初始化块设备