Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ 715748fa

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

    
73
typedef enum {
74
    chn_a, chn_b,
75
} chn_id_t;
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
    int irq;
90
    int reg;
91
    int rxint, txint;
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
} ChannelState;
99

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

    
104
#define SERIAL_MAXADDR 7
105

    
106
static void handle_kbd_command(ChannelState *s, int val);
107
static int serial_can_receive(void *opaque);
108
static void serial_receive_byte(ChannelState *s, int ch);
109

    
110
static void put_queue(void *opaque, int b)
111
{
112
    ChannelState *s = opaque;
113
    SERIOQueue *q = &s->queue;
114

    
115
    SER_DPRINTF("put: 0x%02x\n", b);
116
    if (q->count >= SERIO_QUEUE_SIZE)
117
        return;
118
    q->data[q->wptr] = b;
119
    if (++q->wptr == SERIO_QUEUE_SIZE)
120
        q->wptr = 0;
121
    q->count++;
122
    serial_receive_byte(s, 0);
123
}
124

    
125
static uint32_t get_queue(void *opaque)
126
{
127
    ChannelState *s = opaque;
128
    SERIOQueue *q = &s->queue;
129
    int val;
130
    
131
    if (q->count == 0) {
132
        return 0;
133
    } else {
134
        val = q->data[q->rptr];
135
        if (++q->rptr == SERIO_QUEUE_SIZE)
136
            q->rptr = 0;
137
        q->count--;
138
    }
139
    KBD_DPRINTF("get 0x%02x\n", val);
140
    if (q->count > 0)
141
        serial_receive_byte(s, 0);
142
    return val;
143
}
144

    
145
static void slavio_serial_update_irq(ChannelState *s)
146
{
147
    if ((s->wregs[1] & 1) && // interrupts enabled
148
        (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
149
         ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
150
          s->rxint == 1) || // rx ints enabled, pending
151
         ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
152
        pic_set_irq(s->irq, 1);
153
    } else {
154
        pic_set_irq(s->irq, 0);
155
    }
156
}
157

    
158
static void slavio_serial_reset_chn(ChannelState *s)
159
{
160
    int i;
161

    
162
    s->reg = 0;
163
    for (i = 0; i < SERIAL_MAXADDR; i++) {
164
        s->rregs[i] = 0;
165
        s->wregs[i] = 0;
166
    }
167
    s->wregs[4] = 4;
168
    s->wregs[9] = 0xc0;
169
    s->wregs[11] = 8;
170
    s->wregs[14] = 0x30;
171
    s->wregs[15] = 0xf8;
172
    s->rregs[0] = 0x44;
173
    s->rregs[1] = 6;
174

    
175
    s->rx = s->tx = 0;
176
    s->rxint = s->txint = 0;
177
}
178

    
179
static void slavio_serial_reset(void *opaque)
180
{
181
    SerialState *s = opaque;
182
    slavio_serial_reset_chn(&s->chn[0]);
183
    slavio_serial_reset_chn(&s->chn[1]);
184
}
185

    
186
static inline void clr_rxint(ChannelState *s)
187
{
188
    s->rxint = 0;
189
    if (s->chn == 0)
190
        s->rregs[3] &= ~0x20;
191
    else {
192
        s->otherchn->rregs[3] &= ~4;
193
    }
194
    slavio_serial_update_irq(s);
195
}
196

    
197
static inline void set_rxint(ChannelState *s)
198
{
199
    s->rxint = 1;
200
    if (s->chn == 0)
201
        s->rregs[3] |= 0x20;
202
    else {
203
        s->otherchn->rregs[3] |= 4;
204
    }
205
    slavio_serial_update_irq(s);
206
}
207

    
208
static inline void clr_txint(ChannelState *s)
209
{
210
    s->txint = 0;
211
    if (s->chn == 0)
212
        s->rregs[3] &= ~0x10;
213
    else {
214
        s->otherchn->rregs[3] &= ~2;
215
    }
216
    slavio_serial_update_irq(s);
217
}
218

    
219
static inline void set_txint(ChannelState *s)
220
{
221
    s->txint = 1;
222
    if (s->chn == 0)
223
        s->rregs[3] |= 0x10;
224
    else {
225
        s->otherchn->rregs[3] |= 2;
226
    }
227
    slavio_serial_update_irq(s);
228
}
229

    
230
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
231
{
232
    SerialState *ser = opaque;
233
    ChannelState *s;
234
    uint32_t saddr;
235
    int newreg, channel;
236

    
237
    val &= 0xff;
238
    saddr = (addr & 3) >> 1;
239
    channel = (addr & SERIAL_MAXADDR) >> 2;
240
    s = &ser->chn[channel];
241
    switch (saddr) {
242
    case 0:
243
        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, val & 0xff);
244
        newreg = 0;
245
        switch (s->reg) {
246
        case 0:
247
            newreg = val & 7;
248
            val &= 0x38;
249
            switch (val) {
250
            case 8:
251
                newreg |= 0x8;
252
                break;
253
            case 0x20:
254
                clr_rxint(s);
255
                break;
256
            case 0x28:
257
                clr_txint(s);
258
                break;
259
            case 0x38:
260
                clr_rxint(s);
261
                clr_txint(s);
262
                break;
263
            default:
264
                break;
265
            }
266
            break;
267
        case 1 ... 8:
268
        case 10 ... 15:
269
            s->wregs[s->reg] = val;
270
            break;
271
        case 9:
272
            switch (val & 0xc0) {
273
            case 0:
274
            default:
275
                break;
276
            case 0x40:
277
                slavio_serial_reset_chn(&ser->chn[1]);
278
                return;
279
            case 0x80:
280
                slavio_serial_reset_chn(&ser->chn[0]);
281
                return;
282
            case 0xc0:
283
                slavio_serial_reset(ser);
284
                return;
285
            }
286
            break;
287
        default:
288
            break;
289
        }
290
        if (s->reg == 0)
291
            s->reg = newreg;
292
        else
293
            s->reg = 0;
294
        break;
295
    case 1:
296
        SER_DPRINTF("Write channel %c, ch %d\n", channel? 'b' : 'a', val);
297
        if (s->wregs[5] & 8) { // tx enabled
298
            s->tx = val;
299
            if (s->chr)
300
                qemu_chr_write(s->chr, &s->tx, 1);
301
            else if (s->type == kbd) {
302
                handle_kbd_command(s, val);
303
            }
304
            s->txint = 1;
305
            s->rregs[0] |= 4; // Tx buffer empty
306
            s->rregs[1] |= 1; // All sent
307
            set_txint(s);
308
            slavio_serial_update_irq(s);
309
        }
310
        break;
311
    default:
312
        break;
313
    }
