1e8c330e2SRuoqing He // Copyright © 2024 Institute of Software, CAS. All rights reserved. 2b32d3025SMichael Zhao // Copyright 2020, ARM Limited. 3b32d3025SMichael Zhao // 4b32d3025SMichael Zhao // SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause 5b32d3025SMichael Zhao 661e57e1cSRuoqing He use std::{io, result}; 788a9f799SRob Bradford 889b429c7SSamrutGadde use thiserror::Error; 93bd47ffdSSebastien Boeuf use vmm_sys_util::eventfd::EventFd; 10b32d3025SMichael Zhao 1189b429c7SSamrutGadde #[derive(Debug, Error)] 12b32d3025SMichael Zhao pub enum Error { 13b32d3025SMichael Zhao /// Invalid trigger mode. 1489b429c7SSamrutGadde #[error("Invalid trigger mode")] 15b32d3025SMichael Zhao InvalidTriggerMode, 16b32d3025SMichael Zhao /// Invalid delivery mode. 1789b429c7SSamrutGadde #[error("Invalid delivery mode")] 18b32d3025SMichael Zhao InvalidDeliveryMode, 19b32d3025SMichael Zhao /// Failed creating the interrupt source group. 20*1b91aa8eSPhilipp Schuster #[error("Failed creating the interrupt source group")] 2193b599e5SPhilipp Schuster CreateInterruptSourceGroup(#[source] io::Error), 22b32d3025SMichael Zhao /// Failed triggering the interrupt. 23*1b91aa8eSPhilipp Schuster #[error("Failed triggering the interrupt")] 2493b599e5SPhilipp Schuster TriggerInterrupt(#[source] io::Error), 25b32d3025SMichael Zhao /// Failed masking the interrupt. 26*1b91aa8eSPhilipp Schuster #[error("Failed masking the interrupt")] 2793b599e5SPhilipp Schuster MaskInterrupt(#[source] io::Error), 28b32d3025SMichael Zhao /// Failed unmasking the interrupt. 29*1b91aa8eSPhilipp Schuster #[error("Failed unmasking the interrupt")] 3093b599e5SPhilipp Schuster UnmaskInterrupt(#[source] io::Error), 31b32d3025SMichael Zhao /// Failed updating the interrupt. 32*1b91aa8eSPhilipp Schuster #[error("Failed updating the interrupt")] 3393b599e5SPhilipp Schuster UpdateInterrupt(#[source] io::Error), 34b32d3025SMichael Zhao /// Failed enabling the interrupt. 35*1b91aa8eSPhilipp Schuster #[error("Failed enabling the interrupt")] 3693b599e5SPhilipp Schuster EnableInterrupt(#[source] io::Error), 37b173f6f6SMichael Zhao #[cfg(target_arch = "aarch64")] 38957d3a74SMichael Zhao /// Failed creating GIC device. 39*1b91aa8eSPhilipp Schuster #[error("Failed creating GIC device")] 40ab575a54SPhilipp Schuster CreateGic(#[source] hypervisor::HypervisorVmError), 41b173f6f6SMichael Zhao #[cfg(target_arch = "aarch64")] 42b173f6f6SMichael Zhao /// Failed restoring GIC device. 43*1b91aa8eSPhilipp Schuster #[error("Failed restoring GIC device")] 44ab575a54SPhilipp Schuster RestoreGic(#[source] hypervisor::arch::aarch64::gic::Error), 45e8c330e2SRuoqing He #[cfg(target_arch = "riscv64")] 46e8c330e2SRuoqing He /// Failed creating AIA device. 47*1b91aa8eSPhilipp Schuster #[error("Failed creating AIA device")] 48ab575a54SPhilipp Schuster CreateAia(#[source] hypervisor::HypervisorVmError), 49e8c330e2SRuoqing He #[cfg(target_arch = "riscv64")] 50e8c330e2SRuoqing He /// Failed restoring AIA device. 51*1b91aa8eSPhilipp Schuster #[error("Failed restoring AIA device")] 52ab575a54SPhilipp Schuster RestoreAia(#[source] hypervisor::arch::riscv64::aia::Error), 53b32d3025SMichael Zhao } 54b32d3025SMichael Zhao 55b32d3025SMichael Zhao type Result<T> = result::Result<T, Error>; 56b32d3025SMichael Zhao 57b32d3025SMichael Zhao pub struct MsiMessage { 58b32d3025SMichael Zhao // Message Address Register 59b32d3025SMichael Zhao // 31-20: Base address. Fixed value (0x0FEE) 60b32d3025SMichael Zhao // 19-12: Destination ID 61b32d3025SMichael Zhao // 11-4: Reserved 62b32d3025SMichael Zhao // 3: Redirection Hint indication 63b32d3025SMichael Zhao // 2: Destination Mode 64b32d3025SMichael Zhao // 1-0: Reserved 65b32d3025SMichael Zhao pub addr: u32, 66b32d3025SMichael Zhao // Message Data Register 67b32d3025SMichael Zhao // 32-16: Reserved 68b32d3025SMichael Zhao // 15: Trigger Mode. 0 = Edge, 1 = Level 69b32d3025SMichael Zhao // 14: Level. 0 = Deassert, 1 = Assert 70b32d3025SMichael Zhao // 13-11: Reserved 71b32d3025SMichael Zhao // 10-8: Delivery Mode 72b32d3025SMichael Zhao // 7-0: Vector 73b32d3025SMichael Zhao pub data: u32, 74b32d3025SMichael Zhao } 75b32d3025SMichael Zhao 76b32d3025SMichael Zhao // Introduce trait InterruptController to uniform the interrupt 77b32d3025SMichael Zhao // service provided for devices. 78b32d3025SMichael Zhao // Device manager uses this trait without caring whether it is a 79e8c330e2SRuoqing He // IOAPIC (X86), GIC (Arm) or AIA (RISC-V). 80b32d3025SMichael Zhao pub trait InterruptController: Send { service_irq(&mut self, irq: usize) -> Result<()>81b32d3025SMichael Zhao fn service_irq(&mut self, irq: usize) -> Result<()>; 828f1f9d9eSMichael Zhao #[cfg(target_arch = "x86_64")] end_of_interrupt(&mut self, vec: u8)83b32d3025SMichael Zhao fn end_of_interrupt(&mut self, vec: u8); notifier(&self, irq: usize) -> Option<EventFd>843bd47ffdSSebastien Boeuf fn notifier(&self, irq: usize) -> Option<EventFd>; 85b32d3025SMichael Zhao } 86