Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ 9277bc72

History | View | Annotate | Download (25 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 "hw.h"
25
#include "sun4m.h"
26
#include "qemu-char.h"
27
#include "console.h"
28

    
29
/* debug serial */
30
//#define DEBUG_SERIAL
31

    
32
/* debug keyboard */
33
//#define DEBUG_KBD
34

    
35
/* debug mouse */
36
//#define DEBUG_MOUSE
37

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

    
49
/*
50
 * Modifications:
51
 *  2006-Aug-10  Igor Kovalenko :   Renamed KBDQueue to SERIOQueue, implemented
52
 *                                  serial mouse queue.
53
 *                                  Implemented serial mouse protocol.
54
 */
55

    
56
#ifdef DEBUG_SERIAL
57
#define SER_DPRINTF(fmt, args...) \
58
do { printf("SER: " fmt , ##args); } while (0)
59
#else
60
#define SER_DPRINTF(fmt, args...)
61
#endif
62
#ifdef DEBUG_KBD
63
#define KBD_DPRINTF(fmt, args...) \
64
do { printf("KBD: " fmt , ##args); } while (0)
65
#else
66
#define KBD_DPRINTF(fmt, args...)
67
#endif
68
#ifdef DEBUG_MOUSE
69
#define MS_DPRINTF(fmt, args...) \
70
do { printf("MSC: " fmt , ##args); } while (0)
71
#else
72
#define MS_DPRINTF(fmt, args...)
73
#endif
74

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

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

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

    
85
#define SERIO_QUEUE_SIZE 256
86

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

    
92
#define SERIAL_REGS 16
93
typedef struct ChannelState {
94
    qemu_irq irq;
95
    uint32_t reg;
96
    uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
97
    chn_id_t chn; // this channel, A (base+4) or B (base+0)
98
    chn_type_t type;
99
    struct ChannelState *otherchn;
100
    uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
101
    SERIOQueue queue;
102
    CharDriverState *chr;
103
    int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
104
    int disabled;
105
} ChannelState;
106

    
107
struct SerialState {
108
    struct ChannelState chn[2];
109
};
110

    
111
#define SERIAL_MAXADDR 7
112
#define SERIAL_SIZE (SERIAL_MAXADDR + 1)
113
#define SERIAL_CTRL 0
114
#define SERIAL_DATA 1
115

    
116
#define W_CMD     0
117
#define CMD_PTR_MASK   0x07
118
#define CMD_CMD_MASK   0x38
119
#define CMD_HI         0x08
120
#define CMD_CLR_TXINT  0x28
121
#define CMD_CLR_IUS    0x38
122
#define W_INTR    1
123
#define INTR_INTALL    0x01
124
#define INTR_TXINT     0x02
125
#define INTR_RXMODEMSK 0x18
126
#define INTR_RXINT1ST  0x08
127
#define INTR_RXINTALL  0x10
128
#define W_IVEC    2
129
#define W_RXCTRL  3
130
#define RXCTRL_RXEN    0x01
131
#define W_TXCTRL1 4
132
#define TXCTRL1_PAREN  0x01
133
#define TXCTRL1_PAREV  0x02
134
#define TXCTRL1_1STOP  0x04
135
#define TXCTRL1_1HSTOP 0x08
136
#define TXCTRL1_2STOP  0x0c
137
#define TXCTRL1_STPMSK 0x0c
138
#define TXCTRL1_CLK1X  0x00
139
#define TXCTRL1_CLK16X 0x40
140
#define TXCTRL1_CLK32X 0x80
141
#define TXCTRL1_CLK64X 0xc0
142
#define TXCTRL1_CLKMSK 0xc0
143
#define W_TXCTRL2 5
144
#define TXCTRL2_TXEN   0x08
145
#define TXCTRL2_BITMSK 0x60
146
#define TXCTRL2_5BITS  0x00
147
#define TXCTRL2_7BITS  0x20
148
#define TXCTRL2_6BITS  0x40
149
#define TXCTRL2_8BITS  0x60
150
#define W_SYNC1   6
151
#define W_SYNC2   7
152
#define W_TXBUF   8
153
#define W_MINTR   9
154
#define MINTR_STATUSHI 0x10
155
#define MINTR_RST_MASK 0xc0
156
#define MINTR_RST_B    0x40
157
#define MINTR_RST_A    0x80
158
#define MINTR_RST_ALL  0xc0
159
#define W_MISC1  10
160
#define W_CLOCK  11
161
#define CLOCK_TRXC     0x08
162
#define W_BRGLO  12
163
#define W_BRGHI  13
164
#define W_MISC2  14
165
#define MISC2_PLLDIS   0x30
166
#define W_EXTINT 15
167
#define EXTINT_DCD     0x08
168
#define EXTINT_SYNCINT 0x10
169
#define EXTINT_CTSINT  0x20
170
#define EXTINT_TXUNDRN 0x40
171
#define EXTINT_BRKINT  0x80
172

    
173
#define R_STATUS  0
174
#define STATUS_RXAV    0x01
175
#define STATUS_ZERO    0x02
176
#define STATUS_TXEMPTY 0x04
177
#define STATUS_DCD     0x08
178
#define STATUS_SYNC    0x10
179
#define STATUS_CTS     0x20
180
#define STATUS_TXUNDRN 0x40
181
#define STATUS_BRK     0x80
182
#define R_SPEC    1
183
#define SPEC_ALLSENT   0x01
184
#define SPEC_BITS8     0x06
185
#define R_IVEC    2
186
#define IVEC_TXINTB    0x00
187
#define IVEC_LONOINT   0x06
188
#define IVEC_LORXINTA  0x0c
189
#define IVEC_LORXINTB  0x04
190
#define IVEC_LOTXINTA  0x08
191
#define IVEC_HINOINT   0x60
192
#define IVEC_HIRXINTA  0x30
193
#define IVEC_HIRXINTB  0x20
194
#define IVEC_HITXINTA  0x10
195
#define R_INTR    3
196
#define INTR_EXTINTB   0x01
197
#define INTR_TXINTB    0x02
198
#define INTR_RXINTB    0x04
199
#define INTR_EXTINTA   0x08
200
#define INTR_TXINTA    0x10
201
#define INTR_RXINTA    0x20
202
#define R_IPEN    4
203
#define R_TXCTRL1 5
204
#define R_TXCTRL2 6
205
#define R_BC      7
206
#define R_RXBUF   8
207
#define R_RXCTRL  9
208
#define R_MISC   10
209
#define R_MISC1  11
210
#define R_BRGLO  12
211
#define R_BRGHI  13
212
#define R_MISC1I 14
213
#define R_EXTINT 15
214

    
215
static void handle_kbd_command(ChannelState *s, int val);
216
static int serial_can_receive(void *opaque);
217
static void serial_receive_byte(ChannelState *s, int ch);
218

    
219
static void clear_queue(void *opaque)
220
{
221
    ChannelState *s = opaque;
222
    SERIOQueue *q = &s->queue;
223
    q->rptr = q->wptr = q->count = 0;
224
}
225

    
226
static void put_queue(void *opaque, int b)
227
{
228
    ChannelState *s = opaque;
229
    SERIOQueue *q = &s->queue;
230

    
231
    SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
232
    if (q->count >= SERIO_QUEUE_SIZE)
233
        return;
234
    q->data[q->wptr] = b;
235
    if (++q->wptr == SERIO_QUEUE_SIZE)
236
        q->wptr = 0;
237
    q->count++;
238
    serial_receive_byte(s, 0);
239
}
240

    
241
static uint32_t get_queue(void *opaque)
242
{
243
    ChannelState *s = opaque;
244
    SERIOQueue *q = &s->queue;
245
    int val;
246

    
247
    if (q->count == 0) {
248
        return 0;
249
    } else {
250
        val = q->data[q->rptr];
251
        if (++q->rptr == SERIO_QUEUE_SIZE)
252
            q->rptr = 0;
253
        q->count--;
254
    }
255
    SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
256
    if (q->count > 0)
257
        serial_receive_byte(s, 0);
258
    return val;
259
}
260

    
261
static int slavio_serial_update_irq_chn(ChannelState *s)
262
{
263
    if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
264
         // tx ints enabled, pending
265
         ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
266
           ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
267
          s->rxint == 1) || // rx ints enabled, pending
268
         ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
269
          (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
270
        return 1;
271
    }
272
    return 0;
273
}
274

    
275
static void slavio_serial_update_irq(ChannelState *s)
276
{
277
    int irq;
278

    
279
    irq = slavio_serial_update_irq_chn(s);
280
    irq |= slavio_serial_update_irq_chn(s->otherchn);
281

    
282
    SER_DPRINTF("IRQ = %d\n", irq);
283
    qemu_set_irq(s->irq, irq);
284
}
285

    
286
static void slavio_serial_reset_chn(ChannelState *s)
287
{
288
    int i;
289

    
290
    s->reg = 0;
291
    for (i = 0; i < SERIAL_SIZE; i++) {
292
        s->rregs[i] = 0;
293
        s->wregs[i] = 0;
294
    }
295
    s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
296
    s->wregs[W_MINTR] = MINTR_RST_ALL;
297
    s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
298
    s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
299
    s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
300
        EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
301
    if (s->disabled)
302
        s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
303
            STATUS_CTS | STATUS_TXUNDRN;
304
    else
305
        s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
306
    s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
307

    
308
    s->rx = s->tx = 0;
309
    s->rxint = s->txint = 0;
310
    s->rxint_under_svc = s->txint_under_svc = 0;
311
    s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
312
    clear_queue(s);
313
}
314

    
315
static void slavio_serial_reset(void *opaque)
316
{
317
    SerialState *s = opaque;
318
    slavio_serial_reset_chn(&s->chn[0]);
319
    slavio_serial_reset_chn(&s->chn[1]);
320
}
321

    
322
static inline void set_rxint(ChannelState *s)
323
{
324
    s->rxint = 1;
325
    if (!s->txint_under_svc) {
326
        s->rxint_under_svc = 1;
327
        if (s->chn == chn_a) {
328
            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
329
                s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
330
            else
331
                s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
332
        } else {
333
            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
334
                s->rregs[R_IVEC] = IVEC_HIRXINTB;
335
            else
336
                s->rregs[R_IVEC] = IVEC_LORXINTB;
337
        }
338
    }
339
    if (s->chn == chn_a)
340
        s->rregs[R_INTR] |= INTR_RXINTA;
341
    else
342
        s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
343
    slavio_serial_update_irq(s);
344
}
345

    
346
static inline void set_txint(ChannelState *s)
347
{
348
    s->txint = 1;
349
    if (!s->rxint_under_svc) {
350
        s->txint_under_svc = 1;
351
        if (s->chn == chn_a) {
352
            if (s->wregs[W_MINTR] & MINTR_STATUSHI)
353
                s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
354
            else
355
                s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
356
        } else {
357
            s->rregs[R_IVEC] = IVEC_TXINTB;
358
        }
359
    }
360
    if (s->chn == chn_a)
361
        s->rregs[R_INTR] |= INTR_TXINTA;
362
    else
363
        s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
364
    slavio_serial_update_irq(s);
365
}
366

    
367
static inline void clr_rxint(ChannelState *s)
368
{
369
    s->rxint = 0;
370
    s->rxint_under_svc = 0;
371
    if (s->chn == chn_a) {
372
        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
373
            s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
374
        else
375
            s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
376
        s->rregs[R_INTR] &= ~INTR_RXINTA;
377
    } else {
378
        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
379
            s->rregs[R_IVEC] = IVEC_HINOINT;
380
        else
381
            s->rregs[R_IVEC] = IVEC_LONOINT;
382
        s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
383
    }
384
    if (s->txint)
385
        set_txint(s);
386
    slavio_serial_update_irq(s);
387
}
388

    
389
static inline void clr_txint(ChannelState *s)
390
{
391
    s->txint = 0;
392
    s->txint_under_svc = 0;
393
    if (s->chn == chn_a) {
394
        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
395
            s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
396
        else
397
            s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
398
        s->rregs[R_INTR] &= ~INTR_TXINTA;
399
    } else {
400
        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
401
            s->rregs[R_IVEC] = IVEC_HINOINT;
402
        else
403
            s->rregs[R_IVEC] = IVEC_LONOINT;
404
        s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
405
    }
406
    if (s->rxint)
407
        set_rxint(s);
408
    slavio_serial_update_irq(s);
409
}
410

    
411
static void slavio_serial_update_parameters(ChannelState *s)
412
{
413
    int speed, parity, data_bits, stop_bits;
414
    QEMUSerialSetParams ssp;
415

    
416
    if (!s->chr || s->type != ser)
417
        return;
418

    
419
    if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
420
        if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
421
            parity = 'E';
422
        else
423
            parity = 'O';
424
    } else {
425
        parity = 'N';
426
    }
427
    if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
428
        stop_bits = 2;
429
    else
430
        stop_bits = 1;
431
    switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
432
    case TXCTRL2_5BITS:
433
        data_bits = 5;
434
        break;
435
    case TXCTRL2_7BITS:
436
        data_bits = 7;
437
        break;
438
    case TXCTRL2_6BITS:
439
        data_bits = 6;
440
        break;
441
    default:
442
    case TXCTRL2_8BITS:
443
        data_bits = 8;
444
        break;
445
    }
446
    speed = 2457600 / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
447
    switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
448
    case TXCTRL1_CLK1X:
449
        break;
450
    case TXCTRL1_CLK16X:
451
        speed /= 16;
452
        break;
453
    case TXCTRL1_CLK32X:
454
        speed /= 32;
455
        break;
456
    default:
457
    case TXCTRL1_CLK64X:
458
        speed /= 64;
459
        break;
460
    }
461
    ssp.speed = speed;
462
    ssp.parity = parity;
463
    ssp.data_bits = data_bits;
464
    ssp.stop_bits = stop_bits;
465
    SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
466
                speed, parity, data_bits, stop_bits);
467
    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
468
}
469

    
470
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
471
                                     uint32_t val)
472
{
473
    SerialState *serial = opaque;
474
    ChannelState *s;
475
    uint32_t saddr;
476
    int newreg, channel;
477

    
478
    val &= 0xff;
479
    saddr = (addr & 3) >> 1;
480
    channel = (addr & SERIAL_MAXADDR) >> 2;
481
    s = &serial->chn[channel];
482
    switch (saddr) {
483
    case SERIAL_CTRL:
484
        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
485
                    val & 0xff);
486
        newreg = 0;
487
        switch (s->reg) {
488
        case W_CMD:
489
            newreg = val & CMD_PTR_MASK;
490
            val &= CMD_CMD_MASK;
491
            switch (val) {
492
            case CMD_HI:
493
                newreg |= CMD_HI;
494
                break;
495
            case CMD_CLR_TXINT:
496
                clr_txint(s);
497
                break;
498
            case CMD_CLR_IUS:
499
                if (s->rxint_under_svc)
500
                    clr_rxint(s);
501
                else if (s->txint_under_svc)
502
                    clr_txint(s);
503
                break;
504
            default:
505
                break;
506
            }
507
            break;
508
        case W_INTR ... W_RXCTRL:
509
        case W_SYNC1 ... W_TXBUF:
510
        case W_MISC1 ... W_CLOCK:
511
        case W_MISC2 ... W_EXTINT:
512
            s->wregs[s->reg] = val;
513
            break;
514
        case W_TXCTRL1:
515
        case W_TXCTRL2:
516
            s->wregs[s->reg] = val;
517
            slavio_serial_update_parameters(s);
518
            break;
519
        case W_BRGLO:
520
        case W_BRGHI:
521
            s->wregs[s->reg] = val;
522
            s->rregs[s->reg] = val;
523
            slavio_serial_update_parameters(s);
524
            break;
525
        case W_MINTR:
526
            switch (val & MINTR_RST_MASK) {
527
            case 0:
528
            default:
529
                break;
530
            case MINTR_RST_B:
531
                slavio_serial_reset_chn(&serial->chn[0]);
532
                return;
533
            case MINTR_RST_A:
534
                slavio_serial_reset_chn(&serial->chn[1]);
535
                return;
536
            case MINTR_RST_ALL:
537
                slavio_serial_reset(serial);
538
                return;
539
            }
540
            break;
541
        default:
542
            break;
543
        }
544
        if (s->reg == 0)
545
            s->reg = newreg;
546
        else
547
            s->reg = 0;
548
        break;
549
    case SERIAL_DATA:
550
        SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
551
        s->tx = val;
552
        if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
553
            if (s->chr)
554
                qemu_chr_write(s->chr, &s->tx, 1);
555
            else if (s->type == kbd && !s->disabled) {
556
                handle_kbd_command(s, val);
557
            }
558
        }
559
        s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
560
        s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
561
        set_txint(s);
562
        break;
563
    default:
564
        break;
565
    }
