Skip to content

Commit

Permalink
Improve documentation and examples
Browse files Browse the repository at this point in the history
Closes rust-vmm#28

Signed-off-by: Sergii Glushchenko <[email protected]>
  • Loading branch information
Sergii Glushchenko authored and lauralt committed Dec 3, 2021
1 parent 6d35cd7 commit ae78cbf
Show file tree
Hide file tree
Showing 4 changed files with 328 additions and 13 deletions.
6 changes: 5 additions & 1 deletion src/bus/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause

//! Provides abstractions for modelling a bus, which is seen here as a mapping between
//! Provides abstractions for modelling an I/O bus.
//!
//! A bus is seen here as a mapping between
//! disjoint intervals (ranges) from an address space and objects (devices) associated with them.
//! A single device can be registered with multiple ranges, but no two ranges can overlap,
//! regardless with their device associations.
Expand Down Expand Up @@ -117,7 +119,9 @@ impl<A: BusAddress, D> Bus<A, D> {
}
}

/// Represents an MMIO bus.
pub type MmioBus<D> = Bus<MmioAddress, D>;
/// Represents a PIO bus.
pub type PioBus<D> = Bus<PioAddress, D>;

/// Helper trait that can be implemented by types which hold one or more buses.
Expand Down
4 changes: 3 additions & 1 deletion src/bus/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ impl<A: BusAddress> BusRange<A> {
self.base
}

/// Return the size of the range.
pub fn size(&self) -> A::V {
self.size
}
Expand Down Expand Up @@ -81,8 +82,9 @@ impl<A: BusAddress> Ord for BusRange<A> {
}
}

// Helper type aliases.
/// Represents an MMIO bus range.
pub type MmioRange = BusRange<MmioAddress>;
/// Represents a PIO bus range.
pub type PioRange = BusRange<PioAddress>;

#[cfg(test)]
Expand Down
114 changes: 109 additions & 5 deletions src/device_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,116 @@

