summary refs log blame commit diff
path: root/devices/src/split_irqchip_common.rs
blob: 1e513f24bb0afdb31b86c31c3b834914efecb8c8 (plain) (tree)
1
2
3
4
5
6
7
8
9






                                                                                      
                      
 

                                        




                          

                                        




                      

                                        
                       







                                                                



                                 
                              
                        

                                      








                                                                                   
                           
                      

                                

                        

                         

                          
































                                                                                                
// 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<EventFd>; kvm::NUM_IOAPIC_PINS],
    pub irqfd_resample: [Option<EventFd>; 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);
    }
}