566
}
567

    
568
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
569
{
570
    SerialState *serial = opaque;
571
    ChannelState *s;
572
    uint32_t saddr;
573
    uint32_t ret;
574
    int channel;
575

    
576
    saddr = (addr & 3) >> 1;
577
    channel = (addr & SERIAL_MAXADDR) >> 2;
578
    s = &serial->chn[channel];
579
    switch (saddr) {
580
    case SERIAL_CTRL:
581
        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
582
                    s->rregs[s->reg]);
583
        ret = s->rregs[s->reg];
584
        s->reg = 0;
585
        return ret;
586
    case SERIAL_DATA:
587
        s->rregs[R_STATUS] &= ~STATUS_RXAV;
588
        clr_rxint(s);
589
        if (s->type == kbd || s->type == mouse)
590
            ret = get_queue(s);
591
        else
592
            ret = s->rx;
593
        SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
594
        if (s->chr)
595
            qemu_chr_accept_input(s->chr);
596
        return ret;
597
    default:
598
        break;
599
    }
600
    return 0;
601
}
602

    
603
static int serial_can_receive(void *opaque)
604
{
605
    ChannelState *s = opaque;
606
    int ret;
607

    
608
    if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
609
        || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
610
        // char already available
611
        ret = 0;
612
    else
613
        ret = 1;
614
    return ret;
615
}
616

    
617
static void serial_receive_byte(ChannelState *s, int ch)
618
{
619
    SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
620
    s->rregs[R_STATUS] |= STATUS_RXAV;
621
    s->rx = ch;
622
    set_rxint(s);
623
}
624

    
625
static void serial_receive_break(ChannelState *s)
626
{
627
    s->rregs[R_STATUS] |= STATUS_BRK;
628
    slavio_serial_update_irq(s);
629
}
630

    
631
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
632
{
633
    ChannelState *s = opaque;
634
    serial_receive_byte(s, buf[0]);
635
}
636

    
637
static void serial_event(void *opaque, int event)
638
{
639
    ChannelState *s = opaque;
640
    if (event == CHR_EVENT_BREAK)
641
        serial_receive_break(s);
642
}
643

    
644
static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
645
    slavio_serial_mem_readb,