//! System level device management.
//!
//! [IoManager](struct.IoManager.html) is respondsible for managing
//! [`IoManager`] is responsible for managing
//! all devices of virtual machine, registering IO resources callback,
//! deregistering devices and helping VM IO exit handling.
//!VMM would be responsible for getting device resource request, ask
//! vm_allocator to allocate the resources, ask vm_device to register the
//! devices IO ranges, and finally set resources to virtual device.
//! It defines two buses, one for PIO and one for MMIO, and provides default
//! implementations of [`PioManager`] and [`MmioManager`].
//!
//! The VMM must first allocate unique resources (such as bus ranges), and then
//! call into the vm-device interface to register the devices with their
//! corresponding resources.
//!
//! # Examples
//!
//! Registering a new device can be done using the register methods of [`PioManager`]
//! and [`MmioManager`] with an appropriate bus range
//! ([`PioRange`](../bus/type.PioRange.html) or [`MmioRange`](../bus/type.MmioRange.html)).
//! ```
//! # use std::sync::Arc;
//! # use vm_device::bus::{PioAddress, PioAddressOffset, PioRange};
//! # use vm_device::bus::{MmioAddress, MmioAddressOffset, MmioRange};
//! # use vm_device::device_manager::{IoManager, PioManager, MmioManager};
//! # use vm_device::{DevicePio, DeviceMmio};
//! struct NoopDevice {}
//!
//! impl DevicePio for NoopDevice {
//! fn pio_read(&self, base: PioAddress, offset: PioAddressOffset, data: &mut [u8]) {}
//! fn pio_write(&self, base: PioAddress, offset: PioAddressOffset, data: &[u8]) {}
//! }
//!
//! impl DeviceMmio for NoopDevice {
//! fn mmio_read(&self, base: MmioAddress, offset: MmioAddressOffset, data: &mut [u8]) {}
//! fn mmio_write(&self, base: MmioAddress, offset: MmioAddressOffset, data: &[u8]) {}
//! }
//!
//! // IoManager implements both PioManager and MmioManager.
//! let mut manager = IoManager::new();
//!
//! // Register the device on the PIO bus.
//! let pio_range = PioRange::new(PioAddress(0), 10).unwrap();
//! manager
//! .register_pio(pio_range, Arc::new(NoopDevice {}))
//! .unwrap();
//!
//! // Register the device on the MMIO bus.
//! let mmio_range = MmioRange::new(MmioAddress(0), 10).unwrap();
//! manager
//! .register_mmio(mmio_range, Arc::new(NoopDevice {}))
//! .unwrap();
//!
//! // Dispatch I/O on the PIO bus.
//! manager.pio_write(PioAddress(0), &vec![b'o', b'k']).unwrap();
//!
//! // Dispatch I/O on the MMIO bus.
//! manager
//! .mmio_write(MmioAddress(0), &vec![b'o', b'k'])
//! .unwrap();
//! ```
//!
//! An alternative way would be to use [`resources`](../resources/index.html) and the
//! resources registration methods of [`IoManager`]:
//! * [`register_pio_resources`](struct.IoManager.html#method.register_pio_resources)
//! * [`register_mmio_resources`](struct.IoManager.html#method.register_mmio_resources)
//! * or generic [`register_resources`](struct.IoManager.html#method.register_resources)
//! ```
//! # use std::sync::Arc;
//! # use vm_device::bus::{PioAddress, PioAddressOffset, PioRange};
//! # use vm_device::bus::{MmioAddress, MmioAddressOffset, MmioRange};
//! # use vm_device::device_manager::{IoManager, PioManager, MmioManager};
//! # use vm_device::{DevicePio, DeviceMmio};
//! # use vm_device::resources::Resource;
//! # struct NoopDevice {}
//! #
//! # impl DevicePio for NoopDevice {
//! # fn pio_read(&self, base: PioAddress, offset: PioAddressOffset, data: &mut [u8]) {}
//! # fn pio_write(&self, base: PioAddress, offset: PioAddressOffset, data: &[u8]) {}
//! # }
//! #
//! # impl DeviceMmio for NoopDevice {
//! # fn mmio_read(&self, base: MmioAddress, offset: MmioAddressOffset, data: &mut [u8]) {}
//! # fn mmio_write(&self, base: MmioAddress, offset: MmioAddressOffset, data: &[u8]) {}
//! # }
//! // Use the same NoopDevice defined above.
//!
//! let mut manager = IoManager::new();
//!
//! // Define a PIO address range resource.
//! let pio = Resource::PioAddressRange {
//! base: 0,
//! size: 10,
//! };
//!
//! // Define a MMIO address range resource.
//! let mmio = Resource::MmioAddressRange {
//! base: 0,
//! size: 10,
//! };
//!
//! // Register the PIO resource.
//! manager
//! .register_pio_resources(Arc::new(NoopDevice {}), &vec![pio])
//! .unwrap();
//!
//! // Register the MMIO resource.
//! manager
//! .register_mmio_resources(Arc::new(NoopDevice {}), &vec![mmio])
//! .unwrap();
//!
//! // Dispatching I/O is the same.
//! manager.pio_write(PioAddress(0), &vec![b'o', b'k']).unwrap();
//! manager.mmio_write(MmioAddress(0), &vec![b'o', b'k']).unwrap();
//! ```
use std::fmt::{Display, Formatter};
use std::result::Result;
Expand All @@ -18,7 +122,7 @@ use crate::bus::{self, BusManager, MmioAddress, MmioBus, MmioRange, PioAddress,
use crate::resources::Resource;
use crate::{DeviceMmio, DevicePio};

/// Error type for `IoManager` usage.
/// Error type for [IoManager] usage.
#[derive(Debug)]
pub enum Error {
/// Error during bus operation.
Expand Down
Loading

0 comments on commit ae78cbf

Please sign in to comment.