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