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