All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Add serial loopback mode (+ fixes reset)
@ 2008-02-06 11:28 Hervé Poussineau
  0 siblings, 0 replies; only message in thread
From: Hervé Poussineau @ 2008-02-06 11:28 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 290 bytes --]

Hi,

Serial emulation lacks loopback mode (ie a transmitted byte is directly 
received in the serial port).

After a reset, serial port registers should go back to default values. 
This is done by adding a call to qemu_register_reset().

Attached patch fixes both issues.

Hervé

[-- Attachment #2: serial-loopback.patch --]
[-- Type: text/plain, Size: 2947 bytes --]

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) {


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-02-06 11:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-06 11:28 [Qemu-devel] [PATCH] Add serial loopback mode (+ fixes reset) Hervé Poussineau

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.