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