646
    NULL,
647
    NULL,
648
};
649

    
650
static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
651
    slavio_serial_mem_writeb,
652
    NULL,
653
    NULL,
654
};
655

    
656
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
657
{
658
    uint32_t tmp = 0;
659

    
660
    qemu_put_be32s(f, &tmp); /* unused, was IRQ.  */
661
    qemu_put_be32s(f, &s->reg);
662
    qemu_put_be32s(f, &s->rxint);
663
    qemu_put_be32s(f, &s->txint);
664
    qemu_put_be32s(f, &s->rxint_under_svc);
665
    qemu_put_be32s(f, &s->txint_under_svc);
666
    qemu_put_8s(f, &s->rx);
667
    qemu_put_8s(f, &s->tx);
668
    qemu_put_buffer(f, s->wregs, SERIAL_REGS);
669
    qemu_put_buffer(f, s->rregs, SERIAL_REGS);
670
}
671

    
672
static void slavio_serial_save(QEMUFile *f, void *opaque)
673
{
674
    SerialState *s = opaque;
675

    
676
    slavio_serial_save_chn(f, &s->chn[0]);
677
    slavio_serial_save_chn(f, &s->chn[1]);
678
}
679

    
680
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
681
{
682
    uint32_t tmp;
683

    
684
    if (version_id > 2)
685
        return -EINVAL;
686

    
687
    qemu_get_be32s(f, &tmp); /* unused */
688
    qemu_get_be32s(f, &s->reg);
689
    qemu_get_be32s(f, &s->rxint);
690
    qemu_get_be32s(f, &s->txint);
691
    if (version_id >= 2) {
692
        qemu_get_be32s(f, &s->rxint_under_svc);
693
        qemu_get_be32s(f, &s->txint_under_svc);
694
    }
695
    qemu_get_8s(f, &s->rx);
696
    qemu_get_8s(f, &s->tx);
697
    qemu_get_buffer(f, s->wregs, SERIAL_REGS);
698
    qemu_get_buffer(f, s->rregs, SERIAL_REGS);
699
    return 0;
700
}
701

    
702
static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
703
{
704
    SerialState *s = opaque;
705
    int ret;
706

    
707
    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
708
    if (ret != 0)
709
        return ret;
710
    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
711
    return ret;
712

    
713
}
714

    
715
SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
716
                                CharDriverState *chr1, CharDriverState *chr2)
