2019-04-18 09:59:12 +00:00
|
|
|
// Copyright 2018 The Chromium OS Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
2019-05-08 10:22:53 +00:00
|
|
|
// found in the LICENSE-BSD-3-Clause file.
|
2019-04-18 09:59:12 +00:00
|
|
|
|
2019-07-19 17:50:30 +00:00
|
|
|
use crate::configuration::{self, PciBarRegionType};
|
2019-05-29 23:33:29 +00:00
|
|
|
use crate::msix::MsixTableEntry;
|
2019-04-18 09:59:12 +00:00
|
|
|
use crate::PciInterruptPin;
|
|
|
|
use devices::BusDevice;
|
|
|
|
use std;
|
|
|
|
use std::fmt::{self, Display};
|
2019-06-03 20:57:26 +00:00
|
|
|
use std::sync::Arc;
|
2019-04-18 09:59:12 +00:00
|
|
|
use vm_allocator::SystemAllocator;
|
|
|
|
use vm_memory::{GuestAddress, GuestUsize};
|
2019-08-02 14:23:52 +00:00
|
|
|
use vmm_sys_util::eventfd::EventFd;
|
2019-04-18 09:59:12 +00:00
|
|
|
|
2019-06-06 19:38:48 +00:00
|
|
|
pub struct InterruptParameters<'a> {
|
|
|
|
pub msix: Option<&'a MsixTableEntry>,
|
2019-06-05 16:53:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type InterruptDelivery =
|
2019-08-15 15:41:40 +00:00
|
|
|
Box<dyn Fn(InterruptParameters) -> std::result::Result<(), std::io::Error> + Send + Sync>;
|
2019-06-03 20:57:26 +00:00
|
|
|
|
2019-04-18 09:59:12 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
/// Setup of the device capabilities failed.
|
|
|
|
CapabilitiesSetup(configuration::Error),
|
|
|
|
/// Allocating space for an IO BAR failed.
|
|
|
|
IoAllocationFailed(u64),
|
|
|
|
/// Registering an IO BAR failed.
|
|
|
|
IoRegistrationFailed(u64, configuration::Error),
|
|
|
|
}
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
|
|
|
|
impl Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
use self::Error::*;
|
|
|
|
|
|
|
|
match self {
|
|
|
|
CapabilitiesSetup(e) => write!(f, "failed to add capability {}", e),
|
|
|
|
IoAllocationFailed(size) => {
|
|
|
|
write!(f, "failed to allocate space for an IO BAR, size={}", size)
|
|
|
|
}
|
|
|
|
IoRegistrationFailed(addr, e) => {
|
|
|
|
write!(f, "failed to register an IO BAR, addr={} err={}", addr, e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait PciDevice: BusDevice {
|
|
|
|
/// Assign a legacy PCI IRQ to this device.
|
|
|
|
/// The device may write to `irq_evt` to trigger an interrupt.
|
2019-05-29 23:33:29 +00:00
|
|
|
fn assign_pin_irq(
|
|
|
|
&mut self,
|
2019-06-05 16:53:24 +00:00
|
|
|
_irq_cb: Arc<InterruptDelivery>,
|
2019-05-29 23:33:29 +00:00
|
|
|
_irq_num: u32,
|
|
|
|
_irq_pin: PciInterruptPin,
|
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Assign MSI-X to this device.
|
2019-06-05 16:53:24 +00:00
|
|
|
fn assign_msix(&mut self, _msi_cb: Arc<InterruptDelivery>) {}
|
2019-04-18 09:59:12 +00:00
|
|
|
|
|
|
|
/// 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: &mut SystemAllocator,
|
2019-07-19 17:50:30 +00:00
|
|
|
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
|
2019-04-18 09:59:12 +00:00
|
|
|
Ok(Vec::new())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Gets a list of ioeventfds that should be registered with the running VM. The list is
|
|
|
|
/// returned as a Vec of (eventfd, addr, datamatch) tuples.
|
2019-05-06 17:27:40 +00:00
|
|
|
fn ioeventfds(&self) -> Vec<(&EventFd, u64, u64)> {
|
2019-04-18 09:59:12 +00:00
|
|
|
Vec::new()
|
|
|
|
}
|
2019-06-05 09:24:18 +00:00
|
|
|
/// Sets a register in the configuration space.
|
|
|
|
/// * `reg_idx` - The index of the config register to modify.
|
|
|
|
/// * `offset` - Offset in to the register.
|
|
|
|
fn write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8]);
|
|
|
|
/// Gets a register from the configuration space.
|
|
|
|
/// * `reg_idx` - The index of the config register to read.
|
|
|
|
fn read_config_register(&self, reg_idx: usize) -> u32;
|
2019-04-18 09:59:12 +00:00
|
|
|
/// Reads from a BAR region mapped in to the device.
|
|
|
|
/// * `addr` - The guest address inside the BAR.
|
|
|
|
/// * `data` - Filled with the data from `addr`.
|
2019-06-04 06:51:00 +00:00
|
|
|
fn read_bar(&mut self, _base: u64, _offset: u64, _data: &mut [u8]) {}
|
2019-04-18 09:59:12 +00:00
|
|
|
/// Writes to a BAR region mapped in to the device.
|
|
|
|
/// * `addr` - The guest address inside the BAR.
|
|
|
|
/// * `data` - The data to write.
|
2019-06-04 06:51:00 +00:00
|
|
|
fn write_bar(&mut self, _base: u64, _offset: u64, _data: &[u8]) {}
|
2019-04-18 09:59:12 +00:00
|
|
|
}
|