vm_superio/
serial.rs

1// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2//
3// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the THIRD-PARTY file.
6//
7// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
8
9//! Provides emulation for Linux serial console.
10//!
11//! This is done by emulating an UART serial port.
12
13use std::collections::VecDeque;
14use std::error::Error as StdError;
15use std::fmt;
16use std::io::{self, Write};
17use std::result::Result;
18use std::sync::Arc;
19
20use crate::Trigger;
21
22// Register offsets.
23// Receiver and Transmitter registers offset, depending on the I/O
24// access type: write -> THR, read -> RBR.
25const DATA_OFFSET: u8 = 0;
26const IER_OFFSET: u8 = 1;
27const IIR_OFFSET: u8 = 2;
28const LCR_OFFSET: u8 = 3;
29const MCR_OFFSET: u8 = 4;
30const LSR_OFFSET: u8 = 5;
31const MSR_OFFSET: u8 = 6;
32const SCR_OFFSET: u8 = 7;
33const DLAB_LOW_OFFSET: u8 = 0;
34const DLAB_HIGH_OFFSET: u8 = 1;
35
36const FIFO_SIZE: usize = 0x40;
37
38// Received Data Available interrupt - for letting the driver know that
39// there is some pending data to be processed.
40const IER_RDA_BIT: u8 = 0b0000_0001;
41// Transmitter Holding Register Empty interrupt - for letting the driver
42// know that the entire content of the output buffer was sent.
43const IER_THR_EMPTY_BIT: u8 = 0b0000_0010;
44// The interrupts that are available on 16550 and older models.
45const IER_UART_VALID_BITS: u8 = 0b0000_1111;
46
47//FIFO enabled.
48const IIR_FIFO_BITS: u8 = 0b1100_0000;
49const IIR_NONE_BIT: u8 = 0b0000_0001;
50const IIR_THR_EMPTY_BIT: u8 = 0b0000_0010;
51const IIR_RDA_BIT: u8 = 0b0000_0100;
52
53const LCR_DLAB_BIT: u8 = 0b1000_0000;
54
55const LSR_DATA_READY_BIT: u8 = 0b0000_0001;
56// These two bits help the driver know if the device is ready to accept
57// another character.
58// THR is empty.
59const LSR_EMPTY_THR_BIT: u8 = 0b0010_0000;
60// The shift register, which takes a byte from THR and breaks it in bits
61// for sending them on the line, is empty.
62const LSR_IDLE_BIT: u8 = 0b0100_0000;
63
64// The following five MCR bits allow direct manipulation of the device and
65// are available on 16550 and older models.
66// Data Terminal Ready.
67const MCR_DTR_BIT: u8 = 0b0000_0001;
68// Request To Send.
69const MCR_RTS_BIT: u8 = 0b0000_0010;
70// Auxiliary Output 1.
71const MCR_OUT1_BIT: u8 = 0b0000_0100;
72// Auxiliary Output 2.
73const MCR_OUT2_BIT: u8 = 0b0000_1000;
74// Loopback Mode.
75const MCR_LOOP_BIT: u8 = 0b0001_0000;
76
77// Clear To Send.
78const MSR_CTS_BIT: u8 = 0b0001_0000;
79// Data Set Ready.
80const MSR_DSR_BIT: u8 = 0b0010_0000;
81// Ring Indicator.
82const MSR_RI_BIT: u8 = 0b0100_0000;
83// Data Carrier Detect.
84const MSR_DCD_BIT: u8 = 0b1000_0000;
85
86// The following values can be used to set the baud rate to 9600 bps.
87const DEFAULT_BAUD_DIVISOR_HIGH: u8 = 0x00;
88const DEFAULT_BAUD_DIVISOR_LOW: u8 = 0x0C;
89
90// No interrupts enabled.
91const DEFAULT_INTERRUPT_ENABLE: u8 = 0x00;
92// No pending interrupt.
93const DEFAULT_INTERRUPT_IDENTIFICATION: u8 = IIR_NONE_BIT;
94// We're setting the default to include LSR_EMPTY_THR_BIT and LSR_IDLE_BIT
95// and never update those bits because we're working with a virtual device,
96// hence we should always be ready to receive more data.
97const DEFAULT_LINE_STATUS: u8 = LSR_EMPTY_THR_BIT | LSR_IDLE_BIT;
98// 8 bits word length.
99const DEFAULT_LINE_CONTROL: u8 = 0b0000_0011;
100// Most UARTs need Auxiliary Output 2 set to '1' to enable interrupts.
101const DEFAULT_MODEM_CONTROL: u8 = MCR_OUT2_BIT;
102const DEFAULT_MODEM_STATUS: u8 = MSR_DSR_BIT | MSR_CTS_BIT | MSR_DCD_BIT;
103const DEFAULT_SCRATCH: u8 = 0x00;
104
105/// Defines a series of callbacks that are invoked in response to the occurrence of specific
106/// events as part of the serial emulation logic (for example, when the driver reads data). The
107/// methods below can be implemented by a backend that keeps track of such events by incrementing
108/// metrics, logging messages, or any other action.
109///
110/// We're using a trait to avoid constraining the concrete characteristics of the backend in
111/// any way, enabling zero-cost abstractions and use case-specific implementations.
112// TODO: The events defined below are just some examples for now to validate the approach. If
113// things look good, we can move on to establishing the initial list. It's also worth mentioning
114// the methods can have extra parameters that provide additional information about the event.
115pub trait SerialEvents {
116    /// The driver reads data from the input buffer.
117    fn buffer_read(&self);
118    /// The driver successfully wrote one byte to serial output.
119    fn out_byte(&self);
120    /// An error occurred while writing a byte to serial output resulting in a lost byte.
121    fn tx_lost_byte(&self);
122    /// This event can be used by the consumer to re-enable events coming from
123    /// the serial input.
124    fn in_buffer_empty(&self);
125}
126
127/// Provides a no-op implementation of `SerialEvents` which can be used in situations that
128/// do not require logging or otherwise doing anything in response to the events defined
129/// as part of `SerialEvents`.
130#[derive(Debug, Clone, Copy)]
131pub struct NoEvents;
132
133impl SerialEvents for NoEvents {
134    fn buffer_read(&self) {}
135    fn out_byte(&self) {}
136    fn tx_lost_byte(&self) {}
137    fn in_buffer_empty(&self) {}
138}
139
140impl<EV: SerialEvents> SerialEvents for Arc<EV> {
141    fn buffer_read(&self) {
142        self.as_ref().buffer_read();
143    }
144
145    fn out_byte(&self) {
146        self.as_ref().out_byte();
147    }
148
149    fn tx_lost_byte(&self) {
150        self.as_ref().tx_lost_byte();
151    }
152
153    fn in_buffer_empty(&self) {
154        self.as_ref().in_buffer_empty();
155    }
156}
157
158/// The state of the Serial device.
159#[derive(Clone, Debug, Eq, PartialEq)]
160pub struct SerialState {
161    /// Divisor Latch Low Byte
162    pub baud_divisor_low: u8,
163    /// Divisor Latch High Byte
164    pub baud_divisor_high: u8,
165    /// Interrupt Enable Register
166    pub interrupt_enable: u8,
167    /// Interrupt Identification Register
168    pub interrupt_identification: u8,
169    /// Line Control Register
170    pub line_control: u8,
171    /// Line Status Register
172    pub line_status: u8,
173    /// Modem Control Register
174    pub modem_control: u8,
175    /// Modem Status Register
176    pub modem_status: u8,
177    /// Scratch Register
178    pub scratch: u8,
179    /// Transmitter Holding Buffer/Receiver Buffer
180    pub in_buffer: Vec<u8>,
181}
182
183impl Default for SerialState {
184    fn default() -> Self {
185        SerialState {
186            baud_divisor_low: DEFAULT_BAUD_DIVISOR_LOW,
187            baud_divisor_high: DEFAULT_BAUD_DIVISOR_HIGH,
188            interrupt_enable: DEFAULT_INTERRUPT_ENABLE,
189            interrupt_identification: DEFAULT_INTERRUPT_IDENTIFICATION,
190            line_control: DEFAULT_LINE_CONTROL,
191            line_status: DEFAULT_LINE_STATUS,
192            modem_control: DEFAULT_MODEM_CONTROL,
193            modem_status: DEFAULT_MODEM_STATUS,
194            scratch: DEFAULT_SCRATCH,
195            in_buffer: Vec::new(),
196        }
197    }
198}
199
200/// The serial console emulation is done by emulating a serial COM port.
201///
202/// Each serial COM port (COM1-4) has an associated Port I/O address base and
203/// 12 registers mapped into 8 consecutive Port I/O locations (with the first
204/// one being the base).
205/// This structure emulates the registers that make sense for UART 16550 (and below)
206/// and helps in the interaction between the driver and device by using a
207/// [`Trigger`](../trait.Trigger.html) object for notifications. It also writes the
208/// guest's output to an `out` Write object.
209///
210/// # Example
211///
212/// ```rust
213/// # use std::io::{sink, Error, Result};
214/// # use std::ops::Deref;
215/// # use vm_superio::Trigger;
216/// # use vm_superio::Serial;
217/// # use vmm_sys_util::eventfd::EventFd;
218///
219/// struct EventFdTrigger(EventFd);
220/// impl Trigger for EventFdTrigger {
221///     type E = Error;
222///
223///     fn trigger(&self) -> Result<()> {
224///         self.write(1)
225///     }
226/// }
227/// impl Deref for EventFdTrigger {
228///     type Target = EventFd;
229///     fn deref(&self) -> &Self::Target {
230///         &self.0
231///     }
232/// }
233/// impl EventFdTrigger {
234///     pub fn new(flag: i32) -> Self {
235///         EventFdTrigger(EventFd::new(flag).unwrap())
236///     }
237///     pub fn try_clone(&self) -> Self {
238///         EventFdTrigger((**self).try_clone().unwrap())
239///     }
240/// }
241///
242/// let intr_evt = EventFdTrigger::new(libc::EFD_NONBLOCK);
243/// let mut serial = Serial::new(intr_evt.try_clone(), Vec::new());
244/// // std::io::Sink can be used if user is not interested in guest's output.
245/// let serial_with_sink = Serial::new(intr_evt, sink());
246///
247/// // Write 0x01 to THR register.
248/// serial.write(0, 0x01).unwrap();
249/// // Read from RBR register.
250/// let value = serial.read(0);
251///
252/// // Send more bytes to the guest in one shot.
253/// let input = &[b'a', b'b', b'c'];
254/// // Before enqueuing bytes we first check if there is enough free space
255/// // in the FIFO.
256/// if serial.fifo_capacity() >= input.len() {
257///     serial.enqueue_raw_bytes(input).unwrap();
258/// }
259/// ```
260#[derive(Debug)]
261pub struct Serial<T: Trigger, EV: SerialEvents, W: Write> {
262    // Some UART registers.
263    baud_divisor_low: u8,
264    baud_divisor_high: u8,
265    interrupt_enable: u8,
266    interrupt_identification: u8,
267    line_control: u8,
268    line_status: u8,
269    modem_control: u8,
270    modem_status: u8,
271    scratch: u8,
272    // This is the buffer that is used for achieving the Receiver register
273    // functionality in FIFO mode. Reading from RBR will return the oldest
274    // unread byte from the RX FIFO.
275    in_buffer: VecDeque<u8>,
276
277    // Used for notifying the driver about some in/out events.
278    interrupt_evt: T,
279    events: EV,
280    out: W,
281}
282
283/// Errors encountered while handling serial console operations.
284#[derive(Debug)]
285pub enum Error<E> {
286    /// Failed to trigger interrupt.
287    Trigger(E),
288    /// Couldn't write/flush to the given destination.
289    IOError(io::Error),
290    /// No space left in FIFO.
291    FullFifo,
292}
293
294impl<E: fmt::Display> fmt::Display for Error<E> {
295    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
296        match self {
297            Error::Trigger(e) => write!(f, "Failed to trigger interrupt: {e}"),
298            Error::IOError(e) => write!(f, "Couldn't write/flush to the given destination: {e}"),
299            Error::FullFifo => write!(f, "No space left in FIFO"),
300        }
301    }
302}
303
304impl<E: StdError> StdError for Error<E> {}
305
306impl<T: Trigger, W: Write> Serial<T, NoEvents, W> {
307    /// Creates a new `Serial` instance which writes the guest's output to
308    /// `out` and uses `trigger` object to notify the driver about new
309    /// events.
310    ///
311    /// # Arguments
312    /// * `trigger` - The Trigger object that will be used to notify the driver
313    ///   about events.
314    /// * `out` - An object for writing guest's output to. In case the output
315    ///   is not of interest,
316    ///   [std::io::Sink](https://doc.rust-lang.org/std/io/struct.Sink.html)
317    ///   can be used here.
318    ///
319    /// # Example
320    ///
321    /// You can see an example of how to use this function in the
322    /// [`Example` section from `Serial`](struct.Serial.html#example).
323    pub fn new(trigger: T, out: W) -> Serial<T, NoEvents, W> {
324        Self::with_events(trigger, NoEvents, out)
325    }
326}
327
328impl<T: Trigger, EV: SerialEvents, W: Write> Serial<T, EV, W> {
329    /// Creates a new `Serial` instance from a given `state`, which writes the guest's output to
330    /// `out`, uses `trigger` object to notify the driver about new
331    /// events, and invokes the `serial_evts` implementation of `SerialEvents`
332    /// during operation.
333    /// For creating the instance from a default state, [`with_events`](#method.with_events) method
334    /// can be used.
335    ///
336    /// # Arguments
337    /// * `state` - A reference to the state from which the `Serial` is constructed.
338    /// * `trigger` - The `Trigger` object that will be used to notify the driver
339    ///   about events.
340    /// * `serial_evts` - The `SerialEvents` implementation used to track the occurrence
341    ///   of significant events in the serial operation logic.
342    /// * `out` - An object for writing guest's output to. In case the output
343    ///   is not of interest,
344    ///   [std::io::Sink](https://doc.rust-lang.org/std/io/struct.Sink.html)
345    ///   can be used here.
346    pub fn from_state(
347        state: &SerialState,
348        trigger: T,
349        serial_evts: EV,
350        out: W,
351    ) -> Result<Self, Error<T::E>> {
352        if state.in_buffer.len() > FIFO_SIZE {
353            return Err(Error::FullFifo);
354        }
355
356        let mut serial = Serial {
357            baud_divisor_low: state.baud_divisor_low,
358            baud_divisor_high: state.baud_divisor_high,
359            interrupt_enable: state.interrupt_enable,
360            interrupt_identification: state.interrupt_identification,
361            line_control: state.line_control,
362            line_status: state.line_status,
363            modem_control: state.modem_control,
364            modem_status: state.modem_status,
365            scratch: state.scratch,
366            in_buffer: VecDeque::from(state.in_buffer.clone()),
367            interrupt_evt: trigger,
368            events: serial_evts,
369            out,
370        };
371
372        if serial.is_thr_interrupt_enabled() && serial.is_thr_interrupt_set() {
373            serial.trigger_interrupt().map_err(Error::Trigger)?;
374        }
375        if serial.is_rda_interrupt_enabled() && serial.is_rda_interrupt_set() {
376            serial.trigger_interrupt().map_err(Error::Trigger)?;
377        }
378
379        Ok(serial)
380    }
381
382    /// Creates a new `Serial` instance from the default state, which writes the guest's output to
383    /// `out`, uses `trigger` object to notify the driver about new
384    /// events, and invokes the `serial_evts` implementation of `SerialEvents`
385    /// during operation.
386    ///
387    /// # Arguments
388    /// * `trigger` - The `Trigger` object that will be used to notify the driver
389    ///   about events.
390    /// * `serial_evts` - The `SerialEvents` implementation used to track the occurrence
391    ///   of significant events in the serial operation logic.
392    /// * `out` - An object for writing guest's output to. In case the output
393    ///   is not of interest,
394    ///   [std::io::Sink](https://doc.rust-lang.org/std/io/struct.Sink.html)
395    ///   can be used here.
396    pub fn with_events(trigger: T, serial_evts: EV, out: W) -> Self {
397        // Safe because we are using the default state that has an appropriately size input buffer
398        // and there are no pending interrupts to be triggered.
399        Self::from_state(&SerialState::default(), trigger, serial_evts, out).unwrap()
400    }
401
402    /// Returns the state of the Serial.
403    pub fn state(&self) -> SerialState {
404        SerialState {
405            baud_divisor_low: self.baud_divisor_low,
406            baud_divisor_high: self.baud_divisor_high,
407            interrupt_enable: self.interrupt_enable,
408            interrupt_identification: self.interrupt_identification,
409            line_control: self.line_control,
410            line_status: self.line_status,
411            modem_control: self.modem_control,
412            modem_status: self.modem_status,
413            scratch: self.scratch,
414            in_buffer: Vec::from(self.in_buffer.clone()),
415        }
416    }
417
418    /// Gets a reference to the output Write object
419    ///
420    /// ```rust
421    /// # use vm_superio::Trigger;
422    /// # use vm_superio::serial::Serial;
423    /// # struct DummyTrigger;
424    /// # impl Trigger for DummyTrigger {
425    /// #     type E = ();
426    /// #     fn trigger(&self) -> Result<(), ()> { Ok(()) }
427    /// # }
428    /// const DATA_OFFSET: u8 = 0;
429    ///
430    /// let output = Vec::new();
431    /// let mut serial = Serial::new(DummyTrigger, output);
432    /// serial.write(DATA_OFFSET, 0x66).unwrap();
433    /// assert_eq!(serial.writer().first().copied(), Some(0x66));
434    /// ```
435    pub fn writer(&self) -> &W {
436        &self.out
437    }
438
439    /// Gets a mutable reference to the output Write object
440    ///
441    /// ```rust
442    /// # use vm_superio::Trigger;
443    /// # use vm_superio::serial::Serial;
444    /// # struct DummyTrigger;
445    /// # impl Trigger for DummyTrigger {
446    /// #     type E = ();
447    /// #     fn trigger(&self) -> Result<(), ()> { Ok(()) }
448    /// # }
449    /// const DATA_OFFSET: u8 = 0;
450    ///
451    /// let output = Vec::new();
452    /// let mut serial = Serial::new(DummyTrigger, output);
453    /// serial.write(DATA_OFFSET, 0x66).unwrap();
454    /// serial.writer_mut().clear();
455    /// assert_eq!(serial.writer().first(), None);
456    /// ```
457    pub fn writer_mut(&mut self) -> &mut W {
458        &mut self.out
459    }
460
461    /// Consumes the device and retrieves the inner writer. This
462    /// can be useful when restoring a copy of the device.
463    ///
464    /// ```rust
465    /// # use vm_superio::Trigger;
466    /// # use vm_superio::serial::{NoEvents, Serial};
467    /// # struct DummyTrigger;
468    /// # impl Trigger for DummyTrigger {
469    /// #    type E = ();
470    /// #    fn trigger(&self) -> Result<(), ()> { Ok(()) }
471    /// # }
472    /// const DATA_OFFSET: u8 = 0;
473    ///
474    /// // Create a device with some state
475    /// let output = Vec::new();
476    /// let mut serial = Serial::new(DummyTrigger, output);
477    /// serial.write(DATA_OFFSET, 0x66).unwrap();
478    ///
479    /// // Save the state
480    /// let state = serial.state();
481    /// let output = serial.into_writer();
482    ///
483    /// // Restore the device
484    /// let restored_serial = Serial::from_state(&state, DummyTrigger, NoEvents, output).unwrap();
485    /// assert_eq!(restored_serial.writer().first().copied(), Some(0x66));
486    /// ```
487    pub fn into_writer(self) -> W {
488        self.out
489    }
490
491    /// Provides a reference to the interrupt event object.
492    pub fn interrupt_evt(&self) -> &T {
493        &self.interrupt_evt
494    }
495
496    /// Provides a reference to the serial events object.
497    pub fn events(&self) -> &EV {
498        &self.events
499    }
500
501    fn is_dlab_set(&self) -> bool {
502        (self.line_control & LCR_DLAB_BIT) != 0
503    }
504
505    fn is_rda_interrupt_enabled(&self) -> bool {
506        (self.interrupt_enable & IER_RDA_BIT) != 0
507    }
508
509    fn is_thr_interrupt_enabled(&self) -> bool {
510        (self.interrupt_enable & IER_THR_EMPTY_BIT) != 0
511    }
512
513    fn is_rda_interrupt_set(&self) -> bool {
514        (self.interrupt_identification & IIR_RDA_BIT) != 0
515    }
516
517    fn is_thr_interrupt_set(&self) -> bool {
518        (self.interrupt_identification & IIR_THR_EMPTY_BIT) != 0
519    }
520
521    fn is_in_loop_mode(&self) -> bool {
522        (self.modem_control & MCR_LOOP_BIT) != 0
523    }
524
525    fn trigger_interrupt(&mut self) -> Result<(), T::E> {
526        self.interrupt_evt.trigger()
527    }
528
529    fn set_lsr_rda_bit(&mut self) {
530        self.line_status |= LSR_DATA_READY_BIT
531    }
532
533    fn clear_lsr_rda_bit(&mut self) {
534        self.line_status &= !LSR_DATA_READY_BIT
535    }
536
537    fn add_interrupt(&mut self, interrupt_bits: u8) {
538        self.interrupt_identification &= !IIR_NONE_BIT;
539        self.interrupt_identification |= interrupt_bits;
540    }
541
542    fn del_interrupt(&mut self, interrupt_bits: u8) {
543        self.interrupt_identification &= !interrupt_bits;
544        if self.interrupt_identification == 0x00 {
545            self.interrupt_identification = IIR_NONE_BIT;
546        }
547    }
548
549    fn thr_empty_interrupt(&mut self) -> Result<(), T::E> {
550        if self.is_thr_interrupt_enabled() {
551            // Trigger the interrupt only if the identification bit wasn't
552            // set or acknowledged.
553            if self.interrupt_identification & IIR_THR_EMPTY_BIT == 0 {
554                self.add_interrupt(IIR_THR_EMPTY_BIT);
555                self.trigger_interrupt()?
556            }
557        }
558        Ok(())
559    }
560
561    fn received_data_interrupt(&mut self) -> Result<(), T::E> {
562        if self.is_rda_interrupt_enabled() {
563            // Trigger the interrupt only if the identification bit wasn't
564            // set or acknowledged.
565            if self.interrupt_identification & IIR_RDA_BIT == 0 {
566                self.add_interrupt(IIR_RDA_BIT);
567                self.trigger_interrupt()?
568            }
569        }
570        Ok(())
571    }
572
573    fn reset_iir(&mut self) {
574        self.interrupt_identification = DEFAULT_INTERRUPT_IDENTIFICATION
575    }
576
577    /// Handles a write request from the driver at `offset` offset from the
578    /// base Port I/O address.
579    ///
580    /// # Arguments
581    /// * `offset` - The offset that will be added to the base PIO address
582    ///   for writing to a specific register.
583    /// * `value` - The byte that should be written.
584    ///
585    /// # Example
586    ///
587    /// You can see an example of how to use this function in the
588    /// [`Example` section from `Serial`](struct.Serial.html#example).
589    pub fn write(&mut self, offset: u8, value: u8) -> Result<(), Error<T::E>> {
590        match offset {
591            DLAB_LOW_OFFSET if self.is_dlab_set() => self.baud_divisor_low = value,
592            DLAB_HIGH_OFFSET if self.is_dlab_set() => self.baud_divisor_high = value,
593            DATA_OFFSET => {
594                if self.is_in_loop_mode() {
595                    // In loopback mode, what is written in the transmit register
596                    // will be immediately found in the receive register, so we
597                    // simulate this behavior by adding in `in_buffer` the
598                    // transmitted bytes and letting the driver know there is some
599                    // pending data to be read, by setting RDA bit and its
600                    // corresponding interrupt.
601                    if self.in_buffer.len() < FIFO_SIZE {
602                        self.in_buffer.push_back(value);
603                        self.set_lsr_rda_bit();
604                        self.received_data_interrupt().map_err(Error::Trigger)?;
605                    }
606                } else {
607                    let res = self
608                        .out
609                        .write_all(&[value])
610                        .map_err(Error::IOError)
611                        .and_then(|_| self.out.flush().map_err(Error::IOError))
612                        .map(|_| self.events.out_byte())
613                        .inspect_err(|_| {
614                            self.events.tx_lost_byte();
615                        });
616                    // Because we cannot block the driver, the THRE interrupt is sent
617                    // irrespective of whether we are able to write the byte or not
618                    self.thr_empty_interrupt().map_err(Error::Trigger)?;
619                    return res;
620                }
621            }
622            // We want to enable only the interrupts that are available for 16550A (and below).
623            IER_OFFSET => self.interrupt_enable = value & IER_UART_VALID_BITS,
624            LCR_OFFSET => self.line_control = value,
625            MCR_OFFSET => self.modem_control = value,
626            SCR_OFFSET => self.scratch = value,
627            // We are not interested in writing to other offsets (such as FCR offset).
628            _ => {}
629        }
630        Ok(())
631    }
632
633    /// Handles a read request from the driver at `offset` offset from the
634    /// base Port I/O address.
635    ///
636    /// Returns the read value.
637    ///
638    /// # Arguments
639    /// * `offset` - The offset that will be added to the base PIO address
640    ///   for reading from a specific register.
641    ///
642    /// # Example
643    ///
644    /// You can see an example of how to use this function in the
645    /// [`Example` section from `Serial`](struct.Serial.html#example).
646    pub fn read(&mut self, offset: u8) -> u8 {
647        match offset {
648            DLAB_LOW_OFFSET if self.is_dlab_set() => self.baud_divisor_low,
649            DLAB_HIGH_OFFSET if self.is_dlab_set() => self.baud_divisor_high,
650            DATA_OFFSET => {
651                // Here we emulate the reset method for when RDA interrupt
652                // was raised (i.e. read the receive buffer and clear the
653                // interrupt identification register and RDA bit when no
654                // more data is available).
655                self.del_interrupt(IIR_RDA_BIT);
656                let byte = self.in_buffer.pop_front().unwrap_or_default();
657                if self.in_buffer.is_empty() {
658                    self.clear_lsr_rda_bit();
659                    self.events.in_buffer_empty();
660                }
661                self.events.buffer_read();
662                byte
663            }
664            IER_OFFSET => self.interrupt_enable,
665            IIR_OFFSET => {
666                // We're enabling FIFO capability by setting the serial port to 16550A:
667                // https://elixir.bootlin.com/linux/latest/source/drivers/tty/serial/8250/8250_port.c#L1299.
668                let iir = self.interrupt_identification | IIR_FIFO_BITS;
669                self.reset_iir();
670                iir
671            }
672            LCR_OFFSET => self.line_control,
673            MCR_OFFSET => self.modem_control,
674            LSR_OFFSET => self.line_status,
675            MSR_OFFSET => {
676                if self.is_in_loop_mode() {
677                    // In loopback mode, the four modem control inputs (CTS, DSR, RI, DCD) are
678                    // internally connected to the four modem control outputs (RTS, DTR, OUT1, OUT2).
679                    // This way CTS is controlled by RTS, DSR by DTR, RI by OUT1 and DCD by OUT2.
680                    // (so they will basically contain the same value).
681                    let mut msr =
682                        self.modem_status & !(MSR_DSR_BIT | MSR_CTS_BIT | MSR_RI_BIT | MSR_DCD_BIT);
683                    if (self.modem_control & MCR_DTR_BIT) != 0 {
684                        msr |= MSR_DSR_BIT;
685                    }
686                    if (self.modem_control & MCR_RTS_BIT) != 0 {
687                        msr |= MSR_CTS_BIT;
688                    }
689                    if (self.modem_control & MCR_OUT1_BIT) != 0 {
690                        msr |= MSR_RI_BIT;
691                    }
692                    if (self.modem_control & MCR_OUT2_BIT) != 0 {
693                        msr |= MSR_DCD_BIT;
694                    }
695                    msr
696                } else {
697                    self.modem_status
698                }
699            }
700            SCR_OFFSET => self.scratch,
701            _ => 0,
702        }
703    }
704
705    /// Returns how much space is still available in the FIFO.
706    ///
707    /// # Example
708    ///
709    /// You can see an example of how to use this function in the
710    /// [`Example` section from `Serial`](struct.Serial.html#example).
711    #[inline]
712    pub fn fifo_capacity(&self) -> usize {
713        FIFO_SIZE - self.in_buffer.len()
714    }
715
716    /// Helps in sending more bytes to the guest in one shot, by storing
717    /// `input` bytes in UART buffer and letting the driver know there is
718    /// some pending data to be read by setting RDA bit and its corresponding
719    /// interrupt when not already triggered.
720    ///
721    /// # Arguments
722    /// * `input` - The data to be sent to the guest.
723    ///
724    /// # Returns
725    ///
726    /// The function returns the number of bytes it was able to write to the fifo,
727    /// or `FullFifo` error when the fifo is full. Users can use
728    /// [`fifo_capacity`](#method.fifo_capacity) before calling this function
729    /// to check the available space.
730    ///
731    /// # Example
732    ///
733    /// You can see an example of how to use this function in the
734    /// [`Example` section from `Serial`](struct.Serial.html#example).
735    pub fn enqueue_raw_bytes(&mut self, input: &[u8]) -> Result<usize, Error<T::E>> {
736        let mut write_count = 0;
737        if !self.is_in_loop_mode() {
738            // First check if the input slice and the fifo are non-empty so we can return early in
739            // those cases. Any subsequent `write` to the `in_buffer` will write at least one byte.
740            if input.is_empty() {
741                return Ok(0);
742            }
743            if self.fifo_capacity() == 0 {
744                return Err(Error::FullFifo);
745            }
746
747            write_count = std::cmp::min(self.fifo_capacity(), input.len());
748            self.in_buffer.extend(&input[0..write_count]);
749            self.set_lsr_rda_bit();
750            self.received_data_interrupt().map_err(Error::Trigger)?;
751        }
752        Ok(write_count)
753    }
754}
755
756#[cfg(test)]
757mod tests {
758    use super::*;
759
760    use std::io::{sink, Result};
761    use std::sync::atomic::AtomicU64;
762    use std::sync::Arc;
763
764    use vmm_sys_util::eventfd::EventFd;
765    use vmm_sys_util::metric::Metric;
766
767    const RAW_INPUT_BUF: [u8; 3] = [b'a', b'b', b'c'];
768
769    impl Trigger for EventFd {
770        type E = io::Error;
771
772        fn trigger(&self) -> Result<()> {
773            self.write(1)
774        }
775    }
776
777    struct ExampleSerialEvents {
778        read_count: AtomicU64,
779        out_byte_count: AtomicU64,
780        tx_lost_byte_count: AtomicU64,
781        buffer_ready_event: EventFd,
782    }
783
784    impl ExampleSerialEvents {
785        fn new() -> Self {
786            ExampleSerialEvents {
787                read_count: AtomicU64::new(0),
788                out_byte_count: AtomicU64::new(0),
789                tx_lost_byte_count: AtomicU64::new(0),
790                buffer_ready_event: EventFd::new(libc::EFD_NONBLOCK).unwrap(),
791            }
792        }
793    }
794
795    impl SerialEvents for ExampleSerialEvents {
796        fn buffer_read(&self) {
797            self.read_count.inc();
798            // We can also log a message here, or as part of any of the other methods.
799        }
800
801        fn out_byte(&self) {
802            self.out_byte_count.inc();
803        }
804
805        fn tx_lost_byte(&self) {
806            self.tx_lost_byte_count.inc();
807        }
808
809        fn in_buffer_empty(&self) {
810            self.buffer_ready_event.write(1).unwrap();
811        }
812    }
813
814    #[test]
815    fn test_serial_output() {
816        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
817        let mut serial = Serial::new(intr_evt, Vec::new());
818
819        // Valid one char at a time writes.
820        RAW_INPUT_BUF
821            .iter()
822            .for_each(|&c| serial.write(DATA_OFFSET, c).unwrap());
823        assert_eq!(serial.writer().as_slice(), &RAW_INPUT_BUF);
824    }
825
826    #[test]
827    fn test_serial_raw_input() {
828        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
829        let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
830
831        serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
832
833        serial.enqueue_raw_bytes(&[]).unwrap();
834        // When enqueuing 0 bytes, the serial should neither raise an interrupt,
835        // nor set the `DATA_READY` bit.
836        assert_eq!(
837            intr_evt.read().unwrap_err().kind(),
838            io::ErrorKind::WouldBlock
839        );
840        let mut lsr = serial.read(LSR_OFFSET);
841        assert_eq!(lsr & LSR_DATA_READY_BIT, 0);
842
843        // Enqueue a non-empty slice.
844        serial.enqueue_raw_bytes(&RAW_INPUT_BUF).unwrap();
845
846        // Verify the serial raised an interrupt.
847        assert_eq!(intr_evt.read().unwrap(), 1);
848
849        // `DATA_READY` bit should've been set by `enqueue_raw_bytes()`.
850        lsr = serial.read(LSR_OFFSET);
851        assert_ne!(lsr & LSR_DATA_READY_BIT, 0);
852
853        // Verify reading the previously pushed buffer.
854        RAW_INPUT_BUF.iter().for_each(|&c| {
855            lsr = serial.read(LSR_OFFSET);
856            // `DATA_READY` bit won't be cleared until there is
857            // just one byte left in the receive buffer.
858            assert_ne!(lsr & LSR_DATA_READY_BIT, 0);
859            assert_eq!(serial.read(DATA_OFFSET), c);
860            // The Received Data Available interrupt bit should be
861            // cleared after reading the first pending byte.
862            assert_eq!(
863                serial.interrupt_identification,
864                DEFAULT_INTERRUPT_IDENTIFICATION
865            );
866        });
867
868        lsr = serial.read(LSR_OFFSET);
869        assert_eq!(lsr & LSR_DATA_READY_BIT, 0);
870    }
871
872    #[test]
873    fn test_serial_thr() {
874        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
875        let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
876
877        serial.write(IER_OFFSET, IER_THR_EMPTY_BIT).unwrap();
878        assert_eq!(
879            serial.interrupt_enable,
880            IER_THR_EMPTY_BIT & IER_UART_VALID_BITS
881        );
882        serial.write(DATA_OFFSET, b'a').unwrap();
883
884        // Verify the serial raised an interrupt.
885        assert_eq!(intr_evt.read().unwrap(), 1);
886
887        let ier = serial.read(IER_OFFSET);
888        assert_eq!(ier & IER_UART_VALID_BITS, IER_THR_EMPTY_BIT);
889        let iir = serial.read(IIR_OFFSET);
890        // Verify the raised interrupt is indeed the empty THR one.
891        assert_ne!(iir & IIR_THR_EMPTY_BIT, 0);
892
893        // When reading from IIR offset, the returned value will tell us that
894        // FIFO feature is enabled.
895        assert_eq!(iir, IIR_THR_EMPTY_BIT | IIR_FIFO_BITS);
896        assert_eq!(
897            serial.interrupt_identification,
898            DEFAULT_INTERRUPT_IDENTIFICATION
899        );
900    }
901
902    #[test]
903    fn test_serial_loop_mode() {
904        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
905        let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
906
907        serial.write(MCR_OFFSET, MCR_LOOP_BIT).unwrap();
908        serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
909
910        for value in 0..FIFO_SIZE as u8 {
911            serial.write(DATA_OFFSET, value).unwrap();
912            assert_eq!(intr_evt.read().unwrap(), 1);
913            assert_eq!(serial.in_buffer.len(), 1);
914            // Immediately read a pushed value.
915            assert_eq!(serial.read(DATA_OFFSET), value);
916        }
917
918        assert_eq!(serial.line_status & LSR_DATA_READY_BIT, 0);
919
920        for value in 0..FIFO_SIZE as u8 {
921            serial.write(DATA_OFFSET, value).unwrap();
922        }
923
924        assert_eq!(intr_evt.read().unwrap(), 1);
925        assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
926
927        // Read the pushed values at the end.
928        for value in 0..FIFO_SIZE as u8 {
929            assert_ne!(serial.line_status & LSR_DATA_READY_BIT, 0);
930            assert_eq!(serial.read(DATA_OFFSET), value);
931        }
932        assert_eq!(serial.line_status & LSR_DATA_READY_BIT, 0);
933    }
934
935    #[test]
936    fn test_serial_dlab() {
937        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
938        let mut serial = Serial::new(intr_evt, sink());
939
940        // For writing to DLAB registers, `DLAB` bit from LCR should be set.
941        serial.write(LCR_OFFSET, LCR_DLAB_BIT).unwrap();
942        serial.write(DLAB_HIGH_OFFSET, 0x12).unwrap();
943        assert_eq!(serial.read(DLAB_LOW_OFFSET), DEFAULT_BAUD_DIVISOR_LOW);
944        assert_eq!(serial.read(DLAB_HIGH_OFFSET), 0x12);
945
946        serial.write(DLAB_LOW_OFFSET, 0x34).unwrap();
947
948        assert_eq!(serial.read(DLAB_LOW_OFFSET), 0x34);
949        assert_eq!(serial.read(DLAB_HIGH_OFFSET), 0x12);
950
951        // If LCR_DLAB_BIT is not set, the values from `DLAB_LOW_OFFSET` and
952        // `DLAB_HIGH_OFFSET` won't be the expected ones.
953        serial.write(LCR_OFFSET, 0x00).unwrap();
954        assert_ne!(serial.read(DLAB_LOW_OFFSET), 0x12);
955        assert_ne!(serial.read(DLAB_HIGH_OFFSET), 0x34);
956    }
957
958    #[test]
959    fn test_basic_register_accesses() {
960        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
961        let mut serial = Serial::new(intr_evt, sink());
962
963        // Writing to these registers does not alter the initial values to be written
964        // and reading from these registers just returns those values, without
965        // modifying them.
966        let basic_register_accesses = [LCR_OFFSET, MCR_OFFSET, SCR_OFFSET];
967        for offset in basic_register_accesses.iter() {
968            serial.write(*offset, 0x12).unwrap();
969            assert_eq!(serial.read(*offset), 0x12);
970        }
971    }
972
973    #[test]
974    fn test_invalid_access() {
975        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
976        let mut serial = Serial::new(intr_evt, sink());
977
978        // Check if reading from an offset outside 0-7 returns for sure 0.
979        serial.write(SCR_OFFSET + 1, 5).unwrap();
980        assert_eq!(serial.read(SCR_OFFSET + 1), 0);
981    }
982
983    #[test]
984    fn test_serial_msr() {
985        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
986        let mut serial = Serial::new(intr_evt, sink());
987
988        assert_eq!(serial.read(MSR_OFFSET), DEFAULT_MODEM_STATUS);
989
990        // Activate loopback mode.
991        serial.write(MCR_OFFSET, MCR_LOOP_BIT).unwrap();
992
993        // In loopback mode, MSR won't contain the default value anymore.
994        assert_ne!(serial.read(MSR_OFFSET), DEFAULT_MODEM_STATUS);
995        assert_eq!(serial.read(MSR_OFFSET), 0x00);
996
997        // Depending on which bytes we enable for MCR, MSR will be modified accordingly.
998        serial
999            .write(MCR_OFFSET, DEFAULT_MODEM_CONTROL | MCR_LOOP_BIT)
1000            .unwrap();
1001        // DEFAULT_MODEM_CONTROL sets OUT2 from MCR to 1. In loopback mode, OUT2 is equivalent
1002        // to DCD bit from MSR.
1003        assert_eq!(serial.read(MSR_OFFSET), MSR_DCD_BIT);
1004
1005        // The same should happen with OUT1 and RI.
1006        serial
1007            .write(MCR_OFFSET, MCR_OUT1_BIT | MCR_LOOP_BIT)
1008            .unwrap();
1009        assert_eq!(serial.read(MSR_OFFSET), MSR_RI_BIT);
1010
1011        serial
1012            .write(MCR_OFFSET, MCR_LOOP_BIT | MCR_DTR_BIT | MCR_RTS_BIT)
1013            .unwrap();
1014        // DSR and CTS from MSR are "matching wires" to DTR and RTS from MCR (so they will
1015        // have the same value).
1016        assert_eq!(serial.read(MSR_OFFSET), MSR_DSR_BIT | MSR_CTS_BIT);
1017    }
1018
1019    #[test]
1020    fn test_fifo_max_size() {
1021        let event_fd = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1022        let mut serial = Serial::new(event_fd, sink());
1023
1024        // Test case: trying to write too many bytes in an empty fifo will just write
1025        // `FIFO_SIZE`. Any other subsequent writes, will return a `FullFifo` error.
1026        let too_many_bytes = vec![1u8; FIFO_SIZE + 1];
1027        let written_bytes = serial.enqueue_raw_bytes(&too_many_bytes).unwrap();
1028        assert_eq!(written_bytes, FIFO_SIZE);
1029        assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
1030
1031        // A subsequent call to `enqueue_raw_bytes` with an empty slice should not fail,
1032        // even though the fifo is now full.
1033        let written_bytes = serial.enqueue_raw_bytes(&[]).unwrap();
1034        assert_eq!(written_bytes, 0);
1035        assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
1036
1037        // A subsequent call to `enqueue_raw_bytes` with a non-empty slice fails because
1038        // the fifo is now full.
1039        let one_byte_input = [1u8];
1040        match serial.enqueue_raw_bytes(&one_byte_input) {
1041            Err(Error::FullFifo) => (),
1042            _ => unreachable!(),
1043        }
1044
1045        // Test case: consuming one byte from a full fifo does not allow writes
1046        // bigger than one byte.
1047        let _ = serial.read(DATA_OFFSET);
1048        let written_bytes = serial.enqueue_raw_bytes(&too_many_bytes[..2]).unwrap();
1049        assert_eq!(written_bytes, 1);
1050        assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
1051    }
1052
1053    #[test]
1054    fn test_serial_events() {
1055        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1056
1057        let events_ = Arc::new(ExampleSerialEvents::new());
1058        let mut oneslot_buf = [0u8; 1];
1059        let mut serial = Serial::with_events(intr_evt, events_, oneslot_buf.as_mut());
1060
1061        // This should be an error because buffer_ready_event has not been
1062        // triggered yet so no one should have written to that fd yet.
1063        assert_eq!(
1064            serial.events.buffer_ready_event.read().unwrap_err().kind(),
1065            io::ErrorKind::WouldBlock
1066        );
1067
1068        // Check everything is equal to 0 at the beginning.
1069        assert_eq!(serial.events.read_count.count(), 0);
1070        assert_eq!(serial.events.out_byte_count.count(), 0);
1071        assert_eq!(serial.events.tx_lost_byte_count.count(), 0);
1072
1073        // This DATA read should cause the `SerialEvents::buffer_read` method to be invoked.
1074        // And since the in_buffer is empty the buffer_ready_event should have
1075        // been triggered, hence we can read from that fd.
1076        serial.read(DATA_OFFSET);
1077        assert_eq!(serial.events.read_count.count(), 1);
1078        assert_eq!(serial.events.buffer_ready_event.read().unwrap(), 1);
1079
1080        // This DATA write should cause `SerialEvents::out_byte` to be called.
1081        serial.write(DATA_OFFSET, 1).unwrap();
1082        assert_eq!(serial.events.out_byte_count.count(), 1);
1083        // `SerialEvents::tx_lost_byte` should not have been called.
1084        assert_eq!(serial.events.tx_lost_byte_count.count(), 0);
1085
1086        // This DATA write should cause `SerialEvents::tx_lost_byte` to be called.
1087        serial.write(DATA_OFFSET, 1).unwrap_err();
1088        assert_eq!(serial.events.tx_lost_byte_count.count(), 1);
1089
1090        // Check that every metric has the expected value at the end, to ensure we didn't
1091        // unexpectedly invoked any extra callbacks.
1092        assert_eq!(serial.events.read_count.count(), 1);
1093        assert_eq!(serial.events.out_byte_count.count(), 1);
1094        assert_eq!(serial.events.tx_lost_byte_count.count(), 1);
1095
1096        // This DATA read should cause the `SerialEvents::buffer_read` method to be invoked.
1097        // And since it was the last byte from in buffer the `SerialEvents::in_buffer_empty`
1098        // was also invoked.
1099        serial.read(DATA_OFFSET);
1100        assert_eq!(serial.events.read_count.count(), 2);
1101        assert_eq!(serial.events.buffer_ready_event.read().unwrap(), 1);
1102        let _res = serial.enqueue_raw_bytes(&[1, 2]);
1103        serial.read(DATA_OFFSET);
1104        // Since there is still one byte in the in_buffer, buffer_ready_events
1105        // should have not been triggered so we shouldn't have anything to read
1106        // from that fd.
1107        assert_eq!(
1108            serial.events.buffer_ready_event.read().unwrap_err().kind(),
1109            io::ErrorKind::WouldBlock
1110        );
1111    }
1112
1113    #[test]
1114    fn test_out_descrp_full_thre_sent() {
1115        let mut nospace_buf = [0u8; 0];
1116        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1117        let mut serial = Serial::new(intr_evt, nospace_buf.as_mut());
1118
1119        // Enable THR interrupt.
1120        serial.write(IER_OFFSET, IER_THR_EMPTY_BIT).unwrap();
1121
1122        // Write some data.
1123        let res = serial.write(DATA_OFFSET, 5);
1124        let iir = serial.read(IIR_OFFSET);
1125
1126        // The write failed.
1127        assert!(
1128            matches!(res.unwrap_err(), Error::IOError(io_err) if io_err.kind() == io::ErrorKind::WriteZero
1129            )
1130        );
1131        // THR empty interrupt was raised nevertheless.
1132        assert_eq!(iir & IIR_THR_EMPTY_BIT, IIR_THR_EMPTY_BIT);
1133    }
1134
1135    #[test]
1136    fn test_serial_state_default() {
1137        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1138        let serial = Serial::new(intr_evt, Vec::new());
1139
1140        assert_eq!(serial.state(), SerialState::default());
1141    }
1142
1143    #[test]
1144    fn test_from_state_with_too_many_bytes() {
1145        let mut state = SerialState::default();
1146        let too_many_bytes = vec![1u8; 128];
1147
1148        state.in_buffer.extend(too_many_bytes);
1149
1150        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1151        let serial = Serial::from_state(&state, intr_evt, NoEvents, sink());
1152
1153        assert!(matches!(serial, Err(Error::FullFifo)));
1154    }
1155
1156    #[test]
1157    fn test_from_state_with_pending_thre_interrupt() {
1158        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1159        let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
1160
1161        serial.write(IER_OFFSET, IER_THR_EMPTY_BIT).unwrap();
1162        serial.write(DATA_OFFSET, b'a').unwrap();
1163        assert_eq!(intr_evt.read().unwrap(), 1);
1164
1165        let state = serial.state();
1166        let mut serial_after_restore =
1167            Serial::from_state(&state, intr_evt.try_clone().unwrap(), NoEvents, sink()).unwrap();
1168
1169        let ier = serial_after_restore.read(IER_OFFSET);
1170        assert_eq!(ier & IER_UART_VALID_BITS, IER_THR_EMPTY_BIT);
1171        let iir = serial_after_restore.read(IIR_OFFSET);
1172        assert_ne!(iir & IIR_THR_EMPTY_BIT, 0);
1173
1174        // Verify the serial raised an interrupt again.
1175        assert_eq!(intr_evt.read().unwrap(), 1);
1176    }
1177
1178    #[test]
1179    fn test_from_state_with_pending_rda_interrupt() {
1180        let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1181        let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
1182
1183        serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
1184        serial.enqueue_raw_bytes(&RAW_INPUT_BUF).unwrap();
1185        assert_eq!(intr_evt.read().unwrap(), 1);
1186
1187        let state = serial.state();
1188        let mut serial_after_restore =
1189            Serial::from_state(&state, intr_evt.try_clone().unwrap(), NoEvents, sink()).unwrap();
1190
1191        let ier = serial_after_restore.read(IER_OFFSET);
1192        assert_eq!(ier & IER_UART_VALID_BITS, IER_RDA_BIT);
1193        let iir = serial_after_restore.read(IIR_OFFSET);
1194        assert_ne!(iir & IIR_RDA_BIT, 0);
1195
1196        // Verify the serial raised an interrupt again.
1197        assert_eq!(intr_evt.read().unwrap(), 1);
1198    }
1199}