]> git.proxmox.com Git - mirror_qemu.git/blob - hw/slavio_serial.c
added mouse protocol (Igor Kovalenko)
[mirror_qemu.git] / hw / slavio_serial.c
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 }