]> Git Repo - qemu.git/blobdiff - hw/escc.c
target-mips: Replace macros by inline functions
[qemu.git] / hw / escc.c
index 71d6368a536dd4e6d9359966ed587dd0cd57221d..f09904aae4cf6a61a07e53dfd6bffc03f6cdab7a 100644 (file)
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -1,5 +1,5 @@
 /*
- * QEMU Sparc SLAVIO serial port emulation
+ * QEMU ESCC (Z8030/Z8530/Z85C30/SCC/ESCC) serial port emulation
  *
  * Copyright (c) 2003-2005 Fabrice Bellard
  *
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "hw.h"
-#include "sun4m.h"
-#include "qemu-char.h"
-#include "console.h"
-
-/* debug serial */
-//#define DEBUG_SERIAL
-
-/* debug keyboard */
-//#define DEBUG_KBD
 
-/* debug mouse */
-//#define DEBUG_MOUSE
+#include "hw.h"
+#include "sysbus.h"
+#include "escc.h"
+#include "char/char.h"
+#include "ui/console.h"
+#include "trace.h"
 
 /*
- * This is the serial port, mouse and keyboard part of chip STP2001
+ * Chipset docs:
+ * "Z80C30/Z85C30/Z80230/Z85230/Z85233 SCC/ESCC User Manual",
+ * http://www.zilog.com/docs/serial/scc_escc_um.pdf
+ *
+ * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001
  * (Slave I/O), also produced as NCR89C105. See
  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
  *
  * mouse and keyboard ports don't implement all functions and they are
  * only asynchronous. There is no DMA.
  *
+ * Z85C30 is also used on PowerMacs. There are some small differences
+ * between Sparc version (sunzilog) and PowerMac (pmac):
+ *  Offset between control and data registers
+ *  There is some kind of lockup bug, but we can ignore it
+ *  CTS is inverted
+ *  DMA on pmac using DBDMA chip
+ *  pmac can do IRDA and faster rates, sunzilog can only do 38400
+ *  pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz
  */
 
 /*
  *  2006-Aug-10  Igor Kovalenko :   Renamed KBDQueue to SERIOQueue, implemented
  *                                  serial mouse queue.
  *                                  Implemented serial mouse protocol.
+ *
+ *  2010-May-23  Artyom Tarasenko:  Reworked IUS logic
  */
 
