Statistics
| Branch: | Revision:

root / hw / slavio_serial.c @ 61271e5c

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

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

    
68
typedef enum {
69
    ser, kbd, mouse,
70
} chn_type_t;
71

    
72
#define KBD_QUEUE_SIZE 256
73

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

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

    
91
struct SerialState {
92
    struct ChannelState chn[2];
93
};
94

    
95
#define SERIAL_MAXADDR 7
96

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

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

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

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

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

    
149
static void slavio_serial_reset_chn(ChannelState *s)
150
{
151
    int i;
152

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

    
166
    s->rx = s->tx = 0;
167
    s->rxint = s->txint = 0;
168
}
169

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

    
177
static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
178
{
179
    SerialState *ser = opaque;
180
    ChannelState *s;
181
    uint32_t saddr;
182
    int newreg, channel;
183

    
184
    val &= 0xff;
185
    saddr = (addr & 3) >> 1;
186
    channel = (addr & SERIAL_MAXADDR) >> 2;
187
    s = &ser->chn[channel];
188
    switch (saddr) {
189
    case 0:
190
        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, val & 0xff);
191
        newreg = 0;
192
        switch (s->reg) {
193
        case 0:
194
            newreg = val & 7;
195
            val &= 0x38;
196
            switch (val) {
197
            case 8:
198
                s->reg |= 0x8;
199
                break;
200
            case 0x20:
201
                s->rxint = 0;
202
                break;
203
            case 0x28:
204
                s->txint = 0;
205
                break;
206
            default:
207
                break;
208
            }
209
            break;
210
        case 1 ... 8:
211
        case 10 ... 15:
212
            s->wregs[s->reg] = val;
213
            break;
214
        case 9:
215
            switch (val & 0xc0) {
216
            case 0:
217
            default:
218
                break;
219
            case 0x40:
220
                slavio_serial_reset_chn(&ser->chn[1]);
221
                return;
222
            case 0x80:
223
                slavio_serial_reset_chn(&ser->chn[0]);
224
                return;
225
            case 0xc0:
226
                slavio_serial_reset(ser);
227
                return;
228
            }
229
            break;
230
        default:
231
            break;
232
        }
233
        if (s->reg == 0)
234
            s->reg = newreg;
235
        else
236
            s->reg = 0;
237
        break;
238
    case 1:
239
        SER_DPRINTF("Write channel %c, ch %d\n", channel? 'b' : 'a', val);
240
        if (s->wregs[5] & 8) { // tx enabled
241
            s->tx = val;
242
            if (s->chr)
243
                qemu_chr_write(s->chr, &s->tx, 1);
244
            else if (s->type == kbd) {
245
                handle_kbd_command(s, val);
246
            }
247
            s->txint = 1;
248
            s->rregs[0] |= 4;
249
            // Interrupts reported only on channel A
250
            if (s->chn == 0)
251
                s->rregs[3] |= 0x10;
252
            else {
253
                s->otherchn->rregs[3] |= 2;
254
            }
255
            slavio_serial_update_irq(s);
256
        }
257
        break;
258
    default:
259
        break;
260
    }
261
}
262

    
263
static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
264
{
265
    SerialState *ser = opaque;
266
    ChannelState *s;
267
    uint32_t saddr;
268
    uint32_t ret;
269
    int channel;
270

    
271
    saddr = (addr & 3) >> 1;
272
    channel = (addr & SERIAL_MAXADDR) >> 2;
273
    s = &ser->chn[channel];
274
    switch (saddr) {
275
    case 0:
276
        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", channel? 'b' : 'a', s->reg, s->rregs[s->reg]);
277
        ret = s->rregs[s->reg];
278
        s->reg = 0;
279
        return ret;
280
    case 1:
281
        SER_DPRINTF("Read channel %c, ch %d\n", channel? 'b' : 'a', s->rx);
282
        s->rregs[0] &= ~1;
283
        if (s->type == kbd)
284
            ret = get_queue(s);
285
        else
286
            ret = s->rx;
287
        return ret;
288
    default:
289
        break;
290
    }
291
    return 0;
292
}
293

    
294
static int serial_can_receive(void *opaque)
295
{
296
    ChannelState *s = opaque;
297
    if (((s->wregs[3] & 1) == 0) // Rx not enabled
298
        || ((s->rregs[0] & 1) == 1)) // char already available
299
        return 0;
300
    else
301
        return 1;
302
}
303

    
304
static void serial_receive_byte(ChannelState *s, int ch)
305
{
306
    s->rregs[0] |= 1;
307
    // Interrupts reported only on channel A
308
    if (s->chn == 0)
309
        s->rregs[3] |= 0x20;
310
    else {
311
        s->otherchn->rregs[3] |= 4;
312
    }
313
    s->rx = ch;
314
    s->rxint = 1;
315
    slavio_serial_update_irq(s);
316
}
317

    
318
static void serial_receive_break(ChannelState *s)
319
{
320
    s->rregs[0] |= 0x80;
321
    slavio_serial_update_irq(s);
322
}
323

    
324
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
325
{
326
    ChannelState *s = opaque;
327
    serial_receive_byte(s, buf[0]);
328
}
329

    
330
static void serial_event(void *opaque, int event)
331
{
332
    ChannelState *s = opaque;
333
    if (event == CHR_EVENT_BREAK)
334
        serial_receive_break(s);
335
}
336

    
337
static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
338
    slavio_serial_mem_readb,
