xref: /aosp_15_r20/external/crosvm/devices/src/irqchip/mod.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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