-#ifdef DEBUG_SERIAL
-#define SER_DPRINTF(fmt, args...) \
-do { printf("SER: " fmt , ##args); } while (0)
-#else
-#define SER_DPRINTF(fmt, args...)
-#endif
-#ifdef DEBUG_KBD
-#define KBD_DPRINTF(fmt, args...) \
-do { printf("KBD: " fmt , ##args); } while (0)
-#else
-#define KBD_DPRINTF(fmt, args...)
-#endif
-#ifdef DEBUG_MOUSE
-#define MS_DPRINTF(fmt, args...) \
-do { printf("MSC: " fmt , ##args); } while (0)
-#else
-#define MS_DPRINTF(fmt, args...)
-#endif
-
 typedef enum {
     chn_a, chn_b,
-} chn_id_t;
+} ChnID;
 
 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
 
 typedef enum {
     ser, kbd, mouse,
-} chn_type_t;
+} ChnType;
 
 #define SERIO_QUEUE_SIZE 256
 
@@ -92,23 +81,30 @@ typedef struct {
 #define SERIAL_REGS 16
 typedef struct ChannelState {
     qemu_irq irq;
-    uint32_t reg;
     uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
-    chn_id_t chn; // this channel, A (base+4) or B (base+0)
-    chn_type_t type;
     struct ChannelState *otherchn;
-    uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
+    uint32_t reg;
+    uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
     SERIOQueue queue;
     CharDriverState *chr;
     int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
     int disabled;
+    int clock;
+    uint32_t vmstate_dummy;
+    ChnID chn; // this channel, A (base+4) or B (base+0)
+    ChnType type;
+    uint8_t rx, tx;
 } ChannelState;
 
 struct SerialState {
+    SysBusDevice busdev;
     struct ChannelState chn[2];
+    uint32_t it_shift;
+    MemoryRegion mmio;
+    uint32_t disabled;
+    uint32_t frequency;
 };
 
-#define SERIAL_SIZE 8
 #define SERIAL_CTRL 0
 #define SERIAL_DATA 1
 
@@ -227,7 +223,7 @@ static void put_queue(void *opaque, int b)
     ChannelState *s = opaque;
     SERIOQueue *q = &s->queue;
 
-    SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
+    trace_escc_put_queue(CHN_C(s), b);
     if (q->count >= SERIO_QUEUE_SIZE)
         return;
     q->data[q->wptr] = b;
@@ -251,15 +247,15 @@ static uint32_t get_queue(void *opaque)
             q->rptr = 0;
         q->count--;
     }
-    SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
+    trace_escc_get_queue(CHN_C(s), val);
     if (q->count > 0)
         serial_receive_byte(s, 0);
     return val;
 }
 
-static int slavio_serial_update_irq_chn(ChannelState *s)
+static int escc_update_irq_chn(ChannelState *s)
 {
-    if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
+    if ((((s->wregs[W_INTR] & INTR_TXINT) && (s->txint == 1)) ||
          // tx ints enabled, pending
          ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
            ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
@@ -271,18 +267,18 @@ static int slavio_serial_update_irq_chn(ChannelState *s)
     return 0;
 }
 
-static void slavio_serial_update_irq(ChannelState *s)
+static void escc_update_irq(ChannelState *s)
 {
     int irq;
 
-    irq = slavio_serial_update_irq_chn(s);
-    irq |= slavio_serial_update_irq_chn(s->otherchn);
+    irq = escc_update_irq_chn(s);
+    irq |= escc_update_irq_chn(s->otherchn);
 
-    SER_DPRINTF("IRQ = %d\n", irq);
+    trace_escc_update_irq(irq);
     qemu_set_irq(s->irq, irq);
 }
 
-static void slavio_serial_reset_chn(ChannelState *s)
+static void escc_reset_chn(ChannelState *s)
 {
     int i;
 
@@ -311,35 +307,34 @@ static void slavio_serial_reset_chn(ChannelState *s)
     clear_queue(s);
 }
 
-static void slavio_serial_reset(void *opaque)
+static void escc_reset(DeviceState *d)
 {
-    SerialState *s = opaque;
-    slavio_serial_reset_chn(&s->chn[0]);
-    slavio_serial_reset_chn(&s->chn[1]);
+    SerialState *s = container_of(d, SerialState, busdev.qdev);
+
+    escc_reset_chn(&s->chn[0]);
+    escc_reset_chn(&s->chn[1]);
 }
 
 static inline void set_rxint(ChannelState *s)
 {
     s->rxint = 1;
-    if (!s->txint_under_svc) {
-        s->rxint_under_svc = 1;
-        if (s->chn == chn_a) {
-            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
-                s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
-            else
-                s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
-        } else {
-            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
-                s->rregs[R_IVEC] = IVEC_HIRXINTB;
-            else
-                s->rregs[R_IVEC] = IVEC_LORXINTB;
-        }
-    }
-    if (s->chn == chn_a)
+    /* XXX: missing daisy chainnig: chn_b rx should have a lower priority
+       than chn_a rx/tx/special_condition service*/
+    s->rxint_under_svc = 1;
+    if (s->chn == chn_a) {
         s->rregs[R_INTR] |= INTR_RXINTA;
-    else
+        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+            s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
+        else
+            s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
+    } else {
         s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
-    slavio_serial_update_irq(s);
+        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
+            s->rregs[R_IVEC] = IVEC_HIRXINTB;
+        else
+            s->rregs[R_IVEC] = IVEC_LORXINTB;
+    }
+    escc_update_irq(s);
 }
 
 static inline void set_txint(ChannelState *s)
@@ -348,19 +343,21 @@ static inline void set_txint(ChannelState *s)
     if (!s->rxint_under_svc) {
         s->txint_under_svc = 1;
         if (s->chn == chn_a) {
+            if (s->wregs[W_INTR] & INTR_TXINT) {
+                s->rregs[R_INTR] |= INTR_TXINTA;
+            }
             if (s->wregs[W_MINTR] & MINTR_STATUSHI)
                 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
             else
                 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
         } else {
             s->rregs[R_IVEC] = IVEC_TXINTB;
+            if (s->wregs[W_INTR] & INTR_TXINT) {
+                s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
+            }
         }
+    escc_update_irq(s);
     }
-    if (s->chn == chn_a)
-        s->rregs[R_INTR] |= INTR_TXINTA;
-    else
-        s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
-    slavio_serial_update_irq(s);
 }
 
 static inline void clr_rxint(ChannelState *s)
@@ -382,7 +379,7 @@ static inline void clr_rxint(ChannelState *s)
     }
     if (s->txint)
         set_txint(s);
-    slavio_serial_update_irq(s);
+    escc_update_irq(s);
 }
 
 static inline void clr_txint(ChannelState *s)
@@ -396,6 +393,7 @@ static inline void clr_txint(ChannelState *s)
             s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
         s->rregs[R_INTR] &= ~INTR_TXINTA;
     } else {
+        s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
         if (s->wregs[W_MINTR] & MINTR_STATUSHI)
             s->rregs[R_IVEC] = IVEC_HINOINT;
         else
@@ -404,10 +402,10 @@ static inline void clr_txint(ChannelState *s)
     }
     if (s->rxint)
         set_rxint(s);
-    slavio_serial_update_irq(s);
+    escc_update_irq(s);
 }
 
