devices/
serial.rs

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
5pub(crate) mod sys;
6
7use std::collections::VecDeque;
8use std::io;
9use std::sync::atomic::AtomicU8;
10use std::sync::atomic::Ordering;
11use std::sync::mpsc::channel;
12use std::sync::mpsc::Receiver;
13use std::sync::mpsc::TryRecvError;
14use std::sync::Arc;
15use std::time::Duration;
16use std::time::Instant;
17
18use anyhow::Context;
19use base::error;
20use base::warn;
21use base::Event;
22use base::EventToken;
23use base::Result;
24use base::WaitContext;
25use base::WorkerThread;
26use serde::Deserialize;
27use serde::Serialize;
28use snapshot::AnySnapshot;
29
30use crate::bus::BusAccessInfo;
31use crate::pci::CrosvmDeviceId;
32use crate::serial_device::SerialInput;
33use crate::suspendable::DeviceState;
34use crate::suspendable::Suspendable;
35use crate::BusDevice;
36use crate::DeviceId;
37
38const LOOP_SIZE: usize = 0x40;
39
40const DATA: u8 = 0;
41const IER: u8 = 1;
42const IIR: u8 = 2;
43const LCR: u8 = 3;
44const MCR: u8 = 4;
45const LSR: u8 = 5;
46const MSR: u8 = 6;
47const SCR: u8 = 7;
48const DLAB_LOW: u8 = 0;
49const DLAB_HIGH: u8 = 1;
50
51const IER_RECV_BIT: u8 = 0x1;
52const IER_THR_BIT: u8 = 0x2;
53const IER_FIFO_BITS: u8 = 0x0f;
54
55const IIR_FIFO_BITS: u8 = 0xc0;
56const IIR_NONE_BIT: u8 = 0x1;
57const IIR_THR_BIT: u8 = 0x2;
58const IIR_RECV_BIT: u8 = 0x4;
59
60const LSR_DATA_BIT: u8 = 0x1;
61const LSR_EMPTY_BIT: u8 = 0x20;
62const LSR_IDLE_BIT: u8 = 0x40;
63
64const MCR_DTR_BIT: u8 = 0x01; // Data Terminal Ready
65const MCR_RTS_BIT: u8 = 0x02; // Request to Send
66const MCR_OUT1_BIT: u8 = 0x04;
67const MCR_OUT2_BIT: u8 = 0x08;
68const MCR_LOOP_BIT: u8 = 0x10;
69
70const MSR_CTS_BIT: u8 = 0x10; // Clear to Send
71const MSR_DSR_BIT: u8 = 0x20; // Data Set Ready
72const MSR_RI_BIT: u8 = 0x40; // Ring Indicator
73const MSR_DCD_BIT: u8 = 0x80; // Data Carrier Detect
74
75const DEFAULT_INTERRUPT_IDENTIFICATION: u8 = IIR_NONE_BIT; // no pending interrupt
76const DEFAULT_LINE_STATUS: u8 = LSR_EMPTY_BIT | LSR_IDLE_BIT; // THR empty and line is idle
77const DEFAULT_LINE_CONTROL: u8 = 0x3; // 8-bits per character
78const DEFAULT_MODEM_CONTROL: u8 = MCR_OUT2_BIT;
79const DEFAULT_MODEM_STATUS: u8 = MSR_DSR_BIT | MSR_CTS_BIT | MSR_DCD_BIT;
80const DEFAULT_BAUD_DIVISOR: u16 = 12; // 9600 bps
81
82const 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.
89pub 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
114impl Serial {
115    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.
146    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`.
151    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.
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
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
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.
308    pub fn interrupt_event(&self) -> &Event {
309        &self.interrupt_evt
310    }
311
312    fn is_dlab_set(&self) -> bool {
313        (self.line_control & 0x80) != 0
314    }
315
316    fn is_recv_intr_enabled(&self) -> bool {
317        (self.interrupt_enable.load(Ordering::SeqCst) & IER_RECV_BIT) != 0
318    }
319
320    fn is_thr_intr_enabled(&self) -> bool {
321        (self.interrupt_enable.load(Ordering::SeqCst) & IER_THR_BIT) != 0
322    }
323
324    fn is_thr_intr_changed(&self, bit: u8) -> bool {
325        (self.interrupt_enable.load(Ordering::SeqCst) ^ bit) & IER_FIFO_BITS != 0
326    }
327
328    fn is_loop(&self) -> bool {
329        (self.modem_control & MCR_LOOP_BIT) != 0
330    }
331
332    fn add_intr_bit(&mut self, bit: u8) {
333        self.interrupt_identification &= !IIR_NONE_BIT;
334        self.interrupt_identification |= bit;
335    }
336
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
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
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
364    fn trigger_interrupt(&mut self) -> Result<()> {
365        self.interrupt_evt.signal()
366    }
367
368    fn set_data_bit(&mut self) {
369        self.line_status |= LSR_DATA_BIT;
370    }
371
372    fn is_data_avaiable(&self) -> bool {
373        (self.line_status & LSR_DATA_BIT) != 0
374    }
375
376    fn iir_reset(&mut self) {
377        self.interrupt_identification = DEFAULT_INTERRUPT_IDENTIFICATION;
378    }
379
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`.
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
440impl BusDevice for Serial {
441    fn device_id(&self) -> DeviceId {
442        CrosvmDeviceId::Serial.into()
443    }
444
445    fn debug_label(&self) -> String {
446        "serial".to_owned()
447    }
448
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
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)]
527struct 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
545impl Suspendable for Serial {
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
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
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
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)]
618mod 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 {
637        pub fn clear_in_buffer(&mut self) {
638            self.in_buffer.clear()
639        }
640    }
641
642    impl SharedBuffer {
643        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 {
651        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
652            self.buf.lock().write(buf)
653        }
654        fn flush(&mut self) -> io::Result<()> {
655            self.buf.lock().flush()
656        }
657    }
658
659    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]
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]
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]
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]
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]
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]
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]
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]
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
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
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]
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}