Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ ffcdb539

History | View | Annotate | Download (13.2 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
#ifdef DEBUG_SERIAL
46
#define SER_DPRINTF(fmt, args...) \
47
do { printf("SER: " fmt , ##args); } while (0)
48
#define pic_set_irq(irq, level) \
49
do { printf("SER: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0)
50
#else
51
#define SER_DPRINTF(fmt, args...)
52
#endif
53
#ifdef DEBUG_KBD
54
#define KBD_DPRINTF(fmt, args...) \
55
do { printf("KBD: " fmt , ##args); } while (0)
56
#else
57
#define KBD_DPRINTF(fmt, args...)
58
#endif
59
#ifdef DEBUG_MOUSE
60
#define MS_DPRINTF(fmt, args...) \
61
do { printf("SER: " fmt , ##args); } while (0)
62
#else
63
#define MS_DPRINTF(fmt, args...)
64
#endif
65

    
66
typedef enum {
67
    chn_a, chn_b,
68
} chn_id_t;
69

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

    
74
#define KBD_QUEUE_SIZE 256
75

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

    
81
typedef struct ChannelState {
82
    int irq;
83
    int reg;
84
    int rxint, txint;
85
    chn_id_t chn; // this channel, A (base+4) or B (base+0)
86
    chn_type_t type;
87
    struct ChannelState *otherchn;
88
    uint8_t rx, tx, wregs[16], rregs[16];
89
    KBDQueue queue;
90
    CharDriverState *chr;
91
} ChannelState;
92

    
93
struct SerialState {
94
    struct ChannelState chn[2];
95
};
96

    
97
#define SERIAL_MAXADDR 7
98

    
99
static void handle_kbd_command(ChannelState *s, int val);
100
static int serial_can_receive(void *opaque);
101
static void serial_receive_byte(ChannelState *s, int ch);
102

    
103
static void put_queue(void *opaque, int b)
104
{
105
    ChannelState *s = opaque;
106
    KBDQueue *q = &s->queue;
107

    
108
    KBD_DPRINTF("put: 0x%02x\n", b);
109
    if (q->count >= KBD_QUEUE_SIZE)
110
        return;
111
    q->data[q->wptr] = b;
112
    if (++q->wptr == KBD_QUEUE_SIZE)
113
        q->wptr = 0;
114
    q->count++;
115
    serial_receive_byte(s, 0);
116
}
117

    
118
static uint32_t get_queue(void *opaque)
119
{
120
    ChannelState *s = opaque;
121
    KBDQueue *q = &s->queue;
122
    int val;
123
    
124
    if (q->count == 0) {
125
        return 0;
126
    } else {
127
        val = q->data[q->rptr];
128
        if (++q->rptr == KBD_QUEUE_SIZE)
129
            q->rptr = 0;
130
        q->count--;
131
    }
132
    KBD_DPRINTF("get 0x%02x\n", val);
133
    if (q->count > 0)
134
        serial_receive_byte(s, 0);
135
    return val;
136
}
137

    
138
static void slavio_serial_update_irq(ChannelState *s)
139
{
140
    if ((s->wregs[1] & 1) && // interrupts enabled
141
        (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
142
         ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
143
          s->rxint == 1) || // rx ints enabled, pending
144
         ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
145
        pic_set_irq(s->irq, 1);
146
    } else {
147
        pic_set_irq(s->irq, 0);
148
    }
149
}
150

    
151
static void slavio_serial_reset_chn(ChannelState *s)
152
{
153
    int i;
154

    
155
    s->reg = 0;
156
    for (i = 0; i < SERIAL_MAXADDR; i++) {
157
        s->rregs[i] = 0;
158
        s->wregs[i] = 0;
159
    }
160
    s->wregs[4] = 4;
161
    s->wregs[9] = 0xc0;
162
    s->wregs[11] = 8;
163
    s->wregs[14] = 0x30;
164
    s->wregs[15] = 0xf8;
165
    s->rregs[0] = 0x44;
166
    s->rregs[1] = 6;
167

    
168
    s->rx = s->tx = 0;
169
    s->rxint = s->txint = 0;
170
}
171

    
172
static void slavio_serial_reset(void *opaque)
173
{
174
    SerialState *s = opaque;
175
    slavio_serial_reset_chn(&s->chn[0]);
176
    slavio_serial_reset_chn(&s->chn[1]);
177
}
178

    
179
static inline void clr_rxint(ChannelState *s)
180
{
181
    s->rxint = 0;
182
    if (s->chn == 0)
183
        s->rregs[3] &= ~0x20;
184
    else {
185
        s->otherchn->rregs[3] &= ~4;
186
    }
187
    slavio_serial_update_irq(s);
188
}
189

    
190
static inline void set_rxint(ChannelState *s)
191
{
192
    s->rxint = 1;
193
    if (s->chn == 0)
194
        s->rregs[3] |= 0x20;
195
    else {
196
        s->otherchn->rregs[3] |= 4;
197
    }
198
    slavio_serial_update_irq(s);
199
}
200

    
201
static inline void clr_txint(ChannelState *s)
202
{
203
    s->txint = 0;
204
    if (s->chn == 0)
205
        s->rregs[3] &= ~0x10;
206
    else {
207
        s->otherchn->rregs[3] &= ~2;
208
    }
209
    slavio_serial_update_irq(s);
210
}
211

    
212
static inline void set_txint(ChannelState *s)
213
{
214
    s->txint = 1;
215
    if (s->chn == 0)
216
        s->rregs[3] |= 0x10;
217
    else {
218
        s->otherchn->rregs[3] |= 2;
219
    }
220
    slavio_serial_update_irq(s);
221
}
222

    
223
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
224
{
225
    SerialState *ser = opaque;
226
    ChannelState *s;
227
    uint32_t saddr;
228
    int newreg, channel;
229

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

    
309
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
310
{
311
    SerialState *ser = opaque;
312
    ChannelState *s;
313
    uint32_t saddr;
314
    uint32_t ret;
315
    int channel;
316

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

    
341
static int serial_can_receive(void *opaque)
342
{
343
    ChannelState *s = opaque;
344
    if (((s->wregs[3] & 1) == 0) // Rx not enabled
345
        || ((s->rregs[0] & 1) == 1)) // char already available
346
        return 0;
347
    else
348
        return 1;
349
}
350

    
351
static void serial_receive_byte(ChannelState *s, int ch)
352
{
353
    SER_DPRINTF("put ch %d\n", ch);
354
    s->rregs[0] |= 1;
355
    s->rx = ch;
356
    set_rxint(s);
357
}
358

    
359
static void serial_receive_break(ChannelState *s)
360
{
361
    s->rregs[0] |= 0x80;
362
    slavio_serial_update_irq(s);
363
}
364

    
365
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
366
{
367
    ChannelState *s = opaque;
368
    serial_receive_byte(s, buf[0]);
369
}
370

    
371
static void serial_event(void *opaque, int event)
372
{
373
    ChannelState *s = opaque;
374
    if (event == CHR_EVENT_BREAK)
375
        serial_receive_break(s);
376
}
377

    
378
static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
379
    slavio_serial_mem_readb,
380
    slavio_serial_mem_readb,
381
    slavio_serial_mem_readb,
382
};
383

    
384
static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
385
    slavio_serial_mem_writeb,
386
    slavio_serial_mem_writeb,
387
    slavio_serial_mem_writeb,
388
};
389

    
390
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
391
{
392
    qemu_put_be32s(f, &s->irq);
393
    qemu_put_be32s(f, &s->reg);
394
    qemu_put_be32s(f, &s->rxint);
395
    qemu_put_be32s(f, &s->txint);
396
    qemu_put_8s(f, &s->rx);
397
    qemu_put_8s(f, &s->tx);
398
    qemu_put_buffer(f, s->wregs, 16);
399
    qemu_put_buffer(f, s->rregs, 16);
400
}
401

    
402
static void slavio_serial_save(QEMUFile *f, void *opaque)
403
{
404
    SerialState *s = opaque;
405

    
406
    slavio_serial_save_chn(f, &s->chn[0]);
407
    slavio_serial_save_chn(f, &s->chn[1]);
408
}
409

    
410
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
411
{
412
    if (version_id != 1)
413
        return -EINVAL;
414

    
415
    qemu_get_be32s(f, &s->irq);
416
    qemu_get_be32s(f, &s->reg);
417
    qemu_get_be32s(f, &s->rxint);
418
    qemu_get_be32s(f, &s->txint);
419
    qemu_get_8s(f, &s->rx);
420
    qemu_get_8s(f, &s->tx);
421
    qemu_get_buffer(f, s->wregs, 16);
422
    qemu_get_buffer(f, s->rregs, 16);
423
    return 0;
424
}
425

    
426
static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
427
{
428
    SerialState *s = opaque;
429
    int ret;
430

    
431
    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
432
    if (ret != 0)
433
        return ret;
434
    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
435
    return ret;
436

    
437
}
438

    
439
SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
440
{
441
    int slavio_serial_io_memory, i;
442
    SerialState *s;
443

    
444
    s = qemu_mallocz(sizeof(SerialState));
445
    if (!s)
446
        return NULL;
447

    
448
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
449
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
450

    
451
    s->chn[0].chr = chr1;
452
    s->chn[1].chr = chr2;
453

    
454
    for (i = 0; i < 2; i++) {
455
        s->chn[i].irq = irq;
456
        s->chn[i].chn = 1 - i;
457
        s->chn[i].type = ser;
458
        if (s->chn[i].chr) {
459
            qemu_chr_add_read_handler(s->chn[i].chr, serial_can_receive, serial_receive1, &s->chn[i]);
460
            qemu_chr_add_event_handler(s->chn[i].chr, serial_event);
461
        }
462
    }
463
    s->chn[0].otherchn = &s->chn[1];
464
    s->chn[1].otherchn = &s->chn[0];
465
    register_savevm("slavio_serial", base, 1, slavio_serial_save, slavio_serial_load, s);
466
    qemu_register_reset(slavio_serial_reset, s);
467
    slavio_serial_reset(s);
468
    return s;
469
}
470

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

    
482
static void sunkbd_event(void *opaque, int ch)
483
{
484
    ChannelState *s = opaque;
485
    int release = ch & 0x80;
486

    
487
    ch = keycodes[ch & 0x7f];
488
    KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
489
    put_queue(s, ch | release);
490
}
491

    
492
static void handle_kbd_command(ChannelState *s, int val)
493
{
494
    KBD_DPRINTF("Command %d\n", val);
495
    switch (val) {
496
    case 1: // Reset, return type code
497
        put_queue(s, 0xff);
498
        put_queue(s, 5); // Type 5
499
        break;
500
    case 7: // Query layout
501
        put_queue(s, 0xfe);
502
        put_queue(s, 0x20); // XXX, layout?
503
        break;
504
    default:
505
        break;
506
    }
507
}
508

    
509
static void sunmouse_event(void *opaque, 
510
                               int dx, int dy, int dz, int buttons_state)
511
{
512
    ChannelState *s = opaque;
513
    int ch;
514

    
515
    // XXX
516
    ch = 0x42;
517
    serial_receive_byte(s, ch);
518
}
519

    
520
void slavio_serial_ms_kbd_init(int base, int irq)
521
{
522
    int slavio_serial_io_memory, i;
523
    SerialState *s;
524

    
525
    s = qemu_mallocz(sizeof(SerialState));
526
    if (!s)
527
        return;
528
    for (i = 0; i < 2; i++) {
529
        s->chn[i].irq = irq;
530
        s->chn[i].chn = 1 - i;
531
        s->chn[i].chr = NULL;
532
    }
533
    s->chn[0].otherchn = &s->chn[1];
534
    s->chn[1].otherchn = &s->chn[0];
535
    s->chn[0].type = mouse;
536
    s->chn[1].type = kbd;
537

    
538
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
539
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
540

    
541
    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0);
542
    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
543
    qemu_register_reset(slavio_serial_reset, s);
544
    slavio_serial_reset(s);
545
}