-static void slavio_serial_update_parameters(ChannelState *s)
+static void escc_update_parameters(ChannelState *s)
 {
     int speed, parity, data_bits, stop_bits;
     QEMUSerialSetParams ssp;
@@ -442,7 +440,7 @@ static void slavio_serial_update_parameters(ChannelState *s)
         data_bits = 8;
         break;
     }
-    speed = 2457600 / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
+    speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
     switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
     case TXCTRL1_CLK1X:
         break;
@@ -461,13 +459,12 @@ static void slavio_serial_update_parameters(ChannelState *s)
     ssp.parity = parity;
     ssp.data_bits = data_bits;
     ssp.stop_bits = stop_bits;
-    SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
-                speed, parity, data_bits, stop_bits);
-    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+    trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
+    qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
-static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
-                                     uint32_t val)
+static void escc_mem_write(void *opaque, hwaddr addr,
+                           uint64_t val, unsigned size)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -475,13 +472,12 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
     int newreg, channel;
 
     val &= 0xff;
-    saddr = (addr & 3) >> 1;
-    channel = addr >> 2;
+    saddr = (addr >> serial->it_shift) & 1;
+    channel = (addr >> (serial->it_shift + 1)) & 1;
     s = &serial->chn[channel];
     switch (saddr) {
     case SERIAL_CTRL:
-        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
-                    val & 0xff);
+        trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
         newreg = 0;
         switch (s->reg) {
         case W_CMD:
@@ -495,10 +491,15 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
                 clr_txint(s);
                 break;
             case CMD_CLR_IUS:
-                if (s->rxint_under_svc)
-                    clr_rxint(s);
-                else if (s->txint_under_svc)
-                    clr_txint(s);
+                if (s->rxint_under_svc) {
+                    s->rxint_under_svc = 0;
+                    if (s->txint) {
+                        set_txint(s);
+                    }
+                } else if (s->txint_under_svc) {
+                    s->txint_under_svc = 0;
+                }
+                escc_update_irq(s);
                 break;
             default:
                 break;
@@ -513,13 +514,13 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
         case W_TXCTRL1:
         case W_TXCTRL2:
             s->wregs[s->reg] = val;
-            slavio_serial_update_parameters(s);
+            escc_update_parameters(s);
             break;
         case W_BRGLO:
         case W_BRGHI:
             s->wregs[s->reg] = val;
             s->rregs[s->reg] = val;
-            slavio_serial_update_parameters(s);
+            escc_update_parameters(s);
             break;
         case W_MINTR:
             switch (val & MINTR_RST_MASK) {
@@ -527,13 +528,13 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
             default:
                 break;
             case MINTR_RST_B:
-                slavio_serial_reset_chn(&serial->chn[0]);
+                escc_reset_chn(&serial->chn[0]);
                 return;
             case MINTR_RST_A:
-                slavio_serial_reset_chn(&serial->chn[1]);
+                escc_reset_chn(&serial->chn[1]);
                 return;
             case MINTR_RST_ALL:
-                slavio_serial_reset(serial);
+                escc_reset(&serial->busdev.qdev);
                 return;
             }
             break;
@@ -546,11 +547,11 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
             s->reg = 0;
         break;
     case SERIAL_DATA:
-        SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
+        trace_escc_mem_writeb_data(CHN_C(s), val);
         s->tx = val;
         if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
             if (s->chr)
-                qemu_chr_write(s->chr, &s->tx, 1);
+                qemu_chr_fe_write(s->chr, &s->tx, 1);
             else if (s->type == kbd && !s->disabled) {
                 handle_kbd_command(s, val);
             }
@@ -564,7 +565,8 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t escc_mem_read(void *opaque, hwaddr addr,
+                              unsigned size)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -572,13 +574,12 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
     uint32_t ret;
     int channel;
 
-    saddr = (addr & 3) >> 1;
-    channel = addr >> 2;
+    saddr = (addr >> serial->it_shift) & 1;
+    channel = (addr >> (serial->it_shift + 1)) & 1;
     s = &serial->chn[channel];
     switch (saddr) {
     case SERIAL_CTRL:
-        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
-                    s->rregs[s->reg]);
+        trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
         ret = s->rregs[s->reg];
         s->reg = 0;
         return ret;
@@ -589,7 +590,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
             ret = get_queue(s);
         else
             ret = s->rx;
-        SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
+        trace_escc_mem_readb_data(CHN_C(s), ret);
         if (s->chr)
             qemu_chr_accept_input(s->chr);
         return ret;
@@ -599,6 +600,16 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
     return 0;
 }
 
