xref: /aosp_15_r20/external/crosvm/devices/src/serial.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2017 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 pub(crate) mod sys;
6 
7 use std::collections::VecDeque;
8 use std::io;
9 use std::sync::atomic::AtomicU8;
10 use std::sync::atomic::Ordering;
11 use std::sync::mpsc::channel;
12 use std::sync::mpsc::Receiver;
13 use std::sync::mpsc::TryRecvError;
14 use std::sync::Arc;
15 use std::time::Duration;
16 use std::time::Instant;
17 
18 use anyhow::Context;
19 use base::error;
20 use base::warn;
21 use base::Event;
22 use base::EventToken;
23 use base::Result;
24 use base::WaitContext;
25 use base::WorkerThread;
26 use serde::Deserialize;
27 use serde::Serialize;
28 
29 use crate::bus::BusAccessInfo;
30 use crate::pci::CrosvmDeviceId;
31 use crate::serial_device::SerialInput;
32 use crate::suspendable::DeviceState;
33 use crate::suspendable::Suspendable;
34 use crate::BusDevice;
35 use crate::DeviceId;
36 
37 const LOOP_SIZE: usize = 0x40;
38 
39 const DATA: u8 = 0;
40 const IER: u8 = 1;
41 const IIR: u8 = 2;
42 const LCR: u8 = 3;
43 const MCR: u8 = 4;
44 const LSR: u8 = 5;
45 const MSR: u8 = 6;
46 const SCR: u8 = 7;
47 const DLAB_LOW: u8 = 0;
48 const DLAB_HIGH: u8 = 1;
49 
50 const IER_RECV_BIT: u8 = 0x1;
51 const IER_THR_BIT: u8 = 0x2;
52 const IER_FIFO_BITS: u8 = 0x0f;
53 
54 const IIR_FIFO_BITS: u8 = 0xc0;
55 const IIR_NONE_BIT: u8 = 0x1;
56 const IIR_THR_BIT: u8 = 0x2;
57 const IIR_RECV_BIT: u8 = 0x4;
58 
59 const LSR_DATA_BIT: u8 = 0x1;
60 const LSR_EMPTY_BIT: u8 = 0x20;
61 const LSR_IDLE_BIT: u8 = 0x40;
62 
63 const MCR_DTR_BIT: u8 = 0x01; // Data Terminal Ready
64 const MCR_RTS_BIT: u8 = 0x02; // Request to Send
65 const MCR_OUT1_BIT: u8 = 0x04;
66 const MCR_OUT2_BIT: u8 = 0x08;
67 const MCR_LOOP_BIT: u8 = 0x10;
68 
69 const MSR_CTS_BIT: u8 = 0x10; // Clear to Send
70 const MSR_DSR_BIT: u8 = 0x20; // Data Set Ready
71 const MSR_RI_BIT: u8 = 0x40; // Ring Indicator
72 const MSR_DCD_BIT: u8 = 0x80; // Data Carrier Detect
73 
74 const DEFAULT_INTERRUPT_IDENTIFICATION: u8 = IIR_NONE_BIT; // no pending interrupt
75 const DEFAULT_LINE_STATUS: u8 = LSR_EMPTY_BIT | LSR_IDLE_BIT; // THR empty and line is idle
76 const DEFAULT_LINE_CONTROL: u8 = 0x3; // 8-bits per character
77 const DEFAULT_MODEM_CONTROL: u8 = MCR_OUT2_BIT;
78 const DEFAULT_MODEM_STATUS: u8 = MSR_DSR_BIT | MSR_CTS_BIT | MSR_DCD_BIT;
79 const DEFAULT_BAUD_DIVISOR: u16 = 12; // 9600 bps
80 
81 const TIMESTAMP_PREFIX_FMT: &str = "[ %F %T%.9f ]: ";
82 
83 /// Emulates serial COM ports commonly seen on x86 I/O ports 0x3f8/0x2f8/0x3e8/0x2e8.
84 ///
85 /// This can optionally write the guest's output to a Write trait object. To send input to the
86 /// guest, use `queue_input_bytes` directly, or give a Read trait object which will be used queue
87 /// bytes when `used_command` is called.
88 pub struct Serial {
89     // Serial port registers
90     interrupt_enable: Arc<AtomicU8>,
91     interrupt_identification: u8,
92     interrupt_evt: Event,
93     line_control: u8,
94     line_status: u8,
95     modem_control: u8,
96     modem_status: u8,
97     scratch: u8,
98     baud_divisor: u16,
99 
100     // Host input/output
101     in_buffer: VecDeque<u8>,
102     in_channel: Option<Receiver<u8>>,
103     input: Option<Box<dyn SerialInput>>,
104     out: Option<Box<dyn io::Write + Send>>,
105     out_timestamp: bool,
106     last_write_was_newline: bool,
107     #[cfg(windows)]
108     pub system_params: sys::windows::SystemSerialParams,
109     device_state: DeviceState,
110     worker: Option<WorkerThread<Box<dyn SerialInput>>>,
111 }
112 
113 impl Serial {
new_common( interrupt_evt: Event, input: Option<Box<dyn SerialInput>>, out: Option<Box<dyn io::Write + Send>>, out_timestamp: bool, #[cfg(windows)] system_params: sys::windows::SystemSerialParams, ) -> Serial114     fn new_common(
115         interrupt_evt: Event,
116         input: Option<Box<dyn SerialInput>>,
117         out: Option<Box<dyn io::Write + Send>>,
118         out_timestamp: bool,
119         #[cfg(windows)] system_params: sys::windows::SystemSerialParams,
120     ) -> Serial {
121         Serial {
122             interrupt_enable: Default::default(),
123             interrupt_identification: DEFAULT_INTERRUPT_IDENTIFICATION,
124             interrupt_evt,
125             line_control: DEFAULT_LINE_CONTROL,
126             line_status: DEFAULT_LINE_STATUS,
127             modem_control: DEFAULT_MODEM_CONTROL,
128             modem_status: DEFAULT_MODEM_STATUS,
129             scratch: 0,
130             baud_divisor: DEFAULT_BAUD_DIVISOR,
131             in_buffer: Default::default(),
132             in_channel: None,
133             input,
134             out,
135             out_timestamp,
136             last_write_was_newline: true,
137             #[cfg(windows)]
138             system_params,
139             device_state: DeviceState::Awake,
140             worker: None,
141         }
142     }
143 
144     /// Returns a unique ID for the serial device.
device_id() -> DeviceId145     pub fn device_id() -> DeviceId {
146         CrosvmDeviceId::Serial.into()
147     }
148 
149     /// Returns a debug label for the serial device. Used when setting up `IrqEventSource`.
debug_label() -> String150     pub fn debug_label() -> String {
151         "serial".to_owned()
152     }
153 
154     /// Queues raw bytes for the guest to read and signals the interrupt if the line status would
155     /// change. These bytes will be read by the guest before any bytes from the input stream that
156     /// have not already been queued.
queue_input_bytes(&mut self, c: &[u8]) -> Result<()>157     pub fn queue_input_bytes(&mut self, c: &[u8]) -> Result<()> {
158         if !c.is_empty() && !self.is_loop() {
159             self.in_buffer.extend(c);
160             self.set_data_bit();
161             self.trigger_recv_interrupt()?;
162         }
163 
164         Ok(())
165     }
166 
spawn_input_thread(&mut self)167     fn spawn_input_thread(&mut self) {
168         let mut rx = match self.input.take() {
169             Some(input) => input,
170             None => return,
171         };
172 
173         let (send_channel, recv_channel) = channel();
174 
175         // The interrupt enable and interrupt event are used to trigger the guest serial driver to
176         // read the serial device, which will give the VCPU threads time to queue input bytes from
177         // the input thread's buffer, changing the serial device state accordingly.
178         let interrupt_enable = self.interrupt_enable.clone();
179         let interrupt_evt = match self.interrupt_evt.try_clone() {
180             Ok(e) => e,
181             Err(e) => {
182                 error!("failed to clone interrupt event: {}", e);
183                 return;
184             }
185         };
186 
187         self.worker = Some(WorkerThread::start(
188             format!("{} input thread", self.debug_label()),
189             move |kill_evt| {
190                 let mut rx_buf = [0u8; 1];
191 
192                 #[derive(EventToken)]
193                 enum Token {
194                     Kill,
195                     SerialEvent,
196                 }
197 
198                 let wait_ctx_res: Result<WaitContext<Token>> = WaitContext::build_with(&[
199                     (&kill_evt, Token::Kill),
200                     (rx.get_read_notifier(), Token::SerialEvent),
201                 ]);
202                 let wait_ctx = match wait_ctx_res {
203                     Ok(wait_context) => wait_context,
204                     Err(e) => {
205                         error!("Failed to create wait context. {}", e);
206                         return rx;
207                     }
208                 };
209                 let mut kill_timeout = None;
210                 loop {
211                     let events = match wait_ctx.wait() {
212                         Ok(events) => events,
213                         Err(e) => {
214                             error!("Failed to wait for events. {}", e);
215                             return rx;
216                         }
217                     };
218                     for event in events.iter() {
219                         match event.token {
220                             Token::Kill => {
221                                 // Ignore the kill event until there are no other events to process
222                                 // so that we drain `rx` as much as possible. The next
223                                 // `wait_ctx.wait()` call will immediately re-entry this case since
224                                 // we don't call `kill_evt.wait()`.
225                                 if events.iter().all(|e| matches!(e.token, Token::Kill)) {
226                                     return rx;
227                                 }
228                                 const TIMEOUT_DURATION: Duration = Duration::from_millis(500);
229                                 match kill_timeout {
230                                     None => {
231                                         kill_timeout = Some(Instant::now() + TIMEOUT_DURATION);
232                                     }
233                                     Some(t) => {
234                                         if Instant::now() >= t {
235                                             error!(
236                                                 "failed to drain serial input within {:?}, giving up",
237                                                 TIMEOUT_DURATION
238                                             );
239                                             return rx;
240                                         }
241                                     }
242                                 }
243                             }
244                             Token::SerialEvent => {
245                                 // Matches both is_readable and is_hungup.
246                                 // In the case of is_hungup, there might still be data in the
247                                 // buffer, and a regular read would occur. When the buffer is
248                                 // empty, is_hungup would read EOF.
249                                 match rx.read(&mut rx_buf) {
250                                     // Assume the stream of input has ended.
251                                     Ok(0) => {
252                                         return rx;
253                                     }
254                                     Ok(_n) => {
255                                         if send_channel.send(rx_buf[0]).is_err() {
256                                             // The receiver has disconnected.
257                                             return rx;
258                                         }
259                                         if (interrupt_enable.load(Ordering::SeqCst) & IER_RECV_BIT)
260                                             != 0
261                                         {
262                                             interrupt_evt.signal().unwrap();
263                                         }
264                                     }
265                                     Err(e) => {
266                                         // Being interrupted is not an error, but everything else
267                                         // is.
268                                         if e.kind() != io::ErrorKind::Interrupted {
269                                             error!(
270                                                 "failed to read for bytes to queue into serial device: {}",
271                                                 e
272                                             );
273                                             return rx;
274                                         }
275                                     }
276                                 }
277                             }
278                         }
279                     }
280                 }
281             },
282         ));
283         self.in_channel = Some(recv_channel);
284     }
285 
drain_in_channel(&mut self)286     fn drain_in_channel(&mut self) {
287         loop {
288             let in_channel = match self.in_channel.as_ref() {
289                 Some(v) => v,
290                 None => return,
291             };
292             match in_channel.try_recv() {
293                 Ok(byte) => {
294                     self.queue_input_bytes(&[byte]).unwrap();
295                 }
296                 Err(TryRecvError::Empty) => break,
297                 Err(TryRecvError::Disconnected) => {
298                     self.in_channel = None;
299                     return;
300                 }
301             }
302         }
303     }
304 
305     /// Gets the interrupt event used to interrupt the driver when it needs to respond to this
306     /// device.
interrupt_event(&self) -> &Event307     pub fn interrupt_event(&self) -> &Event {
308         &self.interrupt_evt
309     }
310 
is_dlab_set(&self) -> bool311     fn is_dlab_set(&self) -> bool {
312         (self.line_control & 0x80) != 0
313     }
314 
is_recv_intr_enabled(&self) -> bool315     fn is_recv_intr_enabled(&self) -> bool {
316         (self.interrupt_enable.load(Ordering::SeqCst) & IER_RECV_BIT) != 0
317     }
318 
is_thr_intr_enabled(&self) -> bool319     fn is_thr_intr_enabled(&self) -> bool {
320         (self.interrupt_enable.load(Ordering::SeqCst) & IER_THR_BIT) != 0
321     }
322 
is_thr_intr_changed(&self, bit: u8) -> bool323     fn is_thr_intr_changed(&self, bit: u8) -> bool {
324         (self.interrupt_enable.load(Ordering::SeqCst) ^ bit) & IER_FIFO_BITS != 0
325     }
326 
is_loop(&self) -> bool327     fn is_loop(&self) -> bool {
328         (self.modem_control & MCR_LOOP_BIT) != 0
329     }
330 
add_intr_bit(&mut self, bit: u8)331     fn add_intr_bit(&mut self, bit: u8) {
332         self.interrupt_identification &= !IIR_NONE_BIT;
333         self.interrupt_identification |= bit;
334     }
335 
del_intr_bit(&mut self, bit: u8)336     fn del_intr_bit(&mut self, bit: u8) {
337         self.interrupt_identification &= !bit;
338         if self.interrupt_identification == 0x0 {
339             self.interrupt_identification = IIR_NONE_BIT;
340         }
341     }
342 
trigger_thr_empty(&mut self) -> Result<()>343     fn trigger_thr_empty(&mut self) -> Result<()> {
344         if self.is_thr_intr_enabled() {
345             self.add_intr_bit(IIR_THR_BIT);
346             self.trigger_interrupt()?
347         }
348         Ok(())
349     }
350 
trigger_recv_interrupt(&mut self) -> Result<()>351     fn trigger_recv_interrupt(&mut self) -> Result<()> {
352         if self.is_recv_intr_enabled() {
353             // Only bother triggering the interrupt if the identification bit wasn't set or
354             // acknowledged.
355             if self.interrupt_identification & IIR_RECV_BIT == 0 {
356                 self.add_intr_bit(IIR_RECV_BIT);
357                 self.trigger_interrupt()?
358             }
359         }
360         Ok(())
361     }
362 
trigger_interrupt(&mut self) -> Result<()>363     fn trigger_interrupt(&mut self) -> Result<()> {
364         self.interrupt_evt.signal()
365     }
366 
set_data_bit(&mut self)367     fn set_data_bit(&mut self) {
368         self.line_status |= LSR_DATA_BIT;
369     }
370 
is_data_avaiable(&self) -> bool371     fn is_data_avaiable(&self) -> bool {
372         (self.line_status & LSR_DATA_BIT) != 0
373     }
374 
iir_reset(&mut self)375     fn iir_reset(&mut self) {
376         self.interrupt_identification = DEFAULT_INTERRUPT_IDENTIFICATION;
377     }
378 
handle_write(&mut self, offset: u8, v: u8) -> Result<()>379     fn handle_write(&mut self, offset: u8, v: u8) -> Result<()> {
380         match offset {
381             DLAB_LOW if self.is_dlab_set() => {
382                 self.baud_divisor = (self.baud_divisor & 0xff00) | v as u16
383             }
384             DLAB_HIGH if self.is_dlab_set() => {
385                 self.baud_divisor = (self.baud_divisor & 0x00ff) | ((v as u16) << 8)
386             }
387             DATA => {
388                 if self.is_loop() {
389                     if self.in_buffer.len() < LOOP_SIZE {
390                         self.in_buffer.push_back(v);
391                         self.set_data_bit();
392                         self.trigger_recv_interrupt()?;
393                     }
394                 } else {
395                     self.handle_write_data(v)?;
396                     self.trigger_thr_empty()?;
397                 }
398             }
399             IER => {
400                 let tx_changed = self.is_thr_intr_changed(v);
401                 self.interrupt_enable
402                     .store(v & IER_FIFO_BITS, Ordering::SeqCst);
403 
404                 if self.is_data_avaiable() {
405                     self.trigger_recv_interrupt()?;
406                 }
407 
408                 if tx_changed {
409                     self.trigger_thr_empty()?;
410                 }
411             }
412             LCR => self.line_control = v,
413             MCR => self.modem_control = v,
414             SCR => self.scratch = v,
415             _ => {}
416         }
417         Ok(())
418     }
419 
420     // Write a single byte of data to `self.out`.
handle_write_data(&mut self, v: u8) -> Result<()>421     fn handle_write_data(&mut self, v: u8) -> Result<()> {
422         let out = match self.out.as_mut() {
423             Some(out) => out,
424             None => return Ok(()),
425         };
426 
427         if self.out_timestamp && self.last_write_was_newline {
428             write!(out, "{}", chrono::Utc::now().format(TIMESTAMP_PREFIX_FMT))?;
429         }
430 
431         self.last_write_was_newline = v == b'\n';
432 
433         out.write_all(&[v])?;
434         out.flush()?;
435         Ok(())
436     }
437 }
438 
439 impl BusDevice for Serial {
device_id(&self) -> DeviceId440     fn device_id(&self) -> DeviceId {
441         CrosvmDeviceId::Serial.into()
442     }
443 
debug_label(&self) -> String444     fn debug_label(&self) -> String {
445         "serial".to_owned()
446     }
447 
write(&mut self, info: BusAccessInfo, data: &[u8])448     fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
449         if matches!(self.device_state, DeviceState::Sleep) {
450             panic!("Unexpected action: Attempt to write to serial when device is in sleep mode");
451         }
452 
453         if data.len() != 1 {
454             return;
455         }
456 
457         #[cfg(windows)]
458         self.handle_sync_thread();
459 
460         if let Err(e) = self.handle_write(info.offset as u8, data[0]) {
461             error!("serial failed write: {}", e);
462         }
463     }
464 
read(&mut self, info: BusAccessInfo, data: &mut [u8])465     fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
466         if matches!(self.device_state, DeviceState::Sleep) {
467             panic!("Unexpected action: Attempt to write to serial when device is in sleep mode");
468         }
469 
470         if data.len() != 1 {
471             return;
472         }
473 
474         if self.input.is_some() {
475             self.spawn_input_thread();
476         }
477         self.drain_in_channel();
478 
479         data[0] = match info.offset as u8 {
480             DLAB_LOW if self.is_dlab_set() => self.baud_divisor as u8,
481             DLAB_HIGH if self.is_dlab_set() => (self.baud_divisor >> 8) as u8,
482             DATA => {
483                 self.del_intr_bit(IIR_RECV_BIT);
484                 if self.in_buffer.len() <= 1 {
485                     self.line_status &= !LSR_DATA_BIT;
486                 }
487                 self.in_buffer.pop_front().unwrap_or_default()
488             }
489             IER => self.interrupt_enable.load(Ordering::SeqCst),
490             IIR => {
491                 let v = self.interrupt_identification | IIR_FIFO_BITS;
492                 self.iir_reset();
493                 v
494             }
495             LCR => self.line_control,
496             MCR => self.modem_control,
497             LSR => self.line_status,
498             MSR => {
499                 if self.is_loop() {
500                     let mut msr =
501                         self.modem_status & !(MSR_DSR_BIT | MSR_CTS_BIT | MSR_RI_BIT | MSR_DCD_BIT);
502                     if self.modem_control & MCR_DTR_BIT != 0 {
503                         msr |= MSR_DSR_BIT;
504                     }
505                     if self.modem_control & MCR_RTS_BIT != 0 {
506                         msr |= MSR_CTS_BIT;
507                     }
508                     if self.modem_control & MCR_OUT1_BIT != 0 {
509                         msr |= MSR_RI_BIT;
510                     }
511                     if self.modem_control & MCR_OUT2_BIT != 0 {
512                         msr |= MSR_DCD_BIT;
513                     }
514                     msr
515                 } else {
516                     self.modem_status
517                 }
518             }
519             SCR => self.scratch,
520             _ => 0,
521         };
522     }
523 }
524 
525 #[derive(Serialize, Deserialize)]
526 struct SerialSnapshot {
527     interrupt_enable: u8,
528     interrupt_identification: u8,
529     line_control: u8,
530     line_status: u8,
531     modem_control: u8,
532     modem_status: u8,
533     scratch: u8,
534     baud_divisor: u16,
535 
536     in_buffer: VecDeque<u8>,
537 
538     has_input: bool,
539     has_output: bool,
540 
541     last_write_was_newline: bool,
542 }
543 
544 impl Suspendable for Serial {
snapshot(&mut self) -> anyhow::Result<serde_json::Value>545     fn snapshot(&mut self) -> anyhow::Result<serde_json::Value> {
546         self.spawn_input_thread();
547         if let Some(worker) = self.worker.take() {
548             self.input = Some(worker.stop());
549         }
550         self.drain_in_channel();
551         let snap = SerialSnapshot {
552             interrupt_enable: self.interrupt_enable.load(Ordering::SeqCst),
553             interrupt_identification: self.interrupt_identification,
554             line_control: self.line_control,
555             line_status: self.line_status,
556             modem_control: self.modem_control,
557             modem_status: self.modem_status,
558             scratch: self.scratch,
559             baud_divisor: self.baud_divisor,
560             in_buffer: self.in_buffer.clone(),
561             has_input: self.input.is_some(),
562             has_output: self.out.is_some(),
563             last_write_was_newline: self.last_write_was_newline,
564         };
565 
566         let serialized = serde_json::to_value(snap).context("error serializing")?;
567         Ok(serialized)
568     }
569 
restore(&mut self, data: serde_json::Value) -> anyhow::Result<()>570     fn restore(&mut self, data: serde_json::Value) -> anyhow::Result<()> {
571         let serial_snapshot: SerialSnapshot =
572             serde_json::from_value(data).context("error deserializing")?;
573         self.interrupt_enable = Arc::new(AtomicU8::new(serial_snapshot.interrupt_enable));
574         self.interrupt_identification = serial_snapshot.interrupt_identification;
575         self.line_control = serial_snapshot.line_control;
576         self.line_status = serial_snapshot.line_status;
577         self.modem_control = serial_snapshot.modem_control;
578         self.modem_status = serial_snapshot.modem_status;
579         self.scratch = serial_snapshot.scratch;
580         self.baud_divisor = serial_snapshot.baud_divisor;
581         self.in_buffer = serial_snapshot.in_buffer;
582         if serial_snapshot.has_input && self.input.is_none() {
583             warn!("Restore serial input missing when restore expected an input");
584         }
585         if serial_snapshot.has_output && self.out.is_none() {
586             warn!("Restore serial out missing when restore expected an out");
587         }
588         self.last_write_was_newline = serial_snapshot.last_write_was_newline;
589         Ok(())
590     }
591 
sleep(&mut self) -> anyhow::Result<()>592     fn sleep(&mut self) -> anyhow::Result<()> {
593         if !matches!(self.device_state, DeviceState::Sleep) {
594             self.device_state = DeviceState::Sleep;
595             if let Some(worker) = self.worker.take() {
596                 self.input = Some(worker.stop());
597             }
598 
599             self.drain_in_channel();
600             self.in_channel = None;
601         }
602         Ok(())
603     }
604 
wake(&mut self) -> anyhow::Result<()>605     fn wake(&mut self) -> anyhow::Result<()> {
606         if !matches!(self.device_state, DeviceState::Awake) {
607             self.device_state = DeviceState::Awake;
608             if self.input.is_some() {
609                 self.spawn_input_thread();
610             }
611         }
612         Ok(())
613     }
614 }
615 
616 #[cfg(test)]
617 mod tests {
618     use std::io;
619     use std::sync::Arc;
620 
621     use hypervisor::ProtectionType;
622     use sync::Mutex;
623 
624     use super::*;
625     use crate::serial_device::SerialOptions;
626     use crate::suspendable_tests;
627     pub use crate::sys::serial_device::SerialDevice;
628 
629     #[derive(Clone)]
630     pub(super) struct SharedBuffer {
631         pub(super) buf: Arc<Mutex<Vec<u8>>>,
632     }
633 
634     /// Empties the in_buffer.
635     impl Serial {
clear_in_buffer(&mut self)636         pub fn clear_in_buffer(&mut self) {
637             self.in_buffer.clear()
638         }
639     }
640 
641     impl SharedBuffer {
new() -> SharedBuffer642         pub(super) fn new() -> SharedBuffer {
643             SharedBuffer {
644                 buf: Arc::new(Mutex::new(Vec::new())),
645             }
646         }
647     }
648 
649     impl io::Write for SharedBuffer {
write(&mut self, buf: &[u8]) -> io::Result<usize>650         fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
651             self.buf.lock().write(buf)
652         }
flush(&mut self) -> io::Result<()>653         fn flush(&mut self) -> io::Result<()> {
654             self.buf.lock().flush()
655         }
656     }
657 
serial_bus_address(offset: u8) -> BusAccessInfo658     pub(super) fn serial_bus_address(offset: u8) -> BusAccessInfo {
659         // Serial devices only use the offset of the BusAccessInfo
660         BusAccessInfo {
661             offset: offset as u64,
662             address: 0,
663             id: 0,
664         }
665     }
666 
667     #[test]
serial_output()668     fn serial_output() {
669         let intr_evt = Event::new().unwrap();
670         let serial_out = SharedBuffer::new();
671 
672         let mut serial = Serial::new(
673             ProtectionType::Unprotected,
674             intr_evt,
675             None,
676             Some(Box::new(serial_out.clone())),
677             None,
678             Default::default(),
679             Vec::new(),
680         );
681 
682         serial.write(serial_bus_address(DATA), b"a");
683         serial.write(serial_bus_address(DATA), b"b");
684         serial.write(serial_bus_address(DATA), b"c");
685         assert_eq!(serial_out.buf.lock().as_slice(), b"abc");
686     }
687 
688     #[test]
serial_input()689     fn serial_input() {
690         let intr_evt = Event::new().unwrap();
691         let serial_out = SharedBuffer::new();
692 
693         let mut serial = Serial::new(
694             ProtectionType::Unprotected,
695             intr_evt.try_clone().unwrap(),
696             None,
697             Some(Box::new(serial_out)),
698             None,
699             Default::default(),
700             Vec::new(),
701         );
702 
703         serial.write(serial_bus_address(IER), &[IER_RECV_BIT]);
704         serial.queue_input_bytes(b"abc").unwrap();
705 
706         assert_eq!(intr_evt.wait(), Ok(()));
707         let mut data = [0u8; 1];
708         serial.read(serial_bus_address(DATA), &mut data[..]);
709         assert_eq!(data[0], b'a');
710         serial.read(serial_bus_address(DATA), &mut data[..]);
711         assert_eq!(data[0], b'b');
712         serial.read(serial_bus_address(DATA), &mut data[..]);
713         assert_eq!(data[0], b'c');
714     }
715 
716     #[test]
serial_input_sleep_snapshot_restore_wake()717     fn serial_input_sleep_snapshot_restore_wake() {
718         let intr_evt = Event::new().unwrap();
719         let serial_out = SharedBuffer::new();
720 
721         let mut serial = Serial::new(
722             ProtectionType::Unprotected,
723             intr_evt.try_clone().unwrap(),
724             None,
725             Some(Box::new(serial_out)),
726             None,
727             Default::default(),
728             Vec::new(),
729         );
730 
731         serial.write(serial_bus_address(IER), &[IER_RECV_BIT]);
732         serial.queue_input_bytes(b"abc").unwrap();
733 
734         assert_eq!(intr_evt.wait(), Ok(()));
735         let mut data = [0u8; 1];
736         serial.read(serial_bus_address(DATA), &mut data[..]);
737         assert_eq!(data[0], b'a');
738         let sleep_res = serial.sleep();
739         match sleep_res {
740             Ok(_res) => (),
741             Err(e) => println!("{}", e),
742         }
743         let snap_res = serial.snapshot();
744         match snap_res {
745             Ok(snap) => {
746                 let restore_res = serial.restore(snap);
747                 match restore_res {
748                     Ok(_rest) => (),
749                     Err(e) => println!("{}", e),
750                 }
751             }
752             Err(e) => println!("{}", e),
753         }
754         let wake_res = serial.wake();
755         match wake_res {
756             Ok(_res) => (),
757             Err(e) => println!("{}", e),
758         }
759         serial.read(serial_bus_address(DATA), &mut data[..]);
760         assert_eq!(data[0], b'b');
761         serial.read(serial_bus_address(DATA), &mut data[..]);
762         assert_eq!(data[0], b'c');
763     }
764 
765     #[test]
serial_input_snapshot_restore()766     fn serial_input_snapshot_restore() {
767         let intr_evt = Event::new().unwrap();
768         let serial_out = SharedBuffer::new();
769 
770         let mut serial = Serial::new(
771             ProtectionType::Unprotected,
772             intr_evt.try_clone().unwrap(),
773             None,
774             Some(Box::new(serial_out)),
775             None,
776             Default::default(),
777             Vec::new(),
778         );
779 
780         serial.write(serial_bus_address(IER), &[IER_RECV_BIT]);
781         serial.queue_input_bytes(b"abc").unwrap();
782 
783         assert_eq!(intr_evt.wait(), Ok(()));
784         let mut data = [0u8; 1];
785         serial.read(serial_bus_address(DATA), &mut data[..]);
786         assert_eq!(data[0], b'a');
787         // Take snapshot after reading b'a'. Serial still contains b'b' and b'c'.
788         let snap = serial.snapshot().expect("failed to snapshot serial");
789         serial.read(serial_bus_address(DATA), &mut data[..]);
790         assert_eq!(data[0], b'b');
791         // Restore snapshot taken after reading b'a'. New reading should give us b'b' since it was
792         // the saved state at the moment of taking a snapshot.
793         let restore_res = serial.restore(snap);
794         match restore_res {
795             Ok(()) => (),
796             Err(e) => println!("Error: {}", e),
797         }
798         serial.read(serial_bus_address(DATA), &mut data[..]);
799         assert_eq!(data[0], b'b');
800         serial.read(serial_bus_address(DATA), &mut data[..]);
801         assert_eq!(data[0], b'c');
802     }
803 
804     #[test]
serial_input_snapshot_write_restore()805     fn serial_input_snapshot_write_restore() {
806         let intr_evt = Event::new().unwrap();
807         let serial_out = SharedBuffer::new();
808 
809         let mut serial = Serial::new(
810             ProtectionType::Unprotected,
811             intr_evt.try_clone().unwrap(),
812             None,
813             Some(Box::new(serial_out)),
814             None,
815             Default::default(),
816             Vec::new(),
817         );
818 
819         serial.write(serial_bus_address(IER), &[IER_RECV_BIT]);
820         serial.queue_input_bytes(b"abc").unwrap();
821 
822         assert_eq!(intr_evt.wait(), Ok(()));
823         let mut data = [0u8; 1];
824         serial.read(serial_bus_address(DATA), &mut data[..]);
825         assert_eq!(data[0], b'a');
826         // Take snapshot after reading b'a'. Serial still contains b'b' and b'c'.
827         let snap = serial.snapshot().expect("failed to snapshot serial");
828         serial.clear_in_buffer();
829         serial.queue_input_bytes(b"abc").unwrap();
830         serial.read(serial_bus_address(DATA), &mut data[..]);
831         assert_eq!(data[0], b'a');
832         serial.read(serial_bus_address(DATA), &mut data[..]);
833         assert_eq!(data[0], b'b');
834         serial.read(serial_bus_address(DATA), &mut data[..]);
835         assert_eq!(data[0], b'c');
836         // Restore snapshot taken after reading b'a'. New reading should give us b'b' since it was
837         // the saved state at the moment of taking a snapshot.
838         let restore_res = serial.restore(snap);
839         match restore_res {
840             Ok(()) => (),
841             Err(e) => println!("Error: {}", e),
842         }
843         serial.read(serial_bus_address(DATA), &mut data[..]);
844         assert_eq!(data[0], b'b');
845         serial.read(serial_bus_address(DATA), &mut data[..]);
846         assert_eq!(data[0], b'c');
847     }
848 
849     // Test should panic. Sleep, try to read while sleeping.
850     #[test]
851     #[should_panic]
serial_input_sleep_read_panic()852     fn serial_input_sleep_read_panic() {
853         let intr_evt = Event::new().unwrap();
854         let serial_out = SharedBuffer::new();
855 
856         let mut serial = Serial::new(
857             ProtectionType::Unprotected,
858             intr_evt.try_clone().unwrap(),
859             None,
860             Some(Box::new(serial_out)),
861             None,
862             Default::default(),
863             Vec::new(),
864         );
865 
866         serial.write(serial_bus_address(IER), &[IER_RECV_BIT]);
867         serial.queue_input_bytes(b"abc").unwrap();
868 
869         assert_eq!(intr_evt.wait(), Ok(()));
870         let mut data = [0u8; 1];
871         serial.read(serial_bus_address(DATA), &mut data[..]);
872         assert_eq!(data[0], b'a');
873         serial.read(serial_bus_address(DATA), &mut data[..]);
874         assert_eq!(data[0], b'b');
875         let sleep_res = serial.sleep();
876         match sleep_res {
877             Ok(_res) => (),
878             Err(e) => println!("{}", e),
879         }
880         // Test should panic when trying to read after sleep.
881         serial.read(serial_bus_address(DATA), &mut data[..]);
882         assert_eq!(data[0], b'b');
883     }
884 
885     // Test should panic. Sleep, try to read while sleeping.
886     #[test]
887     #[should_panic]
serial_input_sleep_write_panic()888     fn serial_input_sleep_write_panic() {
889         let intr_evt = Event::new().unwrap();
890         let serial_out = SharedBuffer::new();
891 
892         let mut serial = Serial::new(
893             ProtectionType::Unprotected,
894             intr_evt.try_clone().unwrap(),
895             None,
896             Some(Box::new(serial_out)),
897             None,
898             Default::default(),
899             Vec::new(),
900         );
901 
902         let sleep_res = serial.sleep();
903         match sleep_res {
904             Ok(_res) => (),
905             Err(e) => println!("{}", e),
906         }
907         // Test should panic when trying to read after sleep.
908         serial.write(serial_bus_address(IER), &[IER_RECV_BIT]);
909     }
910 
911     #[test]
serial_input_sleep_wake()912     fn serial_input_sleep_wake() {
913         let intr_evt = Event::new().unwrap();
914         let serial_out = SharedBuffer::new();
915 
916         let mut serial = Serial::new(
917             ProtectionType::Unprotected,
918             intr_evt.try_clone().unwrap(),
919             None,
920             Some(Box::new(serial_out)),
921             None,
922             Default::default(),
923             Vec::new(),
924         );
925 
926         serial.write(serial_bus_address(IER), &[IER_RECV_BIT]);
927         serial.queue_input_bytes(b"abc").unwrap();
928 
929         assert_eq!(intr_evt.wait(), Ok(()));
930         let mut data = [0u8; 1];
931         serial.read(serial_bus_address(DATA), &mut data[..]);
932         assert_eq!(data[0], b'a');
933         serial.read(serial_bus_address(DATA), &mut data[..]);
934         assert_eq!(data[0], b'b');
935         let sleep_res = serial.sleep();
936         match sleep_res {
937             Ok(_res) => (),
938             Err(e) => println!("{}", e),
939         }
940         let wake_res = serial.wake();
941         match wake_res {
942             Ok(_res) => (),
943             Err(e) => println!("{}", e),
944         }
945         serial.read(serial_bus_address(DATA), &mut data[..]);
946         assert_eq!(data[0], b'c');
947     }
948 
modify_device(serial: &mut Serial)949     fn modify_device(serial: &mut Serial) {
950         serial.clear_in_buffer();
951         serial.queue_input_bytes(b"abc").unwrap();
952     }
953 
954     suspendable_tests!(
955         serial,
956         Serial::new(
957             ProtectionType::Unprotected,
958             Event::new().unwrap(),
959             None,
960             Some(Box::new(SharedBuffer::new())),
961             None,
962             Default::default(),
963             Vec::new(),
964         ),
965         modify_device
966     );
967 
assert_timestamp_is_present(data: &[u8], serial_message: &str)968     fn assert_timestamp_is_present(data: &[u8], serial_message: &str) {
969         const TIMESTAMP_START: &str = "[";
970         const TIMESTAMP_END: &str = "]: ";
971 
972         let data_str = std::str::from_utf8(data).unwrap();
973         let timestamp_bracket = data_str
974             .find(TIMESTAMP_END)
975             .expect("missing timestamp end bracket");
976         let (timestamp, message) = data_str.split_at(timestamp_bracket + TIMESTAMP_END.len());
977 
978         assert!(timestamp.starts_with(TIMESTAMP_START));
979         assert!(timestamp.ends_with(TIMESTAMP_END));
980 
981         assert_eq!(message.trim_end(), serial_message);
982     }
983 
984     #[test]
serial_output_timestamp()985     fn serial_output_timestamp() {
986         let intr_evt = Event::new().unwrap();
987         let serial_out = SharedBuffer::new();
988 
989         let mut serial = Serial::new(
990             ProtectionType::Unprotected,
991             intr_evt,
992             None,
993             Some(Box::new(serial_out.clone())),
994             None,
995             SerialOptions {
996                 out_timestamp: true,
997                 ..Default::default()
998             },
999             Vec::new(),
1000         );
1001 
1002         serial.write(serial_bus_address(DATA), b"a");
1003         serial.write(serial_bus_address(DATA), b"\n");
1004         assert_timestamp_is_present(serial_out.buf.lock().as_slice(), "a");
1005         serial_out.buf.lock().clear();
1006 
1007         serial.write(serial_bus_address(DATA), b"b");
1008         serial.write(serial_bus_address(DATA), b"\n");
1009         assert_timestamp_is_present(serial_out.buf.lock().as_slice(), "b");
1010         serial_out.buf.lock().clear();
1011 
1012         serial.write(serial_bus_address(DATA), b"c");
1013         serial.write(serial_bus_address(DATA), b"\n");
1014         assert_timestamp_is_present(serial_out.buf.lock().as_slice(), "c");
1015         serial_out.buf.lock().clear();
1016     }
1017 }
1018