mips jz glue function
[qemu/qemu-JZ.git] / hw / slavio_serial.c
blob1028ed944c71508d7c1130daeeac8dbba2563e28
1 /*
2 * QEMU Sparc SLAVIO serial port emulation
4 * Copyright (c) 2003-2005 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
24 #include "hw.h"
25 #include "sun4m.h"
26 #include "qemu-char.h"
27 #include "console.h"
29 /* debug serial */
30 //#define DEBUG_SERIAL
32 /* debug keyboard */
33 //#define DEBUG_KBD
35 /* debug mouse */
36 //#define DEBUG_MOUSE
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
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.
50 * Modifications:
51 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
52 * serial mouse queue.
53 * Implemented serial mouse protocol.
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
75 typedef enum {
76 chn_a, chn_b,
77 } chn_id_t;
79 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
81 typedef enum {
82 ser, kbd, mouse,
83 } chn_type_t;
85 #define SERIO_QUEUE_SIZE 256
87 typedef struct {
88 uint8_t data[SERIO_QUEUE_SIZE];
89 int rptr, wptr, count;
90 } SERIOQueue;
92 #define SERIAL_REGS 16
93 typedef struct ChannelState {
94 qemu_irq irq;
95 uint32_t reg;
96 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
97 chn_id_t chn; // this channel, A (base+4) or B (base+0)
98 chn_type_t type;
99 struct ChannelState *otherchn;
100 uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
101 SERIOQueue queue;
102 CharDriverState *chr;
103 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
104 int disabled;
105 } ChannelState;
107 struct SerialState {
108 struct ChannelState chn[2];
111 #define SERIAL_SIZE 8
112 #define SERIAL_CTRL 0
113 #define SERIAL_DATA 1
115 #define W_CMD 0
116 #define CMD_PTR_MASK 0x07
117 #define CMD_CMD_MASK 0x38
118 #define CMD_HI 0x08
119 #define CMD_CLR_TXINT 0x28
120 #define CMD_CLR_IUS 0x38
121 #define W_INTR 1
122 #define INTR_INTALL 0x01
123 #define INTR_TXINT 0x02
124 #define INTR_RXMODEMSK 0x18
125 #define INTR_RXINT1ST 0x08
126 #define INTR_RXINTALL 0x10
127 #define W_IVEC 2
128 #define W_RXCTRL 3
129 #define RXCTRL_RXEN 0x01
130 #define W_TXCTRL1 4
131 #define TXCTRL1_PAREN 0x01
132 #define TXCTRL1_PAREV 0x02
133 #define TXCTRL1_1STOP 0x04
134 #define TXCTRL1_1HSTOP 0x08
135 #define TXCTRL1_2STOP 0x0c
136 #define TXCTRL1_STPMSK 0x0c
137 #define TXCTRL1_CLK1X 0x00
138 #define TXCTRL1_CLK16X 0x40
139 #define TXCTRL1_CLK32X 0x80
140 #define TXCTRL1_CLK64X 0xc0
141 #define TXCTRL1_CLKMSK 0xc0
142 #define W_TXCTRL2 5
143 #define TXCTRL2_TXEN 0x08
144 #define TXCTRL2_BITMSK 0x60
145 #define TXCTRL2_5BITS 0x00
146 #define TXCTRL2_7BITS 0x20
147 #define TXCTRL2_6BITS 0x40
148 #define TXCTRL2_8BITS 0x60
149 #define W_SYNC1 6
150 #define W_SYNC2 7
151 #define W_TXBUF 8
152 #define W_MINTR 9
153 #define MINTR_STATUSHI 0x10
154 #define MINTR_RST_MASK 0xc0
155 #define MINTR_RST_B 0x40
156 #define MINTR_RST_A 0x80
157 #define MINTR_RST_ALL 0xc0
158 #define W_MISC1 10
159 #define W_CLOCK 11
160 #define CLOCK_TRXC 0x08
161 #define W_BRGLO 12
162 #define W_BRGHI 13
163 #define W_MISC2 14
164 #define MISC2_PLLDIS 0x30
165 #define W_EXTINT 15
166 #define EXTINT_DCD 0x08
167 #define EXTINT_SYNCINT 0x10
168 #define EXTINT_CTSINT 0x20
169 #define EXTINT_TXUNDRN 0x40
170 #define EXTINT_BRKINT 0x80
172 #define R_STATUS 0
173 #define STATUS_RXAV 0x01
174 #define STATUS_ZERO 0x02
175 #define STATUS_TXEMPTY 0x04
176 #define STATUS_DCD 0x08
177 #define STATUS_SYNC 0x10
178 #define STATUS_CTS 0x20
179 #define STATUS_TXUNDRN 0x40
180 #define STATUS_BRK 0x80
181 #define R_SPEC 1
182 #define SPEC_ALLSENT 0x01
183 #define SPEC_BITS8 0x06
184 #define R_IVEC 2
185 #define IVEC_TXINTB 0x00
186 #define IVEC_LONOINT 0x06
187 #define IVEC_LORXINTA 0x0c
188 #define IVEC_LORXINTB 0x04
189 #define IVEC_LOTXINTA 0x08
190 #define IVEC_HINOINT 0x60
191 #define IVEC_HIRXINTA 0x30
192 #define IVEC_HIRXINTB 0x20
193 #define IVEC_HITXINTA 0x10
194 #define R_INTR 3
195 #define INTR_EXTINTB 0x01
196 #define INTR_TXINTB 0x02
197 #define INTR_RXINTB 0x04
198 #define INTR_EXTINTA 0x08
199 #define INTR_TXINTA 0x10
200 #define INTR_RXINTA 0x20
201 #define R_IPEN 4
202 #define R_TXCTRL1 5
203 #define R_TXCTRL2 6
204 #define R_BC 7
205 #define R_RXBUF 8
206 #define R_RXCTRL 9
207 #define R_MISC 10
208 #define R_MISC1 11
209 #define R_BRGLO 12
210 #define R_BRGHI 13
211 #define R_MISC1I 14
212 #define R_EXTINT 15
214 static void handle_kbd_command(ChannelState *s, int val);
215 static int serial_can_receive(void *opaque);
216 static void serial_receive_byte(ChannelState *s, int ch);
218 static void clear_queue(void *opaque)
220 ChannelState *s = opaque;
221 SERIOQueue *q = &s->queue;
222 q->rptr = q->wptr = q->count = 0;
225 static void put_queue(void *opaque, int b)
227 ChannelState *s = opaque;
228 SERIOQueue *q = &s->queue;
230 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
231 if (q->count >= SERIO_QUEUE_SIZE)
232 return;
233 q->data[q->wptr] = b;
234 if (++q->wptr == SERIO_QUEUE_SIZE)
235 q->wptr = 0;
236 q->count++;
237 serial_receive_byte(s, 0);
240 static uint32_t get_queue(void *opaque)
242 ChannelState *s = opaque;
243 SERIOQueue *q = &s->queue;
244 int val;
246 if (q->count == 0) {
247 return 0;
248 } else {
249 val = q->data[q->rptr];
250 if (++q->rptr == SERIO_QUEUE_SIZE)
251 q->rptr = 0;
252 q->count--;
254 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
255 if (q->count > 0)
256 serial_receive_byte(s, 0);
257 return val;
260 static int slavio_serial_update_irq_chn(ChannelState *s)
262 if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
263 // tx ints enabled, pending
264 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
265 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
266 s->rxint == 1) || // rx ints enabled, pending
267 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
268 (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
269 return 1;
271 return 0;
274 static void slavio_serial_update_irq(ChannelState *s)
276 int irq;
278 irq = slavio_serial_update_irq_chn(s);
279 irq |= slavio_serial_update_irq_chn(s->otherchn);
281 SER_DPRINTF("IRQ = %d\n", irq);
282 qemu_set_irq(s->irq, irq);
285 static void slavio_serial_reset_chn(ChannelState *s)
287 int i;
289 s->reg = 0;
290 for (i = 0; i < SERIAL_SIZE; i++) {
291 s->rregs[i] = 0;
292 s->wregs[i] = 0;
294 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
295 s->wregs[W_MINTR] = MINTR_RST_ALL;
296 s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
297 s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
298 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
299 EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
300 if (s->disabled)
301 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
302 STATUS_CTS | STATUS_TXUNDRN;
303 else
304 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
305 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
307 s->rx = s->tx = 0;
308 s->rxint = s->txint = 0;
309 s->rxint_under_svc = s->txint_under_svc = 0;
310 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
311 clear_queue(s);
314 static void slavio_serial_reset(void *opaque)
316 SerialState *s = opaque;
317 slavio_serial_reset_chn(&s->chn[0]);
318 slavio_serial_reset_chn(&s->chn[1]);
321 static inline void set_rxint(ChannelState *s)
323 s->rxint = 1;
324 if (!s->txint_under_svc) {
325 s->rxint_under_svc = 1;
326 if (s->chn == chn_a) {
327 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
328 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
329 else
330 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
331 } else {
332 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
333 s->rregs[R_IVEC] = IVEC_HIRXINTB;
334 else
335 s->rregs[R_IVEC] = IVEC_LORXINTB;
338 if (s->chn == chn_a)
339 s->rregs[R_INTR] |= INTR_RXINTA;
340 else
341 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
342 slavio_serial_update_irq(s);
345 static inline void set_txint(ChannelState *s)
347 s->txint = 1;
348 if (!s->rxint_under_svc) {
349 s->txint_under_svc = 1;
350 if (s->chn == chn_a) {
351 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
352 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
353 else
354 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
355 } else {
356 s->rregs[R_IVEC] = IVEC_TXINTB;
359 if (s->chn == chn_a)
360 s->rregs[R_INTR] |= INTR_TXINTA;
361 else
362 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
363 slavio_serial_update_irq(s);
366 static inline void clr_rxint(ChannelState *s)
368 s->rxint = 0;
369 s->rxint_under_svc = 0;
370 if (s->chn == chn_a) {
371 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
372 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
373 else
374 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
375 s->rregs[R_INTR] &= ~INTR_RXINTA;
376 } else {
377 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
378 s->rregs[R_IVEC] = IVEC_HINOINT;
379 else
380 s->rregs[R_IVEC] = IVEC_LONOINT;
381 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
383 if (s->txint)
384 set_txint(s);
385 slavio_serial_update_irq(s);
388 static inline void clr_txint(ChannelState *s)
390 s->txint = 0;
391 s->txint_under_svc = 0;
392 if (s->chn == chn_a) {
393 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
394 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
395 else
396 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
397 s->rregs[R_INTR] &= ~INTR_TXINTA;
398 } else {
399 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
400 s->rregs[R_IVEC] = IVEC_HINOINT;
401 else
402 s->rregs[R_IVEC] = IVEC_LONOINT;
403 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
405 if (s->rxint)
406 set_rxint(s);
407 slavio_serial_update_irq(s);
410 static void slavio_serial_update_parameters(ChannelState *s)
412 int speed, parity, data_bits, stop_bits;
413 QEMUSerialSetParams ssp;
415 if (!s->chr || s->type != ser)
416 return;
418 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
419 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
420 parity = 'E';
421 else
422 parity = 'O';
423 } else {
424 parity = 'N';
426 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
427 stop_bits = 2;
428 else
429 stop_bits = 1;
430 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
431 case TXCTRL2_5BITS:
432 data_bits = 5;
433 break;
434 case TXCTRL2_7BITS:
435 data_bits = 7;
436 break;
437 case TXCTRL2_6BITS:
438 data_bits = 6;
439 break;
440 default:
441 case TXCTRL2_8BITS:
442 data_bits = 8;
443 break;
445 speed = 2457600 / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
446 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
447 case TXCTRL1_CLK1X:
448 break;
449 case TXCTRL1_CLK16X:
450 speed /= 16;
451 break;
452 case TXCTRL1_CLK32X:
453 speed /= 32;
454 break;
455 default:
456 case TXCTRL1_CLK64X:
457 speed /= 64;
458 break;
460 ssp.speed = speed;
461 ssp.parity = parity;
462 ssp.data_bits = data_bits;
463 ssp.stop_bits = stop_bits;
464 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
465 speed, parity, data_bits, stop_bits);
466 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
469 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
470 uint32_t val)
472 SerialState *serial = opaque;
473 ChannelState *s;
474 uint32_t saddr;
475 int newreg, channel;
477 val &= 0xff;
478 saddr = (addr & 3) >> 1;
479 channel = addr >> 2;
480 s = &serial->chn[channel];
481 switch (saddr) {
482 case SERIAL_CTRL:
483 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
484 val & 0xff);
485 newreg = 0;
486 switch (s->reg) {
487 case W_CMD:
488 newreg = val & CMD_PTR_MASK;
489 val &= CMD_CMD_MASK;
490 switch (val) {
491 case CMD_HI:
492 newreg |= CMD_HI;
493 break;
494 case CMD_CLR_TXINT:
495 clr_txint(s);
496 break;
497 case CMD_CLR_IUS:
498 if (s->rxint_under_svc)
499 clr_rxint(s);
500 else if (s->txint_under_svc)
501 clr_txint(s);
502 break;
503 default:
504 break;
506 break;
507 case W_INTR ... W_RXCTRL:
508 case W_SYNC1 ... W_TXBUF:
509 case W_MISC1 ... W_CLOCK:
510 case W_MISC2 ... W_EXTINT:
511 s->wregs[s->reg] = val;
512 break;
513 case W_TXCTRL1:
514 case W_TXCTRL2:
515 s->wregs[s->reg] = val;
516 slavio_serial_update_parameters(s);
517 break;
518 case W_BRGLO:
519 case W_BRGHI:
520 s->wregs[s->reg] = val;
521 s->rregs[s->reg] = val;
522 slavio_serial_update_parameters(s);
523 break;
524 case W_MINTR:
525 switch (val & MINTR_RST_MASK) {
526 case 0:
527 default:
528 break;
529 case MINTR_RST_B:
530 slavio_serial_reset_chn(&serial->chn[0]);
531 return;
532 case MINTR_RST_A:
533 slavio_serial_reset_chn(&serial->chn[1]);
534 return;
535 case MINTR_RST_ALL:
536 slavio_serial_reset(serial);
537 return;
539 break;
540 default:
541 break;
543 if (s->reg == 0)
544 s->reg = newreg;
545 else
546 s->reg = 0;
547 break;
548 case SERIAL_DATA:
549 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
550 s->tx = val;
551 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
552 if (s->chr)
553 qemu_chr_write(s->chr, &s->tx, 1);
554 else if (s->type == kbd && !s->disabled) {
555 handle_kbd_command(s, val);
558 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
559 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
560 set_txint(s);
561 break;
562 default:
563 break;
567 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
569 SerialState *serial = opaque;
570 ChannelState *s;
571 uint32_t saddr;
572 uint32_t ret;
573 int channel;
575 saddr = (addr & 3) >> 1;
576 channel = addr >> 2;
577 s = &serial->chn[channel];
578 switch (saddr) {
579 case SERIAL_CTRL:
580 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
581 s->rregs[s->reg]);
582 ret = s->rregs[s->reg];
583 s->reg = 0;
584 return ret;
585 case SERIAL_DATA:
586 s->rregs[R_STATUS] &= ~STATUS_RXAV;
587 clr_rxint(s);
588 if (s->type == kbd || s->type == mouse)
589 ret = get_queue(s);
590 else
591 ret = s->rx;
592 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
593 if (s->chr)
594 qemu_chr_accept_input(s->chr);
595 return ret;
596 default:
597 break;
599 return 0;
602 static int serial_can_receive(void *opaque)
604 ChannelState *s = opaque;
605 int ret;
607 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
608 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
609 // char already available
610 ret = 0;
611 else
612 ret = 1;
613 return ret;
616 static void serial_receive_byte(ChannelState *s, int ch)
618 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
619 s->rregs[R_STATUS] |= STATUS_RXAV;
620 s->rx = ch;
621 set_rxint(s);
624 static void serial_receive_break(ChannelState *s)
626 s->rregs[R_STATUS] |= STATUS_BRK;
627 slavio_serial_update_irq(s);
630 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
632 ChannelState *s = opaque;
633 serial_receive_byte(s, buf[0]);
636 static void serial_event(void *opaque, int event)
638 ChannelState *s = opaque;
639 if (event == CHR_EVENT_BREAK)
640 serial_receive_break(s);
643 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
644 slavio_serial_mem_readb,
645 NULL,
646 NULL,
649 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
650 slavio_serial_mem_writeb,
651 NULL,
652 NULL,
655 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
657 uint32_t tmp = 0;
659 qemu_put_be32s(f, &tmp); /* unused, was IRQ. */
660 qemu_put_be32s(f, &s->reg);
661 qemu_put_be32s(f, &s->rxint);
662 qemu_put_be32s(f, &s->txint);
663 qemu_put_be32s(f, &s->rxint_under_svc);
664 qemu_put_be32s(f, &s->txint_under_svc);
665 qemu_put_8s(f, &s->rx);
666 qemu_put_8s(f, &s->tx);
667 qemu_put_buffer(f, s->wregs, SERIAL_REGS);
668 qemu_put_buffer(f, s->rregs, SERIAL_REGS);
671 static void slavio_serial_save(QEMUFile *f, void *opaque)
673 SerialState *s = opaque;
675 slavio_serial_save_chn(f, &s->chn[0]);
676 slavio_serial_save_chn(f, &s->chn[1]);
679 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
681 uint32_t tmp;
683 if (version_id > 2)
684 return -EINVAL;
686 qemu_get_be32s(f, &tmp); /* unused */
687 qemu_get_be32s(f, &s->reg);
688 qemu_get_be32s(f, &s->rxint);
689 qemu_get_be32s(f, &s->txint);
690 if (version_id >= 2) {
691 qemu_get_be32s(f, &s->rxint_under_svc);
692 qemu_get_be32s(f, &s->txint_under_svc);
694 qemu_get_8s(f, &s->rx);
695 qemu_get_8s(f, &s->tx);
696 qemu_get_buffer(f, s->wregs, SERIAL_REGS);
697 qemu_get_buffer(f, s->rregs, SERIAL_REGS);
698 return 0;
701 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
703 SerialState *s = opaque;
704 int ret;
706 ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
707 if (ret != 0)
708 return ret;
709 ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
710 return ret;
714 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
715 CharDriverState *chr1, CharDriverState *chr2)
717 int slavio_serial_io_memory, i;
718 SerialState *s;
720 s = qemu_mallocz(sizeof(SerialState));
721 if (!s)
722 return NULL;
724 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
725 slavio_serial_mem_write,
727 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
729 s->chn[0].chr = chr1;
730 s->chn[1].chr = chr2;
731 s->chn[0].disabled = 0;
732 s->chn[1].disabled = 0;
734 for (i = 0; i < 2; i++) {
735 s->chn[i].irq = irq;
736 s->chn[i].chn = 1 - i;
737 s->chn[i].type = ser;
738 if (s->chn[i].chr) {
739 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
740 serial_receive1, serial_event, &s->chn[i]);
743 s->chn[0].otherchn = &s->chn[1];
744 s->chn[1].otherchn = &s->chn[0];
745 register_savevm("slavio_serial", base, 2, slavio_serial_save,
746 slavio_serial_load, s);
747 qemu_register_reset(slavio_serial_reset, s);
748 slavio_serial_reset(s);
749 return s;
752 static const uint8_t keycodes[128] = {
753 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
754 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
755 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
756 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
757 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
758 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
759 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
760 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
763 static const uint8_t e0_keycodes[128] = {
764 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
765 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
766 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
767 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
768 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
769 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
771 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
774 static void sunkbd_event(void *opaque, int ch)
776 ChannelState *s = opaque;
777 int release = ch & 0x80;
779 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
780 "press");
781 switch (ch) {
782 case 58: // Caps lock press
783 s->caps_lock_mode ^= 1;
784 if (s->caps_lock_mode == 2)
785 return; // Drop second press
786 break;
787 case 69: // Num lock press
788 s->num_lock_mode ^= 1;
789 if (s->num_lock_mode == 2)
790 return; // Drop second press
791 break;
792 case 186: // Caps lock release
793 s->caps_lock_mode ^= 2;
794 if (s->caps_lock_mode == 3)
795 return; // Drop first release
796 break;
797 case 197: // Num lock release
798 s->num_lock_mode ^= 2;
799 if (s->num_lock_mode == 3)
800 return; // Drop first release
801 break;
802 case 0xe0:
803 s->e0_mode = 1;
804 return;
805 default:
806 break;
808 if (s->e0_mode) {
809 s->e0_mode = 0;
810 ch = e0_keycodes[ch & 0x7f];
811 } else {
812 ch = keycodes[ch & 0x7f];
814 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
815 put_queue(s, ch | release);
818 static void handle_kbd_command(ChannelState *s, int val)
820 KBD_DPRINTF("Command %d\n", val);
821 if (s->led_mode) { // Ignore led byte
822 s->led_mode = 0;
823 return;
825 switch (val) {
826 case 1: // Reset, return type code
827 clear_queue(s);
828 put_queue(s, 0xff);
829 put_queue(s, 4); // Type 4
830 put_queue(s, 0x7f);
831 break;
832 case 0xe: // Set leds
833 s->led_mode = 1;
834 break;
835 case 7: // Query layout
836 case 0xf:
837 clear_queue(s);
838 put_queue(s, 0xfe);
839 put_queue(s, 0); // XXX, layout?
840 break;
841 default:
842 break;
846 static void sunmouse_event(void *opaque,
847 int dx, int dy, int dz, int buttons_state)
849 ChannelState *s = opaque;
850 int ch;
852 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
854 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
856 if (buttons_state & MOUSE_EVENT_LBUTTON)
857 ch ^= 0x4;
858 if (buttons_state & MOUSE_EVENT_MBUTTON)
859 ch ^= 0x2;
860 if (buttons_state & MOUSE_EVENT_RBUTTON)
861 ch ^= 0x1;
863 put_queue(s, ch);
865 ch = dx;
867 if (ch > 127)
868 ch=127;
869 else if (ch < -127)
870 ch=-127;
872 put_queue(s, ch & 0xff);
874 ch = -dy;
876 if (ch > 127)
877 ch=127;
878 else if (ch < -127)
879 ch=-127;
881 put_queue(s, ch & 0xff);
883 // MSC protocol specify two extra motion bytes
885 put_queue(s, 0);
886 put_queue(s, 0);
889 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
890 int disabled)
892 int slavio_serial_io_memory, i;
893 SerialState *s;
895 s = qemu_mallocz(sizeof(SerialState));
896 if (!s)
897 return;
898 for (i = 0; i < 2; i++) {
899 s->chn[i].irq = irq;
900 s->chn[i].chn = 1 - i;
901 s->chn[i].chr = NULL;
903 s->chn[0].otherchn = &s->chn[1];
904 s->chn[1].otherchn = &s->chn[0];
905 s->chn[0].type = mouse;
906 s->chn[1].type = kbd;
907 s->chn[0].disabled = disabled;
908 s->chn[1].disabled = disabled;
910 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
911 slavio_serial_mem_write,
913 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
915 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
916 "QEMU Sun Mouse");
917 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
918 register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save,
919 slavio_serial_load, s);
920 qemu_register_reset(slavio_serial_reset, s);
921 slavio_serial_reset(s);