+static const MemoryRegionOps escc_mem_ops = {
+    .read = escc_mem_read,
+    .write = escc_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
 static int serial_can_receive(void *opaque)
 {
     ChannelState *s = opaque;
@@ -615,7 +626,7 @@ static int serial_can_receive(void *opaque)
 
 static void serial_receive_byte(ChannelState *s, int ch)
 {
-    SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
+    trace_escc_serial_receive_byte(CHN_C(s), ch);
     s->rregs[R_STATUS] |= STATUS_RXAV;
     s->rx = ch;
     set_rxint(s);
@@ -624,7 +635,7 @@ static void serial_receive_byte(ChannelState *s, int ch)
 static void serial_receive_break(ChannelState *s)
 {
     s->rregs[R_STATUS] |= STATUS_BRK;
-    slavio_serial_update_irq(s);
+    escc_update_irq(s);
 }
 
 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
@@ -640,113 +651,64 @@ static void serial_event(void *opaque, int event)
         serial_receive_break(s);
 }
 
-static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
-    slavio_serial_mem_readb,
-    NULL,
-    NULL,
+static const VMStateDescription vmstate_escc_chn = {
+    .name ="escc_chn",
+    .version_id = 2,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT32(vmstate_dummy, ChannelState),
+        VMSTATE_UINT32(reg, ChannelState),
+        VMSTATE_UINT32(rxint, ChannelState),
+        VMSTATE_UINT32(txint, ChannelState),
+        VMSTATE_UINT32(rxint_under_svc, ChannelState),
+        VMSTATE_UINT32(txint_under_svc, ChannelState),
+        VMSTATE_UINT8(rx, ChannelState),
+        VMSTATE_UINT8(tx, ChannelState),
+        VMSTATE_BUFFER(wregs, ChannelState),
+        VMSTATE_BUFFER(rregs, ChannelState),
+        VMSTATE_END_OF_LIST()
+    }
 };
 
-static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
-    slavio_serial_mem_writeb,
-    NULL,
-    NULL,
+static const VMStateDescription vmstate_escc = {
+    .name ="escc",
+    .version_id = 2,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_STRUCT_ARRAY(chn, SerialState, 2, 2, vmstate_escc_chn,
+                             ChannelState),
+        VMSTATE_END_OF_LIST()
+    }
 };
 
