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 => {
624 self.interrupt_enable = value & IER_UART_VALID_BITS;
625 // On a real UART the interrupt output is a level signal derived from
626 // the interrupt conditions that are both pending and enabled, so
627 // (re-)enabling an interrupt whose condition is already pending
628 // asserts it immediately. Drivers rely on this: for instance the
629 // Linux 8250 console masks IER while it writes a message and, once
630 // it restores IER, expects the RX interrupt to fire again if data
631 // was received in the meantime (otherwise that input is never read).
632 if !self.in_buffer.is_empty() {
633 self.received_data_interrupt().map_err(Error::Trigger)?;
634 }
635 // The transmitter holding register is always empty in this model.
636 self.thr_empty_interrupt().map_err(Error::Trigger)?;
637 }
638 LCR_OFFSET => self.line_control = value,
639 MCR_OFFSET => self.modem_control = value,
640 SCR_OFFSET => self.scratch = value,
641 // We are not interested in writing to other offsets (such as FCR offset).
642 _ => {}
643 }
644 Ok(())
645 }
646
647 /// Handles a read request from the driver at `offset` offset from the
648 /// base Port I/O address.
649 ///
650 /// Returns the read value.
651 ///
652 /// # Arguments
653 /// * `offset` - The offset that will be added to the base PIO address
654 /// for reading from a specific register.
655 ///
656 /// # Example
657 ///
658 /// You can see an example of how to use this function in the
659 /// [`Example` section from `Serial`](struct.Serial.html#example).
660 pub fn read(&mut self, offset: u8) -> u8 {
661 match offset {
662 DLAB_LOW_OFFSET if self.is_dlab_set() => self.baud_divisor_low,
663 DLAB_HIGH_OFFSET if self.is_dlab_set() => self.baud_divisor_high,
664 DATA_OFFSET => {
665 // Here we emulate the reset method for when RDA interrupt
666 // was raised (i.e. read the receive buffer and clear the
667 // interrupt identification register and RDA bit when no
668 // more data is available).
669 self.del_interrupt(IIR_RDA_BIT);
670 let byte = self.in_buffer.pop_front().unwrap_or_default();
671 if self.in_buffer.is_empty() {
672 self.clear_lsr_rda_bit();
673 self.events.in_buffer_empty();
674 }
675 self.events.buffer_read();
676 byte
677 }
678 IER_OFFSET => self.interrupt_enable,
679 IIR_OFFSET => {
680 // We're enabling FIFO capability by setting the serial port to 16550A:
681 // https://elixir.bootlin.com/linux/latest/source/drivers/tty/serial/8250/8250_port.c#L1299.
682 let iir = self.interrupt_identification | IIR_FIFO_BITS;
683 self.reset_iir();
684 iir
685 }
686 LCR_OFFSET => self.line_control,
687 MCR_OFFSET => self.modem_control,
688 LSR_OFFSET => self.line_status,
689 MSR_OFFSET => {
690 if self.is_in_loop_mode() {
691 // In loopback mode, the four modem control inputs (CTS, DSR, RI, DCD) are
692 // internally connected to the four modem control outputs (RTS, DTR, OUT1, OUT2).
693 // This way CTS is controlled by RTS, DSR by DTR, RI by OUT1 and DCD by OUT2.
694 // (so they will basically contain the same value).
695 let mut msr =
696 self.modem_status & !(MSR_DSR_BIT | MSR_CTS_BIT | MSR_RI_BIT | MSR_DCD_BIT);
697 if (self.modem_control & MCR_DTR_BIT) != 0 {
698 msr |= MSR_DSR_BIT;
699 }
700 if (self.modem_control & MCR_RTS_BIT) != 0 {
701 msr |= MSR_CTS_BIT;
702 }
703 if (self.modem_control & MCR_OUT1_BIT) != 0 {
704 msr |= MSR_RI_BIT;
705 }
706 if (self.modem_control & MCR_OUT2_BIT) != 0 {
707 msr |= MSR_DCD_BIT;
708 }
709 msr
710 } else {
711 self.modem_status
712 }
713 }
714 SCR_OFFSET => self.scratch,
715 _ => 0,
716 }
717 }
718
719 /// Returns how much space is still available in the FIFO.
720 ///
721 /// # Example
722 ///
723 /// You can see an example of how to use this function in the
724 /// [`Example` section from `Serial`](struct.Serial.html#example).
725 #[inline]
726 pub fn fifo_capacity(&self) -> usize {
727 FIFO_SIZE - self.in_buffer.len()
728 }
729
730 /// Helps in sending more bytes to the guest in one shot, by storing
731 /// `input` bytes in UART buffer and letting the driver know there is
732 /// some pending data to be read by setting RDA bit and its corresponding
733 /// interrupt when not already triggered.
734 ///
735 /// # Arguments
736 /// * `input` - The data to be sent to the guest.
737 ///
738 /// # Returns
739 ///
740 /// The function returns the number of bytes it was able to write to the fifo,
741 /// or `FullFifo` error when the fifo is full. Users can use
742 /// [`fifo_capacity`](#method.fifo_capacity) before calling this function
743 /// to check the available space.
744 ///
745 /// # Example
746 ///
747 /// You can see an example of how to use this function in the
748 /// [`Example` section from `Serial`](struct.Serial.html#example).
749 pub fn enqueue_raw_bytes(&mut self, input: &[u8]) -> Result<usize, Error<T::E>> {
750 let mut write_count = 0;
751 if !self.is_in_loop_mode() {
752 // First check if the input slice and the fifo are non-empty so we can return early in
753 // those cases. Any subsequent `write` to the `in_buffer` will write at least one byte.
754 if input.is_empty() {
755 return Ok(0);
756 }
757 if self.fifo_capacity() == 0 {
758 return Err(Error::FullFifo);
759 }
760
761 write_count = std::cmp::min(self.fifo_capacity(), input.len());
762 self.in_buffer.extend(&input[0..write_count]);
763 self.set_lsr_rda_bit();
764 self.received_data_interrupt().map_err(Error::Trigger)?;
765 }
766 Ok(write_count)
767 }
768}
769
770#[cfg(test)]
771mod tests {
772 use super::*;
773
774 use std::io::{sink, Result};
775 use std::sync::atomic::AtomicU64;
776 use std::sync::Arc;
777
778 use vmm_sys_util::eventfd::EventFd;
779 use vmm_sys_util::metric::Metric;
780
781 const RAW_INPUT_BUF: [u8; 3] = [b'a', b'b', b'c'];
782
783 impl Trigger for EventFd {
784 type E = io::Error;
785
786 fn trigger(&self) -> Result<()> {
787 self.write(1)
788 }
789 }
790
791 struct ExampleSerialEvents {
792 read_count: AtomicU64,
793 out_byte_count: AtomicU64,
794 tx_lost_byte_count: AtomicU64,
795 buffer_ready_event: EventFd,
796 }
797
798 impl ExampleSerialEvents {
799 fn new() -> Self {
800 ExampleSerialEvents {
801 read_count: AtomicU64::new(0),
802 out_byte_count: AtomicU64::new(0),
803 tx_lost_byte_count: AtomicU64::new(0),
804 buffer_ready_event: EventFd::new(libc::EFD_NONBLOCK).unwrap(),
805 }
806 }
807 }
808
809 impl SerialEvents for ExampleSerialEvents {
810 fn buffer_read(&self) {
811 self.read_count.inc();
812 // We can also log a message here, or as part of any of the other methods.
813 }
814
815 fn out_byte(&self) {
816 self.out_byte_count.inc();
817 }
818
819 fn tx_lost_byte(&self) {
820 self.tx_lost_byte_count.inc();
821 }
822
823 fn in_buffer_empty(&self) {
824 self.buffer_ready_event.write(1).unwrap();
825 }
826 }
827
828 #[test]
829 fn test_serial_output() {
830 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
831 let mut serial = Serial::new(intr_evt, Vec::new());
832
833 // Valid one char at a time writes.
834 RAW_INPUT_BUF
835 .iter()
836 .for_each(|&c| serial.write(DATA_OFFSET, c).unwrap());
837 assert_eq!(serial.writer().as_slice(), &RAW_INPUT_BUF);
838 }
839
840 #[test]
841 fn test_serial_raw_input() {
842 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
843 let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
844
845 serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
846
847 serial.enqueue_raw_bytes(&[]).unwrap();
848 // When enqueuing 0 bytes, the serial should neither raise an interrupt,
849 // nor set the `DATA_READY` bit.
850 assert_eq!(
851 intr_evt.read().unwrap_err().kind(),
852 io::ErrorKind::WouldBlock
853 );
854 let mut lsr = serial.read(LSR_OFFSET);
855 assert_eq!(lsr & LSR_DATA_READY_BIT, 0);
856
857 // Enqueue a non-empty slice.
858 serial.enqueue_raw_bytes(&RAW_INPUT_BUF).unwrap();
859
860 // Verify the serial raised an interrupt.
861 assert_eq!(intr_evt.read().unwrap(), 1);
862
863 // `DATA_READY` bit should've been set by `enqueue_raw_bytes()`.
864 lsr = serial.read(LSR_OFFSET);
865 assert_ne!(lsr & LSR_DATA_READY_BIT, 0);
866
867 // Verify reading the previously pushed buffer.
868 RAW_INPUT_BUF.iter().for_each(|&c| {
869 lsr = serial.read(LSR_OFFSET);
870 // `DATA_READY` bit won't be cleared until there is
871 // just one byte left in the receive buffer.
872 assert_ne!(lsr & LSR_DATA_READY_BIT, 0);
873 assert_eq!(serial.read(DATA_OFFSET), c);
874 // The Received Data Available interrupt bit should be
875 // cleared after reading the first pending byte.
876 assert_eq!(
877 serial.interrupt_identification,
878 DEFAULT_INTERRUPT_IDENTIFICATION
879 );
880 });
881
882 lsr = serial.read(LSR_OFFSET);
883 assert_eq!(lsr & LSR_DATA_READY_BIT, 0);
884 }
885
886 #[test]
887 fn test_rda_interrupt_reasserted_on_ier_write() {
888 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
889 let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
890
891 serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
892
893 // This is what the Linux 8250 console does around each message it
894 // prints: save IER, mask all interrupts, write, restore IER.
895 let saved_ier = serial.read(IER_OFFSET);
896 serial.write(IER_OFFSET, 0).unwrap();
897
898 // Data arrives while interrupts are masked: the FIFO and LSR reflect
899 // it, but no interrupt must be raised.
900 serial.enqueue_raw_bytes(&RAW_INPUT_BUF).unwrap();
901 assert_ne!(serial.read(LSR_OFFSET) & LSR_DATA_READY_BIT, 0);
902 assert_eq!(
903 intr_evt.read().unwrap_err().kind(),
904 io::ErrorKind::WouldBlock
905 );
906 assert_eq!(
907 serial.interrupt_identification,
908 DEFAULT_INTERRUPT_IDENTIFICATION
909 );
910
911 // Restoring IER with data pending in the FIFO must assert the RDA
912 // interrupt, like the level-triggered output of a real UART would.
913 serial.write(IER_OFFSET, saved_ier).unwrap();
914 assert_eq!(intr_evt.read().unwrap(), 1);
915 let iir = serial.read(IIR_OFFSET);
916 assert_eq!(iir & IIR_NONE_BIT, 0);
917 assert_ne!(iir & IIR_RDA_BIT, 0);
918
919 // Once the interrupt has been identified, writing IER again with the
920 // FIFO still non-empty must not raise a second one (the RDA bit is
921 // only cleared by reading the data register).
922 serial.write(IER_OFFSET, saved_ier).unwrap();
923 assert_eq!(intr_evt.read().unwrap(), 1);
924 serial.read(IIR_OFFSET);
925 RAW_INPUT_BUF.iter().for_each(|&c| {
926 assert_eq!(serial.read(DATA_OFFSET), c);
927 });
928 serial.write(IER_OFFSET, saved_ier).unwrap();
929 assert_eq!(
930 intr_evt.read().unwrap_err().kind(),
931 io::ErrorKind::WouldBlock
932 );
933 assert_eq!(
934 serial.interrupt_identification,
935 DEFAULT_INTERRUPT_IDENTIFICATION
936 );
937 }
938
939 #[test]
940 fn test_thr_interrupt_asserted_on_ier_write() {
941 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
942 let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
943
944 // Enabling the THR empty interrupt while the THR is empty (always, in
945 // this model) asserts it right away, as on a 16550.
946 serial.write(IER_OFFSET, IER_THR_EMPTY_BIT).unwrap();
947 assert_eq!(intr_evt.read().unwrap(), 1);
948 let iir = serial.read(IIR_OFFSET);
949 assert_ne!(iir & IIR_THR_EMPTY_BIT, 0);
950
951 // Writing an IER value that does not enable THRE does not.
952 serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
953 assert_eq!(
954 intr_evt.read().unwrap_err().kind(),
955 io::ErrorKind::WouldBlock
956 );
957 assert_eq!(
958 serial.interrupt_identification,
959 DEFAULT_INTERRUPT_IDENTIFICATION
960 );
961 }
962
963 #[test]
964 fn test_serial_thr() {
965 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
966 let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
967
968 serial.write(IER_OFFSET, IER_THR_EMPTY_BIT).unwrap();
969 assert_eq!(
970 serial.interrupt_enable,
971 IER_THR_EMPTY_BIT & IER_UART_VALID_BITS
972 );
973 serial.write(DATA_OFFSET, b'a').unwrap();
974
975 // Verify the serial raised an interrupt.
976 assert_eq!(intr_evt.read().unwrap(), 1);
977
978 let ier = serial.read(IER_OFFSET);
979 assert_eq!(ier & IER_UART_VALID_BITS, IER_THR_EMPTY_BIT);
980 let iir = serial.read(IIR_OFFSET);
981 // Verify the raised interrupt is indeed the empty THR one.
982 assert_ne!(iir & IIR_THR_EMPTY_BIT, 0);
983
984 // When reading from IIR offset, the returned value will tell us that
985 // FIFO feature is enabled.
986 assert_eq!(iir, IIR_THR_EMPTY_BIT | IIR_FIFO_BITS);
987 assert_eq!(
988 serial.interrupt_identification,
989 DEFAULT_INTERRUPT_IDENTIFICATION
990 );
991 }
992
993 #[test]
994 fn test_serial_loop_mode() {
995 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
996 let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
997
998 serial.write(MCR_OFFSET, MCR_LOOP_BIT).unwrap();
999 serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
1000
1001 for value in 0..FIFO_SIZE as u8 {
1002 serial.write(DATA_OFFSET, value).unwrap();
1003 assert_eq!(intr_evt.read().unwrap(), 1);
1004 assert_eq!(serial.in_buffer.len(), 1);
1005 // Immediately read a pushed value.
1006 assert_eq!(serial.read(DATA_OFFSET), value);
1007 }
1008
1009 assert_eq!(serial.line_status & LSR_DATA_READY_BIT, 0);
1010
1011 for value in 0..FIFO_SIZE as u8 {
1012 serial.write(DATA_OFFSET, value).unwrap();
1013 }
1014
1015 assert_eq!(intr_evt.read().unwrap(), 1);
1016 assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
1017
1018 // Read the pushed values at the end.
1019 for value in 0..FIFO_SIZE as u8 {
1020 assert_ne!(serial.line_status & LSR_DATA_READY_BIT, 0);
1021 assert_eq!(serial.read(DATA_OFFSET), value);
1022 }
1023 assert_eq!(serial.line_status & LSR_DATA_READY_BIT, 0);
1024 }
1025
1026 #[test]
1027 fn test_serial_dlab() {
1028 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1029 let mut serial = Serial::new(intr_evt, sink());
1030
1031 // For writing to DLAB registers, `DLAB` bit from LCR should be set.
1032 serial.write(LCR_OFFSET, LCR_DLAB_BIT).unwrap();
1033 serial.write(DLAB_HIGH_OFFSET, 0x12).unwrap();
1034 assert_eq!(serial.read(DLAB_LOW_OFFSET), DEFAULT_BAUD_DIVISOR_LOW);
1035 assert_eq!(serial.read(DLAB_HIGH_OFFSET), 0x12);
1036
1037 serial.write(DLAB_LOW_OFFSET, 0x34).unwrap();
1038
1039 assert_eq!(serial.read(DLAB_LOW_OFFSET), 0x34);
1040 assert_eq!(serial.read(DLAB_HIGH_OFFSET), 0x12);
1041
1042 // If LCR_DLAB_BIT is not set, the values from `DLAB_LOW_OFFSET` and
1043 // `DLAB_HIGH_OFFSET` won't be the expected ones.
1044 serial.write(LCR_OFFSET, 0x00).unwrap();
1045 assert_ne!(serial.read(DLAB_LOW_OFFSET), 0x12);
1046 assert_ne!(serial.read(DLAB_HIGH_OFFSET), 0x34);
1047 }
1048
1049 #[test]
1050 fn test_basic_register_accesses() {
1051 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1052 let mut serial = Serial::new(intr_evt, sink());
1053
1054 // Writing to these registers does not alter the initial values to be written
1055 // and reading from these registers just returns those values, without
1056 // modifying them.
1057 let basic_register_accesses = [LCR_OFFSET, MCR_OFFSET, SCR_OFFSET];
1058 for offset in basic_register_accesses.iter() {
1059 serial.write(*offset, 0x12).unwrap();
1060 assert_eq!(serial.read(*offset), 0x12);
1061 }
1062 }
1063
1064 #[test]
1065 fn test_invalid_access() {
1066 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1067 let mut serial = Serial::new(intr_evt, sink());
1068
1069 // Check if reading from an offset outside 0-7 returns for sure 0.
1070 serial.write(SCR_OFFSET + 1, 5).unwrap();
1071 assert_eq!(serial.read(SCR_OFFSET + 1), 0);
1072 }
1073
1074 #[test]
1075 fn test_serial_msr() {
1076 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1077 let mut serial = Serial::new(intr_evt, sink());
1078
1079 assert_eq!(serial.read(MSR_OFFSET), DEFAULT_MODEM_STATUS);
1080
1081 // Activate loopback mode.
1082 serial.write(MCR_OFFSET, MCR_LOOP_BIT).unwrap();
1083
1084 // In loopback mode, MSR won't contain the default value anymore.
1085 assert_ne!(serial.read(MSR_OFFSET), DEFAULT_MODEM_STATUS);
1086 assert_eq!(serial.read(MSR_OFFSET), 0x00);
1087
1088 // Depending on which bytes we enable for MCR, MSR will be modified accordingly.
1089 serial
1090 .write(MCR_OFFSET, DEFAULT_MODEM_CONTROL | MCR_LOOP_BIT)
1091 .unwrap();
1092 // DEFAULT_MODEM_CONTROL sets OUT2 from MCR to 1. In loopback mode, OUT2 is equivalent
1093 // to DCD bit from MSR.
1094 assert_eq!(serial.read(MSR_OFFSET), MSR_DCD_BIT);
1095
1096 // The same should happen with OUT1 and RI.
1097 serial
1098 .write(MCR_OFFSET, MCR_OUT1_BIT | MCR_LOOP_BIT)
1099 .unwrap();
1100 assert_eq!(serial.read(MSR_OFFSET), MSR_RI_BIT);
1101
1102 serial
1103 .write(MCR_OFFSET, MCR_LOOP_BIT | MCR_DTR_BIT | MCR_RTS_BIT)
1104 .unwrap();
1105 // DSR and CTS from MSR are "matching wires" to DTR and RTS from MCR (so they will
1106 // have the same value).
1107 assert_eq!(serial.read(MSR_OFFSET), MSR_DSR_BIT | MSR_CTS_BIT);
1108 }
1109
1110 #[test]
1111 fn test_fifo_max_size() {
1112 let event_fd = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1113 let mut serial = Serial::new(event_fd, sink());
1114
1115 // Test case: trying to write too many bytes in an empty fifo will just write
1116 // `FIFO_SIZE`. Any other subsequent writes, will return a `FullFifo` error.
1117 let too_many_bytes = vec![1u8; FIFO_SIZE + 1];
1118 let written_bytes = serial.enqueue_raw_bytes(&too_many_bytes).unwrap();
1119 assert_eq!(written_bytes, FIFO_SIZE);
1120 assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
1121
1122 // A subsequent call to `enqueue_raw_bytes` with an empty slice should not fail,
1123 // even though the fifo is now full.
1124 let written_bytes = serial.enqueue_raw_bytes(&[]).unwrap();
1125 assert_eq!(written_bytes, 0);
1126 assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
1127
1128 // A subsequent call to `enqueue_raw_bytes` with a non-empty slice fails because
1129 // the fifo is now full.
1130 let one_byte_input = [1u8];
1131 match serial.enqueue_raw_bytes(&one_byte_input) {
1132 Err(Error::FullFifo) => (),
1133 _ => unreachable!(),
1134 }
1135
1136 // Test case: consuming one byte from a full fifo does not allow writes
1137 // bigger than one byte.
1138 let _ = serial.read(DATA_OFFSET);
1139 let written_bytes = serial.enqueue_raw_bytes(&too_many_bytes[..2]).unwrap();
1140 assert_eq!(written_bytes, 1);
1141 assert_eq!(serial.in_buffer.len(), FIFO_SIZE);
1142 }
1143
1144 #[test]
1145 fn test_serial_events() {
1146 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1147
1148 let events_ = Arc::new(ExampleSerialEvents::new());
1149 let mut oneslot_buf = [0u8; 1];
1150 let mut serial = Serial::with_events(intr_evt, events_, oneslot_buf.as_mut());
1151
1152 // This should be an error because buffer_ready_event has not been
1153 // triggered yet so no one should have written to that fd yet.
1154 assert_eq!(
1155 serial.events.buffer_ready_event.read().unwrap_err().kind(),
1156 io::ErrorKind::WouldBlock
1157 );
1158
1159 // Check everything is equal to 0 at the beginning.
1160 assert_eq!(serial.events.read_count.count(), 0);
1161 assert_eq!(serial.events.out_byte_count.count(), 0);
1162 assert_eq!(serial.events.tx_lost_byte_count.count(), 0);
1163
1164 // This DATA read should cause the `SerialEvents::buffer_read` method to be invoked.
1165 // And since the in_buffer is empty the buffer_ready_event should have
1166 // been triggered, hence we can read from that fd.
1167 serial.read(DATA_OFFSET);
1168 assert_eq!(serial.events.read_count.count(), 1);
1169 assert_eq!(serial.events.buffer_ready_event.read().unwrap(), 1);
1170
1171 // This DATA write should cause `SerialEvents::out_byte` to be called.
1172 serial.write(DATA_OFFSET, 1).unwrap();
1173 assert_eq!(serial.events.out_byte_count.count(), 1);
1174 // `SerialEvents::tx_lost_byte` should not have been called.
1175 assert_eq!(serial.events.tx_lost_byte_count.count(), 0);
1176
1177 // This DATA write should cause `SerialEvents::tx_lost_byte` to be called.
1178 serial.write(DATA_OFFSET, 1).unwrap_err();
1179 assert_eq!(serial.events.tx_lost_byte_count.count(), 1);
1180
1181 // Check that every metric has the expected value at the end, to ensure we didn't
1182 // unexpectedly invoked any extra callbacks.
1183 assert_eq!(serial.events.read_count.count(), 1);
1184 assert_eq!(serial.events.out_byte_count.count(), 1);
1185 assert_eq!(serial.events.tx_lost_byte_count.count(), 1);
1186
1187 // This DATA read should cause the `SerialEvents::buffer_read` method to be invoked.
1188 // And since it was the last byte from in buffer the `SerialEvents::in_buffer_empty`
1189 // was also invoked.
1190 serial.read(DATA_OFFSET);
1191 assert_eq!(serial.events.read_count.count(), 2);
1192 assert_eq!(serial.events.buffer_ready_event.read().unwrap(), 1);
1193 let _res = serial.enqueue_raw_bytes(&[1, 2]);
1194 serial.read(DATA_OFFSET);
1195 // Since there is still one byte in the in_buffer, buffer_ready_events
1196 // should have not been triggered so we shouldn't have anything to read
1197 // from that fd.
1198 assert_eq!(
1199 serial.events.buffer_ready_event.read().unwrap_err().kind(),
1200 io::ErrorKind::WouldBlock
1201 );
1202 }
1203
1204 #[test]
1205 fn test_out_descrp_full_thre_sent() {
1206 let mut nospace_buf = [0u8; 0];
1207 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1208 let mut serial = Serial::new(intr_evt, nospace_buf.as_mut());
1209
1210 // Enable THR interrupt.
1211 serial.write(IER_OFFSET, IER_THR_EMPTY_BIT).unwrap();
1212
1213 // Write some data.
1214 let res = serial.write(DATA_OFFSET, 5);
1215 let iir = serial.read(IIR_OFFSET);
1216
1217 // The write failed.
1218 assert!(
1219 matches!(res.unwrap_err(), Error::IOError(io_err) if io_err.kind() == io::ErrorKind::WriteZero
1220 )
1221 );
1222 // THR empty interrupt was raised nevertheless.
1223 assert_eq!(iir & IIR_THR_EMPTY_BIT, IIR_THR_EMPTY_BIT);
1224 }
1225
1226 #[test]
1227 fn test_serial_state_default() {
1228 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1229 let serial = Serial::new(intr_evt, Vec::new());
1230
1231 assert_eq!(serial.state(), SerialState::default());
1232 }
1233
1234 #[test]
1235 fn test_from_state_with_too_many_bytes() {
1236 let mut state = SerialState::default();
1237 let too_many_bytes = vec![1u8; 128];
1238
1239 state.in_buffer.extend(too_many_bytes);
1240
1241 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1242 let serial = Serial::from_state(&state, intr_evt, NoEvents, sink());
1243
1244 assert!(matches!(serial, Err(Error::FullFifo)));
1245 }
1246
1247 #[test]
1248 fn test_from_state_with_pending_thre_interrupt() {
1249 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1250 let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
1251
1252 serial.write(IER_OFFSET, IER_THR_EMPTY_BIT).unwrap();
1253 serial.write(DATA_OFFSET, b'a').unwrap();
1254 assert_eq!(intr_evt.read().unwrap(), 1);
1255
1256 let state = serial.state();
1257 let mut serial_after_restore =
1258 Serial::from_state(&state, intr_evt.try_clone().unwrap(), NoEvents, sink()).unwrap();
1259
1260 let ier = serial_after_restore.read(IER_OFFSET);
1261 assert_eq!(ier & IER_UART_VALID_BITS, IER_THR_EMPTY_BIT);
1262 let iir = serial_after_restore.read(IIR_OFFSET);
1263 assert_ne!(iir & IIR_THR_EMPTY_BIT, 0);
1264
1265 // Verify the serial raised an interrupt again.
1266 assert_eq!(intr_evt.read().unwrap(), 1);
1267 }
1268
1269 #[test]
1270 fn test_from_state_with_pending_rda_interrupt() {
1271 let intr_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap();
1272 let mut serial = Serial::new(intr_evt.try_clone().unwrap(), sink());
1273
1274 serial.write(IER_OFFSET, IER_RDA_BIT).unwrap();
1275 serial.enqueue_raw_bytes(&RAW_INPUT_BUF).unwrap();
1276 assert_eq!(intr_evt.read().unwrap(), 1);
1277
1278 let state = serial.state();
1279 let mut serial_after_restore =
1280 Serial::from_state(&state, intr_evt.try_clone().unwrap(), NoEvents, sink()).unwrap();
1281
1282 let ier = serial_after_restore.read(IER_OFFSET);
1283 assert_eq!(ier & IER_UART_VALID_BITS, IER_RDA_BIT);
1284 let iir = serial_after_restore.read(IIR_OFFSET);
1285 assert_ne!(iir & IIR_RDA_BIT, 0);
1286
1287 // Verify the serial raised an interrupt again.
1288 assert_eq!(intr_evt.read().unwrap(), 1);
1289 }
1290}