Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ b76482e7

History | View | Annotate | Download (20.5 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
typedef struct ChannelState {
93
    qemu_irq irq;
94
    int reg;
95
    int rxint, txint, rxint_under_svc, txint_under_svc;
96
    chn_id_t chn; // this channel, A (base+4) or B (base+0)
97
    chn_type_t type;
98
    struct ChannelState *otherchn;
99
    uint8_t rx, tx, wregs[16], rregs[16];
100
    SERIOQueue queue;
101
    CharDriverState *chr;
102
    int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
103
} ChannelState;
104

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

    
109
#define SERIAL_MAXADDR 7
110
#define SERIAL_SIZE (SERIAL_MAXADDR + 1)
111

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

    
117
static void clear_queue(void *opaque)
118
{
119
    ChannelState *s = opaque;
120
    SERIOQueue *q = &s->queue;
121
    q->rptr = q->wptr = q->count = 0;
122
}
123

    
124
static void put_queue(void *opaque, int b)
125
{
126
    ChannelState *s = opaque;
127
    SERIOQueue *q = &s->queue;
128

    
129
    SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
130
    if (q->count >= SERIO_QUEUE_SIZE)
131
        return;
132
    q->data[q->wptr] = b;
133
    if (++q->wptr == SERIO_QUEUE_SIZE)
134
        q->wptr = 0;
135
    q->count++;
136
    serial_receive_byte(s, 0);
137
}
138

    
139
static uint32_t get_queue(void *opaque)
140
{
141
    ChannelState *s = opaque;
142
    SERIOQueue *q = &s->queue;
143
    int val;
144

    
145
    if (q->count == 0) {
146
        return 0;
147
    } else {
148
        val = q->data[q->rptr];
149
        if (++q->rptr == SERIO_QUEUE_SIZE)
150
            q->rptr = 0;
151
        q->count--;
152
    }
153
    SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
154
    if (q->count > 0)
155
        serial_receive_byte(s, 0);
156
    return val;
157
}
158

    
159
static int slavio_serial_update_irq_chn(ChannelState *s)
160
{
161
    if ((s->wregs[1] & 1) && // interrupts enabled
162
        (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
163
         ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
164
          s->rxint == 1) || // rx ints enabled, pending
165
         ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
166
        return 1;
167
    }
168
    return 0;
169
}
170

    
171
static void slavio_serial_update_irq(ChannelState *s)
172
{
173
    int irq;
174

    
175
    irq = slavio_serial_update_irq_chn(s);
176
    irq |= slavio_serial_update_irq_chn(s->otherchn);
177

    
178
    SER_DPRINTF("IRQ = %d\n", irq);
179
    qemu_set_irq(s->irq, irq);
180
}
181

    
182
static void slavio_serial_reset_chn(ChannelState *s)
183
{
184
    int i;
185

    
186
    s->reg = 0;
187
    for (i = 0; i < SERIAL_SIZE; i++) {
188
        s->rregs[i] = 0;
189
        s->wregs[i] = 0;
190
    }
191
    s->wregs[4] = 4;
192
    s->wregs[9] = 0xc0;
193
    s->wregs[11] = 8;
194
    s->wregs[14] = 0x30;
195
    s->wregs[15] = 0xf8;
196
    s->rregs[0] = 0x44;
197
    s->rregs[1] = 6;
198

    
199
    s->rx = s->tx = 0;
200
    s->rxint = s->txint = 0;
201
    s->rxint_under_svc = s->txint_under_svc = 0;
202
    s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
203
    clear_queue(s);
204
}
205

    
206
static void slavio_serial_reset(void *opaque)
207
{
208
    SerialState *s = opaque;
209
    slavio_serial_reset_chn(&s->chn[0]);
210
    slavio_serial_reset_chn(&s->chn[1]);
211
}
212

    
213
static inline void clr_rxint(ChannelState *s)
214
{
215
    s->rxint = 0;
216
    s->rxint_under_svc = 0;
217
    if (s->chn == chn_a) {
218
        if (s->wregs[9] & 0x10)
219
            s->otherchn->rregs[2] = 0x60;
220
        else
221
            s->otherchn->rregs[2] = 0x06;
222
        s->rregs[3] &= ~0x20;
223
    } else {
224
        if (s->wregs[9] & 0x10)
225
            s->rregs[2] = 0x60;
226
        else
227
            s->rregs[2] = 0x06;
228
        s->otherchn->rregs[3] &= ~4;
229
    }
230
    if (s->txint)
231
        set_txint(s);
232
    slavio_serial_update_irq(s);
233
}
234

    
235
static inline void set_rxint(ChannelState *s)
236
{
237
    s->rxint = 1;
238
    if (!s->txint_under_svc) {
239
        s->rxint_under_svc = 1;
240
        if (s->chn == chn_a) {
241
            if (s->wregs[9] & 0x10)
242
                s->otherchn->rregs[2] = 0x30;
243
            else
244
                s->otherchn->rregs[2] = 0x0c;
245
        } else {
246
            if (s->wregs[9] & 0x10)
247
                s->rregs[2] = 0x20;
248
            else
249
                s->rregs[2] = 0x04;
250
        }
251
    }
252
    if (s->chn == chn_a)
253
        s->rregs[3] |= 0x20;
254
    else
255
        s->otherchn->rregs[3] |= 4;
256
    slavio_serial_update_irq(s);
257
}
258

    
259
static inline void clr_txint(ChannelState *s)
260
{
261
    s->txint = 0;
262
    s->txint_under_svc = 0;
263
    if (s->chn == chn_a) {
264
        if (s->wregs[9] & 0x10)
265
            s->otherchn->rregs[2] = 0x60;
266
        else
267
            s->otherchn->rregs[2] = 0x06;
268
        s->rregs[3] &= ~0x10;
269
    } else {
270
        if (s->wregs[9] & 0x10)
271
            s->rregs[2] = 0x60;
272
        else
273
            s->rregs[2] = 0x06;
274
        s->otherchn->rregs[3] &= ~2;
275
    }
276
    if (s->rxint)
277
        set_rxint(s);
278
    slavio_serial_update_irq(s);
279
}
280

    
281
static inline void set_txint(ChannelState *s)
282
{
283
    s->txint = 1;
284
    if (!s->rxint_under_svc) {
285
        s->txint_under_svc = 1;
286
        if (s->chn == chn_a) {
287
            if (s->wregs[9] & 0x10)
288
                s->otherchn->rregs[2] = 0x10;
289
            else
290
                s->otherchn->rregs[2] = 0x08;
291
        } else {
292
            s->rregs[2] = 0;
293
        }
294
    }
295
    if (s->chn == chn_a)
296
        s->rregs[3] |= 0x10;
297
    else
298
        s->otherchn->rregs[3] |= 2;
299
    slavio_serial_update_irq(s);
300
}
301

    
302
static void slavio_serial_update_parameters(ChannelState *s)
303
{
304
    int speed, parity, data_bits, stop_bits;
305
    QEMUSerialSetParams ssp;
306

    
307
    if (!s->chr || s->type != ser)
308
        return;
309

    
310
    if (s->wregs[4] & 1) {
311
        if (s->wregs[4] & 2)
312
            parity = 'E';
313
        else
314
            parity = 'O';
315
    } else {
316
        parity = 'N';
317
    }
318
    if ((s->wregs[4] & 0x0c) == 0x0c)
319
        stop_bits = 2;
320
    else
321
        stop_bits = 1;
322
    switch (s->wregs[5] & 0x60) {
323
    case 0x00:
324
        data_bits = 5;
325
        break;
326
    case 0x20:
327
        data_bits = 7;
328
        break;
329
    case 0x40:
330
        data_bits = 6;
331
        break;
332
    default:
333
    case 0x60:
334
        data_bits = 8;
335
        break;
336
    }
337
    speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
338
    switch (s->wregs[4] & 0xc0) {
339
    case 0x00:
340
        break;
341
    case 0x40:
342
        speed /= 16;
343
        break;
344
    case 0x80:
345
        speed /= 32;
346
        break;
347
    default:
348
    case 0xc0:
349
        speed /= 64;
350
        break;
351
    }
352
    ssp.speed = speed;
353
    ssp.parity = parity;
354
    ssp.data_bits = data_bits;
355
    ssp.stop_bits = stop_bits;
356
    SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
357
                speed, parity, data_bits, stop_bits);
358
    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
359
}
360

    
361
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
362
{
363
    SerialState *serial = opaque;
364
    ChannelState *s;
365
    uint32_t saddr;
366
    int newreg, channel;
367

    
368
    val &= 0xff;
369
    saddr = (addr & 3) >> 1;
370
    channel = (addr & SERIAL_MAXADDR) >> 2;
371
    s = &serial->chn[channel];
372
    switch (saddr) {
373
    case 0:
374
        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
375
        newreg = 0;
376
        switch (s->reg) {
377
        case 0:
378
            newreg = val & 7;
379
            val &= 0x38;
380
            switch (val) {
381
            case 8:
382
                newreg |= 0x8;
383
                break;
384
            case 0x28:
385
                clr_txint(s);
386
                break;
387
            case 0x38:
388
                if (s->rxint_under_svc)
389
                    clr_rxint(s);
390
                else if (s->txint_under_svc)
391
                    clr_txint(s);
392
                break;
393
            default:
394
                break;
395
            }
396
            break;
397
        case 1 ... 3:
398
        case 6 ... 8:
399
        case 10 ... 11:
400
        case 14 ... 15:
401
            s->wregs[s->reg] = val;
402
            break;
403
        case 4:
404
        case 5:
405
        case 12:
406
        case 13:
407
            s->wregs[s->reg] = val;
408
            slavio_serial_update_parameters(s);
409
            break;
410
        case 9:
411
            switch (val & 0xc0) {
412
            case 0:
413
            default:
414
                break;
415
            case 0x40:
416
                slavio_serial_reset_chn(&serial->chn[1]);
417
                return;
418
            case 0x80:
419
                slavio_serial_reset_chn(&serial->chn[0]);
420
                return;
421
            case 0xc0:
422
                slavio_serial_reset(serial);
423
                return;
424
            }
425
            break;
426
        default:
427
            break;
428
        }
429
        if (s->reg == 0)
430
            s->reg = newreg;
431
        else
432
            s->reg = 0;
433
        break;
434
    case 1:
435
        SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
436
        s->tx = val;
437
        if (s->wregs[5] & 8) { // tx enabled
438
            if (s->chr)
439
                qemu_chr_write(s->chr, &s->tx, 1);
440
            else if (s->type == kbd) {
441
                handle_kbd_command(s, val);
442
            }
443
        }
444
        s->rregs[0] |= 4; // Tx buffer empty
445
        s->rregs[1] |= 1; // All sent
446
        set_txint(s);
447
        break;
448
    default:
449
        break;
450
    }
451
}
452

    
453
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
454
{
455
    SerialState *serial = opaque;
456
    ChannelState *s;
457
    uint32_t saddr;
458
    uint32_t ret;
459
    int channel;
460

    
461
    saddr = (addr & 3) >> 1;
462
    channel = (addr & SERIAL_MAXADDR) >> 2;
463
    s = &serial->chn[channel];
464
    switch (saddr) {
465
    case 0:
466
        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
467
        ret = s->rregs[s->reg];
468
        s->reg = 0;
469
        return ret;
470
    case 1:
471
        s->rregs[0] &= ~1;
472
        clr_rxint(s);
473
        if (s->type == kbd || s->type == mouse)
474
            ret = get_queue(s);
475
        else
476
            ret = s->rx;
477
        SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
478
        if (s->chr)
479
            qemu_chr_accept_input(s->chr);
480
        return ret;
481
    default:
482
        break;
483
    }
484
    return 0;
485
}
486

    
487
static int serial_can_receive(void *opaque)
488
{
489
    ChannelState *s = opaque;
490
    int ret;
491

    
492
    if (((s->wregs[3] & 1) == 0) // Rx not enabled
493
        || ((s->rregs[0] & 1) == 1)) // char already available
494
        ret = 0;
495
    else
496
        ret = 1;
497
    //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
498
    return ret;
499
}
500

    
501
static void serial_receive_byte(ChannelState *s, int ch)
502
{
503
    SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
504
    s->rregs[0] |= 1;
505
    s->rx = ch;
506
    set_rxint(s);
507
}
508

    
509
static void serial_receive_break(ChannelState *s)
510
{
511
    s->rregs[0] |= 0x80;
512
    slavio_serial_update_irq(s);
513
}
514

    
515
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
516
{
517
    ChannelState *s = opaque;
518
    serial_receive_byte(s, buf[0]);
519
}
520

    
521
static void serial_event(void *opaque, int event)
522
{
523
    ChannelState *s = opaque;
524
    if (event == CHR_EVENT_BREAK)
525
        serial_receive_break(s);
526
}
527

    
528
static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
529
    slavio_serial_mem_readb,
