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