// Copyright 2019 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Common constants and types used for Split IRQ chip devices (e.g. PIC, PIT, IOAPIC). use bit_field::*; use sys_util::EventFd; #[bitfield] #[derive(Clone, Copy, Debug, PartialEq)] pub enum DestinationMode { Physical = 0, Logical = 1, } #[bitfield] #[derive(Clone, Copy, Debug, PartialEq)] pub enum TriggerMode { Edge = 0, Level = 1, } #[bitfield] #[derive(Debug, Clone, Copy, PartialEq)] pub enum DeliveryMode { Fixed = 0b000, Lowest = 0b001, SMI = 0b010, // System management interrupt RemoteRead = 0b011, // This is no longer supported by intel. NMI = 0b100, // Non maskable interrupt Init = 0b101, Startup = 0b110, External = 0b111, } #[bitfield] #[derive(Clone, Copy, PartialEq)] pub struct MsiAddressMessage { reserved: BitField2, #[bits = 1] destination_mode: DestinationMode, redirection_hint: BitField1, reserved_2: BitField8, destination_id: BitField8, // According to Intel's implementation of MSI, these bits must always be 0xfee. always_0xfee: BitField12, } #[bitfield] #[derive(Clone, Copy, PartialEq)] pub struct MsiDataMessage { vector: BitField8, #[bits = 3] delivery_mode: DeliveryMode, reserved: BitField3, level: BitField1, #[bits = 1] trigger: TriggerMode, reserved2: BitField16, } /// Acts as a relay of interrupt signals between devices and IRQ chips. #[derive(Default)] pub struct GsiRelay { pub irqfd: [Option; kvm::NUM_IOAPIC_PINS], pub irqfd_resample: [Option; kvm::NUM_IOAPIC_PINS], } impl GsiRelay { pub fn new() -> GsiRelay { GsiRelay { irqfd: Default::default(), irqfd_resample: Default::default(), } } pub fn register_irqfd(&mut self, evt: EventFd, gsi: usize) { if gsi >= kvm::NUM_IOAPIC_PINS { // Invalid gsi; ignore. return; } self.irqfd[gsi] = Some(evt); } pub fn register_irqfd_resample(&mut self, evt: EventFd, resample_evt: EventFd, gsi: usize) { if gsi >= kvm::NUM_IOAPIC_PINS { // Invalid gsi; ignore. return; } self.irqfd[gsi] = Some(evt); self.irqfd_resample[gsi] = Some(resample_evt); } }