xref: /cloud-hypervisor/devices/src/interrupt_controller.rs (revision 5e52729453cb62edbe4fb3a4aa24f8cca31e667e)
1 // Copyright 2020, ARM Limited.
2 //
3 // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
4 
5 use std::io;
6 use std::result;
7 use vmm_sys_util::eventfd::EventFd;
8 
9 #[derive(Debug)]
10 pub enum Error {
11     /// Invalid trigger mode.
12     InvalidTriggerMode,
13     /// Invalid delivery mode.
14     InvalidDeliveryMode,
15     /// Failed creating the interrupt source group.
16     CreateInterruptSourceGroup(io::Error),
17     /// Failed triggering the interrupt.
18     TriggerInterrupt(io::Error),
19     /// Failed masking the interrupt.
20     MaskInterrupt(io::Error),
21     /// Failed unmasking the interrupt.
22     UnmaskInterrupt(io::Error),
23     /// Failed updating the interrupt.
24     UpdateInterrupt(io::Error),
25     /// Failed enabling the interrupt.
26     EnableInterrupt(io::Error),
27     #[cfg(target_arch = "aarch64")]
28     /// Failed creating GIC device.
29     CreateGic(hypervisor::HypervisorVmError),
30     #[cfg(target_arch = "aarch64")]
31     /// Failed restoring GIC device.
32     RestoreGic(hypervisor::arch::aarch64::gic::Error),
33 }
34 
35 type Result<T> = result::Result<T, Error>;
36 
37 pub struct MsiMessage {
38     // Message Address Register
39     //   31-20: Base address. Fixed value (0x0FEE)
40     //   19-12: Destination ID
41     //   11-4:  Reserved
42     //   3:     Redirection Hint indication
43     //   2:     Destination Mode
44     //   1-0:   Reserved
45     pub addr: u32,
46     // Message Data Register
47     //   32-16: Reserved
48     //   15:    Trigger Mode. 0 = Edge, 1 = Level
49     //   14:    Level. 0 = Deassert, 1 = Assert
50     //   13-11: Reserved
51     //   10-8:  Delivery Mode
52     //   7-0:   Vector
53     pub data: u32,
54 }
55 
56 // Introduce trait InterruptController to uniform the interrupt
57 // service provided for devices.
58 // Device manager uses this trait without caring whether it is a
59 // IOAPIC (X86) or GIC (Arm).
60 pub trait InterruptController: Send {
61     fn service_irq(&mut self, irq: usize) -> Result<()>;
62     #[cfg(target_arch = "x86_64")]
63     fn end_of_interrupt(&mut self, vec: u8);
64     fn notifier(&self, irq: usize) -> Option<EventFd>;
65 }
66