]> git.proxmox.com Git - mirror_qemu.git/blob - hw/slavio_serial.c
Add input buffer to mux chr (patch by Tristan Gingold).
[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 "hw.h"
25 #include "sun4m.h"
26 #include "qemu-char.h"
27 #include "console.h"
28
29 /* debug serial */
30 //#define DEBUG_SERIAL
31
32 /* debug keyboard */
33 //#define DEBUG_KBD
34
35 /* debug mouse */
36 //#define DEBUG_MOUSE
37
38 /*
39 * This is the serial port, mouse and keyboard part of chip STP2001
40 * (Slave I/O), also produced as NCR89C105. See
41 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
42 *
43 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
44 * mouse and keyboard ports don't implement all functions and they are
45 * only asynchronous. There is no DMA.
46 *
47 */
48
49 /*
50 * Modifications:
51 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
52 * serial mouse queue.
53 * Implemented serial mouse protocol.
54 */
55
56 #ifdef DEBUG_SERIAL
57 #define SER_DPRINTF(fmt, args...) \
58 do { printf("SER: " fmt , ##args); } while (0)
59 #else
60 #define SER_DPRINTF(fmt, args...)
61 #endif
62 #ifdef DEBUG_KBD
63 #define KBD_DPRINTF(fmt, args...) \
64 do { printf("KBD: " fmt , ##args); } while (0)
65 #else
66 #define KBD_DPRINTF(fmt, args...)
67 #endif
68 #ifdef DEBUG_MOUSE
69 #define MS_DPRINTF(fmt, args...) \
70 do { printf("MSC: " fmt , ##args); } while (0)
71 #else
72 #define MS_DPRINTF(fmt, args...)
73 #endif
74
75 typedef enum {
76 chn_a, chn_b,
77 } chn_id_t;
78
79 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
80
81 typedef enum {
82 ser, kbd, mouse,
83 } chn_type_t;
84
85 #define SERIO_QUEUE_SIZE 256
86
87 typedef struct {
88 uint8_t data[SERIO_QUEUE_SIZE];
89 int rptr, wptr, count;
90 } SERIOQueue;
91
92 typedef struct ChannelState {
93 qemu_irq irq;
94 int reg;
95 int rxint, txint, rxint_under_svc, txint_under_svc;
96 chn_id_t chn; // this channel, A (base+4) or B (base+0)
97 chn_type_t type;
98 struct ChannelState *otherchn;
99 uint8_t rx, tx, wregs[16], rregs[16];
100 SERIOQueue queue;
101 CharDriverState *chr;
102 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
103 } ChannelState;
104
105 struct SerialState {
106 struct ChannelState chn[2];
107 };
108
109 #define SERIAL_MAXADDR 7
110 #define SERIAL_SIZE (SERIAL_MAXADDR + 1)
111
112 static void handle_kbd_command(ChannelState *s, int val);
113 static int serial_can_receive(void *opaque);
114 static void serial_receive_byte(ChannelState *s, int ch);
115 static inline void set_txint(ChannelState *s);
116
117 static void clear_queue(void *opaque)
118 {
119 ChannelState *s = opaque;
120 SERIOQueue *q = &s->queue;
121 q->rptr = q->wptr = q->count = 0;
122 }
123
124 static void put_queue(void *opaque, int b)
125 {
126 ChannelState *s = opaque;
127 SERIOQueue *q = &s->queue;
128
129 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
130 if (q->count >= SERIO_QUEUE_SIZE)
131 return;
132 q->data[q->wptr] = b;
133 if (++q->wptr == SERIO_QUEUE_SIZE)
134 q->wptr = 0;
135 q->count++;
136 serial_receive_byte(s, 0);
137 }
138
139 static uint32_t get_queue(void *opaque)
140 {
141 ChannelState *s = opaque;
142 SERIOQueue *q = &s->queue;
143 int val;
144
145 if (q->count == 0) {
146 return 0;
147 } else {
148 val = q->data[q->rptr];
149 if (++q->rptr == SERIO_QUEUE_SIZE)
150 q->rptr = 0;
151 q->count--;
152 }
153 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
154 if (q->count > 0)
155 serial_receive_byte(s, 0);
156 return val;
157 }
158
159 static int slavio_serial_update_irq_chn(ChannelState *s)
160 {
161 if ((s->wregs[1] & 1) && // interrupts enabled
162 (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
163 ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
164 s->rxint == 1) || // rx ints enabled, pending
165 ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
166 return 1;
167 }
168 return 0;
169 }
170
171 static void slavio_serial_update_irq(ChannelState *s)
172 {
173 int irq;
174
175 irq = slavio_serial_update_irq_chn(s);
176 irq |= slavio_serial_update_irq_chn(s->otherchn);
177
178 SER_DPRINTF("IRQ = %d\n", irq);
179 qemu_set_irq(s->irq, irq);
180 }
181
182 static void slavio_serial_reset_chn(ChannelState *s)
183 {
184 int i;
185
186 s->reg = 0;
187 for (i = 0; i < SERIAL_SIZE; i++) {
188 s->rregs[i] = 0;
189 s->wregs[i] = 0;
190 }
191 s->wregs[4] = 4;
192 s->wregs[9] = 0xc0;
193 s->wregs[11] = 8;
194 s->wregs[14] = 0x30;
195 s->wregs[15] = 0xf8;
196 s->rregs[0] = 0x44;
197 s->rregs[1] = 6;
198
199 s->rx = s->tx = 0;
200 s->rxint = s->txint = 0;
201 s->rxint_under_svc = s->txint_under_svc = 0;
202 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
203 clear_queue(s);
204 }
205
206 static void slavio_serial_reset(void *opaque)
207 {
208 SerialState *s = opaque;
209 slavio_serial_reset_chn(&s->chn[0]);
210 slavio_serial_reset_chn(&s->chn[1]);
211 }
212
213 static inline void clr_rxint(ChannelState *s)
214 {
215 s->rxint = 0;
216 s->rxint_under_svc = 0;
217 if (s->chn == chn_a) {
218 if (s->wregs[9] & 0x10)
219 s->otherchn->rregs[2] = 0x60;
220 else
221 s->otherchn->rregs[2] = 0x06;
222 s->rregs[3] &= ~0x20;
223 } else {
224 if (s->wregs[9] & 0x10)
225 s->rregs[2] = 0x60;
226 else
227 s->rregs[2] = 0x06;
228 s->otherchn->rregs[3] &= ~4;
229 }
230 if (s->txint)
231 set_txint(s);
232 slavio_serial_update_irq(s);
233 }
234
235 static inline void set_rxint(ChannelState *s)
236 {
237 s->rxint = 1;
238 if (!s->txint_under_svc) {
239 s->rxint_under_svc = 1;
240 if (s->chn == chn_a) {
241 if (s->wregs[9] & 0x10)
242 s->otherchn->rregs[2] = 0x30;
243 else
244 s->otherchn->rregs[2] = 0x0c;
245 } else {
246 if (s->wregs[9] & 0x10)
247 s->rregs[2] = 0x20;
248 else
249 s->rregs[2] = 0x04;
250 }
251 }
252 if (s->chn == chn_a)
253 s->rregs[3] |= 0x20;
254 else
255 s->otherchn->rregs[3] |= 4;
256 slavio_serial_update_irq(s);
257 }
258
259 static inline void clr_txint(ChannelState *s)
260 {
261 s->txint = 0;
262 s->txint_under_svc = 0;
263 if (s->chn == chn_a) {
264 if (s->wregs[9] & 0x10)
265 s->otherchn->rregs[2] = 0x60;
266 else
267 s->otherchn->rregs[2] = 0x06;
268 s->rregs[3] &= ~0x10;
269 } else {
270 if (s->wregs[9] & 0x10)
271 s->rregs[2] = 0x60;
272 else
273 s->rregs[2] = 0x06;
274 s->otherchn->rregs[3] &= ~2;
275 }
276 if (s->rxint)
277 set_rxint(s);
278 slavio_serial_update_irq(s);
279 }
280
281 static inline void set_txint(ChannelState *s)
282 {
283 s->txint = 1;
284 if (!s->rxint_under_svc) {
285 s->txint_under_svc = 1;
286 if (s->chn == chn_a) {
287 if (s->wregs[9] & 0x10)
288 s->otherchn->rregs[2] = 0x10;
289 else
290 s->otherchn->rregs[2] = 0x08;
291 } else {
292 s->rregs[2] = 0;
293 }
294 }
295 if (s->chn == chn_a)
296 s->rregs[3] |= 0x10;
297 else
298 s->otherchn->rregs[3] |= 2;
299 slavio_serial_update_irq(s);
300 }
301
302 static void slavio_serial_update_parameters(ChannelState *s)
303 {
304 int speed, parity, data_bits, stop_bits;
305 QEMUSerialSetParams ssp;
306
307 if (!s->chr || s->type != ser)
308 return;
309
310 if (s->wregs[4] & 1) {
311 if (s->wregs[4] & 2)
312 parity = 'E';
313 else
314 parity = 'O';
315 } else {
316 parity = 'N';
317 }
318 if ((s->wregs[4] & 0x0c) == 0x0c)
319 stop_bits = 2;
320 else
321 stop_bits = 1;
322 switch (s->wregs[5] & 0x60) {
323 case 0x00:
324 data_bits = 5;
325 break;
326 case 0x20:
327 data_bits = 7;
328 break;
329 case 0x40:
330 data_bits = 6;
331 break;
332 default:
333 case 0x60:
334 data_bits = 8;
335 break;
336 }
337 speed = 2457600 / ((s->wregs[12] | (s->wregs[13] << 8)) + 2);
338 switch (s->wregs[4] & 0xc0) {
339 case 0x00:
340 break;
341 case 0x40:
342 speed /= 16;
343 break;
344 case 0x80:
345 speed /= 32;
346 break;
347 default:
348 case 0xc0:
349 speed /= 64;
350 break;
351 }
352 ssp.speed = speed;
353 ssp.parity = parity;
354 ssp.data_bits = data_bits;
355 ssp.stop_bits = stop_bits;
356 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
357 speed, parity, data_bits, stop_bits);
358 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
359 }
360
361 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
362 {
363 SerialState *serial = opaque;
364 ChannelState *s;
365 uint32_t saddr;
366 int newreg, channel;
367
368 val &= 0xff;
369 saddr = (addr & 3) >> 1;
370 channel = (addr & SERIAL_MAXADDR) >> 2;
371 s = &serial->chn[channel];
372 switch (saddr) {
373 case 0:
374 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, val & 0xff);
375 newreg = 0;
376 switch (s->reg) {
377 case 0:
378 newreg = val & 7;
379 val &= 0x38;
380 switch (val) {
381 case 8:
382 newreg |= 0x8;
383 break;
384 case 0x28:
385 clr_txint(s);
386 break;
387 case 0x38:
388 if (s->rxint_under_svc)
389 clr_rxint(s);
390 else if (s->txint_under_svc)
391 clr_txint(s);
392 break;
393 default:
394 break;
395 }
396 break;
397 case 1 ... 3:
398 case 6 ... 8:
399 case 10 ... 11:
400 case 14 ... 15:
401 s->wregs[s->reg] = val;
402 break;
403 case 4:
404 case 5:
405 case 12:
406 case 13:
407 s->wregs[s->reg] = val;
408 slavio_serial_update_parameters(s);
409 break;
410 case 9:
411 switch (val & 0xc0) {
412 case 0:
413 default:
414 break;
415 case 0x40:
416 slavio_serial_reset_chn(&serial->chn[1]);
417 return;
418 case 0x80:
419 slavio_serial_reset_chn(&serial->chn[0]);
420 return;
421 case 0xc0:
422 slavio_serial_reset(serial);
423 return;
424 }
425 break;
426 default:
427 break;
428 }
429 if (s->reg == 0)
430 s->reg = newreg;
431 else
432 s->reg = 0;
433 break;
434 case 1:
435 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
436 s->tx = val;
437 if (s->wregs[5] & 8) { // tx enabled
438 if (s->chr)
439 qemu_chr_write(s->chr, &s->tx, 1);
440 else if (s->type == kbd) {
441 handle_kbd_command(s, val);
442 }
443 }
444 s->rregs[0] |= 4; // Tx buffer empty
445 s->rregs[1] |= 1; // All sent
446 set_txint(s);
447 break;
448 default:
449 break;
450 }
451 }
452
453 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
454 {
455 SerialState *serial = opaque;
456 ChannelState *s;
457 uint32_t saddr;
458 uint32_t ret;
459 int channel;
460
461 saddr = (addr & 3) >> 1;
462 channel = (addr & SERIAL_MAXADDR) >> 2;
463 s = &serial->chn[channel];
464 switch (saddr) {
465 case 0:
466 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg, s->rregs[s->reg]);
467 ret = s->rregs[s->reg];
468 s->reg = 0;
469 return ret;
470 case 1:
471 s->rregs[0] &= ~1;
472 clr_rxint(s);
473 if (s->type == kbd || s->type == mouse)
474 ret = get_queue(s);
475 else
476 ret = s->rx;
477 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
478 qemu_chr_accept_input(s->chr);
479 return ret;
480 default:
481 break;
482 }
483 return 0;
484 }
485
486 static int serial_can_receive(void *opaque)
487 {
488 ChannelState *s = opaque;
489 int ret;
490
491 if (((s->wregs[3] & 1) == 0) // Rx not enabled
492 || ((s->rregs[0] & 1) == 1)) // char already available
493 ret = 0;
494 else
495 ret = 1;
496 //SER_DPRINTF("channel %c can receive %d\n", CHN_C(s), ret);
497 return ret;
498 }
499
500 static void serial_receive_byte(ChannelState *s, int ch)
501 {
502 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
503 s->rregs[0] |= 1;
504 s->rx = ch;
505 set_rxint(s);
506 }
507
508 static void serial_receive_break(ChannelState *s)
509 {
510 s->rregs[0] |= 0x80;
511 slavio_serial_update_irq(s);
512 }
513
514 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
515 {
516 ChannelState *s = opaque;
517 serial_receive_byte(s, buf[0]);
518 }
519
520 static void serial_event(void *opaque, int event)
521 {
522 ChannelState *s = opaque;
523 if (event == CHR_EVENT_BREAK)
524 serial_receive_break(s);
525 }
526
527 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
528 slavio_serial_mem_readb,
529 slavio_serial_mem_readb,
530 slavio_serial_mem_readb,
531 };
532
533 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
534 slavio_serial_mem_writeb,
535 slavio_serial_mem_writeb,
536 slavio_serial_mem_writeb,
537 };
538
539 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
540 {
541 int tmp;
542 tmp = 0;
543 qemu_put_be32s(f, &tmp); /* unused, was IRQ. */
544 qemu_put_be32s(f, &s->reg);
545 qemu_put_be32s(f, &s->rxint);
546 qemu_put_be32s(f, &s->txint);
547 qemu_put_be32s(f, &s->rxint_under_svc);
548 qemu_put_be32s(f, &s->txint_under_svc);
549 qemu_put_8s(f, &s->rx);
550 qemu_put_8s(f, &s->tx);
551 qemu_put_buffer(f, s->wregs, 16);
552 qemu_put_buffer(f, s->rregs, 16);
553 }
554
555 static void slavio_serial_save(QEMUFile *f, void *opaque)
556 {
557 SerialState *s = opaque;
558
559 slavio_serial_save_chn(f, &s->chn[0]);
560 slavio_serial_save_chn(f, &s->chn[1]);
561 }
562
563 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
564 {
565 int tmp;
566
567 if (version_id > 2)
568 return -EINVAL;
569
570 qemu_get_be32s(f, &tmp); /* unused */
571 qemu_get_be32s(f, &s->reg);
572 qemu_get_be32s(f, &s->rxint);
573 qemu_get_be32s(f, &s->txint);
574 if (version_id >= 2) {
575 qemu_get_be32s(f, &s->rxint_under_svc);
576 qemu_get_be32s(f, &s->txint_under_svc);
577 }
578 qemu_get_8s(f, &s->rx);
579 qemu_get_8s(f, &s->tx);
580 qemu_get_buffer(f, s->wregs, 16);
581 qemu_get_buffer(f, s->rregs, 16);
582 return 0;
583 }
584
585 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
586 {
587 SerialState *s = opaque;
588 int ret;
589
590 ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
591 if (ret != 0)
592 return ret;
593 ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
594 return ret;
595
596 }
597
598 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
599 CharDriverState *chr1, CharDriverState *chr2)
600 {
601 int slavio_serial_io_memory, i;
602 SerialState *s;
603
604 s = qemu_mallocz(sizeof(SerialState));
605 if (!s)
606 return NULL;
607
608 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
609 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
610
611 s->chn[0].chr = chr1;
612 s->chn[1].chr = chr2;
613
614 for (i = 0; i < 2; i++) {
615 s->chn[i].irq = irq;
616 s->chn[i].chn = 1 - i;
617 s->chn[i].type = ser;
618 if (s->chn[i].chr) {
619 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
620 serial_receive1, serial_event, &s->chn[i]);
621 }
622 }
623 s->chn[0].otherchn = &s->chn[1];
624 s->chn[1].otherchn = &s->chn[0];
625 register_savevm("slavio_serial", base, 2, slavio_serial_save, slavio_serial_load, s);
626 qemu_register_reset(slavio_serial_reset, s);
627 slavio_serial_reset(s);
628 return s;
629 }
630
631 static const uint8_t keycodes[128] = {
632 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
633 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
634 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
635 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
636 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
637 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
638 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
639 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
640 };
641
642 static const uint8_t e0_keycodes[128] = {
643 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
644 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
645 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
646 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
647 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
648 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
649 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
650 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
651 };
652
653 static void sunkbd_event(void *opaque, int ch)
654 {
655 ChannelState *s = opaque;
656 int release = ch & 0x80;
657
658 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" : "press");
659 switch (ch) {
660 case 58: // Caps lock press
661 s->caps_lock_mode ^= 1;
662 if (s->caps_lock_mode == 2)
663 return; // Drop second press
664 break;
665 case 69: // Num lock press
666 s->num_lock_mode ^= 1;
667 if (s->num_lock_mode == 2)
668 return; // Drop second press
669 break;
670 case 186: // Caps lock release
671 s->caps_lock_mode ^= 2;
672 if (s->caps_lock_mode == 3)
673 return; // Drop first release
674 break;
675 case 197: // Num lock release
676 s->num_lock_mode ^= 2;
677 if (s->num_lock_mode == 3)
678 return; // Drop first release
679 break;
680 case 0xe0:
681 s->e0_mode = 1;
682 return;
683 default:
684 break;
685 }
686 if (s->e0_mode) {
687 s->e0_mode = 0;
688 ch = e0_keycodes[ch & 0x7f];
689 } else {
690 ch = keycodes[ch & 0x7f];
691 }
692 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
693 put_queue(s, ch | release);
694 }
695
696 static void handle_kbd_command(ChannelState *s, int val)
697 {
698 KBD_DPRINTF("Command %d\n", val);
699 if (s->led_mode) { // Ignore led byte
700 s->led_mode = 0;
701 return;
702 }
703 switch (val) {
704 case 1: // Reset, return type code
705 clear_queue(s);
706 put_queue(s, 0xff);
707 put_queue(s, 4); // Type 4
708 put_queue(s, 0x7f);
709 break;
710 case 0xe: // Set leds
711 s->led_mode = 1;
712 break;
713 case 7: // Query layout
714 case 0xf:
715 clear_queue(s);
716 put_queue(s, 0xfe);
717 put_queue(s, 0); // XXX, layout?
718 break;
719 default:
720 break;
721 }
722 }
723
724 static void sunmouse_event(void *opaque,
725 int dx, int dy, int dz, int buttons_state)
726 {
727 ChannelState *s = opaque;
728 int ch;
729
730 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
731
732 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
733
734 if (buttons_state & MOUSE_EVENT_LBUTTON)
735 ch ^= 0x4;
736 if (buttons_state & MOUSE_EVENT_MBUTTON)
737 ch ^= 0x2;
738 if (buttons_state & MOUSE_EVENT_RBUTTON)
739 ch ^= 0x1;
740
741 put_queue(s, ch);
742
743 ch = dx;
744
745 if (ch > 127)
746 ch=127;
747 else if (ch < -127)
748 ch=-127;
749
750 put_queue(s, ch & 0xff);
751
752 ch = -dy;
753
754 if (ch > 127)
755 ch=127;
756 else if (ch < -127)
757 ch=-127;
758
759 put_queue(s, ch & 0xff);
760
761 // MSC protocol specify two extra motion bytes
762
763 put_queue(s, 0);
764 put_queue(s, 0);
765 }
766
767 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq)
768 {
769 int slavio_serial_io_memory, i;
770 SerialState *s;
771
772 s = qemu_mallocz(sizeof(SerialState));
773 if (!s)
774 return;
775 for (i = 0; i < 2; i++) {
776 s->chn[i].irq = irq;
777 s->chn[i].chn = 1 - i;
778 s->chn[i].chr = NULL;
779 }
780 s->chn[0].otherchn = &s->chn[1];
781 s->chn[1].otherchn = &s->chn[0];
782 s->chn[0].type = mouse;
783 s->chn[1].type = kbd;
784
785 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
786 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
787
788 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0, "QEMU Sun Mouse");
789 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
790 register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save, slavio_serial_load, s);
791 qemu_register_reset(slavio_serial_reset, s);
792 slavio_serial_reset(s);
793 }