530
    slavio_serial_mem_readb,
531
    slavio_serial_mem_readb,
532
};
533

    
534
static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
535
    slavio_serial_mem_writeb,
536
    slavio_serial_mem_writeb,
537
    slavio_serial_mem_writeb,
538
};
539

    
540
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
541
{
542
    int tmp;
543
    tmp = 0;
544
    qemu_put_be32s(f, &tmp); /* unused, was IRQ.  */
545
    qemu_put_be32s(f, &s->reg);
546
    qemu_put_be32s(f, &s->rxint);
547
    qemu_put_be32s(f, &s->txint);
548
    qemu_put_be32s(f, &s->rxint_under_svc);
549
    qemu_put_be32s(f, &s->txint_under_svc);
550
    qemu_put_8s(f, &s->rx);
551
    qemu_put_8s(f, &s->tx);
552
    qemu_put_buffer(f, s->wregs, 16);
553
    qemu_put_buffer(f, s->rregs, 16);
554
}
555

    
556
static void slavio_serial_save(QEMUFile *f, void *opaque)
557
{
558
    SerialState *s = opaque;
559

    
560
    slavio_serial_save_chn(f, &s->chn[0]);
561
    slavio_serial_save_chn(f, &s->chn[1]);
562
}
563

    
564
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
565
{
566
    int tmp;
567

    
568
    if (version_id > 2)
569
        return -EINVAL;
570

    
571
    qemu_get_be32s(f, &tmp); /* unused */
572
    qemu_get_be32s(f, &s->reg);
573
    qemu_get_be32s(f, &s->rxint);
574
    qemu_get_be32s(f, &s->txint);
575
    if (version_id >= 2) {
576
        qemu_get_be32s(f, &s->rxint_under_svc);
577
        qemu_get_be32s(f, &s->txint_under_svc);
578
    }
579
    qemu_get_8s(f, &s->rx);
580
    qemu_get_8s(f, &s->tx);
581
    qemu_get_buffer(f, s->wregs, 16);
582
    qemu_get_buffer(f, s->rregs, 16);
583
    return 0;
584
}
585

    
586
static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
587
{
588
    SerialState *s = opaque;
589
    int ret;
590

    
591
    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
592
    if (ret != 0)
593
        return ret;
594
    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
595
    return ret;
596

    
597
}
598

    
599
SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
600
                                CharDriverState *chr1, CharDriverState *chr2)
