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