-static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
+MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
+              CharDriverState *chrA, CharDriverState *chrB,
+              int clock, int it_shift)
 {
-    uint32_t tmp = 0;
-
-    qemu_put_be32s(f, &tmp); /* unused, was IRQ.  */
-    qemu_put_be32s(f, &s->reg);
-    qemu_put_be32s(f, &s->rxint);
-    qemu_put_be32s(f, &s->txint);
-    qemu_put_be32s(f, &s->rxint_under_svc);
-    qemu_put_be32s(f, &s->txint_under_svc);
-    qemu_put_8s(f, &s->rx);
-    qemu_put_8s(f, &s->tx);
-    qemu_put_buffer(f, s->wregs, SERIAL_REGS);
-    qemu_put_buffer(f, s->rregs, SERIAL_REGS);
-}
-
-static void slavio_serial_save(QEMUFile *f, void *opaque)
-{
-    SerialState *s = opaque;
-
-    slavio_serial_save_chn(f, &s->chn[0]);
-    slavio_serial_save_chn(f, &s->chn[1]);
-}
-
-static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
-{
-    uint32_t tmp;
-
-    if (version_id > 2)
-        return -EINVAL;
-
-    qemu_get_be32s(f, &tmp); /* unused */
-    qemu_get_be32s(f, &s->reg);
-    qemu_get_be32s(f, &s->rxint);
-    qemu_get_be32s(f, &s->txint);
-    if (version_id >= 2) {
-        qemu_get_be32s(f, &s->rxint_under_svc);
-        qemu_get_be32s(f, &s->txint_under_svc);
+    DeviceState *dev;
+    SysBusDevice *s;
+    SerialState *d;
+
+    dev = qdev_create(NULL, "escc");
+    qdev_prop_set_uint32(dev, "disabled", 0);
+    qdev_prop_set_uint32(dev, "frequency", clock);
+    qdev_prop_set_uint32(dev, "it_shift", it_shift);
+    qdev_prop_set_chr(dev, "chrB", chrB);
+    qdev_prop_set_chr(dev, "chrA", chrA);
+    qdev_prop_set_uint32(dev, "chnBtype", ser);
+    qdev_prop_set_uint32(dev, "chnAtype", ser);
+    qdev_init_nofail(dev);
+    s = sysbus_from_qdev(dev);
+    sysbus_connect_irq(s, 0, irqB);
+    sysbus_connect_irq(s, 1, irqA);
+    if (base) {
+        sysbus_mmio_map(s, 0, base);
     }
-    qemu_get_8s(f, &s->rx);
-    qemu_get_8s(f, &s->tx);
-    qemu_get_buffer(f, s->wregs, SERIAL_REGS);
-    qemu_get_buffer(f, s->rregs, SERIAL_REGS);
-    return 0;
-}
-
-static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
-{
-    SerialState *s = opaque;
-    int ret;
-
-    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
-    if (ret != 0)
-        return ret;
-    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
-    return ret;
 
-}
-
-SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
-                                CharDriverState *chr1, CharDriverState *chr2)
-{
-    int slavio_serial_io_memory, i;
-    SerialState *s;
-
-    s = qemu_mallocz(sizeof(SerialState));
-    if (!s)
-        return NULL;
-
-    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
-                                                     slavio_serial_mem_write,
-                                                     s);
-    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
-
-    s->chn[0].chr = chr1;
-    s->chn[1].chr = chr2;
-    s->chn[0].disabled = 0;
-    s->chn[1].disabled = 0;
-
-    for (i = 0; i < 2; i++) {
-        s->chn[i].irq = irq;
-        s->chn[i].chn = 1 - i;
-        s->chn[i].type = ser;
-        if (s->chn[i].chr) {
-            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
-                                  serial_receive1, serial_event, &s->chn[i]);
-        }
-    }
-    s->chn[0].otherchn = &s->chn[1];
-    s->chn[1].otherchn = &s->chn[0];
-    register_savevm("slavio_serial", base, 2, slavio_serial_save,
-                    slavio_serial_load, s);
-    qemu_register_reset(slavio_serial_reset, s);
-    slavio_serial_reset(s);
-    return s;
+    d = FROM_SYSBUS(SerialState, s);
+    return &d->mmio;
 }
 
 static const uint8_t keycodes[128] = {
@@ -776,8 +738,7 @@ static void sunkbd_event(void *opaque, int ch)
     ChannelState *s = opaque;
     int release = ch & 0x80;
 
-    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
-                "press");
+    trace_escc_sunkbd_event_in(ch);
     switch (ch) {
     case 58: // Caps lock press
         s->caps_lock_mode ^= 1;
@@ -811,13 +772,13 @@ static void sunkbd_event(void *opaque, int ch)
     } else {
         ch = keycodes[ch & 0x7f];
     }
