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