717
{
718
    int slavio_serial_io_memory, i;
719
    SerialState *s;
720

    
721
    s = qemu_mallocz(sizeof(SerialState));
722
    if (!s)
723
        return NULL;
724

    
725
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
726
                                                     slavio_serial_mem_write,
727
                                                     s);
728
    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
729

    
730
    s->chn[0].chr = chr1;
731
    s->chn[1].chr = chr2;
732
    s->chn[0].disabled = 0;
733
    s->chn[1].disabled = 0;
734

    
735
    for (i = 0; i < 2; i++) {
736
        s->chn[i].irq = irq;
737
        s->chn[i].chn = 1 - i;
738
        s->chn[i].type = ser;
739
        if (s->chn[i].chr) {
740
            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
741
                                  serial_receive1, serial_event, &s->chn[i]);
742
        }
743
    }
744
    s->chn[0].otherchn = &s->chn[1];
745
    s->chn[1].otherchn = &s->chn[0];
746
    register_savevm("slavio_serial", base, 2, slavio_serial_save,
747
                    slavio_serial_load, s);
748
    qemu_register_reset(slavio_serial_reset, s);
749
    slavio_serial_reset(s);
750
    return s;
751
}
752

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

    
764
static const uint8_t e0_keycodes[128] = {
765
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
766
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
767
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
768
    0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
769
    0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
770
    113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
771
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
772
    1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
773
};
774

    
775
static void sunkbd_event(void *opaque, int ch)
776
{
777
    ChannelState *s = opaque;
778
    int release = ch & 0x80;
779

    
780
    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
781
                "press");
