devices: Create Interrupt trait to abstract interrupt delivery

This commit anticipate the future need from having support for both
in kernel and userspace IOAPIC. The way to signal an interrupt from
the serial device will vary depending on the use case, but this should
be independent from the serial implementation itself.

That's why this patch provides a generic trait for the serial device
to call from, so that it can trigger interrupts independently from the
IOAPIC type chosen (in kernel vs userspace).

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2019-06-11 10:49:19 -07:00
committed by Samuel Ortiz
parent 2a7fbe8eae
commit c8c4a4d444
3 changed files with 41 additions and 23 deletions

View File

@@ -5,12 +5,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
use crate::{BusDevice, Interrupt};
use std::collections::VecDeque;
use std::{io, result};
use vmm_sys_util::{EventFd, Result};
use BusDevice;
use vmm_sys_util::Result;
const LOOP_SIZE: usize = 0x40;
@@ -57,7 +55,7 @@ const DEFAULT_BAUD_DIVISOR: u16 = 12; // 9600 bps
pub struct Serial {
interrupt_enable: u8,
interrupt_identification: u8,
interrupt_evt: EventFd,
interrupt: Box<Interrupt>,
line_control: u8,
line_status: u8,
modem_control: u8,
@@ -69,11 +67,11 @@ pub struct Serial {
}
impl Serial {
fn new(interrupt_evt: EventFd, out: Option<Box<io::Write + Send>>) -> Serial {
fn new(interrupt: Box<Interrupt>, out: Option<Box<io::Write + Send>>) -> Serial {
Serial {
interrupt_enable: 0,
interrupt_identification: DEFAULT_INTERRUPT_IDENTIFICATION,
interrupt_evt,
interrupt,
line_control: DEFAULT_LINE_CONTROL,
line_status: DEFAULT_LINE_STATUS,
modem_control: DEFAULT_MODEM_CONTROL,
@@ -86,13 +84,13 @@ impl Serial {
}
/// Constructs a Serial port ready for output.
pub fn new_out(interrupt_evt: EventFd, out: Box<io::Write + Send>) -> Serial {
Self::new(interrupt_evt, Some(out))
pub fn new_out(interrupt: Box<Interrupt>, out: Box<io::Write + Send>) -> Serial {
Self::new(interrupt, Some(out))
}
/// Constructs a Serial port with no connected output.
pub fn new_sink(interrupt_evt: EventFd) -> Serial {
Self::new(interrupt_evt, None)
pub fn new_sink(interrupt: Box<Interrupt>) -> Serial {
Self::new(interrupt, None)
}
/// Queues raw bytes for the guest to read and signals the interrupt if the line status would
@@ -151,7 +149,7 @@ impl Serial {
}
fn trigger_interrupt(&mut self) -> result::Result<(), io::Error> {
self.interrupt_evt.write(1)
self.interrupt.deliver()
}
fn iir_reset(&mut self) {

View File

@@ -14,7 +14,7 @@ extern crate vm_memory;
extern crate vmm_sys_util;
use std::fs::File;
use std::io;
use std::{io, result};
mod bus;
pub mod legacy;
@@ -58,3 +58,7 @@ pub enum Error {
},
IoError(io::Error),
}
pub trait Interrupt: Send {
fn deliver(&self) -> result::Result<(), std::io::Error>;
}