Index: hw/serial.c =================================================================== RCS file: /sources/qemu/qemu/hw/serial.c,v retrieving revision 1.22 diff -u -r1.22 serial.c --- hw/serial.c 25 Nov 2007 00:55:06 -0000 1.22 +++ hw/serial.c 31 Jan 2008 16:51:19 -0000 @@ -93,6 +93,8 @@ int it_shift; }; +static void serial_receive_byte(SerialState *s, int ch); + static void serial_update_irq(SerialState *s) { if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { @@ -161,11 +163,18 @@ s->lsr &= ~UART_LSR_THRE; serial_update_irq(s); ch = val; - qemu_chr_write(s->chr, &ch, 1); + if (!(s->mcr & UART_MCR_LOOP)) { + /* when not in loopback mode, send the char */ + 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); + if (s->mcr & UART_MCR_LOOP) { + /* in loopback mode, say that we just received a char */ + serial_receive_byte(s, ch); + } } break; case 1: @@ -223,7 +232,10 @@ ret = s->rbr; s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); serial_update_irq(s); - qemu_chr_accept_input(s->chr); + if (!(s->mcr & UART_MCR_LOOP)) { + /* in loopback mode, don't receive any data */ + qemu_chr_accept_input(s->chr); + } } break; case 1: @@ -346,6 +358,25 @@ return 0; } +static void serial_reset(void *opaque) +{ + SerialState *s = opaque; + + s->divider = 0; + s->rbr = 0; + s->ier = 0; + s->iir = UART_IIR_NO_INT; + s->lcr = 0; + s->mcr = 0; + s->lsr = UART_LSR_TEMT | UART_LSR_THRE; + s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS; + s->scr = 0; + + s->thr_ipending = 0; + s->last_break_enable = 0; + qemu_irq_lower(s->irq); +} + /* If fd is zero, it means that the serial device uses the console */ SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr) { @@ -355,9 +386,9 @@ if (!s) return NULL; s->irq = irq; - 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; + + qemu_register_reset(serial_reset, s); + serial_reset(s); register_savevm("serial", base, 2, serial_save, serial_load, s); @@ -452,12 +483,12 @@ if (!s) return NULL; s->irq = irq; - 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->base = base; s->it_shift = it_shift; + qemu_register_reset(serial_reset, s); + serial_reset(s); + register_savevm("serial", base, 2, serial_save, serial_load, s); if (ioregister) {