cloud-hypervisor/pci/src/device.rs
Philipp Schuster 363273111a build: treewide: fmt for edition 2024
`cargo +nightly fmt`

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
2025-09-10 18:35:38 +00:00

116 lines
4.1 KiB
Rust

// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
use std::any::Any;
use std::sync::{Arc, Barrier, Mutex};
use std::{io, result};
use thiserror::Error;
use vm_allocator::{AddressAllocator, SystemAllocator};
use vm_device::Resource;
use crate::PciBarConfiguration;
use crate::configuration::{self, PciBarRegionType};
#[derive(Error, Debug)]
pub enum Error {
/// Setup of the device capabilities failed.
#[error("Setup of the device capabilities failed")]
CapabilitiesSetup(#[source] configuration::Error),
/// Allocating space for an IO BAR failed.
#[error("Allocating space for an IO BAR failed")]
IoAllocationFailed(u64),
/// Registering an IO BAR failed.
#[error("Registering an IO BAR failed")]
IoRegistrationFailed(u64, #[source] configuration::Error),
/// Expected resource not found.
#[error("Expected resource not found")]
MissingResource,
/// Invalid resource.
#[error("Invalid resource: {0:?}")]
InvalidResource(Resource),
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Clone, Copy, Debug)]
pub struct BarReprogrammingParams {
pub old_base: u64,
pub new_base: u64,
pub len: u64,
pub region_type: PciBarRegionType,
}
pub trait PciDevice: Send {
/// Allocates the needed PCI BARs space using the `allocate` function which takes a size and
/// returns an address. Returns a Vec of (GuestAddress, GuestUsize) tuples.
fn allocate_bars(
&mut self,
_allocator: &Arc<Mutex<SystemAllocator>>,
_mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
_resources: Option<Vec<Resource>>,
) -> Result<Vec<PciBarConfiguration>> {
Ok(Vec::new())
}
/// Frees the PCI BARs previously allocated with a call to allocate_bars().
fn free_bars(
&mut self,
_allocator: &mut SystemAllocator,
_mmio32_allocator: &mut AddressAllocator,
_mmio64_allocator: &mut AddressAllocator,
) -> Result<()> {
Ok(())
}
/// Sets a register in the configuration space.
/// * `reg_idx` - The index of the config register to modify.
/// * `offset` - Offset into the register.
fn write_config_register(
&mut self,
reg_idx: usize,
offset: u64,
data: &[u8],
) -> (Vec<BarReprogrammingParams>, Option<Arc<Barrier>>);
/// Gets a register from the configuration space.
/// * `reg_idx` - The index of the config register to read.
fn read_config_register(&mut self, reg_idx: usize) -> u32;
/// Reads from a BAR region mapped into the device.
/// * `addr` - The guest address inside the BAR.
/// * `data` - Filled with the data from `addr`.
fn read_bar(&mut self, _base: u64, _offset: u64, _data: &mut [u8]) {}
/// Writes to a BAR region mapped into the device.
/// * `addr` - The guest address inside the BAR.
/// * `data` - The data to write.
fn write_bar(&mut self, _base: u64, _offset: u64, _data: &[u8]) -> Option<Arc<Barrier>> {
None
}
/// Relocates the BAR to a different address in guest address space.
fn move_bar(&mut self, _old_base: u64, _new_base: u64) -> result::Result<(), io::Error> {
Ok(())
}
/// Provides a mutable reference to the Any trait. This is useful to let
/// the caller have access to the underlying type behind the trait.
fn as_any_mut(&mut self) -> &mut dyn Any;
/// Optionally returns a unique identifier.
fn id(&self) -> Option<String>;
}
/// This trait defines a set of functions which can be triggered whenever a
/// PCI device is modified in any way.
pub trait DeviceRelocation: Send + Sync {
/// The BAR needs to be moved to a different location in the guest address
/// space. This follows a decision from the software running in the guest.
fn move_bar(
&self,
old_base: u64,
new_base: u64,
len: u64,
pci_dev: &mut dyn PciDevice,
region_type: PciBarRegionType,
) -> result::Result<(), io::Error>;
}