Skip to content

Instantly share code, notes, and snippets.

@sameo
Created December 5, 2019 18:20
Show Gist options
  • Save sameo/bad2d8407677f345c32ab999742a11bc to your computer and use it in GitHub Desktop.
Save sameo/bad2d8407677f345c32ab999742a11bc to your computer and use it in GitHub Desktop.
/// Trait to manage interrupt sources for virtual device backends.
///
/// The InterruptManager implementations should protect itself from concurrent accesses internally,
/// so it could be invoked from multi-threaded context.
pub trait InterruptManager {
    /// Create an [InterruptSourceGroup](trait.InterruptSourceGroup.html) object to manage
    /// interrupt sources for a virtual device
    ///
    /// An [InterruptSourceGroup](trait.InterruptSourceGroup.html) object manages all interrupt
    /// sources of the same type for a virtual device.
    ///
    /// # Arguments
    /// * ty: type of interrupt source.
    /// * base: base Interrupt Source ID to be managed by the group object.
    /// * count: number of Interrupt Sources to be managed by the group object.
    fn create_group(
        &self,
        base: InterruptIndex,
        count: InterruptIndex,
    ) -> Result<Arc<Box<dyn InterruptSourceGroup>>>;

    /// Destroy an [InterruptSourceGroup](trait.InterruptSourceGroup.html) object created by
    /// [create_group()](trait.InterruptManager.html#tymethod.create_group).
    ///
    /// Assume the caller takes the responsibility to disable all interrupt sources of the group
    /// before calling destroy_group(). This assumption helps to simplify InterruptSourceGroup
    /// implementations.
    fn destroy_group(&self, group: Arc<Box<dyn InterruptSourceGroup>>) -> Result<()>;
}

#[derive(Copy, Clone, Debug, Default)]
pub struct MsiIrqSourceConfig {
    /// High address to delivery message signaled interrupt.
    pub high_addr: u32,
    /// Low address to delivery message signaled interrupt.
    pub low_addr: u32,
    /// Data to write to delivery message signaled interrupt.
    pub data: u32,
}

pub trait InterruptSourceGroup: Send + Sync {
    /// Enable the interrupt sources in the group to generate interrupts.
    fn enable(&self) -> Result<()>;

    /// Disable the interrupt sources in the group to generate interrupts.
    fn disable(&self) -> Result<()>;

    /// Inject an interrupt into the guest.
    ///
    /// If the interrupt has an associated `interrupt_status` register, all bits set in `flag`
    /// will be atomically ORed into the `interrupt_status` register.
    fn trigger(&self, index: InterruptIndex) -> Result<()>;
}

pub trait InterruptSourceGroupMsi: Send + Sync + InterruptSourceGroup {
    /// Change the configuration to generate interrupts.
    ///
    /// # Arguments
    /// * index: sub-index into the group.
    /// * config: configuration data for the interrupt source.
    fn modify(&self, index: InterruptIndex, config: &MsiIrqSourceConfig) -> Result<()>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment