qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 2/3] sh: SCI improvements


From: Jean-Christophe PLAGNIOL-VILLARD
Subject: [Qemu-devel] [PATCH 2/3] sh: SCI improvements
Date: Sun, 26 Apr 2009 18:36:11 +0200

From: Shin-ichiro KAWASAKI <address@hidden>

SE7750 uses SCI := Serial Communication Interface for one of consoles.
This patch completes the SCI implementation, and makes SCI available
for a console.

# Tabs and spaces are mixed in "hw/sh_serial.c" so much.
# Some clean up might be useful.

Signed-off-by: Shin-ichiro KAWASAKI <address@hidden>
---
 hw/sh_serial.c |   92 ++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 53 insertions(+), 39 deletions(-)

diff --git a/hw/sh_serial.c b/hw/sh_serial.c
index 4957c41..c3eb146 100644
--- a/hw/sh_serial.c
+++ b/hw/sh_serial.c
@@ -96,7 +96,7 @@ static void sh_serial_ioport_write(void *opaque, uint32_t 
offs, uint32_t val)
         s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfa : 0xff);
         if (!(val & (1 << 5)))
             s->flags |= SH_SERIAL_FLAG_TEND;
-        if ((s->feat & SH_SERIAL_FEAT_SCIF) && s->txi) {
+        if (s->txi) {
            qemu_set_irq(s->txi, val & (1 << 7));
         }
         if (!(val & (1 << 6))) {
@@ -109,13 +109,15 @@ static void sh_serial_ioport_write(void *opaque, uint32_t 
offs, uint32_t val)
             qemu_chr_write(s->chr, &ch, 1);
        }
        s->dr = val;
-       s->flags &= ~SH_SERIAL_FLAG_TDE;
+        if (s->feat & SH_SERIAL_FEAT_SCIF)
+            s->flags &= ~SH_SERIAL_FLAG_TDE;
+        else
+            s->flags |= SH_SERIAL_FLAG_TDE;
         return;
-#if 0
     case 0x14: /* FRDR / RDR */
-        ret = 0;
+        /* do nothing */
+        return;
         break;
-#endif
     }
     if (s->feat & SH_SERIAL_FEAT_SCIF) {
         switch(offs) {
@@ -165,17 +167,33 @@ static void sh_serial_ioport_write(void *opaque, uint32_t 
offs, uint32_t val)
         case 0x24: /* LSR */
             return;
         }
-    }
-    else {
+    } else { /* SCI */
         switch(offs) {
-#if 0
-        case 0x0c:
-            ret = s->dr;
-            break;
-        case 0x10:
-            ret = 0;
-            break;
-#endif
+        case 0x0c: /* TDR */
+            if (s->chr) {
+                ch = val;
+                qemu_chr_write(s->chr, &ch, 1);
+            }
+            s->dr = val;
+            s->flags |= SH_SERIAL_FLAG_TDE | SH_SERIAL_FLAG_TEND;
+            if (s->scr & (1 << 7) && s->txi) {
+                qemu_set_irq(s->txi, 1);
+            }
+            return;
+        case 0x10: /* SSR */
+            /*
+             * Ignore TDRE (1 << 7) bit because TDR is always
+             * writable in this SCI emulation.
+             */
+            if (!(val & (1 << 6))) {
+                s->flags &= ~SH_SERIAL_FLAG_RDF;
+            }
+            if (!(val & (1 << 6))) {
+                if (s->rxi) {
+                    qemu_set_irq(s->rxi, 0);
+                }
+            }
+            return;
         case 0x1c:
             s->sptr = val & 0x8f;
             return;
@@ -191,30 +209,19 @@ static uint32_t sh_serial_ioport_read(void *opaque, 
uint32_t offs)
     sh_serial_state *s = opaque;
     uint32_t ret = ~0;
 
-#if 0
     switch(offs) {
-    case 0x00:
+    case 0x00: /* SMR */
         ret = s->smr;
         break;
-    case 0x04:
+    case 0x04: /* BRR */
         ret = s->brr;
        break;
-    case 0x08:
+    case 0x08: /* SCR */
         ret = s->scr;
         break;
-    case 0x14:
-        ret = 0;
-        break;
     }
-#endif
     if (s->feat & SH_SERIAL_FEAT_SCIF) {
         switch(offs) {
-        case 0x00: /* SMR */
-            ret = s->smr;
-            break;
-        case 0x08: /* SCR */
-            ret = s->scr;
-            break;
         case 0x10: /* FSR */
             ret = 0;
             if (s->flags & SH_SERIAL_FLAG_TEND)
@@ -242,11 +249,9 @@ static uint32_t sh_serial_ioport_read(void *opaque, 
uint32_t offs)
                     s->flags &= ~SH_SERIAL_FLAG_RDF;
             }
             break;
-#if 0
         case 0x18:
             ret = s->fcr;
             break;
-#endif
         case 0x1c:
             ret = s->rx_cnt;
             break;
@@ -257,21 +262,26 @@ static uint32_t sh_serial_ioport_read(void *opaque, 
uint32_t offs)
             ret = 0;
             break;
         }
-    }
-    else {
+    } else {
         switch(offs) {
-#if 0
-        case 0x0c:
+        case 0x0c: /* TDR */
             ret = s->dr;
             break;
-        case 0x10:
+        case 0x10: /* SSR */
             ret = 0;
+            if (s->flags & SH_SERIAL_FLAG_TDE)
+                ret |= (1 << 7);
+            if (s->flags & SH_SERIAL_FLAG_RDF)
+                ret |= (1 << 6);
+            if (s->flags & SH_SERIAL_FLAG_TEND)
+                ret |= (1 << 2);
+            /* TODO : handle bit MPBT */
             break;
-        case 0x14:
+        case 0x14: /* RDR */
             ret = s->rx_fifo[0];
+            s->flags &= ~SH_SERIAL_FLAG_RDF;
             break;
-#endif
-        case 0x1c:
+        case 0x1c: /* SPTR */
             ret = s->sptr;
             break;
         }
@@ -311,6 +321,10 @@ static void sh_serial_receive_byte(sh_serial_state *s, int 
ch)
         }
     } else {
         s->rx_fifo[0] = ch;
+        s->flags |= SH_SERIAL_FLAG_RDF;
+        if (s->scr & (1 << 6) && s->rxi) {
+            qemu_set_irq(s->rxi, 1);
+        }
     }
 }
 
-- 
1.6.2.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]