314
}
315

    
316
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
317
{
318
    SerialState *ser = opaque;
319
    ChannelState *s;
320
    uint32_t saddr;
321
    uint32_t ret;
322
    int channel;
323

    
324
    saddr = (addr & 3) >> 1;
325
    channel = (addr & SERIAL_MAXADDR) >> 2;
326
    s = &ser->chn[channel];
327
    switch (saddr) {
328
    case 0:
329
        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, s->rregs[s->reg]);
330
        ret = s->rregs[s->reg];
331
        s->reg = 0;
332
        return ret;
333
    case 1:
334
        s->rregs[0] &= ~1;
335
        clr_rxint(s);
336
        if (s->type == kbd || s->type == mouse)
337
            ret = get_queue(s);
338
        else
339
            ret = s->rx;
340
        SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', ret);
341
        return ret;
342
    default:
343
        break;
344
    }
345
    return 0;
346
}
347

    
348
static int serial_can_receive(void *opaque)
349
{
350
    ChannelState *s = opaque;
351
    if (((s->wregs[3] & 1) == 0) // Rx not enabled
352
        || ((s->rregs[0] & 1) == 1)) // char already available
353
        return 0;
354
    else
355
        return 1;
356
}
357

    
358
static void serial_receive_byte(ChannelState *s, int ch)
359
{
360
    SER_DPRINTF("put ch %d\n", ch);
361
    s->rregs[0] |= 1;
362
    s->rx = ch;
363
    set_rxint(s);
364
}
365

    
366
static void serial_receive_break(ChannelState *s)
367
{
368
    s->rregs[0] |= 0x80;
369
    slavio_serial_update_irq(s);
370
}
371

    
372
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
373
{
374
    ChannelState *s = opaque;
375
    serial_receive_byte(s, buf[0]);
376
}
377

    
378
static void serial_event(void *opaque, int event)
379
{
380
    ChannelState *s = opaque;
381
    if (event == CHR_EVENT_BREAK)
382
        serial_receive_break(s);
383
}
384

    
385
static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
386
    slavio_serial_mem_readb,
387
    slavio_serial_mem_readb,
388
    slavio_serial_mem_readb,
389
};
390

    
391
static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
392
    slavio_serial_mem_writeb,
393
    slavio_serial_mem_writeb,
394
    slavio_serial_mem_writeb,
