vmm/devices/legacy/
mod.rs

1// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
5// Use of this source code is governed by a BSD-style license that can be
6// found in the THIRD-PARTY file.
7
8//! Implements legacy devices (UART, RTC etc).
9mod i8042;
10#[cfg(target_arch = "aarch64")]
11pub mod rtc_pl031;
12pub mod serial;
13
14use std::io;
15use std::ops::Deref;
16
17use serde::Serializer;
18use serde::ser::SerializeMap;
19use vm_superio::Trigger;
20use vmm_sys_util::eventfd::EventFd;
21
22pub use self::i8042::{I8042Device, I8042Error as I8042DeviceError};
23#[cfg(target_arch = "aarch64")]
24pub use self::rtc_pl031::RTCDevice;
25pub use self::serial::{
26    IER_RDA_BIT, IER_RDA_OFFSET, SerialDevice, SerialEventsWrapper, SerialWrapper,
27};
28
29/// Wrapper for implementing the trigger functionality for `EventFd`.
30///
31/// The trigger is used for handling events in the legacy devices.
32#[derive(Debug)]
33pub struct EventFdTrigger(EventFd);
34
35impl Trigger for EventFdTrigger {
36    type E = io::Error;
37
38    fn trigger(&self) -> io::Result<()> {
39        self.write(1)
40    }
41}
42
43impl Deref for EventFdTrigger {
44    type Target = EventFd;
45    fn deref(&self) -> &Self::Target {
46        &self.0
47    }
48}
49
50impl EventFdTrigger {
51    /// Clone an `EventFdTrigger`.
52    pub fn try_clone(&self) -> io::Result<Self> {
53        Ok(EventFdTrigger((**self).try_clone()?))
54    }
55
56    /// Create an `EventFdTrigger`.
57    pub fn new(evt: EventFd) -> Self {
58        Self(evt)
59    }
60
61    /// Get the associated event fd out of an `EventFdTrigger`.
62    pub fn get_event(&self) -> EventFd {
63        self.0.try_clone().unwrap()
64    }
65}
66
67/// Called by METRICS.flush(), this function facilitates serialization of aggregated metrics.
68pub fn flush_metrics<S: Serializer>(serializer: S) -> Result<S::Ok, S::Error> {
69    let mut seq = serializer.serialize_map(Some(1))?;
70    seq.serialize_entry("i8042", &i8042::METRICS)?;
71    #[cfg(target_arch = "aarch64")]
72    seq.serialize_entry("rtc", &rtc_pl031::METRICS)?;
73    seq.serialize_entry("uart", &serial::METRICS)?;
74    seq.end()
75}