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: {0}")] 21 CreateInterruptSourceGroup(#[source] io::Error), 22 /// Failed triggering the interrupt. 23 #[error("Failed triggering the interrupt: {0}")] 24 TriggerInterrupt(#[source] io::Error), 25 /// Failed masking the interrupt. 26 #[error("Failed masking the interrupt: {0}")] 27 MaskInterrupt(#[source] io::Error), 28 /// Failed unmasking the interrupt. 29 #[error("Failed unmasking the interrupt: {0}")] 30 UnmaskInterrupt(#[source] io::Error), 31 /// Failed updating the interrupt. 32 #[error("Failed updating the interrupt: {0}")] 33 UpdateInterrupt(#[source] io::Error), 34 /// Failed enabling the interrupt. 35 #[error("Failed enabling the interrupt: {0}")] 36 EnableInterrupt(#[source] io::Error), 37 #[cfg(target_arch = "aarch64")] 38 /// Failed creating GIC device. 39 #[error("Failed creating GIC device: {0}")] 40 CreateGic(#[source] hypervisor::HypervisorVmError), 41 #[cfg(target_arch = "aarch64")] 42 /// Failed restoring GIC device. 43 #[error("Failed restoring GIC device: {0}")] 44 RestoreGic(#[source] hypervisor::arch::aarch64::gic::Error), 45 #[cfg(target_arch = "riscv64")] 46 /// Failed creating AIA device. 47 #[error("Failed creating AIA device: {0}")] 48 CreateAia(#[source] hypervisor::HypervisorVmError), 49 #[cfg(target_arch = "riscv64")] 50 /// Failed restoring AIA device. 51 #[error("Failed restoring AIA device: {0}")] 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 { 81 fn service_irq(&mut self, irq: usize) -> Result<()>; 82 #[cfg(target_arch = "x86_64")] 83 fn end_of_interrupt(&mut self, vec: u8); 84 fn notifier(&self, irq: usize) -> Option<EventFd>; 85 } 86