395
};
396

    
397
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
398
{
399
    qemu_put_be32s(f, &s->irq);
400
    qemu_put_be32s(f, &s->reg);
401
    qemu_put_be32s(f, &s->rxint);
402
    qemu_put_be32s(f, &s->txint);
403
    qemu_put_8s(f, &s->rx);
404
    qemu_put_8s(f, &s->tx);
405
    qemu_put_buffer(f, s->wregs, 16);
406
    qemu_put_buffer(f, s->rregs, 16);
407
}
408

    
409
static void slavio_serial_save(QEMUFile *f, void *opaque)
410
{
411
    SerialState *s = opaque;
412

    
413
    slavio_serial_save_chn(f, &s->chn[0]);
414
    slavio_serial_save_chn(f, &s->chn[1]);
415
}
416

    
417
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
418
{
419
    if (version_id != 1)
420
        return -EINVAL;
421

    
422
    qemu_get_be32s(f, &s->irq);
423
    qemu_get_be32s(f, &s->reg);
424
    qemu_get_be32s(f, &s->rxint);
425
    qemu_get_be32s(f, &s->txint);
426
    qemu_get_8s(f, &s->rx);
427
    qemu_get_8s(f, &s->tx);
428
    qemu_get_buffer(f, s->wregs, 16);
429
    qemu_get_buffer(f, s->rregs, 16);
430
    return 0;
431
}
432

    
433
static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
434
{
435
    SerialState *s = opaque;
436
    int ret;
437

    
438
    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
439
    if (ret != 0)
440
        return ret;
441
    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
442
    return ret;
443

    
444
}
445

    
446
SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
447
{
448
    int slavio_serial_io_memory, i;
449
    SerialState *s;
450

    
451
    s = qemu_mallocz(sizeof(SerialState));
452
    if (!s)
453
        return NULL;
454

    
455
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
456
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
457

    
458
    s->chn[0].chr = chr1;
459
    s->chn[1].chr = chr2;
460

    
461
    for (i = 0; i < 2; i++) {
462
        s->chn[i].irq = irq;
463
        s->chn[i].chn = 1 - i;
464
        s->chn[i].type = ser;
465
        if (s->chn[i].chr) {
466
            qemu_chr_add_read_handler(s->chn[i].chr, serial_can_receive, serial_receive1, &s->chn[i]);
467
            qemu_chr_add_event_handler(s->chn[i].chr, serial_event);
468
        }
469
    }
470
    s->chn[0].otherchn = &s->chn[1];
471
    s->chn[1].otherchn = &s->chn[0];
472
    register_savevm("slavio_serial", base, 1, slavio_serial_save, slavio_serial_load, s);
473
    qemu_register_reset(slavio_serial_reset, s);
474
    slavio_serial_reset(s);
475
    return s;
476
}
477

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

    
489
static void sunkbd_event(void *opaque, int ch)
490
{
491
    ChannelState *s = opaque;
492
    int release = ch & 0x80;
493

    
494
    ch = keycodes[ch & 0x7f];
495
    KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
496
    put_queue(s, ch | release);
497
}
498

    
499
static void handle_kbd_command(ChannelState *s, int val)
500
{
501
    KBD_DPRINTF("Command %d\n", val);
502
    switch (val) {
503
    case 1: // Reset, return type code
504
        put_queue(s, 0xff);
505
        put_queue(s, 5); // Type 5
506
        break;
507
    case 7: // Query layout
508
        put_queue(s, 0xfe);
509
        put_queue(s, 0x20); // XXX, layout?
510
        break;
511
    default:
512
        break;
513
    }
514
}
515

    
516
static void sunmouse_event(void *opaque, 
517
                               int dx, int dy, int dz, int buttons_state)
518
{
519
    ChannelState *s = opaque;
520
    int ch;
521

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

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

    
526
    if (buttons_state & MOUSE_EVENT_LBUTTON)
527
        ch ^= 0x4;
528
    if (buttons_state & MOUSE_EVENT_MBUTTON)
529
        ch ^= 0x2;
530
    if (buttons_state & MOUSE_EVENT_RBUTTON)
531
        ch ^= 0x1;
532

    
533
    put_queue(s, ch);
534

    
535
    ch = dx;
536

    
537
    if (ch > 127)
538
        ch=127;
539
    else if (ch < -127)
540
        ch=-127;
541

    
542
    put_queue(s, ch & 0xff);
543

    
544
    ch = -dy;
545

    
546
    if (ch > 127)
547
        ch=127;
548
    else if (ch < -127)
549
        ch=-127;
550

    
551
    put_queue(s, ch & 0xff);
552

    
553
    // MSC protocol specify two extra motion bytes
554

    
555
    put_queue(s, 0);
556
    put_queue(s, 0);
557
}
558

    
559
void slavio_serial_ms_kbd_init(int base, int irq)
560
{
561
    int slavio_serial_io_memory, i;
562
    SerialState *s;
563

    
564
    s = qemu_mallocz(sizeof(SerialState));
565
    if (!s)
566
        return;
567
    for (i = 0; i < 2; i++) {
568
        s->chn[i].irq = irq;
569
        s->chn[i].chn = 1 - i;
570
        s->chn[i].chr = NULL;
571
    }
572
    s->chn[0].otherchn = &s->chn[1];
573
    s->chn[1].otherchn = &s->chn[0];
574
    s->chn[0].type = mouse;
575
    s->chn[1].type = kbd;
576

    
577
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
578
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
579

    
580
    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0);
581
    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
582
    qemu_register_reset(slavio_serial_reset, s);
583
    slavio_serial_reset(s);
584
}