601
{
602
    int slavio_serial_io_memory, i;
603
    SerialState *s;
604

    
605
    s = qemu_mallocz(sizeof(SerialState));
606
    if (!s)
607
        return NULL;
608

    
609
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
610
    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
611

    
612
    s->chn[0].chr = chr1;
613
    s->chn[1].chr = chr2;
614

    
615
    for (i = 0; i < 2; i++) {
616
        s->chn[i].irq = irq;
617
        s->chn[i].chn = 1 - i;
618
        s->chn[i].type = ser;
619
        if (s->chn[i].chr) {
620
            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
621
                                  serial_receive1, serial_event, &s->chn[i]);
622
        }
623
    }
624
    s->chn[0].otherchn = &s->chn[1];
625
    s->chn[1].otherchn = &s->chn[0];
626
    register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
627
    qemu_register_reset(slavio_serial_reset, s);
628
    slavio_serial_reset(s);
629
    return s;
630
}
631

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

    
643
static const uint8_t e0_keycodes[128] = {
644
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
645
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
646
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
647
    0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
648
    0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
649
    113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
650
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
651
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
652
};
653

    
654
static void sunkbd_event(void *opaque, int ch)
655
{
656
    ChannelState *s = opaque;
657
    int release = ch & 0x80;
658

    
659
    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
660
    switch (ch) {
661
    case 58: // Caps lock press
662
        s->caps_lock_mode ^= 1;
663
        if (s->caps_lock_mode == 2)
664
            return; // Drop second press
665
        break;
666
    case 69: // Num lock press
667
        s->num_lock_mode ^= 1;
668
        if (s->num_lock_mode == 2)
669
            return; // Drop second press
670
        break;
671
    case 186: // Caps lock release
672
        s->caps_lock_mode ^= 2;
673
        if (s->caps_lock_mode == 3)
674
            return; // Drop first release
675
        break;
676
    case 197: // Num lock release
677
        s->num_lock_mode ^= 2;
678
        if (s->num_lock_mode == 3)
679
            return; // Drop first release
680
        break;
681
    case 0xe0:
682
        s->e0_mode = 1;
683
        return;
684
    default:
685
        break;
686
    }
687
    if (s->e0_mode) {
688
        s->e0_mode = 0;
689
        ch = e0_keycodes[ch & 0x7f];
690
    } else {
691
        ch = keycodes[ch & 0x7f];
692
    }
693
    KBD_DPRINTF("Translated keycode %2.2x\n", ch);
694
    put_queue(s, ch | release);
695
}
696

    
697
static void handle_kbd_command(ChannelState *s, int val)
698
{
699
    KBD_DPRINTF("Command %d\n", val);
700
    if (s->led_mode) { // Ignore led byte
701
        s->led_mode = 0;
702
        return;
703
    }
704
    switch (val) {
705
    case 1: // Reset, return type code
706
        clear_queue(s);
707
        put_queue(s, 0xff);
708
        put_queue(s, 4); // Type 4
709
        put_queue(s, 0x7f);
710
        break;
711
    case 0xe: // Set leds
712
        s->led_mode = 1;
713
        break;
714
    case 7: // Query layout
715
    case 0xf:
716
        clear_queue(s);
717
        put_queue(s, 0xfe);
718
        put_queue(s, 0); // XXX, layout?
719
        break;
720
    default:
721
        break;
722
    }
723
}
724

    
725
static void sunmouse_event(void *opaque,
726
                               int dx, int dy, int dz, int buttons_state)