-    KBD_DPRINTF("Translated keycode %2.2x\n", ch);
+    trace_escc_sunkbd_event_out(ch);
     put_queue(s, ch | release);
 }
 
 static void handle_kbd_command(ChannelState *s, int val)
 {
-    KBD_DPRINTF("Command %d\n", val);
+    trace_escc_kbd_command(val);
     if (s->led_mode) { // Ignore led byte
         s->led_mode = 0;
         return;
@@ -849,8 +810,7 @@ static void sunmouse_event(void *opaque,
     ChannelState *s = opaque;
     int ch;
 
-    MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
-
+    trace_escc_sunmouse_event(dx, dy, buttons_state);
     ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
 
     if (buttons_state & MOUSE_EVENT_LBUTTON)
@@ -865,18 +825,18 @@ static void sunmouse_event(void *opaque,
     ch = dx;
 
     if (ch > 127)
-        ch=127;
+        ch = 127;
     else if (ch < -127)
-        ch=-127;
+        ch = -127;
 
     put_queue(s, ch & 0xff);
 
     ch = -dy;
 
     if (ch > 127)
-        ch=127;
+        ch = 127;
     else if (ch < -127)
-        ch=-127;
+        ch = -127;
 
     put_queue(s, ch & 0xff);
 
@@ -886,37 +846,93 @@ static void sunmouse_event(void *opaque,
     put_queue(s, 0);
 }
 
-void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
-                               int disabled)
+void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
+                               int disabled, int clock, int it_shift)
 {
-    int slavio_serial_io_memory, i;
-    SerialState *s;
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_create(NULL, "escc");
+    qdev_prop_set_uint32(dev, "disabled", disabled);
+    qdev_prop_set_uint32(dev, "frequency", clock);
+    qdev_prop_set_uint32(dev, "it_shift", it_shift);
+    qdev_prop_set_chr(dev, "chrB", NULL);
+    qdev_prop_set_chr(dev, "chrA", NULL);
+    qdev_prop_set_uint32(dev, "chnBtype", mouse);
+    qdev_prop_set_uint32(dev, "chnAtype", kbd);
+    qdev_init_nofail(dev);
+    s = sysbus_from_qdev(dev);
+    sysbus_connect_irq(s, 0, irq);
+    sysbus_connect_irq(s, 1, irq);
+    sysbus_mmio_map(s, 0, base);
+}
 
-    s = qemu_mallocz(sizeof(SerialState));
-    if (!s)
-        return;
+static int escc_init1(SysBusDevice *dev)
+{
+    SerialState *s = FROM_SYSBUS(SerialState, dev);
+    unsigned int i;
+
+    s->chn[0].disabled = s->disabled;
+    s->chn[1].disabled = s->disabled;
     for (i = 0; i < 2; i++) {
-        s->chn[i].irq = irq;
+        sysbus_init_irq(dev, &s->chn[i].irq);
         s->chn[i].chn = 1 - i;
-        s->chn[i].chr = NULL;
+        s->chn[i].clock = s->frequency / 2;
+        if (s->chn[i].chr) {
+            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
+                                  serial_receive1, serial_event, &s->chn[i]);
+        }
     }
     s->chn[0].otherchn = &s->chn[1];
     s->chn[1].otherchn = &s->chn[0];
-    s->chn[0].type = mouse;
-    s->chn[1].type = kbd;
-    s->chn[0].disabled = disabled;
-    s->chn[1].disabled = disabled;
-
-    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
-                                                     slavio_serial_mem_write,
-                                                     s);
-    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
-
-    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
-                                 "QEMU Sun Mouse");
-    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
-    register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save,
-                    slavio_serial_load, s);
-    qemu_register_reset(slavio_serial_reset, s);
-    slavio_serial_reset(s);
+
+    memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc",
+                          ESCC_SIZE << s->it_shift);
+    sysbus_init_mmio(dev, &s->mmio);
+
+    if (s->chn[0].type == mouse) {
+        qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
+                                     "QEMU Sun Mouse");
+    }
+    if (s->chn[1].type == kbd) {
+        qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
+    }
+
+    return 0;
 }
+
+static Property escc_properties[] = {
+    DEFINE_PROP_UINT32("frequency", SerialState, frequency,   0),
+    DEFINE_PROP_UINT32("it_shift",  SerialState, it_shift,    0),
+    DEFINE_PROP_UINT32("disabled",  SerialState, disabled,    0),
+    DEFINE_PROP_UINT32("chnBtype",  SerialState, chn[0].type, 0),
+    DEFINE_PROP_UINT32("chnAtype",  SerialState, chn[1].type, 0),
+    DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
+    DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void escc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = escc_init1;
+    dc->reset = escc_reset;
+    dc->vmsd = &vmstate_escc;
+    dc->props = escc_properties;
+}
+
+static TypeInfo escc_info = {
+    .name          = "escc",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(SerialState),
+    .class_init    = escc_class_init,
+};
+
+static void escc_register_types(void)
+{
+    type_register_static(&escc_info);
+}
+
+type_init(escc_register_types)
This page took 0.051826 seconds and 4 git commands to generate.