• 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, 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