782
    switch (ch) {
783
    case 58: // Caps lock press
784
        s->caps_lock_mode ^= 1;
785
        if (s->caps_lock_mode == 2)
786
            return; // Drop second press
787
        break;
788
    case 69: // Num lock press
789
        s->num_lock_mode ^= 1;
790
        if (s->num_lock_mode == 2)
791
            return; // Drop second press
792
        break;
793
    case 186: // Caps lock release
794
        s->caps_lock_mode ^= 2;
795
        if (s->caps_lock_mode == 3)
796
            return; // Drop first release
797
        break;
798
    case 197: // Num lock release
799
        s->num_lock_mode ^= 2;
800
        if (s->num_lock_mode == 3)
801
            return; // Drop first release
802
        break;
803
    case 0xe0:
804
        s->e0_mode = 1;
805
        return;
806
    default:
807
        break;
808
    }
809
    if (s->e0_mode) {
810
        s->e0_mode = 0;
811
        ch = e0_keycodes[ch & 0x7f];
812
    } else {
813
        ch = keycodes[ch & 0x7f];
814
    }
815
    KBD_DPRINTF("Translated keycode %2.2x\n", ch);
816
    put_queue(s, ch | release);
817
}
818

    
819
static void handle_kbd_command(ChannelState *s, int val)
820
{
821
    KBD_DPRINTF("Command %d\n", val);
822
    if (s->led_mode) { // Ignore led byte
823
        s->led_mode = 0;
824
        return;
825
    }
826
    switch (val) {
827
    case 1: // Reset, return type code
828
        clear_queue(s);
829
        put_queue(s, 0xff);
830
        put_queue(s, 4); // Type 4
831
        put_queue(s, 0x7f);
832
        break;
833
    case 0xe: // Set leds
834
        s->led_mode = 1;
835
        break;
836
    case 7: // Query layout
837
    case 0xf:
838
        clear_queue(s);
839
        put_queue(s, 0xfe);
840
        put_queue(s, 0); // XXX, layout?
841
        break;
842
    default:
843
        break;
844
    }
845
}
846

    
847
static void sunmouse_event(void *opaque,
848
                               int dx, int dy, int dz, int buttons_state)
