diff --git a/src/console.rs b/src/console.rs new file mode 100644 index 0000000..9b3f4ee --- /dev/null +++ b/src/console.rs @@ -0,0 +1,145 @@ +//! Console Device + +use num_enum::{FromPrimitive, IntoPrimitive}; +use volatile::access::ReadOnly; +use volatile_macro::VolatileFieldAccess; + +pub use super::features::console::F; +use crate::{le16, le32}; + +/// Console Device Configuration Layout +/// +/// Use [`ConfigVolatileFieldAccess`] to work with this struct. +#[doc(alias = "virtio_console_config")] +#[cfg_attr( + feature = "zerocopy", + derive( + zerocopy_derive::KnownLayout, + zerocopy_derive::Immutable, + zerocopy_derive::FromBytes, + ) +)] +#[derive(VolatileFieldAccess)] +#[repr(C)] +pub struct Config { + #[access(ReadOnly)] + cols: le16, + #[access(ReadOnly)] + rows: le16, + #[access(ReadOnly)] + max_nr_ports: le32, + #[access(ReadOnly)] + emerg_wr: le32, +} + +/// Control Message +#[doc(alias = "virtio_console_control")] +#[cfg_attr( + feature = "zerocopy", + derive( + zerocopy_derive::KnownLayout, + zerocopy_derive::Immutable, + zerocopy_derive::FromBytes, + zerocopy_derive::IntoBytes, + ) +)] +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct Control { + /// Port number + pub id: le32, + /// The kind of control event + pub event: le16, + /// Extra information for the event + pub value: le16, +} + +/// Event +/// +///
+/// +/// This enum is not ABI-compatible with it's corresponding field. +/// Use [`Device::from`] for converting from an integer. +/// +///
+/// +/// [`Device::from`]: Device#impl-From-for-Device +#[doc(alias = "VIRTIO_CONSOLE")] +#[derive(IntoPrimitive, FromPrimitive, PartialEq, Eq, Clone, Copy, Debug)] +#[non_exhaustive] +#[repr(u16)] +pub enum Device { + /// Sent by the driver at initialization to indicate that it is ready to receive control messages. + /// + /// A value of 1 indicates success, and 0 indicates failure. + /// The port number `id` is unused. + #[doc(alias = "VIRTIO_CONSOLE_DEVICE_READY")] + DeviceReady = 0, + + /// Sent by the device, to create a new port. + /// + /// `value` is unused. + #[doc(alias = "VIRTIO_CONSOLE_DEVICE_ADD")] + DeviceAdd = 1, + + /// Sent by the device, to remove an existing port. + /// + /// `value` is unused. + #[doc(alias = "VIRTIO_CONSOLE_DEVICE_REMOVE")] + DeviceRemove = 2, + + /// Sent by the driver in response to the device's VIRTIO_CONSOLE_PORT_ADD message, to indicate that the port is ready to be used. + /// + /// A `value` of 1 indicates success, and 0 indicates failure. + #[doc(alias = "VIRTIO_CONSOLE_PORT_READY")] + PortReady = 3, + + /// Sent by the device to nominate a port as a console port. + /// + /// There MAY be more than one console port. + #[doc(alias = "VIRTIO_CONSOLE_CONSOLE_PORT")] + ConsolePort = 4, + + /// Sent by the device to indicate a console size change. + /// + /// `value` is unused. + /// The buffer is followed by the number of columns and rows ([`virtio_console_resize`]). + /// + /// [`virtio_console_resize`]: Resize + #[doc(alias = "VIRTIO_CONSOLE_RESIZE")] + Resize = 5, + + /// This message is sent by both the device and the driver. + /// + /// `value` indicates the state: 0 (port closed) or 1 (port open). + /// This allows for ports to be used directly by guest and host processes to communicate in an application-defined manner. + #[doc(alias = "VIRTIO_CONSOLE_PORT_OPEN")] + PortOpen = 6, + + /// Sent by the device to give a tag to the port. + /// + /// This control command is immediately followed by the UTF-8 name of the port for identification within the guest (without a NUL terminator). + #[doc(alias = "VIRTIO_CONSOLE_PORT_NAME")] + PortName = 7, + + #[num_enum(catch_all)] + Unknown(u16), +} + +/// Resize Message Layout +#[doc(alias = "virtio_console_resize")] +#[cfg_attr( + feature = "zerocopy", + derive( + zerocopy_derive::KnownLayout, + zerocopy_derive::Immutable, + zerocopy_derive::FromBytes, + zerocopy_derive::IntoBytes, + ) +)] +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct Resize { + pub cols: le16, + pub rows: le16, +} diff --git a/src/features.rs b/src/features.rs index c43aa17..1629c10 100644 --- a/src/features.rs +++ b/src/features.rs @@ -289,6 +289,34 @@ macro_rules! feature_bits { () => {}; } +pub mod console { + use crate::le128; + + feature_bits! { + /// Console Device Feature Bits + #[doc(alias = "VIRTIO_CONSOLE_F")] + pub struct F: le128 { + /// Configuration `cols` and `rows` are valid. + #[doc(alias = "VIRTIO_CONSOLE_F_SIZE")] + const SIZE = 1 << 0; + + /// Device has support for multiple ports; + /// + /// `max_nr_ports` is valid and control virtqueues will be used. + #[doc(alias = "VIRTIO_CONSOLE_F_MULTIPORT")] + const MULTIPORT = 1 << 1; + + /// Device has support for emergency write. + /// + /// Configuration field emerg_wr is valid. + #[doc(alias = "VIRTIO_CONSOLE_F_EMERG_WRITE")] + const EMERG_WRITE = 1 << 2; + } + } + + impl crate::FeatureBits for F {} +} + pub mod net { use crate::le128; diff --git a/src/lib.rs b/src/lib.rs index 3d7e335..ff8472f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -61,27 +61,27 @@ //! //! ## Device Types //! -//! | Device Type | Available | Module | -//! | --------------------------------- | --------- | --------- | -//! | Network Device | ✅ | [`net`] | -//! | Block Device | ❌ | | -//! | Console Device | ❌ | | -//! | Entropy Device | ❌ | | -//! | Traditional Memory Balloon Device | ❌ | | -//! | SCSI Host Device | ❌ | | -//! | GPU Device | ❌ | | -//! | Input Device | ❌ | | -//! | Crypto Device | ❌ | | -//! | Socket Device | ✅ | [`vsock`] | -//! | File System Device | ✅ | [`fs`] | -//! | RPMB Device | ❌ | | -//! | IOMMU Device | ❌ | | -//! | Sound Device | ❌ | | -//! | Memory Device | ❌ | | -//! | I2C Adapter Device | ❌ | | -//! | SCMI Device | ❌ | | -//! | GPIO Device | ❌ | | -//! | PMEM Device | ❌ | | +//! | Device Type | Available | Module | +//! | --------------------------------- | --------- | ----------- | +//! | Network Device | ✅ | [`net`] | +//! | Block Device | ❌ | | +//! | Console Device | ✅ | [`console`] | +//! | Entropy Device | ❌ | | +//! | Traditional Memory Balloon Device | ❌ | | +//! | SCSI Host Device | ❌ | | +//! | GPU Device | ❌ | | +//! | Input Device | ❌ | | +//! | Crypto Device | ❌ | | +//! | Socket Device | ✅ | [`vsock`] | +//! | File System Device | ✅ | [`fs`] | +//! | RPMB Device | ❌ | | +//! | IOMMU Device | ❌ | | +//! | Sound Device | ❌ | | +//! | Memory Device | ❌ | | +//! | I2C Adapter Device | ❌ | | +//! | SCMI Device | ❌ | | +//! | GPIO Device | ❌ | | +//! | PMEM Device | ❌ | | #![cfg_attr(not(test), no_std)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] @@ -94,6 +94,7 @@ extern crate alloc; mod bitflags; #[macro_use] pub mod volatile; +pub mod console; #[cfg(any(feature = "mmio", feature = "pci"))] mod driver_notifications; mod features;