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