849
{
850
    ChannelState *s = opaque;
851
    int ch;
852

    
853
    MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
854

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

    
857
    if (buttons_state & MOUSE_EVENT_LBUTTON)
858
        ch ^= 0x4;
859
    if (buttons_state & MOUSE_EVENT_MBUTTON)
860
        ch ^= 0x2;
861
    if (buttons_state & MOUSE_EVENT_RBUTTON)
862
        ch ^= 0x1;
863

    
864
    put_queue(s, ch);
865

    
866
    ch = dx;
867

    
868
    if (ch > 127)
869
        ch=127;
870
    else if (ch < -127)
871
        ch=-127;
872

    
873
    put_queue(s, ch & 0xff);
874

    
875
    ch = -dy;
876

    
877
    if (ch > 127)
878
        ch=127;
879
    else if (ch < -127)
880
        ch=-127;
881

    
882
    put_queue(s, ch & 0xff);
883

    
884
    // MSC protocol specify two extra motion bytes
885

    
886
    put_queue(s, 0);
887
    put_queue(s, 0);
888
}
889

    
890
void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
891
                               int disabled)
892
{
893
    int slavio_serial_io_memory, i;
894
    SerialState *s;
895

    
896
    s = qemu_mallocz(sizeof(SerialState));
897
    if (!s)
898
        return;
899
    for (i = 0; i < 2; i++) {
900
        s->chn[i].irq = irq;
901
        s->chn[i].chn = 1 - i;
902
        s->chn[i].chr = NULL;
903
    }
904
    s->chn[0].otherchn = &s->chn[1];
905
    s->chn[1].otherchn = &s->chn[0];
906
    s->chn[0].type = mouse;
907
    s->chn[1].type = kbd;
908
    s->chn[0].disabled = disabled;
909
    s->chn[1].disabled = disabled;
910

    
911
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
912
                                                     slavio_serial_mem_write,
913
                                                     s);
914
    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
915

    
916
    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
917
                                 "QEMU Sun Mouse");
918
    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
919
    register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save,
920
                    slavio_serial_load, s);
921
    qemu_register_reset(slavio_serial_reset, s);
922
    slavio_serial_reset(s);
923
}