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