📄 qemu-serial-fixes
字号:
# HG changeset patch# User kfraser@localhost.localdomain# Node ID c33272c2571c7bab7056d8228490700d1df405f9# Parent b3d94f4ddffefed8a5cb8dd65a60da9491d460e7[HVM] Fix Qemu-dm serial issues: 1. Retry transmit via a polling timer if a byte cannot be written immediately to its destination. 2. Turn off output processing of raw serial lines.Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>Signed-off-by: Keir Fraser <keir@xensource.com>Index: ioemu/vl.c===================================================================--- ioemu.orig/vl.c 2007-05-10 15:35:24.000000000 +0100+++ ioemu/vl.c 2007-05-10 15:35:25.000000000 +0100@@ -1871,7 +1871,7 @@ tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP |INLCR|IGNCR|ICRNL|IXON);- tty.c_oflag |= OPOST;+ tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */ tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG); tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS|CSTOPB); switch(data_bits) {Index: ioemu/hw/serial.c===================================================================--- ioemu.orig/hw/serial.c 2007-05-10 15:35:24.000000000 +0100+++ ioemu/hw/serial.c 2007-05-10 15:35:25.000000000 +0100@@ -73,6 +73,11 @@ #define UART_LSR_OE 0x02 /* Overrun error indicator */ #define UART_LSR_DR 0x01 /* Receiver data ready */ +/* Maximum retries for a single byte transmit. */+#define WRITE_MAX_SINGLE_RETRIES 3+/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */+#define WRITE_MAX_TOTAL_RETRIES 10+ struct SerialState { uint16_t divider; uint8_t rbr; /* receive register */@@ -93,6 +98,19 @@ int last_break_enable; target_ulong base; int it_shift;++ /*+ * If a character transmitted via UART cannot be written to its+ * destination immediately we remember it here and retry a few times via+ * a polling timer.+ * - write_single_retries: Number of write retries for current byte.+ * - write_total_retries: Number of write retries for back-to-back+ * unsuccessful transmits.+ */+ int write_single_retries;+ int write_total_retries;+ char write_chr;+ QEMUTimer *write_retry_timer; }; static void serial_update_irq(SerialState *s)@@ -204,10 +222,37 @@ tokens_avail--; } +static void serial_chr_write(void *opaque)+{+ SerialState *s = opaque;++ /* Cancel any outstanding retry if this is a new byte. */+ qemu_del_timer(s->write_retry_timer);++ /* Retry every 100ms for 300ms total. */+ if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {+ s->write_total_retries++; + if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES)+ fprintf(stderr, "serial: write error\n");+ else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) {+ qemu_mod_timer(s->write_retry_timer,+ qemu_get_clock(vm_clock) + ticks_per_sec / 10);+ return;+ }+ } else {+ s->write_total_retries = 0; /* if successful then reset counter */+ }++ /* Success: Notify guest that THR is empty. */+ s->thr_ipending = 1;+ s->lsr |= UART_LSR_THRE;+ s->lsr |= UART_LSR_TEMT;+ serial_update_irq(s);+}+ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) { SerialState *s = opaque;- unsigned char ch; addr &= 7; #ifdef DEBUG_SERIAL@@ -223,12 +268,9 @@ s->thr_ipending = 0; s->lsr &= ~UART_LSR_THRE; serial_update_irq(s);- ch = val;- qemu_chr_write(s->chr, &ch, 1);- s->thr_ipending = 1;- s->lsr |= UART_LSR_THRE;- s->lsr |= UART_LSR_TEMT;- serial_update_irq(s);+ s->write_chr = val;+ s->write_single_retries = 0;+ serial_chr_write(s); } break; case 1:@@ -427,6 +469,7 @@ s->lsr = UART_LSR_TEMT | UART_LSR_THRE; s->iir = UART_IIR_NO_INT; s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;+ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s); register_savevm("serial", base, 2, serial_save, serial_load, s); @@ -514,6 +557,7 @@ s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; s->base = base; s->it_shift = it_shift;+ s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s); register_savevm("serial", base, 2, serial_save, serial_load, s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -