squib_virtio/lib.rs
1//! virtio-MMIO transport and per-device drivers for squib.
2//!
3//! This crate ports the virtio-MMIO state machine and per-device frontends
4//! described in [14-virtio-and-devices.md](../../../specs/14-virtio-and-devices.md).
5//! The transport speaks the [virtio v1.2 MMIO register layout][spec] and
6//! adapts it to squib-native abstractions:
7//!
8//! - [`squib_bus::BusDevice`] for the MMIO-routed register surface.
9//! - [`squib_core::GuestMemory`] for descriptor / payload reads and writes.
10//! - [`squib_gic::Gic::pulse_spi`] for edge-rising IRQ delivery (D24).
11//!
12//! The crate intentionally avoids `vmm-sys-util`, `kvm-ioctls`, and the
13//! upstream Linux-flavoured `EventFd` plumbing โ squib-vmm uses Tokio
14//! channels for cross-thread queue notifications and the GIC's `pulse_spi` is
15//! synchronous through `Arc<dyn Gic>`. See I-CRATE-3 in
16//! [61-crates-and-features.md ยง 7](../../../specs/61-crates-and-features.md#7-invariants).
17//!
18//! ## Module layout
19//!
20//! | Module | Role |
21//! |--------|------|
22//! | [`device`] | Per-device-type trait surface ([`device::VirtioDevice`]) |
23//! | [`device_id`] | Standard virtio device IDs (block=2, net=1, vsock=19, ...) |
24//! | [`device_status`] | Status bits driving the driver-init state machine |
25//! | [`feature_bits`] | Common feature bits (VIRTIO_F_VERSION_1, ...) |
26//! | [`interrupt`] | [`interrupt::IrqLine`] โ wraps `Gic + IntId` for the device side |
27//! | [`queue`] | Virtqueue: descriptors, avail/used rings, [`queue::DescriptorChain`] |
28//! | [`slot`] | MMIO-slot allocator (32-slot ceiling, base `0x0F00_0000 + slot * 0x1000`) |
29//! | [`transport`] | virtio-MMIO `BusDevice`: register layout + driver-init state machine |
30//! | [`devices`] | Per-device frontends: block, net, vsock, balloon, rng, console, pmem, mem, boot-timer |
31//!
32//! [spec]: https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html#x1-1340002
33
34#![forbid(unsafe_code)]
35#![warn(missing_docs)]
36// virtio wire shapes pin every register width: descriptor.len is u32,
37// queue_size is u16, MMIO register payloads are u32. Casting between u64
38// host computations and these wire widths is the device contract โ we keep
39// the casts where they belong and trust the type system at the boundary
40// (validation runs in `Queue::set_size` etc.). The clippy pedantic
41// truncation/precision lints are too noisy to be useful here; the
42// `cast_possible_truncation` lint is informative for app code, not for
43// wire-shape code.
44#![allow(
45 clippy::cast_possible_truncation,
46 clippy::cast_lossless,
47 clippy::cast_sign_loss,
48 clippy::cast_precision_loss,
49 clippy::similar_names
50)]
51
52pub mod device;
53pub mod device_id;
54pub mod device_status;
55pub mod devices;
56pub mod error;
57pub mod feature_bits;
58pub mod interrupt;
59pub mod queue;
60pub mod slot;
61pub mod transport;
62
63pub use device::{ActivateError, VirtioDevice};
64pub use error::VirtioError;
65pub use interrupt::IrqLine;
66pub use queue::{DescriptorChain, MAX_QUEUE_SIZE, Queue, QueueError, QueueIndex};
67pub use slot::{MMIO_SLOT_COUNT, Slot, SlotAllocator, VIRTIO_MMIO_BASE, VIRTIO_MMIO_REGION_SIZE};
68pub use transport::{VIRTIO_MMIO_REGION_BYTES, VirtioMmioTransport};