Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ 52cc07d0

History | View | Annotate | Download (17 kB)

1
/*
2
 * QEMU Sparc SLAVIO serial port emulation
3
 * 
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25
/* debug serial */
26
//#define DEBUG_SERIAL
27

    
28
/* debug keyboard */
29
//#define DEBUG_KBD
30

    
31
/* debug mouse */
32
//#define DEBUG_MOUSE
33

    
34
/*
35
 * This is the serial port, mouse and keyboard part of chip STP2001
36
 * (Slave I/O), also produced as NCR89C105. See
37
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
38
 * 
39
 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
40
 * mouse and keyboard ports don't implement all functions and they are
41
 * only asynchronous. There is no DMA.
42
 *
43
 */
44

    
45
/*
46
 * Modifications:
47
 *  2006-Aug-10  Igor Kovalenko :   Renamed KBDQueue to SERIOQueue, implemented
48
 *                                  serial mouse queue.
49
 *                                  Implemented serial mouse protocol.
50
 */
51

    
52
#ifdef DEBUG_SERIAL
53
#define SER_DPRINTF(fmt, args...) \
54
do { printf("SER: " fmt , ##args); } while (0)
55
#define pic_set_irq_new(intctl, irq, level)                             \
56
    do { printf("SER: set_irq(%d): %d\n", (irq), (level));              \
57
        pic_set_irq_new((intctl), (irq),(level));} while (0)
58
#else
59
#define SER_DPRINTF(fmt, args...)
60
#endif
61
#ifdef DEBUG_KBD
62
#define KBD_DPRINTF(fmt, args...) \
63
do { printf("KBD: " fmt , ##args); } while (0)
64
#else
65
#define KBD_DPRINTF(fmt, args...)
66
#endif
67
#ifdef DEBUG_MOUSE
68
#define MS_DPRINTF(fmt, args...) \
69
do { printf("MSC: " fmt , ##args); } while (0)
70
#else
71
#define MS_DPRINTF(fmt, args...)
72
#endif
73

    
74
typedef enum {
75
    chn_a, chn_b,
76
} chn_id_t;
77

    
78
#define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
79

    
80
typedef enum {
81
    ser, kbd, mouse,
82
} chn_type_t;
83

    
84
#define SERIO_QUEUE_SIZE 256
85

    
86
typedef struct {
87
    uint8_t data[SERIO_QUEUE_SIZE];
88
    int rptr, wptr, count;
89
} SERIOQueue;
90

    
91
typedef struct ChannelState {
92
    int irq;
93
    int reg;
94
    int rxint, txint, rxint_under_svc, txint_under_svc;
95
    chn_id_t chn; // this channel, A (base+4) or B (base+0)
96
    chn_type_t type;
97
    struct ChannelState *otherchn;
98
    uint8_t rx, tx, wregs[16], rregs[16];
99
    SERIOQueue queue;
100
    CharDriverState *chr;
101
    void *intctl;
102
} ChannelState;
103

    
104
struct SerialState {
105
    struct ChannelState chn[2];
106
};
107

    
108
#define SERIAL_MAXADDR 7
109

    
110
static void handle_kbd_command(ChannelState *s, int val);
111
static int serial_can_receive(void *opaque);
112
static void serial_receive_byte(ChannelState *s, int ch);
113
static inline void set_txint(ChannelState *s);
114

    
115
static void put_queue(void *opaque, int b)
116
{
117
    ChannelState *s = opaque;
118
    SERIOQueue *q = &s->queue;
119

    
120
    SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
121
    if (q->count >= SERIO_QUEUE_SIZE)
122
        return;
123
    q->data[q->wptr] = b;
124
    if (++q->wptr == SERIO_QUEUE_SIZE)
125
        q->wptr = 0;
126
    q->count++;
127
    serial_receive_byte(s, 0);
128
}
129

    
130
static uint32_t get_queue(void *opaque)
131
{
132
    ChannelState *s = opaque;
133
    SERIOQueue *q = &s->queue;
134
    int val;
135
    
136
    if (q->count == 0) {
137
        return 0;
138
    } else {
139
        val = q->data[q->rptr];
140
        if (++q->rptr == SERIO_QUEUE_SIZE)
141
            q->rptr = 0;
142
        q->count--;
143
    }
144
    KBD_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
145
    if (q->count > 0)
146
        serial_receive_byte(s, 0);
147
    return val;
148
}
149

    
150
static int slavio_serial_update_irq_chn(ChannelState *s)
151
{
152
    if ((s->wregs[1] & 1) && // interrupts enabled
153
        (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
154
         ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
155
          s->rxint == 1) || // rx ints enabled, pending
156
         ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
157
        return 1;
158
    }
159
    return 0;
160
}
161

    
162
static void slavio_serial_update_irq(ChannelState *s)
163
{
164
    int irq;
165

    
166
    irq = slavio_serial_update_irq_chn(s);
167
    irq |= slavio_serial_update_irq_chn(s->otherchn);
168

    
169
    pic_set_irq_new(s->intctl, s->irq, irq);
170
}
171

    
172
static void slavio_serial_reset_chn(ChannelState *s)
173
{
174
    int i;
175

    
176
    s->reg = 0;
177
    for (i = 0; i < SERIAL_MAXADDR; i++) {
178
        s->rregs[i] = 0;
179
        s->wregs[i] = 0;
180
    }
181
    s->wregs[4] = 4;
182
    s->wregs[9] = 0xc0;
183
    s->wregs[11] = 8;
184
    s->wregs[14] = 0x30;
185
    s->wregs[15] = 0xf8;
186
    s->rregs[0] = 0x44;
187
    s->rregs[1] = 6;
188

    
189
    s->rx = s->tx = 0;
190
    s->rxint = s->txint = 0;
191
    s->rxint_under_svc = s->txint_under_svc = 0;
192
}
193

    
194
static void slavio_serial_reset(void *opaque)
195
{
196
    SerialState *s = opaque;
197
    slavio_serial_reset_chn(&s->chn[0]);
198
    slavio_serial_reset_chn(&s->chn[1]);
199
}
200

    
201
static inline void clr_rxint(ChannelState *s)
202
{
203
    s->rxint = 0;
204
    s->rxint_under_svc = 0;
205
    if (s->chn == chn_a)
206
        s->rregs[3] &= ~0x20;
207
    else
208
        s->otherchn->rregs[3] &= ~4;
209
    if (s->txint)
210
        set_txint(s);
211
    else
212
        s->rregs[2] = 6;
213
    slavio_serial_update_irq(s);
214
}
215

    
216
static inline void set_rxint(ChannelState *s)
217
{
218
    s->rxint = 1;
219
    if (!s->txint_under_svc) {
220
        s->rxint_under_svc = 1;
221
        if (s->chn == chn_a)
222
            s->rregs[3] |= 0x20;
223
        else
224
            s->otherchn->rregs[3] |= 4;
225
        s->rregs[2] = 4;
226
        slavio_serial_update_irq(s);
227
    }
228
}
229

    
230
static inline void clr_txint(ChannelState *s)
231
{
232
    s->txint = 0;
233
    s->txint_under_svc = 0;
234
    if (s->chn == chn_a)
235
        s->rregs[3] &= ~0x10;
236
    else
237
        s->otherchn->rregs[3] &= ~2;
238
    if (s->rxint)
239
        set_rxint(s);
240
    else
241
        s->rregs[2] = 6;
242
    slavio_serial_update_irq(s);
243
}
244

    
245
static inline void set_txint(ChannelState *s)
246
{
247
    s->txint = 1;
248
    if (!s->rxint_under_svc) {
249
        s->txint_under_svc = 1;
250
        if (s->chn == chn_a)
251
            s->rregs[3] |= 0x10;
252
        else
253
            s->otherchn->rregs[3] |= 2;
254
        s->rregs[2] = 0;
255
        slavio_serial_update_irq(s);
256
    }
257
}
258

    
259
static void slavio_serial_update_parameters(ChannelState *s)
260
{
261
    int speed, parity, data_bits, stop_bits;
262
    QEMUSerialSetParams ssp;
263

    
264
    if (!s->chr || s->type != ser)
265
        return;
266

    
267
    if (s->wregs[4] & 1) {
268
        if (s->wregs[4] & 2)
269
            parity = 'E';
270
        else
271
            parity = 'O';
272
    } else {
273
        parity = 'N';
274
    }
275
    if ((s->wregs[4] & 0x0c) == 0x0c)
276
        stop_bits = 2;
277
    else
278
        stop_bits = 1;
279
    switch (s->wregs[5] & 0x60) {
280
    case 0x00:
281
        data_bits = 5;
282
        break;
283
    case 0x20:
284
        data_bits = 7;
285
        break;
286
    case 0x40:
287
        data_bits = 6;
288
        break;
289
    default:
290
    case 0x60:
291
        data_bits = 8;
292
        break;
293
    }
294
    speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
295
    switch (s->wregs[4] & 0xc0) {
296
    case 0x00:
297
        break;
298
    case 0x40:
299
        speed /= 16;
300
        break;
301
    case 0x80:
302
        speed /= 32;
303
        break;
304
    default:
305
    case 0xc0:
306
        speed /= 64;
307
        break;
308
    }
309
    ssp.speed = speed;
310
    ssp.parity = parity;
311
    ssp.data_bits = data_bits;
312
    ssp.stop_bits = stop_bits;
313
    SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
314
                speed, parity, data_bits, stop_bits);
315
    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
316
}
317

    
318
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
319
{
320
    SerialState *ser = opaque;
321
    ChannelState *s;
322
    uint32_t saddr;
323
    int newreg, channel;
324

    
325
    val &= 0xff;
326
    saddr = (addr & 3) >> 1;
327
    channel = (addr & SERIAL_MAXADDR) >> 2;
328
    s = &ser->chn[channel];
329
    switch (saddr) {
330
    case 0:
331
        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
332
        newreg = 0;
333
        switch (s->reg) {
334
        case 0:
335
            newreg = val & 7;
336
            val &= 0x38;
337
            switch (val) {
338
            case 8:
339
                newreg |= 0x8;
340
                break;
341
            case 0x28:
342
                clr_txint(s);
343
                break;
344
            case 0x38:
345
                if (s->rxint_under_svc)
346
                    clr_rxint(s);
347
                else if (s->txint_under_svc)
348
                    clr_txint(s);
349
                break;
350
            default:
351
                break;
352
            }
353
            break;
354
        case 1 ... 3:
355
        case 6 ... 8:
356
        case 10 ... 11:
357
        case 14 ... 15:
358
            s->wregs[s->reg] = val;
359
            break;
360
        case 4:
361
        case 5:
362
        case 12:
363
        case 13:
364
            s->wregs[s->reg] = val;
365
            slavio_serial_update_parameters(s);
366
            break;
367
        case 9:
368
            switch (val & 0xc0) {
369
            case 0:
370
            default:
371
                break;
372
            case 0x40:
373
                slavio_serial_reset_chn(&ser->chn[1]);
374
                return;
375
            case 0x80:
376
                slavio_serial_reset_chn(&ser->chn[0]);
377
                return;
378
            case 0xc0:
379
                slavio_serial_reset(ser);
380
                return;
381
            }
382
            break;
383
        default:
384
            break;
385
        }
386
        if (s->reg == 0)
387
            s->reg = newreg;
388
        else
389
            s->reg = 0;
390
        break;
391
    case 1:
392
        SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
393
        if (s->wregs[5] & 8) { // tx enabled
394
            s->tx = val;
395
            if (s->chr)
396
                qemu_chr_write(s->chr, &s->tx, 1);
397
            else if (s->type == kbd) {
398
                handle_kbd_command(s, val);
399
            }
400
            s->rregs[0] |= 4; // Tx buffer empty
401
            s->rregs[1] |= 1; // All sent
402
            set_txint(s);
403
        }
404
        break;
405
    default:
406
        break;
407
    }
408
}
409

    
410
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
411
{
412
    SerialState *ser = opaque;
413
    ChannelState *s;
414
    uint32_t saddr;
415
    uint32_t ret;
416
    int channel;
417

    
418
    saddr = (addr & 3) >> 1;
419
    channel = (addr & SERIAL_MAXADDR) >> 2;
420
    s = &ser->chn[channel];
421
    switch (saddr) {
422
    case 0:
423
        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
424
        ret = s->rregs[s->reg];
425
        s->reg = 0;
426
        return ret;
427
    case 1:
428
        s->rregs[0] &= ~1;
429
        clr_rxint(s);
430
        if (s->type == kbd || s->type == mouse)
431
            ret = get_queue(s);
432
        else
433
            ret = s->rx;
434
        SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
435
        return ret;
436
    default:
437
        break;
438
    }
439
    return 0;
440
}
441

    
442
static int serial_can_receive(void *opaque)
443
{
444
    ChannelState *s = opaque;
445
    int ret;
446

    
447
    if (((s->wregs[3] & 1) == 0) // Rx not enabled
448
        || ((s->rregs[0] & 1) == 1)) // char already available
449
        ret = 0;
450
    else
451
        ret = 1;
452
    //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
453
    return ret;
454
}
455

    
456
static void serial_receive_byte(ChannelState *s, int ch)
457
{
458
    SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
459
    s->rregs[0] |= 1;
460
    s->rx = ch;
461
    set_rxint(s);
462
}
463

    
464
static void serial_receive_break(ChannelState *s)
465
{
466
    s->rregs[0] |= 0x80;
467
    slavio_serial_update_irq(s);
468
}
469

    
470
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
471
{
472
    ChannelState *s = opaque;
473
    serial_receive_byte(s, buf[0]);
474
}
475

    
476
static void serial_event(void *opaque, int event)
477
{
478
    ChannelState *s = opaque;
479
    if (event == CHR_EVENT_BREAK)
480
        serial_receive_break(s);
481
}
482

    
483
static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
484
    slavio_serial_mem_readb,
485
    slavio_serial_mem_readb,
486
    slavio_serial_mem_readb,
487
};
488

    
489
static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
490
    slavio_serial_mem_writeb,
491
    slavio_serial_mem_writeb,
492
    slavio_serial_mem_writeb,
493
};
494

    
495
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
496
{
497
    qemu_put_be32s(f, &s->irq);
498
    qemu_put_be32s(f, &s->reg);
499
    qemu_put_be32s(f, &s->rxint);
500
    qemu_put_be32s(f, &s->txint);
501
    qemu_put_be32s(f, &s->rxint_under_svc);
502
    qemu_put_be32s(f, &s->txint_under_svc);
503
    qemu_put_8s(f, &s->rx);
504
    qemu_put_8s(f, &s->tx);
505
    qemu_put_buffer(f, s->wregs, 16);
506
    qemu_put_buffer(f, s->rregs, 16);
507
}
508

    
509
static void slavio_serial_save(QEMUFile *f, void *opaque)
510
{
511
    SerialState *s = opaque;
512

    
513
    slavio_serial_save_chn(f, &s->chn[0]);
514
    slavio_serial_save_chn(f, &s->chn[1]);
515
}
516

    
517
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
518
{
519
    if (version_id > 2)
520
        return -EINVAL;
521

    
522
    qemu_get_be32s(f, &s->irq);
523
    qemu_get_be32s(f, &s->reg);
524
    qemu_get_be32s(f, &s->rxint);
525
    qemu_get_be32s(f, &s->txint);
526
    if (version_id >= 2) {
527
        qemu_get_be32s(f, &s->rxint_under_svc);
528
        qemu_get_be32s(f, &s->txint_under_svc);
529
    }
530
    qemu_get_8s(f, &s->rx);
531
    qemu_get_8s(f, &s->tx);
532
    qemu_get_buffer(f, s->wregs, 16);
533
    qemu_get_buffer(f, s->rregs, 16);
534
    return 0;
535
}
536

    
537
static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
538
{
539
    SerialState *s = opaque;
540
    int ret;
541

    
542
    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
543
    if (ret != 0)
544
        return ret;
545
    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
546
    return ret;
547

    
548
}
549

    
550
SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1,
551
                                CharDriverState *chr2, void *intctl)
552
{
553
    int slavio_serial_io_memory, i;
554
    SerialState *s;
555

    
556
    s = qemu_mallocz(sizeof(SerialState));
557
    if (!s)
558
        return NULL;
559

    
560
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
561
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
562

    
563
    s->chn[0].chr = chr1;
564
    s->chn[1].chr = chr2;
565

    
566
    for (i = 0; i < 2; i++) {
567
        s->chn[i].irq = irq;
568
        s->chn[i].chn = 1 - i;
569
        s->chn[i].type = ser;
570
        s->chn[i].intctl = intctl;
571
        if (s->chn[i].chr) {
572
            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
573
                                  serial_receive1, serial_event, &s->chn[i]);
574
        }
575
    }
576
    s->chn[0].otherchn = &s->chn[1];
577
    s->chn[1].otherchn = &s->chn[0];
578
    register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
579
    qemu_register_reset(slavio_serial_reset, s);
580
    slavio_serial_reset(s);
581
    return s;
582
}
583

    
584
static const uint8_t keycodes[128] = {
585
    127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
586
    54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
587
    79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
588
    104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
589
    14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
590
    113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
591
    90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
592
    0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
593
};
594

    
595
static void sunkbd_event(void *opaque, int ch)
596
{
597
    ChannelState *s = opaque;
598
    int release = ch & 0x80;
599

    
600
    ch = keycodes[ch & 0x7f];
601
    KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
602
    put_queue(s, ch | release);
603
}
604

    
605
static void handle_kbd_command(ChannelState *s, int val)
606
{
607
    KBD_DPRINTF("Command %d\n", val);
608
    switch (val) {
609
    case 1: // Reset, return type code
610
        put_queue(s, 0xff);
611
        put_queue(s, 5); // Type 5
612
        break;
613
    case 7: // Query layout
614
        put_queue(s, 0xfe);
615
        put_queue(s, 0x20); // XXX, layout?
616
        break;
617
    default:
618
        break;
619
    }
620
}
621

    
622
static void sunmouse_event(void *opaque, 
623
                               int dx, int dy, int dz, int buttons_state)
624
{
625
    ChannelState *s = opaque;
626
    int ch;
627

    
628
    /* XXX: SDL sometimes generates nul events: we delete them */
629
    if (dx == 0 && dy == 0 && dz == 0 && buttons_state == 0)
630
        return;
631
    MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
632

    
633
    ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
634

    
635
    if (buttons_state & MOUSE_EVENT_LBUTTON)
636
        ch ^= 0x4;
637
    if (buttons_state & MOUSE_EVENT_MBUTTON)
638
        ch ^= 0x2;
639
    if (buttons_state & MOUSE_EVENT_RBUTTON)
640
        ch ^= 0x1;
641

    
642
    put_queue(s, ch);
643

    
644
    ch = dx;
645

    
646
    if (ch > 127)
647
        ch=127;
648
    else if (ch < -127)
649
        ch=-127;
650

    
651
    put_queue(s, ch & 0xff);
652

    
653
    ch = -dy;
654

    
655
    if (ch > 127)
656
        ch=127;
657
    else if (ch < -127)
658
        ch=-127;
659

    
660
    put_queue(s, ch & 0xff);
661

    
662
    // MSC protocol specify two extra motion bytes
663

    
664
    put_queue(s, 0);
665
    put_queue(s, 0);
666
}
667

    
668
void slavio_serial_ms_kbd_init(int base, int irq, void *intctl)
669
{
670
    int slavio_serial_io_memory, i;
671
    SerialState *s;
672

    
673
    s = qemu_mallocz(sizeof(SerialState));
674
    if (!s)
675
        return;
676
    for (i = 0; i < 2; i++) {
677
        s->chn[i].irq = irq;
678
        s->chn[i].chn = 1 - i;
679
        s->chn[i].chr = NULL;
680
        s->chn[i].intctl = intctl;
681
    }
682
    s->chn[0].otherchn = &s->chn[1];
683
    s->chn[1].otherchn = &s->chn[0];
684
    s->chn[0].type = mouse;
685
    s->chn[1].type = kbd;
686

    
687
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
688
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
689

    
690
    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
691
    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
692
    qemu_register_reset(slavio_serial_reset, s);
693
    slavio_serial_reset(s);
694
}