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 /// Failed creating GIC device. 28 CreateGic(hypervisor::HypervisorVmError), 29 } 30 31 type Result<T> = result::Result<T, Error>; 32 33 pub struct MsiMessage { 34 // Message Address Register 35 // 31-20: Base address. Fixed value (0x0FEE) 36 // 19-12: Destination ID 37 // 11-4: Reserved 38 // 3: Redirection Hint indication 39 // 2: Destination Mode 40 // 1-0: Reserved 41 pub addr: u32, 42 // Message Data Register 43 // 32-16: Reserved 44 // 15: Trigger Mode. 0 = Edge, 1 = Level 45 // 14: Level. 0 = Deassert, 1 = Assert 46 // 13-11: Reserved 47 // 10-8: Delivery Mode 48 // 7-0: Vector 49 pub data: u32, 50 } 51 52 // Introduce trait InterruptController to uniform the interrupt 53 // service provided for devices. 54 // Device manager uses this trait without caring whether it is a 55 // IOAPIC (X86) or GIC (Arm). 56 pub trait InterruptController: Send { 57 fn service_irq(&mut self, irq: usize) -> Result<()>; 58 #[cfg(target_arch = "aarch64")] 59 fn enable(&self) -> Result<()>; 60 #[cfg(target_arch = "x86_64")] 61 fn end_of_interrupt(&mut self, vec: u8); 62 fn notifier(&self, irq: usize) -> Option<EventFd>; 63 } 64