Statistics
| Branch: | Revision:

root / hw / escc.c @ 16fd921b

History | View | Annotate | Download (25.9 kB)

1
/*
2
 * QEMU ESCC (Z8030/Z8530/Z85C30/SCC/ESCC) 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

    
25
#include "hw.h"
26
#include "sysbus.h"
27
#include "escc.h"
28
#include "qemu-char.h"
29
#include "console.h"
30
#include "trace.h"
31

    
32
/*
33
 * Chipset docs:
34
 * "Z80C30/Z85C30/Z80230/Z85230/Z85233 SCC/ESCC User Manual",
35
 * http://www.zilog.com/docs/serial/scc_escc_um.pdf
36
 *
37
 * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001
38
 * (Slave I/O), also produced as NCR89C105. See
39
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
40
 *
41
 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
42
 * mouse and keyboard ports don't implement all functions and they are
43
 * only asynchronous. There is no DMA.
44
 *
45
 * Z85C30 is also used on PowerMacs. There are some small differences
46
 * between Sparc version (sunzilog) and PowerMac (pmac):
47
 *  Offset between control and data registers
48
 *  There is some kind of lockup bug, but we can ignore it
49
 *  CTS is inverted
50
 *  DMA on pmac using DBDMA chip
51
 *  pmac can do IRDA and faster rates, sunzilog can only do 38400
52
 *  pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz
53
 */
54

    
55
/*
56
 * Modifications:
57
 *  2006-Aug-10  Igor Kovalenko :   Renamed KBDQueue to SERIOQueue, implemented
58
 *                                  serial mouse queue.
59
 *                                  Implemented serial mouse protocol.
60
 *
61
 *  2010-May-23  Artyom Tarasenko:  Reworked IUS logic
62
 */
