1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::marker::Send; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::marker::Sized; 7*bb4ee6a4SAndroid Build Coastguard Worker 8*bb4ee6a4SAndroid Build Coastguard Worker use base::Event; 9*bb4ee6a4SAndroid Build Coastguard Worker use base::Result; 10*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IrqRoute; 11*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::MPState; 12*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Vcpu; 13*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocator; 14*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize; 15*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::CrosvmDeviceId; 18*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciId; 19*bb4ee6a4SAndroid Build Coastguard Worker use crate::Bus; 20*bb4ee6a4SAndroid Build Coastguard Worker use crate::BusDevice; 21*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqEdgeEvent; 22*bb4ee6a4SAndroid Build Coastguard Worker use crate::IrqLevelEvent; 23*bb4ee6a4SAndroid Build Coastguard Worker 24*bb4ee6a4SAndroid Build Coastguard Worker cfg_if::cfg_if! { 25*bb4ee6a4SAndroid Build Coastguard Worker if #[cfg(any(target_os = "android", target_os = "linux"))] { 26*bb4ee6a4SAndroid Build Coastguard Worker mod kvm; 27*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::KvmKernelIrqChip; 28*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "x86_64")] 29*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::KvmSplitIrqChip; 30*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] 31*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::{AARCH64_GIC_NR_IRQS, AARCH64_GIC_NR_SPIS}; 32*bb4ee6a4SAndroid Build Coastguard Worker } else if #[cfg(all(windows, feature = "whpx"))] { 33*bb4ee6a4SAndroid Build Coastguard Worker mod whpx; 34*bb4ee6a4SAndroid Build Coastguard Worker pub use self::whpx::WhpxSplitIrqChip; 35*bb4ee6a4SAndroid Build Coastguard Worker } 36*bb4ee6a4SAndroid Build Coastguard Worker } 37*bb4ee6a4SAndroid Build Coastguard Worker 38*bb4ee6a4SAndroid Build Coastguard Worker cfg_if::cfg_if! { 39*bb4ee6a4SAndroid Build Coastguard Worker if #[cfg(all(unix, any(target_arch = "arm", target_arch = "aarch64"), feature = "gunyah"))] { 40*bb4ee6a4SAndroid Build Coastguard Worker mod gunyah; 41*bb4ee6a4SAndroid Build Coastguard Worker pub use self::gunyah::GunyahIrqChip; 42*bb4ee6a4SAndroid Build Coastguard Worker } 43*bb4ee6a4SAndroid Build Coastguard Worker } 44*bb4ee6a4SAndroid Build Coastguard Worker 45*bb4ee6a4SAndroid Build Coastguard Worker cfg_if::cfg_if! { 46*bb4ee6a4SAndroid Build Coastguard Worker if #[cfg(target_arch = "x86_64")] { 47*bb4ee6a4SAndroid Build Coastguard Worker mod x86_64; 48*bb4ee6a4SAndroid Build Coastguard Worker pub use x86_64::*; 49*bb4ee6a4SAndroid Build Coastguard Worker mod pic; 50*bb4ee6a4SAndroid Build Coastguard Worker pub use pic::*; 51*bb4ee6a4SAndroid Build Coastguard Worker mod ioapic; 52*bb4ee6a4SAndroid Build Coastguard Worker pub use ioapic::*; 53*bb4ee6a4SAndroid Build Coastguard Worker mod apic; 54*bb4ee6a4SAndroid Build Coastguard Worker pub use apic::*; 55*bb4ee6a4SAndroid Build Coastguard Worker mod userspace; 56*bb4ee6a4SAndroid Build Coastguard Worker pub use userspace::*; 57*bb4ee6a4SAndroid Build Coastguard Worker } else if #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] { 58*bb4ee6a4SAndroid Build Coastguard Worker mod aarch64; 59*bb4ee6a4SAndroid Build Coastguard Worker pub use aarch64::*; 60*bb4ee6a4SAndroid Build Coastguard Worker } else if #[cfg(target_arch = "riscv64")] { 61*bb4ee6a4SAndroid Build Coastguard Worker mod riscv64; 62*bb4ee6a4SAndroid Build Coastguard Worker pub use riscv64::*; 63*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::aia_addr_imsic; 64*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::aia_aplic_addr; 65*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::aia_imsic_addr; 66*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::aia_imsic_size; 67*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::AIA_APLIC_SIZE; 68*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::AIA_IMSIC_BASE; 69*bb4ee6a4SAndroid Build Coastguard Worker pub use self::kvm::IMSIC_MAX_INT_IDS; 70*bb4ee6a4SAndroid Build Coastguard Worker } 71*bb4ee6a4SAndroid Build Coastguard Worker 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker 74*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(all(target_arch = "aarch64", feature = "geniezone"))] 75*bb4ee6a4SAndroid Build Coastguard Worker mod geniezone; 76*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(all(target_arch = "aarch64", feature = "geniezone"))] 77*bb4ee6a4SAndroid Build Coastguard Worker pub use self::geniezone::GeniezoneKernelIrqChip; 78*bb4ee6a4SAndroid Build Coastguard Worker 79*bb4ee6a4SAndroid Build Coastguard Worker pub type IrqEventIndex = usize; 80*bb4ee6a4SAndroid Build Coastguard Worker 81*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(target_arch = "x86_64")] 82*bb4ee6a4SAndroid Build Coastguard Worker struct IrqEvent { 83*bb4ee6a4SAndroid Build Coastguard Worker event: Event, 84*bb4ee6a4SAndroid Build Coastguard Worker gsi: u32, 85*bb4ee6a4SAndroid Build Coastguard Worker resample_event: Option<Event>, 86*bb4ee6a4SAndroid Build Coastguard Worker source: IrqEventSource, 87*bb4ee6a4SAndroid Build Coastguard Worker } 88*bb4ee6a4SAndroid Build Coastguard Worker 89*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] 90*bb4ee6a4SAndroid Build Coastguard Worker pub enum DeviceId { 91*bb4ee6a4SAndroid Build Coastguard Worker /// PCI Device, use its PciId directly. 92*bb4ee6a4SAndroid Build Coastguard Worker PciDeviceId(PciId), 93*bb4ee6a4SAndroid Build Coastguard Worker /// Platform device, use a unique Id. 94*bb4ee6a4SAndroid Build Coastguard Worker PlatformDeviceId(CrosvmDeviceId), 95*bb4ee6a4SAndroid Build Coastguard Worker } 96*bb4ee6a4SAndroid Build Coastguard Worker 97*bb4ee6a4SAndroid Build Coastguard Worker impl From<PciId> for DeviceId { from(v: PciId) -> Self98*bb4ee6a4SAndroid Build Coastguard Worker fn from(v: PciId) -> Self { 99*bb4ee6a4SAndroid Build Coastguard Worker Self::PciDeviceId(v) 100*bb4ee6a4SAndroid Build Coastguard Worker } 101*bb4ee6a4SAndroid Build Coastguard Worker } 102*bb4ee6a4SAndroid Build Coastguard Worker 103*bb4ee6a4SAndroid Build Coastguard Worker impl From<CrosvmDeviceId> for DeviceId { from(v: CrosvmDeviceId) -> Self104*bb4ee6a4SAndroid Build Coastguard Worker fn from(v: CrosvmDeviceId) -> Self { 105*bb4ee6a4SAndroid Build Coastguard Worker Self::PlatformDeviceId(v) 106*bb4ee6a4SAndroid Build Coastguard Worker } 107*bb4ee6a4SAndroid Build Coastguard Worker } 108*bb4ee6a4SAndroid Build Coastguard Worker 109*bb4ee6a4SAndroid Build Coastguard Worker impl TryFrom<u32> for DeviceId { 110*bb4ee6a4SAndroid Build Coastguard Worker type Error = base::Error; 111*bb4ee6a4SAndroid Build Coastguard Worker try_from(value: u32) -> std::result::Result<Self, Self::Error>112*bb4ee6a4SAndroid Build Coastguard Worker fn try_from(value: u32) -> std::result::Result<Self, Self::Error> { 113*bb4ee6a4SAndroid Build Coastguard Worker let device_id = (value & 0xFFFF) as u16; 114*bb4ee6a4SAndroid Build Coastguard Worker let vendor_id = ((value & 0xFFFF_0000) >> 16) as u16; 115*bb4ee6a4SAndroid Build Coastguard Worker if vendor_id == 0xFFFF { 116*bb4ee6a4SAndroid Build Coastguard Worker Ok(DeviceId::PlatformDeviceId(CrosvmDeviceId::try_from( 117*bb4ee6a4SAndroid Build Coastguard Worker device_id, 118*bb4ee6a4SAndroid Build Coastguard Worker )?)) 119*bb4ee6a4SAndroid Build Coastguard Worker } else { 120*bb4ee6a4SAndroid Build Coastguard Worker Ok(DeviceId::PciDeviceId(PciId::new(vendor_id, device_id))) 121*bb4ee6a4SAndroid Build Coastguard Worker } 122*bb4ee6a4SAndroid Build Coastguard Worker } 123*bb4ee6a4SAndroid Build Coastguard Worker } 124*bb4ee6a4SAndroid Build Coastguard Worker 125*bb4ee6a4SAndroid Build Coastguard Worker impl From<DeviceId> for u32 { from(id: DeviceId) -> Self126*bb4ee6a4SAndroid Build Coastguard Worker fn from(id: DeviceId) -> Self { 127*bb4ee6a4SAndroid Build Coastguard Worker match id { 128*bb4ee6a4SAndroid Build Coastguard Worker DeviceId::PciDeviceId(pci_id) => pci_id.into(), 129*bb4ee6a4SAndroid Build Coastguard Worker DeviceId::PlatformDeviceId(id) => 0xFFFF0000 | id as u32, 130*bb4ee6a4SAndroid Build Coastguard Worker } 131*bb4ee6a4SAndroid Build Coastguard Worker } 132*bb4ee6a4SAndroid Build Coastguard Worker } 133*bb4ee6a4SAndroid Build Coastguard Worker 134*bb4ee6a4SAndroid Build Coastguard Worker /// Identification information about the source of an IrqEvent 135*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Serialize, Deserialize)] 136*bb4ee6a4SAndroid Build Coastguard Worker pub struct IrqEventSource { 137*bb4ee6a4SAndroid Build Coastguard Worker pub device_id: DeviceId, 138*bb4ee6a4SAndroid Build Coastguard Worker pub queue_id: usize, 139*bb4ee6a4SAndroid Build Coastguard Worker pub device_name: String, 140*bb4ee6a4SAndroid Build Coastguard Worker } 141*bb4ee6a4SAndroid Build Coastguard Worker 142*bb4ee6a4SAndroid Build Coastguard Worker impl IrqEventSource { from_device(device: &dyn BusDevice) -> Self143*bb4ee6a4SAndroid Build Coastguard Worker pub fn from_device(device: &dyn BusDevice) -> Self { 144*bb4ee6a4SAndroid Build Coastguard Worker Self { 145*bb4ee6a4SAndroid Build Coastguard Worker device_id: device.device_id(), 146*bb4ee6a4SAndroid Build Coastguard Worker queue_id: 0, 147*bb4ee6a4SAndroid Build Coastguard Worker device_name: device.debug_label(), 148*bb4ee6a4SAndroid Build Coastguard Worker } 149*bb4ee6a4SAndroid Build Coastguard Worker } 150*bb4ee6a4SAndroid Build Coastguard Worker } 151*bb4ee6a4SAndroid Build Coastguard Worker 152*bb4ee6a4SAndroid Build Coastguard Worker /// Trait that abstracts interactions with interrupt controllers. 153*bb4ee6a4SAndroid Build Coastguard Worker /// 154*bb4ee6a4SAndroid Build Coastguard Worker /// Each VM will have one IrqChip instance which is responsible for routing IRQ lines and 155*bb4ee6a4SAndroid Build Coastguard Worker /// registering IRQ events. Depending on the implementation, the IrqChip may interact with an 156*bb4ee6a4SAndroid Build Coastguard Worker /// underlying hypervisor API or emulate devices in userspace. 157*bb4ee6a4SAndroid Build Coastguard Worker /// 158*bb4ee6a4SAndroid Build Coastguard Worker /// This trait is generic over a Vcpu type because some IrqChip implementations can support 159*bb4ee6a4SAndroid Build Coastguard Worker /// multiple hypervisors with a single implementation. 160*bb4ee6a4SAndroid Build Coastguard Worker pub trait IrqChip: Send { 161*bb4ee6a4SAndroid Build Coastguard Worker /// Add a vcpu to the irq chip. add_vcpu(&mut self, vcpu_id: usize, vcpu: &dyn Vcpu) -> Result<()>162*bb4ee6a4SAndroid Build Coastguard Worker fn add_vcpu(&mut self, vcpu_id: usize, vcpu: &dyn Vcpu) -> Result<()>; 163*bb4ee6a4SAndroid Build Coastguard Worker 164*bb4ee6a4SAndroid Build Coastguard Worker /// Register an event with edge-trigger semantic that can trigger an interrupt for a particular 165*bb4ee6a4SAndroid Build Coastguard Worker /// GSI. register_edge_irq_event( &mut self, irq: u32, irq_event: &IrqEdgeEvent, source: IrqEventSource, ) -> Result<Option<IrqEventIndex>>166*bb4ee6a4SAndroid Build Coastguard Worker fn register_edge_irq_event( 167*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 168*bb4ee6a4SAndroid Build Coastguard Worker irq: u32, 169*bb4ee6a4SAndroid Build Coastguard Worker irq_event: &IrqEdgeEvent, 170*bb4ee6a4SAndroid Build Coastguard Worker source: IrqEventSource, 171*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Option<IrqEventIndex>>; 172*bb4ee6a4SAndroid Build Coastguard Worker 173*bb4ee6a4SAndroid Build Coastguard Worker /// Unregister an event with edge-trigger semantic for a particular GSI. unregister_edge_irq_event(&mut self, irq: u32, irq_event: &IrqEdgeEvent) -> Result<()>174*bb4ee6a4SAndroid Build Coastguard Worker fn unregister_edge_irq_event(&mut self, irq: u32, irq_event: &IrqEdgeEvent) -> Result<()>; 175*bb4ee6a4SAndroid Build Coastguard Worker 176*bb4ee6a4SAndroid Build Coastguard Worker /// Register an event with level-trigger semantic that can trigger an interrupt for a particular 177*bb4ee6a4SAndroid Build Coastguard Worker /// GSI. register_level_irq_event( &mut self, irq: u32, irq_event: &IrqLevelEvent, source: IrqEventSource, ) -> Result<Option<IrqEventIndex>>178*bb4ee6a4SAndroid Build Coastguard Worker fn register_level_irq_event( 179*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 180*bb4ee6a4SAndroid Build Coastguard Worker irq: u32, 181*bb4ee6a4SAndroid Build Coastguard Worker irq_event: &IrqLevelEvent, 182*bb4ee6a4SAndroid Build Coastguard Worker source: IrqEventSource, 183*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Option<IrqEventIndex>>; 184*bb4ee6a4SAndroid Build Coastguard Worker 185*bb4ee6a4SAndroid Build Coastguard Worker /// Unregister an event with level-trigger semantic for a particular GSI. unregister_level_irq_event(&mut self, irq: u32, irq_event: &IrqLevelEvent) -> Result<()>186*bb4ee6a4SAndroid Build Coastguard Worker fn unregister_level_irq_event(&mut self, irq: u32, irq_event: &IrqLevelEvent) -> Result<()>; 187*bb4ee6a4SAndroid Build Coastguard Worker 188*bb4ee6a4SAndroid Build Coastguard Worker /// Route an IRQ line to an interrupt controller, or to a particular MSI vector. route_irq(&mut self, route: IrqRoute) -> Result<()>189*bb4ee6a4SAndroid Build Coastguard Worker fn route_irq(&mut self, route: IrqRoute) -> Result<()>; 190*bb4ee6a4SAndroid Build Coastguard Worker 191*bb4ee6a4SAndroid Build Coastguard Worker /// Replace all irq routes with the supplied routes set_irq_routes(&mut self, routes: &[IrqRoute]) -> Result<()>192*bb4ee6a4SAndroid Build Coastguard Worker fn set_irq_routes(&mut self, routes: &[IrqRoute]) -> Result<()>; 193*bb4ee6a4SAndroid Build Coastguard Worker 194*bb4ee6a4SAndroid Build Coastguard Worker /// Return a vector of all registered irq numbers and their associated events and event 195*bb4ee6a4SAndroid Build Coastguard Worker /// sources. These should be used by the main thread to wait for irq events. irq_event_tokens(&self) -> Result<Vec<(IrqEventIndex, IrqEventSource, Event)>>196*bb4ee6a4SAndroid Build Coastguard Worker fn irq_event_tokens(&self) -> Result<Vec<(IrqEventIndex, IrqEventSource, Event)>>; 197*bb4ee6a4SAndroid Build Coastguard Worker 198*bb4ee6a4SAndroid Build Coastguard Worker /// Either assert or deassert an IRQ line. Sends to either an interrupt controller, or does 199*bb4ee6a4SAndroid Build Coastguard Worker /// a send_msi if the irq is associated with an MSI. service_irq(&mut self, irq: u32, level: bool) -> Result<()>200*bb4ee6a4SAndroid Build Coastguard Worker fn service_irq(&mut self, irq: u32, level: bool) -> Result<()>; 201*bb4ee6a4SAndroid Build Coastguard Worker 202*bb4ee6a4SAndroid Build Coastguard Worker /// Service an IRQ event by asserting then deasserting an IRQ line. The associated Event 203*bb4ee6a4SAndroid Build Coastguard Worker /// that triggered the irq event will be read from. If the irq is associated with a resample 204*bb4ee6a4SAndroid Build Coastguard Worker /// Event, then the deassert will only happen after an EOI is broadcast for a vector 205*bb4ee6a4SAndroid Build Coastguard Worker /// associated with the irq line. service_irq_event(&mut self, event_index: IrqEventIndex) -> Result<()>206*bb4ee6a4SAndroid Build Coastguard Worker fn service_irq_event(&mut self, event_index: IrqEventIndex) -> Result<()>; 207*bb4ee6a4SAndroid Build Coastguard Worker 208*bb4ee6a4SAndroid Build Coastguard Worker /// Broadcast an end of interrupt. broadcast_eoi(&self, vector: u8) -> Result<()>209*bb4ee6a4SAndroid Build Coastguard Worker fn broadcast_eoi(&self, vector: u8) -> Result<()>; 210*bb4ee6a4SAndroid Build Coastguard Worker 211*bb4ee6a4SAndroid Build Coastguard Worker /// Injects any pending interrupts for `vcpu`. inject_interrupts(&self, vcpu: &dyn Vcpu) -> Result<()>212*bb4ee6a4SAndroid Build Coastguard Worker fn inject_interrupts(&self, vcpu: &dyn Vcpu) -> Result<()>; 213*bb4ee6a4SAndroid Build Coastguard Worker 214*bb4ee6a4SAndroid Build Coastguard Worker /// Notifies the irq chip that the specified VCPU has executed a halt instruction. halted(&self, vcpu_id: usize)215*bb4ee6a4SAndroid Build Coastguard Worker fn halted(&self, vcpu_id: usize); 216*bb4ee6a4SAndroid Build Coastguard Worker 217*bb4ee6a4SAndroid Build Coastguard Worker /// Blocks until `vcpu` is in a runnable state or until interrupted by 218*bb4ee6a4SAndroid Build Coastguard Worker /// `IrqChip::kick_halted_vcpus`. Returns `VcpuRunState::Runnable if vcpu is runnable, or 219*bb4ee6a4SAndroid Build Coastguard Worker /// `VcpuRunState::Interrupted` if the wait was interrupted. wait_until_runnable(&self, vcpu: &dyn Vcpu) -> Result<VcpuRunState>220*bb4ee6a4SAndroid Build Coastguard Worker fn wait_until_runnable(&self, vcpu: &dyn Vcpu) -> Result<VcpuRunState>; 221*bb4ee6a4SAndroid Build Coastguard Worker 222*bb4ee6a4SAndroid Build Coastguard Worker /// Makes unrunnable VCPUs return immediately from `wait_until_runnable`. 223*bb4ee6a4SAndroid Build Coastguard Worker /// For UserspaceIrqChip, every vcpu gets kicked so its current or next call to 224*bb4ee6a4SAndroid Build Coastguard Worker /// `wait_until_runnable` will immediately return false. After that one kick, subsequent 225*bb4ee6a4SAndroid Build Coastguard Worker /// `wait_until_runnable` calls go back to waiting for runnability normally. kick_halted_vcpus(&self)226*bb4ee6a4SAndroid Build Coastguard Worker fn kick_halted_vcpus(&self); 227*bb4ee6a4SAndroid Build Coastguard Worker 228*bb4ee6a4SAndroid Build Coastguard Worker /// Get the current MP state of the specified VCPU. get_mp_state(&self, vcpu_id: usize) -> Result<MPState>229*bb4ee6a4SAndroid Build Coastguard Worker fn get_mp_state(&self, vcpu_id: usize) -> Result<MPState>; 230*bb4ee6a4SAndroid Build Coastguard Worker 231*bb4ee6a4SAndroid Build Coastguard Worker /// Set the current MP state of the specified VCPU. set_mp_state(&mut self, vcpu_id: usize, state: &MPState) -> Result<()>232*bb4ee6a4SAndroid Build Coastguard Worker fn set_mp_state(&mut self, vcpu_id: usize, state: &MPState) -> Result<()>; 233*bb4ee6a4SAndroid Build Coastguard Worker 234*bb4ee6a4SAndroid Build Coastguard Worker /// Attempt to create a shallow clone of this IrqChip instance. try_clone(&self) -> Result<Self> where Self: Sized235*bb4ee6a4SAndroid Build Coastguard Worker fn try_clone(&self) -> Result<Self> 236*bb4ee6a4SAndroid Build Coastguard Worker where 237*bb4ee6a4SAndroid Build Coastguard Worker Self: Sized; 238*bb4ee6a4SAndroid Build Coastguard Worker 239*bb4ee6a4SAndroid Build Coastguard Worker /// Finalize irqchip setup. Should be called once all devices have registered irq events and 240*bb4ee6a4SAndroid Build Coastguard Worker /// been added to the io_bus and mmio_bus. finalize_devices( &mut self, resources: &mut SystemAllocator, io_bus: &Bus, mmio_bus: &Bus, ) -> Result<()>241*bb4ee6a4SAndroid Build Coastguard Worker fn finalize_devices( 242*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 243*bb4ee6a4SAndroid Build Coastguard Worker resources: &mut SystemAllocator, 244*bb4ee6a4SAndroid Build Coastguard Worker io_bus: &Bus, 245*bb4ee6a4SAndroid Build Coastguard Worker mmio_bus: &Bus, 246*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()>; 247*bb4ee6a4SAndroid Build Coastguard Worker 248*bb4ee6a4SAndroid Build Coastguard Worker /// Process any irqs events that were delayed because of any locking issues. process_delayed_irq_events(&mut self) -> Result<()>249*bb4ee6a4SAndroid Build Coastguard Worker fn process_delayed_irq_events(&mut self) -> Result<()>; 250*bb4ee6a4SAndroid Build Coastguard Worker 251*bb4ee6a4SAndroid Build Coastguard Worker /// Return an event which is meant to trigger process of any irqs events that were delayed 252*bb4ee6a4SAndroid Build Coastguard Worker /// by calling process_delayed_irq_events(). This should be used by the main thread to wait 253*bb4ee6a4SAndroid Build Coastguard Worker /// for delayed irq event kick. It is process_delayed_irq_events() responsibility to read 254*bb4ee6a4SAndroid Build Coastguard Worker /// the event as long as there is no more irqs to be serviced. irq_delayed_event_token(&self) -> Result<Option<Event>>255*bb4ee6a4SAndroid Build Coastguard Worker fn irq_delayed_event_token(&self) -> Result<Option<Event>>; 256*bb4ee6a4SAndroid Build Coastguard Worker 257*bb4ee6a4SAndroid Build Coastguard Worker /// Checks if a particular `IrqChipCap` is available. check_capability(&self, c: IrqChipCap) -> bool258*bb4ee6a4SAndroid Build Coastguard Worker fn check_capability(&self, c: IrqChipCap) -> bool; 259*bb4ee6a4SAndroid Build Coastguard Worker } 260*bb4ee6a4SAndroid Build Coastguard Worker 261*bb4ee6a4SAndroid Build Coastguard Worker /// A capability the `IrqChip` can possibly expose. 262*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq)] 263*bb4ee6a4SAndroid Build Coastguard Worker pub enum IrqChipCap { 264*bb4ee6a4SAndroid Build Coastguard Worker /// APIC TSC-deadline timer mode. 265*bb4ee6a4SAndroid Build Coastguard Worker TscDeadlineTimer, 266*bb4ee6a4SAndroid Build Coastguard Worker /// Extended xAPIC (x2APIC) standard. 267*bb4ee6a4SAndroid Build Coastguard Worker X2Apic, 268*bb4ee6a4SAndroid Build Coastguard Worker /// Irqchip exposes mp_state_get/set methods. Calling these methods on chips 269*bb4ee6a4SAndroid Build Coastguard Worker /// without this capability will result in undefined behavior. 270*bb4ee6a4SAndroid Build Coastguard Worker MpStateGetSet, 271*bb4ee6a4SAndroid Build Coastguard Worker } 272*bb4ee6a4SAndroid Build Coastguard Worker 273*bb4ee6a4SAndroid Build Coastguard Worker /// A capability the `IrqChip` can possibly expose. 274*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Copy, Debug, PartialEq, Eq)] 275*bb4ee6a4SAndroid Build Coastguard Worker pub enum VcpuRunState { 276*bb4ee6a4SAndroid Build Coastguard Worker Runnable, 277*bb4ee6a4SAndroid Build Coastguard Worker Interrupted, 278*bb4ee6a4SAndroid Build Coastguard Worker } 279