727
{
728
    ChannelState *s = opaque;
729
    int ch;
730

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

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

    
735
    if (buttons_state & MOUSE_EVENT_LBUTTON)
736
        ch ^= 0x4;
737
    if (buttons_state & MOUSE_EVENT_MBUTTON)
738
        ch ^= 0x2;
739
    if (buttons_state & MOUSE_EVENT_RBUTTON)
740
        ch ^= 0x1;
741

    
742
    put_queue(s, ch);
743

    
744
    ch = dx;
745

    
746
    if (ch > 127)
747
        ch=127;
748
    else if (ch < -127)
749
        ch=-127;
750

    
751
    put_queue(s, ch & 0xff);
752

    
753
    ch = -dy;
754

    
755
    if (ch > 127)
756
        ch=127;
757
    else if (ch < -127)
758
        ch=-127;
759

    
760
    put_queue(s, ch & 0xff);
761

    
762
    // MSC protocol specify two extra motion bytes
763

    
764
    put_queue(s, 0);
765
    put_queue(s, 0);
766
}
767

    
768
void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq)
769
{
770
    int slavio_serial_io_memory, i;
771
    SerialState *s;
772

    
773
    s = qemu_mallocz(sizeof(SerialState));
774
    if (!s)
775
        return;
776
    for (i = 0; i < 2; i++) {
777
        s->chn[i].irq = irq;
778
        s->chn[i].chn = 1 - i;
779
        s->chn[i].chr = NULL;
780
    }
781
    s->chn[0].otherchn = &s->chn[1];
782
    s->chn[1].otherchn = &s->chn[0];
783
    s->chn[0].type = mouse;
784
    s->chn[1].type = kbd;
785

    
786
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
787
    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
788

    
789
    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
790
    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
791
    register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, slavio_serial_load, s);
792
    qemu_register_reset(slavio_serial_reset, s);
793
    slavio_serial_reset(s);
794
}