1 // Copyright 2017 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::collections::VecDeque; 6 use std::io::{self, Write}; 7 use std::sync::atomic::{AtomicU8, Ordering}; 8 use std::sync::mpsc::{channel, Receiver, TryRecvError}; 9 use std::sync::Arc; 10 use std::thread::{self}; 11 12 use base::{error, Event, FileSync, RawDescriptor, Result}; 13 use hypervisor::ProtectionType; 14 15 use crate::bus::BusAccessInfo; 16 use crate::{BusDevice, SerialDevice}; 17 18 const LOOP_SIZE: usize = 0x40; 19 20 const DATA: u8 = 0; 21 const IER: u8 = 1; 22 const IIR: u8 = 2; 23 const LCR: u8 = 3; 24 const MCR: u8 = 4; 25 const LSR: u8 = 5; 26 const MSR: u8 = 6; 27 const SCR: u8 = 7; 28 const DLAB_LOW: u8 = 0; 29 const DLAB_HIGH: u8 = 1; 30 31 const IER_RECV_BIT: u8 = 0x1; 32 const IER_THR_BIT: u8 = 0x2; 33 const IER_FIFO_BITS: u8 = 0x0f; 34 35 const IIR_FIFO_BITS: u8 = 0xc0; 36 const IIR_NONE_BIT: u8 = 0x1; 37 const IIR_THR_BIT: u8 = 0x2; 38 const IIR_RECV_BIT: u8 = 0x4; 39 40 const LSR_DATA_BIT: u8 = 0x1; 41 const LSR_EMPTY_BIT: u8 = 0x20; 42 const LSR_IDLE_BIT: u8 = 0x40; 43 44 const MCR_DTR_BIT: u8 = 0x01; // Data Terminal Ready 45 const MCR_RTS_BIT: u8 = 0x02; // Request to Send 46 const MCR_OUT1_BIT: u8 = 0x04; 47 const MCR_OUT2_BIT: u8 = 0x08; 48 const MCR_LOOP_BIT: u8 = 0x10; 49 50 const MSR_CTS_BIT: u8 = 0x10; // Clear to Send 51 const MSR_DSR_BIT: u8 = 0x20; // Data Set Ready 52 const MSR_RI_BIT: u8 = 0x40; // Ring Indicator 53 const MSR_DCD_BIT: u8 = 0x80; // Data Carrier Detect 54 55 const DEFAULT_INTERRUPT_IDENTIFICATION: u8 = IIR_NONE_BIT; // no pending interrupt 56 const DEFAULT_LINE_STATUS: u8 = LSR_EMPTY_BIT | LSR_IDLE_BIT; // THR empty and line is idle 57 const DEFAULT_LINE_CONTROL: u8 = 0x3; // 8-bits per character 58 const DEFAULT_MODEM_CONTROL: u8 = MCR_OUT2_BIT; 59 const DEFAULT_MODEM_STATUS: u8 = MSR_DSR_BIT | MSR_CTS_BIT | MSR_DCD_BIT; 60 const DEFAULT_BAUD_DIVISOR: u16 = 12; // 9600 bps 61 62 /// Emulates serial COM ports commonly seen on x86 I/O ports 0x3f8/0x2f8/0x3e8/0x2e8. 63 /// 64 /// This can optionally write the guest's output to a Write trait object. To send input to the 65 /// guest, use `queue_input_bytes` directly, or give a Read trait object which will be used queue 66 /// bytes when `used_command` is called. 67 pub struct Serial { 68 // Serial port registers 69 interrupt_enable: Arc<AtomicU8>, 70 interrupt_identification: u8, 71 interrupt_evt: Event, 72 line_control: u8, 73 line_status: u8, 74 modem_control: u8, 75 modem_status: u8, 76 scratch: u8, 77 baud_divisor: u16, 78 79 // Host input/output 80 in_buffer: VecDeque<u8>, 81 in_channel: Option<Receiver<u8>>, 82 input: Option<Box<dyn io::Read + Send>>, 83 out: Option<Box<dyn io::Write + Send>>, 84 } 85 86 impl SerialDevice for Serial { new( _protected_vm: ProtectionType, interrupt_evt: Event, input: Option<Box<dyn io::Read + Send>>, out: Option<Box<dyn io::Write + Send>>, _sync: Option<Box<dyn FileSync + Send>>, _out_timestamp: bool, _keep_rds: Vec<RawDescriptor>, ) -> Serial87 fn new( 88 _protected_vm: ProtectionType, 89 interrupt_evt: Event, 90 input: Option<Box<dyn io::Read + Send>>, 91 out: Option<Box<dyn io::Write + Send>>, 92 _sync: Option<Box<dyn FileSync + Send>>, 93 _out_timestamp: bool, 94 _keep_rds: Vec<RawDescriptor>, 95 ) -> Serial { 96 Serial { 97 interrupt_enable: Default::default(), 98 interrupt_identification: DEFAULT_INTERRUPT_IDENTIFICATION, 99 interrupt_evt, 100 line_control: DEFAULT_LINE_CONTROL, 101 line_status: DEFAULT_LINE_STATUS, 102 modem_control: DEFAULT_MODEM_CONTROL, 103 modem_status: DEFAULT_MODEM_STATUS, 104 scratch: 0, 105 baud_divisor: DEFAULT_BAUD_DIVISOR, 106 in_buffer: Default::default(), 107 in_channel: None, 108 input, 109 out, 110 } 111 } 112 } 113 114 impl Serial { 115 /// Queues raw bytes for the guest to read and signals the interrupt if the line status would 116 /// change. These bytes will be read by the guest before any bytes from the input stream that 117 /// have not already been queued. queue_input_bytes(&mut self, c: &[u8]) -> Result<()>118 pub fn queue_input_bytes(&mut self, c: &[u8]) -> Result<()> { 119 if !c.is_empty() && !self.is_loop() { 120 self.in_buffer.extend(c); 121 self.set_data_bit(); 122 self.trigger_recv_interrupt()?; 123 } 124 125 Ok(()) 126 } 127 spawn_input_thread(&mut self)128 fn spawn_input_thread(&mut self) { 129 let mut rx = match self.input.take() { 130 Some(input) => input, 131 None => return, 132 }; 133 134 let (send_channel, recv_channel) = channel(); 135 136 // The interrupt enable and interrupt event are used to trigger the guest serial driver to 137 // read the serial device, which will give the VCPU threads time to queue input bytes from 138 // the input thread's buffer, changing the serial device state accordingly. 139 let interrupt_enable = self.interrupt_enable.clone(); 140 let interrupt_evt = match self.interrupt_evt.try_clone() { 141 Ok(e) => e, 142 Err(e) => { 143 error!("failed to clone interrupt event: {}", e); 144 return; 145 } 146 }; 147 148 // The input thread runs in detached mode and will exit when channel is disconnected because 149 // the serial device has been dropped. Initial versions of this kept a `JoinHandle` and had 150 // the drop implementation of serial join on this thread, but the input thread can block 151 // indefinitely depending on the `Box<io::Read>` implementation. 152 let res = thread::Builder::new() 153 .name(format!("{} input thread", self.debug_label())) 154 .spawn(move || { 155 let mut rx_buf = [0u8; 1]; 156 loop { 157 match rx.read(&mut rx_buf) { 158 Ok(0) => break, // Assume the stream of input has ended. 159 Ok(_) => { 160 if send_channel.send(rx_buf[0]).is_err() { 161 // The receiver has disconnected. 162 break; 163 } 164 if (interrupt_enable.load(Ordering::SeqCst) & IER_RECV_BIT) != 0 { 165 interrupt_evt.write(1).unwrap(); 166 } 167 } 168 Err(e) => { 169 // Being interrupted is not an error, but everything else is. 170 if e.kind() != io::ErrorKind::Interrupted { 171 error!( 172 "failed to read for bytes to queue into serial device: {}", 173 e 174 ); 175 break; 176 } 177 } 178 } 179 } 180 }); 181 if let Err(e) = res { 182 error!("failed to spawn input thread: {}", e); 183 return; 184 } 185 self.in_channel = Some(recv_channel); 186 } 187 handle_input_thread(&mut self)188 fn handle_input_thread(&mut self) { 189 if self.input.is_some() { 190 self.spawn_input_thread(); 191 } 192 193 loop { 194 let in_channel = match self.in_channel.as_ref() { 195 Some(v) => v, 196 None => return, 197 }; 198 match in_channel.try_recv() { 199 Ok(byte) => { 200 self.queue_input_bytes(&[byte]).unwrap(); 201 } 202 Err(TryRecvError::Empty) => break, 203 Err(TryRecvError::Disconnected) => { 204 self.in_channel = None; 205 return; 206 } 207 } 208 } 209 } 210 211 /// Gets the interrupt event used to interrupt the driver when it needs to respond to this 212 /// device. interrupt_event(&self) -> &Event213 pub fn interrupt_event(&self) -> &Event { 214 &self.interrupt_evt 215 } 216 is_dlab_set(&self) -> bool217 fn is_dlab_set(&self) -> bool { 218 (self.line_control & 0x80) != 0 219 } 220 is_recv_intr_enabled(&self) -> bool221 fn is_recv_intr_enabled(&self) -> bool { 222 (self.interrupt_enable.load(Ordering::SeqCst) & IER_RECV_BIT) != 0 223 } 224 is_thr_intr_enabled(&self) -> bool225 fn is_thr_intr_enabled(&self) -> bool { 226 (self.interrupt_enable.load(Ordering::SeqCst) & IER_THR_BIT) != 0 227 } 228 is_loop(&self) -> bool229 fn is_loop(&self) -> bool { 230 (self.modem_control & MCR_LOOP_BIT) != 0 231 } 232 add_intr_bit(&mut self, bit: u8)233 fn add_intr_bit(&mut self, bit: u8) { 234 self.interrupt_identification &= !IIR_NONE_BIT; 235 self.interrupt_identification |= bit; 236 } 237 del_intr_bit(&mut self, bit: u8)238 fn del_intr_bit(&mut self, bit: u8) { 239 self.interrupt_identification &= !bit; 240 if self.interrupt_identification == 0x0 { 241 self.interrupt_identification = IIR_NONE_BIT; 242 } 243 } 244 trigger_thr_empty(&mut self) -> Result<()>245 fn trigger_thr_empty(&mut self) -> Result<()> { 246 if self.is_thr_intr_enabled() { 247 self.add_intr_bit(IIR_THR_BIT); 248 self.trigger_interrupt()? 249 } 250 Ok(()) 251 } 252 trigger_recv_interrupt(&mut self) -> Result<()>253 fn trigger_recv_interrupt(&mut self) -> Result<()> { 254 if self.is_recv_intr_enabled() { 255 // Only bother triggering the interrupt if the identification bit wasn't set or 256 // acknowledged. 257 if self.interrupt_identification & IIR_RECV_BIT == 0 { 258 self.add_intr_bit(IIR_RECV_BIT); 259 self.trigger_interrupt()? 260 } 261 } 262 Ok(()) 263 } 264 trigger_interrupt(&mut self) -> Result<()>265 fn trigger_interrupt(&mut self) -> Result<()> { 266 self.interrupt_evt.write(1) 267 } 268 set_data_bit(&mut self)269 fn set_data_bit(&mut self) { 270 self.line_status |= LSR_DATA_BIT; 271 } 272 iir_reset(&mut self)273 fn iir_reset(&mut self) { 274 self.interrupt_identification = DEFAULT_INTERRUPT_IDENTIFICATION; 275 } 276 handle_write(&mut self, offset: u8, v: u8) -> Result<()>277 fn handle_write(&mut self, offset: u8, v: u8) -> Result<()> { 278 match offset as u8 { 279 DLAB_LOW if self.is_dlab_set() => { 280 self.baud_divisor = (self.baud_divisor & 0xff00) | v as u16 281 } 282 DLAB_HIGH if self.is_dlab_set() => { 283 self.baud_divisor = (self.baud_divisor & 0x00ff) | ((v as u16) << 8) 284 } 285 DATA => { 286 if self.is_loop() { 287 if self.in_buffer.len() < LOOP_SIZE { 288 self.in_buffer.push_back(v); 289 self.set_data_bit(); 290 self.trigger_recv_interrupt()?; 291 } 292 } else { 293 if let Some(out) = self.out.as_mut() { 294 out.write_all(&[v])?; 295 out.flush()?; 296 } 297 self.trigger_thr_empty()?; 298 } 299 } 300 IER => self 301 .interrupt_enable 302 .store(v & IER_FIFO_BITS, Ordering::SeqCst), 303 LCR => self.line_control = v, 304 MCR => self.modem_control = v, 305 SCR => self.scratch = v, 306 _ => {} 307 } 308 Ok(()) 309 } 310 } 311 312 impl BusDevice for Serial { debug_label(&self) -> String313 fn debug_label(&self) -> String { 314 "serial".to_owned() 315 } 316 write(&mut self, info: BusAccessInfo, data: &[u8])317 fn write(&mut self, info: BusAccessInfo, data: &[u8]) { 318 if data.len() != 1 { 319 return; 320 } 321 322 if let Err(e) = self.handle_write(info.offset as u8, data[0]) { 323 error!("serial failed write: {}", e); 324 } 325 } 326 read(&mut self, info: BusAccessInfo, data: &mut [u8])327 fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) { 328 if data.len() != 1 { 329 return; 330 } 331 332 self.handle_input_thread(); 333 334 data[0] = match info.offset as u8 { 335 DLAB_LOW if self.is_dlab_set() => self.baud_divisor as u8, 336 DLAB_HIGH if self.is_dlab_set() => (self.baud_divisor >> 8) as u8, 337 DATA => { 338 self.del_intr_bit(IIR_RECV_BIT); 339 if self.in_buffer.len() <= 1 { 340 self.line_status &= !LSR_DATA_BIT; 341 } 342 self.in_buffer.pop_front().unwrap_or_default() 343 } 344 IER => self.interrupt_enable.load(Ordering::SeqCst), 345 IIR => { 346 let v = self.interrupt_identification | IIR_FIFO_BITS; 347 self.iir_reset(); 348 v 349 } 350 LCR => self.line_control, 351 MCR => self.modem_control, 352 LSR => self.line_status, 353 MSR => { 354 if self.is_loop() { 355 let mut msr = 356 self.modem_status & !(MSR_DSR_BIT | MSR_CTS_BIT | MSR_RI_BIT | MSR_DCD_BIT); 357 if self.modem_control & MCR_DTR_BIT != 0 { 358 msr |= MSR_DSR_BIT; 359 } 360 if self.modem_control & MCR_RTS_BIT != 0 { 361 msr |= MSR_CTS_BIT; 362 } 363 if self.modem_control & MCR_OUT1_BIT != 0 { 364 msr |= MSR_RI_BIT; 365 } 366 if self.modem_control & MCR_OUT2_BIT != 0 { 367 msr |= MSR_DCD_BIT; 368 } 369 msr 370 } else { 371 self.modem_status 372 } 373 } 374 SCR => self.scratch, 375 _ => 0, 376 }; 377 } 378 } 379 380 #[cfg(test)] 381 mod tests { 382 use super::*; 383 use std::io; 384 use std::sync::Arc; 385 386 use sync::Mutex; 387 388 #[derive(Clone)] 389 struct SharedBuffer { 390 buf: Arc<Mutex<Vec<u8>>>, 391 } 392 393 impl SharedBuffer { new() -> SharedBuffer394 fn new() -> SharedBuffer { 395 SharedBuffer { 396 buf: Arc::new(Mutex::new(Vec::new())), 397 } 398 } 399 } 400 401 impl io::Write for SharedBuffer { write(&mut self, buf: &[u8]) -> io::Result<usize>402 fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 403 self.buf.lock().write(buf) 404 } flush(&mut self) -> io::Result<()>405 fn flush(&mut self) -> io::Result<()> { 406 self.buf.lock().flush() 407 } 408 } 409 serial_bus_address(offset: u8) -> BusAccessInfo410 fn serial_bus_address(offset: u8) -> BusAccessInfo { 411 // Serial devices only use the offset of the BusAccessInfo 412 BusAccessInfo { 413 offset: offset as u64, 414 address: 0, 415 id: 0, 416 } 417 } 418 419 #[test] serial_output()420 fn serial_output() { 421 let intr_evt = Event::new().unwrap(); 422 let serial_out = SharedBuffer::new(); 423 424 let mut serial = Serial::new( 425 ProtectionType::Unprotected, 426 intr_evt, 427 None, 428 Some(Box::new(serial_out.clone())), 429 None, 430 false, 431 Vec::new(), 432 ); 433 434 serial.write(serial_bus_address(DATA), &[b'a']); 435 serial.write(serial_bus_address(DATA), &[b'b']); 436 serial.write(serial_bus_address(DATA), &[b'c']); 437 assert_eq!(serial_out.buf.lock().as_slice(), &[b'a', b'b', b'c']); 438 } 439 440 #[test] serial_input()441 fn serial_input() { 442 let intr_evt = Event::new().unwrap(); 443 let serial_out = SharedBuffer::new(); 444 445 let mut serial = Serial::new( 446 ProtectionType::Unprotected, 447 intr_evt.try_clone().unwrap(), 448 None, 449 Some(Box::new(serial_out)), 450 None, 451 false, 452 Vec::new(), 453 ); 454 455 serial.write(serial_bus_address(IER), &[IER_RECV_BIT]); 456 serial.queue_input_bytes(&[b'a', b'b', b'c']).unwrap(); 457 458 assert_eq!(intr_evt.read(), Ok(1)); 459 let mut data = [0u8; 1]; 460 serial.read(serial_bus_address(DATA), &mut data[..]); 461 assert_eq!(data[0], b'a'); 462 serial.read(serial_bus_address(DATA), &mut data[..]); 463 assert_eq!(data[0], b'b'); 464 serial.read(serial_bus_address(DATA), &mut data[..]); 465 assert_eq!(data[0], b'c'); 466 } 467 } 468