diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2019-05-20 13:37:54 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-05-23 02:14:11 -0700 |
commit | 207b1fd2b5727fa09f0f0528d83ea2920628ddc2 (patch) | |
tree | f35794f1b1570f52e637dc66b6c87d574a8da58e /devices/src | |
parent | af00eb7e26116180ab19dcd840e981b532916afd (diff) | |
download | crosvm-207b1fd2b5727fa09f0f0528d83ea2920628ddc2.tar crosvm-207b1fd2b5727fa09f0f0528d83ea2920628ddc2.tar.gz crosvm-207b1fd2b5727fa09f0f0528d83ea2920628ddc2.tar.bz2 crosvm-207b1fd2b5727fa09f0f0528d83ea2920628ddc2.tar.lz crosvm-207b1fd2b5727fa09f0f0528d83ea2920628ddc2.tar.xz crosvm-207b1fd2b5727fa09f0f0528d83ea2920628ddc2.tar.zst crosvm-207b1fd2b5727fa09f0f0528d83ea2920628ddc2.zip |
devices: serial: implement MSR loop behavior
This fixes the Linux serial driver loopback test for the 4th serial port (COM4, aka /dev/ttyS3). The default value of the modem status register is always returned in the current crosvm implementation; however, this doesn't match the expected value in the loopback mode test used by the Linux kernel 8250 serial driver. The other 3 serial ports (/dev/ttyS[012]) skip this test because of the UPF_SKIP_TEST flag in STD_COMX_FLAGS, but the 4th port uses STD_COM4_FLAGS instead, which doesn't have UPF_SKIP_TEST. The mapping of MCR to MSR bits is defined in the 16550 UART data sheet: http://www.ti.com/product/pc16550d BUG=chromium:953983 TEST=`echo test > /dev/ttyS3` in crosvm Change-Id: I1b52111235a500fef2dee00c5803a2221a25e0c6 Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1620704 Tested-by: kokoro <noreply+kokoro@google.com> Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src')
-rw-r--r-- | devices/src/serial.rs | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/devices/src/serial.rs b/devices/src/serial.rs index 1fa7b61..fb0886f 100644 --- a/devices/src/serial.rs +++ b/devices/src/serial.rs @@ -39,13 +39,22 @@ const LSR_DATA_BIT: u8 = 0x1; const LSR_EMPTY_BIT: u8 = 0x20; const LSR_IDLE_BIT: u8 = 0x40; +const MCR_DTR_BIT: u8 = 0x01; // Data Terminal Ready +const MCR_RTS_BIT: u8 = 0x02; // Request to Send +const MCR_OUT1_BIT: u8 = 0x04; +const MCR_OUT2_BIT: u8 = 0x08; const MCR_LOOP_BIT: u8 = 0x10; +const MSR_CTS_BIT: u8 = 0x10; // Clear to Send +const MSR_DSR_BIT: u8 = 0x20; // Data Set Ready +const MSR_RI_BIT: u8 = 0x40; // Ring Indicator +const MSR_DCD_BIT: u8 = 0x80; // Data Carrier Detect + const DEFAULT_INTERRUPT_IDENTIFICATION: u8 = IIR_NONE_BIT; // no pending interrupt const DEFAULT_LINE_STATUS: u8 = LSR_EMPTY_BIT | LSR_IDLE_BIT; // THR empty and line is idle const DEFAULT_LINE_CONTROL: u8 = 0x3; // 8-bits per character -const DEFAULT_MODEM_CONTROL: u8 = 0x8; // Auxiliary output 2 -const DEFAULT_MODEM_STATUS: u8 = 0x20 | 0x10 | 0x80; // data ready, clear to send, carrier detect +const DEFAULT_MODEM_CONTROL: u8 = MCR_OUT2_BIT; +const DEFAULT_MODEM_STATUS: u8 = MSR_DSR_BIT | MSR_CTS_BIT | MSR_DCD_BIT; const DEFAULT_BAUD_DIVISOR: u16 = 12; // 9600 bps #[derive(Debug)] @@ -378,7 +387,27 @@ impl BusDevice for Serial { LCR => self.line_control, MCR => self.modem_control, LSR => self.line_status, - MSR => self.modem_status, + MSR => { + if self.is_loop() { + let mut msr = + self.modem_status & !(MSR_DSR_BIT | MSR_CTS_BIT | MSR_RI_BIT | MSR_DCD_BIT); + if self.modem_control & MCR_DTR_BIT != 0 { + msr |= MSR_DSR_BIT; + } + if self.modem_control & MCR_RTS_BIT != 0 { + msr |= MSR_CTS_BIT; + } + if self.modem_control & MCR_OUT1_BIT != 0 { + msr |= MSR_RI_BIT; + } + if self.modem_control & MCR_OUT2_BIT != 0 { + msr |= MSR_DCD_BIT; + } + msr + } else { + self.modem_status + } + } SCR => self.scratch, _ => 0, }; |