Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ e64d7d59

History | View | Annotate | Download (24.9 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_SIZE 8
112
#define SERIAL_CTRL 0
113
#define SERIAL_DATA 1
114

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
712
}
713

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
863
    put_queue(s, ch);
864

    
865
    ch = dx;
866

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

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

    
874
    ch = -dy;
875

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

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

    
883
    // MSC protocol specify two extra motion bytes
884

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

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

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

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

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