63

    
64
typedef enum {
65
    chn_a, chn_b,
66
} ChnID;
67

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

    
70
typedef enum {
71
    ser, kbd, mouse,
72
} ChnType;
73

    
74
#define SERIO_QUEUE_SIZE 256
75

    
76
typedef struct {
77
    uint8_t data[SERIO_QUEUE_SIZE];
78
    int rptr, wptr, count;
79
} SERIOQueue;
80

    
81
#define SERIAL_REGS 16
82
typedef struct ChannelState {
83
    qemu_irq irq;
84
    uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
85
    struct ChannelState *otherchn;
86
    uint32_t reg;
87
    uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
88
    SERIOQueue queue;
89
    CharDriverState *chr;
90
    int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
91
    int disabled;
92
    int clock;
93
    uint32_t vmstate_dummy;
94
    ChnID chn; // this channel, A (base+4) or B (base+0)
95
    ChnType type;
96
    uint8_t rx, tx;
97
} ChannelState;
98

    
99
struct SerialState {
100
    SysBusDevice busdev;
101
    struct ChannelState chn[2];
102
    uint32_t it_shift;
103
    MemoryRegion mmio;
104
    uint32_t disabled;
105
    uint32_t frequency;
106
};
107

    
108
#define SERIAL_CTRL 0
109
#define SERIAL_DATA 1
110

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

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

    
210
static void handle_kbd_command(ChannelState *s, int val);
211
static int serial_can_receive(void *opaque);
212
static void serial_receive_byte(ChannelState *s, int ch);
213

    
214
static void clear_queue(void *opaque)
215
{
216
    ChannelState *s = opaque;
217
    SERIOQueue *q = &s->queue;
218
    q->rptr = q->wptr = q->count = 0;
219
}
220

    
221
static void put_queue(void *opaque, int b)
222
{
223
    ChannelState *s = opaque;
224
    SERIOQueue *q = &s->queue;
225

    
226
    trace_escc_put_queue(CHN_C(s), b);
227
    if (q->count >= SERIO_QUEUE_SIZE)
228
        return;
229
    q->data[q->wptr] = b;
230
    if (++q->wptr == SERIO_QUEUE_SIZE)
231
        q->wptr = 0;
232
    q->count++;
233
    serial_receive_byte(s, 0);
234
}
235

    
236
static uint32_t get_queue(void *opaque)
237
{
238
    ChannelState *s = opaque;
239
    SERIOQueue *q = &s->queue;
240
    int val;
241

    
242
    if (q->count == 0) {
243
        return 0;
244
    } else {
245
        val = q->data[q->rptr];
246
        if (++q->rptr == SERIO_QUEUE_SIZE)
247
            q->rptr = 0;
248
        q->count--;
249
    }
250
    trace_escc_get_queue(CHN_C(s), val);
251
    if (q->count > 0)
252
        serial_receive_byte(s, 0);
253
    return val;
254
}
255

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

    
270
static void escc_update_irq(ChannelState *s)
271
{
272
    int irq;
273

    
274
    irq = escc_update_irq_chn(s);
275
    irq |= escc_update_irq_chn(s->otherchn);
276

    
277
    trace_escc_update_irq(irq);
278
    qemu_set_irq(s->irq, irq);
279
}
280

    
281
static void escc_reset_chn(ChannelState *s)
282
{
283
    int i;
284

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

    
303
    s->rx = s->tx = 0;
304
    s->rxint = s->txint = 0;
305
    s->rxint_under_svc = s->txint_under_svc = 0;
306
    s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
307
    clear_queue(s);
308
}
309

    
310
static void escc_reset(DeviceState *d)
311
{
312
    SerialState *s = container_of(d, SerialState, busdev.qdev);
313

    
314
    escc_reset_chn(&s->chn[0]);
315
    escc_reset_chn(&s->chn[1]);
316
}
317

    
318
static inline void set_rxint(ChannelState *s)
319
{
320
    s->rxint = 1;
321
    /* XXX: missing daisy chainnig: chn_b rx should have a lower priority
322
       than chn_a rx/tx/special_condition service*/
323
    s->rxint_under_svc = 1;
324
    if (s->chn == chn_a) {
325
        s->rregs[R_INTR] |= INTR_RXINTA;
326
        if (s->wregs[W_MINTR] & MINTR_STATUSHI)
327
            s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
328
        else
329
            s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
330
    } else {
331
        s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
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
    escc_update_irq(s);
338
}
339

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

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

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

    
408
static void escc_update_parameters(ChannelState *s)
409
{
410
    int speed, parity, data_bits, stop_bits;
411
    QEMUSerialSetParams ssp;
412

    
413
    if (!s->chr || s->type != ser)
414
        return;
415

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

    
466
static void escc_mem_write(void *opaque, target_phys_addr_t addr,
467
                           uint64_t val, unsigned size)
468
{
469
    SerialState *serial = opaque;
470
    ChannelState *s;
471
    uint32_t saddr;
472
    int newreg, channel;
473

    
474
    val &= 0xff;
475
    saddr = (addr >> serial->it_shift) & 1;
476
    channel = (addr >> (serial->it_shift + 1)) & 1;
477
    s = &serial->chn[channel];
478
    switch (saddr) {
479
    case SERIAL_CTRL:
480
        trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
481
        newreg = 0;
482
        switch (s->reg) {
483
        case W_CMD:
484
            newreg = val & CMD_PTR_MASK;
485
            val &= CMD_CMD_MASK;
486
            switch (val) {
487
            case CMD_HI:
488
                newreg |= CMD_HI;
489
                break;
490
            case CMD_CLR_TXINT:
491
                clr_txint(s);
492
                break;
493
            case CMD_CLR_IUS:
494
                if (s->rxint_under_svc) {
495
                    s->rxint_under_svc = 0;
496
                    if (s->txint) {
497
                        set_txint(s);
498
                    }
499
                } else if (s->txint_under_svc) {
500
                    s->txint_under_svc = 0;
501
                }
502
                escc_update_irq(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
            escc_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
            escc_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
                escc_reset_chn(&serial->chn[0]);
532
                return;
533
            case MINTR_RST_A:
534
                escc_reset_chn(&serial->chn[1]);
535
                return;
536
            case MINTR_RST_ALL:
537
                escc_reset(&serial->busdev.qdev);
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
        trace_escc_mem_writeb_data(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_fe_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 uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
569
                              unsigned size)
570
{
571
    SerialState *serial = opaque;
572
    ChannelState *s;
573
    uint32_t saddr;
574
    uint32_t ret;
575
    int channel;
576

    
577
    saddr = (addr >> serial->it_shift) & 1;
578
    channel = (addr >> (serial->it_shift + 1)) & 1;
579
    s = &serial->chn[channel];
580
    switch (saddr) {
581
    case SERIAL_CTRL:
582
        trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, 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
        trace_escc_mem_readb_data(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 const MemoryRegionOps escc_mem_ops = {
604
    .read = escc_mem_read,
605
    .write = escc_mem_write,
606
    .endianness = DEVICE_NATIVE_ENDIAN,
607
    .valid = {
608
        .min_access_size = 1,
609
        .max_access_size = 1,
610
    },
611
};
612

    
613
static int serial_can_receive(void *opaque)
614
{
615
    ChannelState *s = opaque;
616
    int ret;
617

    
618
    if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
619
        || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
620
        // char already available
621
        ret = 0;
622
    else
623
        ret = 1;
624
    return ret;
625
}
626

    
627
static void serial_receive_byte(ChannelState *s, int ch)
628
{
629
    trace_escc_serial_receive_byte(CHN_C(s), ch);
630
    s->rregs[R_STATUS] |= STATUS_RXAV;
631
    s->rx = ch;
632
    set_rxint(s);
633
}
634

    
635
static void serial_receive_break(ChannelState *s)
636
{
637
    s->rregs[R_STATUS] |= STATUS_BRK;
638
    escc_update_irq(s);
639
}
640

    
641
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
642
{
643
    ChannelState *s = opaque;
644
    serial_receive_byte(s, buf[0]);
645
}
646

    
647
static void serial_event(void *opaque, int event)
648
{
649
    ChannelState *s = opaque;
650
    if (event == CHR_EVENT_BREAK)
651
        serial_receive_break(s);
652
}
653

    
654
static const VMStateDescription vmstate_escc_chn = {
655
    .name ="escc_chn",
656
    .version_id = 2,
657
    .minimum_version_id = 1,
658
    .minimum_version_id_old = 1,
659
    .fields      = (VMStateField []) {
660
        VMSTATE_UINT32(vmstate_dummy, ChannelState),
661
        VMSTATE_UINT32(reg, ChannelState),
662
        VMSTATE_UINT32(rxint, ChannelState),
663
        VMSTATE_UINT32(txint, ChannelState),
664
        VMSTATE_UINT32(rxint_under_svc, ChannelState),
665
        VMSTATE_UINT32(txint_under_svc, ChannelState),
666
        VMSTATE_UINT8(rx, ChannelState),
667
        VMSTATE_UINT8(tx, ChannelState),
668
        VMSTATE_BUFFER(wregs, ChannelState),
669
        VMSTATE_BUFFER(rregs, ChannelState),
670
        VMSTATE_END_OF_LIST()
671
    }
672
};
673

    
674
static const VMStateDescription vmstate_escc = {
675
    .name ="escc",
676
    .version_id = 2,
677
    .minimum_version_id = 1,
678
    .minimum_version_id_old = 1,
679
    .fields      = (VMStateField []) {
680
        VMSTATE_STRUCT_ARRAY(chn, SerialState, 2, 2, vmstate_escc_chn,
681
                             ChannelState),
682
        VMSTATE_END_OF_LIST()
683
    }
684
};
685

    
686
MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
687
              CharDriverState *chrA, CharDriverState *chrB,
688
              int clock, int it_shift)
689
{
690
    DeviceState *dev;
691
    SysBusDevice *s;
692
    SerialState *d;
693

    
694
    dev = qdev_create(NULL, "escc");
695
    qdev_prop_set_uint32(dev, "disabled", 0);
696
    qdev_prop_set_uint32(dev, "frequency", clock);
697
    qdev_prop_set_uint32(dev, "it_shift", it_shift);
698
    qdev_prop_set_chr(dev, "chrB", chrB);
699
    qdev_prop_set_chr(dev, "chrA", chrA);
700
    qdev_prop_set_uint32(dev, "chnBtype", ser);
701
    qdev_prop_set_uint32(dev, "chnAtype", ser);
702
    qdev_init_nofail(dev);
703
    s = sysbus_from_qdev(dev);
704
    sysbus_connect_irq(s, 0, irqB);
705
    sysbus_connect_irq(s, 1, irqA);
706
    if (base) {
707
        sysbus_mmio_map(s, 0, base);
708
    }
709

    
710
    d = FROM_SYSBUS(SerialState, s);
711
    return &d->mmio;
712
}
713

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

    
725
static const uint8_t e0_keycodes[128] = {
726
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
727
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
728
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
729
    0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
730
    0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
731
    113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
732
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
733
    1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
734
};
735

    
736
static void sunkbd_event(void *opaque, int ch)
737
{
738
    ChannelState *s = opaque;
739
    int release = ch & 0x80;
740

    
741
    trace_escc_sunkbd_event_in(ch);
742
    switch (ch) {
743
    case 58: // Caps lock press
744
        s->caps_lock_mode ^= 1;
745
        if (s->caps_lock_mode == 2)
746
            return; // Drop second press
747
        break;
748
    case 69: // Num lock press
749
        s->num_lock_mode ^= 1;
750
        if (s->num_lock_mode == 2)
751
            return; // Drop second press
752
        break;
753
    case 186: // Caps lock release
754
        s->caps_lock_mode ^= 2;
755
        if (s->caps_lock_mode == 3)
756
            return; // Drop first release
757
        break;
758
    case 197: // Num lock release
759
        s->num_lock_mode ^= 2;
760
        if (s->num_lock_mode == 3)
761
            return; // Drop first release
762
        break;
763
    case 0xe0:
764
        s->e0_mode = 1;
765
        return;
766
    default:
767
        break;
768
    }
769
    if (s->e0_mode) {
770
        s->e0_mode = 0;
771
        ch = e0_keycodes[ch & 0x7f];
772
    } else {
773
        ch = keycodes[ch & 0x7f];
774
    }
775
    trace_escc_sunkbd_event_out(ch);
776
    put_queue(s, ch | release);
777
}
778

    
779
static void handle_kbd_command(ChannelState *s, int val)
780
{
781
    trace_escc_kbd_command(val);
782
    if (s->led_mode) { // Ignore led byte
783
        s->led_mode = 0;
784
        return;
785
    }
786
    switch (val) {
787
    case 1: // Reset, return type code
788
        clear_queue(s);
789
        put_queue(s, 0xff);
790
        put_queue(s, 4); // Type 4
791
        put_queue(s, 0x7f);
792
        break;
793
    case 0xe: // Set leds
794
        s->led_mode = 1;
795
        break;
796
    case 7: // Query layout
797
    case 0xf:
798
        clear_queue(s);
799
        put_queue(s, 0xfe);
800
        put_queue(s, 0); // XXX, layout?
801
        break;
802
    default:
803
        break;
804
    }
805
}
806

    
807
static void sunmouse_event(void *opaque,
808
                               int dx, int dy, int dz, int buttons_state)
809
{
810
    ChannelState *s = opaque;
811
    int ch;
812

    
813
    trace_escc_sunmouse_event(dx, dy, buttons_state);
814
    ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
815

    
816
    if (buttons_state & MOUSE_EVENT_LBUTTON)
817
        ch ^= 0x4;
818
    if (buttons_state & MOUSE_EVENT_MBUTTON)
819
        ch ^= 0x2;
820
    if (buttons_state & MOUSE_EVENT_RBUTTON)
821
        ch ^= 0x1;
822

    
823
    put_queue(s, ch);
824

    
825
    ch = dx;
826

    
827
    if (ch > 127)
828
        ch = 127;
829
    else if (ch < -127)
830
        ch = -127;
831

    
832
    put_queue(s, ch & 0xff);
833

    
834
    ch = -dy;
835

    
836
    if (ch > 127)
837
        ch = 127;
838
    else if (ch < -127)
839
        ch = -127;
840

    
841
    put_queue(s, ch & 0xff);
842

    
843
    // MSC protocol specify two extra motion bytes
844

    
845
    put_queue(s, 0);
846
    put_queue(s, 0);
847
}
848

    
849
void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
850
                               int disabled, int clock, int it_shift)
851
{
852
    DeviceState *dev;
853
    SysBusDevice *s;
854

    
855
    dev = qdev_create(NULL, "escc");
856
    qdev_prop_set_uint32(dev, "disabled", disabled);
857
    qdev_prop_set_uint32(dev, "frequency", clock);
858
    qdev_prop_set_uint32(dev, "it_shift", it_shift);
859
    qdev_prop_set_chr(dev, "chrB", NULL);
860
    qdev_prop_set_chr(dev, "chrA", NULL);
861
    qdev_prop_set_uint32(dev, "chnBtype", mouse);
862
    qdev_prop_set_uint32(dev, "chnAtype", kbd);
863
    qdev_init_nofail(dev);
864
    s = sysbus_from_qdev(dev);
865
    sysbus_connect_irq(s, 0, irq);
866
    sysbus_connect_irq(s, 1, irq);
867
    sysbus_mmio_map(s, 0, base);
868
}
869

    
870
static int escc_init1(SysBusDevice *dev)
871
{
872
    SerialState *s = FROM_SYSBUS(SerialState, dev);
873
    unsigned int i;
874

    
875
    s->chn[0].disabled = s->disabled;
876
    s->chn[1].disabled = s->disabled;
877
    for (i = 0; i < 2; i++) {
878
        sysbus_init_irq(dev, &s->chn[i].irq);
879
        s->chn[i].chn = 1 - i;
880
        s->chn[i].clock = s->frequency / 2;
881
        if (s->chn[i].chr) {
882
            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
883
                                  serial_receive1, serial_event, &s->chn[i]);
884
        }
885
    }
886
    s->chn[0].otherchn = &s->chn[1];
887
    s->chn[1].otherchn = &s->chn[0];
888

    
889
    memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc",
890
                          ESCC_SIZE << s->it_shift);
891
    sysbus_init_mmio(dev, &s->mmio);
892

    
893
    if (s->chn[0].type == mouse) {
894
        qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
895
                                     "QEMU Sun Mouse");
896
    }
897
    if (s->chn[1].type == kbd) {
898
        qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
899
    }
900

    
901
    return 0;
902
}
903

    
904
static Property escc_properties[] = {
905
    DEFINE_PROP_UINT32("frequency", SerialState, frequency,   0),
906
    DEFINE_PROP_UINT32("it_shift",  SerialState, it_shift,    0),
907
    DEFINE_PROP_UINT32("disabled",  SerialState, disabled,    0),
908
    DEFINE_PROP_UINT32("chnBtype",  SerialState, chn[0].type, 0),
909
    DEFINE_PROP_UINT32("chnAtype",  SerialState, chn[1].type, 0),
910
    DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
911
    DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
912
    DEFINE_PROP_END_OF_LIST(),
913
};
914

    
915
static void escc_class_init(ObjectClass *klass, void *data)
916
{
917
    DeviceClass *dc = DEVICE_CLASS(klass);
918
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
919

    
920
    k->init = escc_init1;
921
    dc->reset = escc_reset;
922
    dc->vmsd = &vmstate_escc;
923
    dc->props = escc_properties;
924
}
925

    
926
static TypeInfo escc_info = {
927
    .name          = "escc",
928
    .parent        = TYPE_SYS_BUS_DEVICE,
929
    .instance_size = sizeof(SerialState),
930
    .class_init    = escc_class_init,
931
};
932

    
933
static void escc_register_types(void)
934
{
935
    type_register_static(&escc_info);
936
}
937

    
938
type_init(escc_register_types)