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}