• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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