339
    slavio_serial_mem_readb,
340
    slavio_serial_mem_readb,
341
};
342

    
343
static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
344
    slavio_serial_mem_writeb,
345
    slavio_serial_mem_writeb,
346
    slavio_serial_mem_writeb,
347
};
348

    
349
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
350
{
351
    qemu_put_be32s(f, &s->irq);
352
    qemu_put_be32s(f, &s->reg);
353
    qemu_put_be32s(f, &s->rxint);
354
    qemu_put_be32s(f, &s->txint);
355
    qemu_put_8s(f, &s->rx);
356
    qemu_put_8s(f, &s->tx);
357
    qemu_put_buffer(f, s->wregs, 16);
358
    qemu_put_buffer(f, s->rregs, 16);
359
}
360

    
361
static void slavio_serial_save(QEMUFile *f, void *opaque)
362
{
363
    SerialState *s = opaque;
364

    
365
    slavio_serial_save_chn(f, &s->chn[0]);
366
    slavio_serial_save_chn(f, &s->chn[1]);
367
}
368

    
369
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
370
{
371
    if (version_id != 1)
372
        return -EINVAL;
373

    
374
    qemu_get_be32s(f, &s->irq);
375
    qemu_get_be32s(f, &s->reg);
376
    qemu_get_be32s(f, &s->rxint);
377
    qemu_get_be32s(f, &s->txint);
378
    qemu_get_8s(f, &s->rx);
379
    qemu_get_8s(f, &s->tx);
380
    qemu_get_buffer(f, s->wregs, 16);
381
    qemu_get_buffer(f, s->rregs, 16);
382
    return 0;
383
}
384

    
385
static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
386
{
387
    SerialState *s = opaque;
388
    int ret;
389

    
390
    ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
391
    if (ret != 0)
392
        return ret;
393
    ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
394
    return ret;
395

    
396
}
397

    
398
SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
399
{
400
    int slavio_serial_io_memory, i;
401
    SerialState *s;
402

    
403
    s = qemu_mallocz(sizeof(SerialState));
404
    if (!s)
405
        return NULL;
406

    
407
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
408
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
409

    
410
    s->chn[0].chr = chr1;
411
    s->chn[1].chr = chr2;
412

    
413
    for (i = 0; i < 2; i++) {
414
        s->chn[i].irq = irq;
415
        s->chn[i].chn = 1 - i;
416
        s->chn[i].type = ser;
417
        if (s->chn[i].chr) {
418
            qemu_chr_add_read_handler(s->chn[i].chr, serial_can_receive, serial_receive1, &s->chn[i]);
419
            qemu_chr_add_event_handler(s->chn[i].chr, serial_event);
420
        }
421
    }
422
    s->chn[0].otherchn = &s->chn[1];
423
    s->chn[1].otherchn = &s->chn[0];
424
    register_savevm("slavio_serial", base, 1, slavio_serial_save, slavio_serial_load, s);
425
    qemu_register_reset(slavio_serial_reset, s);
426
    slavio_serial_reset(s);
427
    return s;
428
}
429

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

    
441
static void sunkbd_event(void *opaque, int ch)
442
{
443
    ChannelState *s = opaque;
444
    int release = ch & 0x80;
445

    
446
    ch = keycodes[ch & 0x7f];
447
    KBD_DPRINTF("Keycode %d (%s)\n", ch, release? "release" : "press");
448
    put_queue(s, ch | release);
449
}
450

    
451
static void handle_kbd_command(ChannelState *s, int val)
452
{
453
    KBD_DPRINTF("Command %d\n", val);
454
    switch (val) {
455
    case 1: // Reset, return type code
456
        put_queue(s, 0xff);
457
        put_queue(s, 0xff);
458
        put_queue(s, 5); // Type 5
459
        break;
460
    case 7: // Query layout
461
        put_queue(s, 0xfe);
462
        put_queue(s, 0x20); // XXX, layout?
463
        break;
464
    default:
465
        break;
466
    }
467
}
468

    
469
static void sunmouse_event(void *opaque, 
470
                               int dx, int dy, int dz, int buttons_state)
471
{
472
    ChannelState *s = opaque;
473
    int ch;
474

    
475
    // XXX
476
    ch = 0x42;
477
    serial_receive_byte(s, ch);
478
}
479

    
480
void slavio_serial_ms_kbd_init(int base, int irq)
481
{
482
    int slavio_serial_io_memory, i;
483
    SerialState *s;
484

    
485
    s = qemu_mallocz(sizeof(SerialState));
486
    if (!s)
487
        return;
488
    for (i = 0; i < 2; i++) {
489
        s->chn[i].irq = irq;
490
        s->chn[i].chn = 1 - i;
491
        s->chn[i].chr = NULL;
492
    }
493
    s->chn[0].otherchn = &s->chn[1];
494
    s->chn[1].otherchn = &s->chn[0];
495
    s->chn[0].type = mouse;
496
    s->chn[1].type = kbd;
497

    
498
    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
499
    cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
500

    
501
    qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0]);
502
    qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
503
    qemu_register_reset(slavio_serial_reset, s);
504
    slavio_serial_reset(s);
505
}