Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ 8731ac03

History | View | Annotate | Download (20.4 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
#else
56
#define SER_DPRINTF(fmt, args...)
57
#endif
58
#ifdef DEBUG_KBD
59
#define KBD_DPRINTF(fmt, args...) \
60
do { printf("KBD: " fmt , ##args); } while (0)
61
#else
62
#define KBD_DPRINTF(fmt, args...)
63
#endif
64
#ifdef DEBUG_MOUSE
65
#define MS_DPRINTF(fmt, args...) \
66
do { printf("MSC: " fmt , ##args); } while (0)
67
#else
68
#define MS_DPRINTF(fmt, args...)
69
#endif
70

    
71
typedef enum {
72
    chn_a, chn_b,
73
} chn_id_t;
74

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

    
77
typedef enum {
78
    ser, kbd, mouse,
79
} chn_type_t;
80

    
81
#define SERIO_QUEUE_SIZE 256
82

    
83
typedef struct {
84
    uint8_t data[SERIO_QUEUE_SIZE];
85
    int rptr, wptr, count;
86
} SERIOQueue;
87

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

    
101
struct SerialState {
102
    struct ChannelState chn[2];
103
};
104

    
105
#define SERIAL_MAXADDR 7
106
#define SERIAL_SIZE (SERIAL_MAXADDR + 1)
107

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

    
113
static void clear_queue(void *opaque)
114
{
115
    ChannelState *s = opaque;
116
    SERIOQueue *q = &s->queue;
117
    q->rptr = q->wptr = q->count = 0;
118
}
119

    
120
static void put_queue(void *opaque, int b)
121
{
122
    ChannelState *s = opaque;
123
    SERIOQueue *q = &s->queue;
124

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

    
135
static uint32_t get_queue(void *opaque)
136
{
137
    ChannelState *s = opaque;
138
    SERIOQueue *q = &s->queue;
139
    int val;
140

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

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

    
167
static void slavio_serial_update_irq(ChannelState *s)
168
{
169
    int irq;
170

    
171
    irq = slavio_serial_update_irq_chn(s);
172
    irq |= slavio_serial_update_irq_chn(s->otherchn);
173

    
174
    SER_DPRINTF("IRQ = %d\n", irq);
175
    qemu_set_irq(s->irq, irq);
176
}
177

    
178
static void slavio_serial_reset_chn(ChannelState *s)
179
{
180
    int i;
181

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

    
195
    s->rx = s->tx = 0;
196
    s->rxint = s->txint = 0;
197
    s->rxint_under_svc = s->txint_under_svc = 0;
198
    s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
199
    clear_queue(s);
200
}
201

    
202
static void slavio_serial_reset(void *opaque)
203
{
204
    SerialState *s = opaque;
205
    slavio_serial_reset_chn(&s->chn[0]);
206
    slavio_serial_reset_chn(&s->chn[1]);
207
}
208

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

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

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

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

    
298
static void slavio_serial_update_parameters(ChannelState *s)
299
{
300
    int speed, parity, data_bits, stop_bits;
301
    QEMUSerialSetParams ssp;
302

    
303
    if (!s->chr || s->type != ser)
304
        return;
305

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

    
357
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
358
{
359
    SerialState *serial = opaque;
360
    ChannelState *s;
361
    uint32_t saddr;
362
    int newreg, channel;
363

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

    
449
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
450
{
451
    SerialState *serial = opaque;
452
    ChannelState *s;
453
    uint32_t saddr;
454
    uint32_t ret;
455
    int channel;
456

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

    
481
static int serial_can_receive(void *opaque)
482
{
483
    ChannelState *s = opaque;
484
    int ret;
485

    
486
    if (((s->wregs[3] & 1) == 0) // Rx not enabled
487
        || ((s->rregs[0] & 1) == 1)) // char already available
488
        ret = 0;
489
    else
490
        ret = 1;
491
    //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
492
    return ret;
493
}
494

    
495
static void serial_receive_byte(ChannelState *s, int ch)
496
{
497
    SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
498
    s->rregs[0] |= 1;
499
    s->rx = ch;
500
    set_rxint(s);
501
}
502

    
503
static void serial_receive_break(ChannelState *s)
504
{
505
    s->rregs[0] |= 0x80;
506
    slavio_serial_update_irq(s);
507
}
508

    
509
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
510
{
511
    ChannelState *s = opaque;
512
    serial_receive_byte(s, buf[0]);
513
}
514

    
515
static void serial_event(void *opaque, int event)
516
{
517
    ChannelState *s = opaque;
518
    if (event == CHR_EVENT_BREAK)
519
        serial_receive_break(s);
520
}
521

    
522
static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
523
    slavio_serial_mem_readb,
524
    slavio_serial_mem_readb,
525
    slavio_serial_mem_readb,
526
};
527

    
528
static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
529
    slavio_serial_mem_writeb,
530
    slavio_serial_mem_writeb,
531
    slavio_serial_mem_writeb,
532
};
533

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

    
550
static void slavio_serial_save(QEMUFile *f, void *opaque)
551
{
552
    SerialState *s = opaque;
553

    
554
    slavio_serial_save_chn(f, &s->chn[0]);
555
    slavio_serial_save_chn(f, &s->chn[1]);
556
}
557

    
558
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
559
{
560
    int tmp;
561

    
562
    if (version_id > 2)
563
        return -EINVAL;
564

    
565
    qemu_get_be32s(f, &tmp); /* unused */
566
    qemu_get_be32s(f, &s->reg);
567
    qemu_get_be32s(f, &s->rxint);
568
    qemu_get_be32s(f, &s->txint);
569
    if (version_id >= 2) {
570
        qemu_get_be32s(f, &s->rxint_under_svc);
571
        qemu_get_be32s(f, &s->txint_under_svc);
572
    }
573
    qemu_get_8s(f, &s->rx);
574
    qemu_get_8s(f, &s->tx);
575
    qemu_get_buffer(f, s->wregs, 16);
576
    qemu_get_buffer(f, s->rregs, 16);
577
    return 0;
578
}
579

    
580
static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
581
{
582
    SerialState *s = opaque;
583
    int ret;
584

    
585
    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
586
    if (ret != 0)
587
        return ret;
588
    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
589
    return ret;
590

    
591
}
592

    
593
SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
594
                                CharDriverState *chr1, CharDriverState *chr2)
595
{
596
    int slavio_serial_io_memory, i;
597
    SerialState *s;
598

    
599
    s = qemu_mallocz(sizeof(SerialState));
600
    if (!s)
601
        return NULL;
602

    
603
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
604
    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
605

    
606
    s->chn[0].chr = chr1;
607
    s->chn[1].chr = chr2;
608

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

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

    
637
static const uint8_t e0_keycodes[128] = {
638
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
639
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
640
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
641
    0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
642
    0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
643
    113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
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, 0, 0, 0, 0,
646
};
647

    
648
static void sunkbd_event(void *opaque, int ch)
649
{
650
    ChannelState *s = opaque;
651
    int release = ch & 0x80;
652

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

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

    
719
static void sunmouse_event(void *opaque,
720
                               int dx, int dy, int dz, int buttons_state)
721
{
722
    ChannelState *s = opaque;
723
    int ch;
724

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

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

    
729
    if (buttons_state & MOUSE_EVENT_LBUTTON)
730
        ch ^= 0x4;
731
    if (buttons_state & MOUSE_EVENT_MBUTTON)
732
        ch ^= 0x2;
733
    if (buttons_state & MOUSE_EVENT_RBUTTON)
734
        ch ^= 0x1;
735

    
736
    put_queue(s, ch);
737

    
738
    ch = dx;
739

    
740
    if (ch > 127)
741
        ch=127;
742
    else if (ch < -127)
743
        ch=-127;
744

    
745
    put_queue(s, ch & 0xff);
746

    
747
    ch = -dy;
748

    
749
    if (ch > 127)
750
        ch=127;
751
    else if (ch < -127)
752
        ch=-127;
753

    
754
    put_queue(s, ch & 0xff);
755

    
756
    // MSC protocol specify two extra motion bytes
757

    
758
    put_queue(s, 0);
759
    put_queue(s, 0);
760
}
761

    
762
void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq)
763
{
764
    int slavio_serial_io_memory, i;
765
    SerialState *s;
766

    
767
    s = qemu_mallocz(sizeof(SerialState));
768
    if (!s)
769
        return;
770
    for (i = 0; i < 2; i++) {
771
        s->chn[i].irq = irq;
772
        s->chn[i].chn = 1 - i;
773
        s->chn[i].chr = NULL;
774
    }
775
    s->chn[0].otherchn = &s->chn[1];
776
    s->chn[1].otherchn = &s->chn[0];
777
    s->chn[0].type = mouse;
778
    s->chn[1].type = kbd;
779

    
780
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
781
    cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
782

    
783
    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
784
    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
785
    register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, slavio_serial_load, s);
786
    qemu_register_reset(slavio_serial_reset, s);
787
    slavio_serial_reset(s);
788
}