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