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 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