Fix tswap size
[qemu/mini2440.git] / hw / slavio_serial.c
blob9f5843af687d6d002d18c8c6b08327240f124b27
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_MAXADDR 7
112 #define SERIAL_SIZE (SERIAL_MAXADDR + 1)
113 #define SERIAL_CTRL 0
114 #define SERIAL_DATA 1
116 #define W_CMD 0
117 #define CMD_PTR_MASK 0x07
118 #define CMD_CMD_MASK 0x38
119 #define CMD_HI 0x08
120 #define CMD_CLR_TXINT 0x28
121 #define CMD_CLR_IUS 0x38
122 #define W_INTR 1
123 #define INTR_INTALL 0x01
124 #define INTR_TXINT 0x02
125 #define INTR_RXMODEMSK 0x18
126 #define INTR_RXINT1ST 0x08
127 #define INTR_RXINTALL 0x10
128 #define W_IVEC 2
129 #define W_RXCTRL 3
130 #define RXCTRL_RXEN 0x01
131 #define W_TXCTRL1 4
132 #define TXCTRL1_PAREN 0x01
133 #define TXCTRL1_PAREV 0x02
134 #define TXCTRL1_1STOP 0x04
135 #define TXCTRL1_1HSTOP 0x08
136 #define TXCTRL1_2STOP 0x0c
137 #define TXCTRL1_STPMSK 0x0c
138 #define TXCTRL1_CLK1X 0x00
139 #define TXCTRL1_CLK16X 0x40
140 #define TXCTRL1_CLK32X 0x80
141 #define TXCTRL1_CLK64X 0xc0
142 #define TXCTRL1_CLKMSK 0xc0
143 #define W_TXCTRL2 5
144 #define TXCTRL2_TXEN 0x08
145 #define TXCTRL2_BITMSK 0x60
146 #define TXCTRL2_5BITS 0x00
147 #define TXCTRL2_7BITS 0x20
148 #define TXCTRL2_6BITS 0x40
149 #define TXCTRL2_8BITS 0x60
150 #define W_SYNC1 6
151 #define W_SYNC2 7
152 #define W_TXBUF 8
153 #define W_MINTR 9
154 #define MINTR_STATUSHI 0x10
155 #define MINTR_RST_MASK 0xc0
156 #define MINTR_RST_B 0x40
157 #define MINTR_RST_A 0x80
158 #define MINTR_RST_ALL 0xc0
159 #define W_MISC1 10
160 #define W_CLOCK 11
161 #define CLOCK_TRXC 0x08
162 #define W_BRGLO 12
163 #define W_BRGHI 13
164 #define W_MISC2 14
165 #define MISC2_PLLDIS 0x30
166 #define W_EXTINT 15
167 #define EXTINT_DCD 0x08
168 #define EXTINT_SYNCINT 0x10
169 #define EXTINT_CTSINT 0x20
170 #define EXTINT_TXUNDRN 0x40
171 #define EXTINT_BRKINT 0x80
173 #define R_STATUS 0
174 #define STATUS_RXAV 0x01
175 #define STATUS_ZERO 0x02
176 #define STATUS_TXEMPTY 0x04
177 #define STATUS_DCD 0x08
178 #define STATUS_SYNC 0x10
179 #define STATUS_CTS 0x20
180 #define STATUS_TXUNDRN 0x40
181 #define STATUS_BRK 0x80
182 #define R_SPEC 1
183 #define SPEC_ALLSENT 0x01
184 #define SPEC_BITS8 0x06
185 #define R_IVEC 2
186 #define IVEC_TXINTB 0x00
187 #define IVEC_LONOINT 0x06
188 #define IVEC_LORXINTA 0x0c
189 #define IVEC_LORXINTB 0x04
190 #define IVEC_LOTXINTA 0x08
191 #define IVEC_HINOINT 0x60
192 #define IVEC_HIRXINTA 0x30
193 #define IVEC_HIRXINTB 0x20
194 #define IVEC_HITXINTA 0x10
195 #define R_INTR 3
196 #define INTR_EXTINTB 0x01
197 #define INTR_TXINTB 0x02
198 #define INTR_RXINTB 0x04
199 #define INTR_EXTINTA 0x08
200 #define INTR_TXINTA 0x10
201 #define INTR_RXINTA 0x20
202 #define R_IPEN 4
203 #define R_TXCTRL1 5
204 #define R_TXCTRL2 6
205 #define R_BC 7
206 #define R_RXBUF 8
207 #define R_RXCTRL 9
208 #define R_MISC 10
209 #define R_MISC1 11
210 #define R_BRGLO 12
211 #define R_BRGHI 13
212 #define R_MISC1I 14
213 #define R_EXTINT 15
215 static void handle_kbd_command(ChannelState *s, int val);
216 static int serial_can_receive(void *opaque);
217 static void serial_receive_byte(ChannelState *s, int ch);
219 static void clear_queue(void *opaque)
221 ChannelState *s = opaque;
222 SERIOQueue *q = &s->queue;
223 q->rptr = q->wptr = q->count = 0;
226 static void put_queue(void *opaque, int b)
228 ChannelState *s = opaque;
229 SERIOQueue *q = &s->queue;
231 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
232 if (q->count >= SERIO_QUEUE_SIZE)
233 return;
234 q->data[q->wptr] = b;
235 if (++q->wptr == SERIO_QUEUE_SIZE)
236 q->wptr = 0;
237 q->count++;
238 serial_receive_byte(s, 0);
241 static uint32_t get_queue(void *opaque)
243 ChannelState *s = opaque;
244 SERIOQueue *q = &s->queue;
245 int val;
247 if (q->count == 0) {
248 return 0;
249 } else {
250 val = q->data[q->rptr];
251 if (++q->rptr == SERIO_QUEUE_SIZE)
252 q->rptr = 0;
253 q->count--;
255 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
256 if (q->count > 0)
257 serial_receive_byte(s, 0);
258 return val;
261 static int slavio_serial_update_irq_chn(ChannelState *s)
263 if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
264 // tx ints enabled, pending
265 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
266 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
267 s->rxint == 1) || // rx ints enabled, pending
268 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
269 (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
270 return 1;
272 return 0;
275 static void slavio_serial_update_irq(ChannelState *s)
277 int irq;
279 irq = slavio_serial_update_irq_chn(s);
280 irq |= slavio_serial_update_irq_chn(s->otherchn);
282 SER_DPRINTF("IRQ = %d\n", irq);
283 qemu_set_irq(s->irq, irq);
286 static void slavio_serial_reset_chn(ChannelState *s)
288 int i;
290 s->reg = 0;
291 for (i = 0; i < SERIAL_SIZE; i++) {
292 s->rregs[i] = 0;
293 s->wregs[i] = 0;
295 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
296 s->wregs[W_MINTR] = MINTR_RST_ALL;
297 s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
298 s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
299 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
300 EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
301 if (s->disabled)
302 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
303 STATUS_CTS | STATUS_TXUNDRN;
304 else
305 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
306 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
308 s->rx = s->tx = 0;
309 s->rxint = s->txint = 0;
310 s->rxint_under_svc = s->txint_under_svc = 0;
311 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
312 clear_queue(s);
315 static void slavio_serial_reset(void *opaque)
317 SerialState *s = opaque;
318 slavio_serial_reset_chn(&s->chn[0]);
319 slavio_serial_reset_chn(&s->chn[1]);
322 static inline void set_rxint(ChannelState *s)
324 s->rxint = 1;
325 if (!s->txint_under_svc) {
326 s->rxint_under_svc = 1;
327 if (s->chn == chn_a) {
328 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
329 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
330 else
331 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
332 } else {
333 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
334 s->rregs[R_IVEC] = IVEC_HIRXINTB;
335 else
336 s->rregs[R_IVEC] = IVEC_LORXINTB;
339 if (s->chn == chn_a)
340 s->rregs[R_INTR] |= INTR_RXINTA;
341 else
342 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
343 slavio_serial_update_irq(s);
346 static inline void set_txint(ChannelState *s)
348 s->txint = 1;
349 if (!s->rxint_under_svc) {
350 s->txint_under_svc = 1;
351 if (s->chn == chn_a) {
352 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
353 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
354 else
355 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
356 } else {
357 s->rregs[R_IVEC] = IVEC_TXINTB;
360 if (s->chn == chn_a)
361 s->rregs[R_INTR] |= INTR_TXINTA;
362 else
363 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
364 slavio_serial_update_irq(s);
367 static inline void clr_rxint(ChannelState *s)
369 s->rxint = 0;
370 s->rxint_under_svc = 0;
371 if (s->chn == chn_a) {
372 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
373 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
374 else
375 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
376 s->rregs[R_INTR] &= ~INTR_RXINTA;
377 } else {
378 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
379 s->rregs[R_IVEC] = IVEC_HINOINT;
380 else
381 s->rregs[R_IVEC] = IVEC_LONOINT;
382 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
384 if (s->txint)
385 set_txint(s);
386 slavio_serial_update_irq(s);
389 static inline void clr_txint(ChannelState *s)
391 s->txint = 0;
392 s->txint_under_svc = 0;
393 if (s->chn == chn_a) {
394 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
395 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
396 else
397 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
398 s->rregs[R_INTR] &= ~INTR_TXINTA;
399 } else {
400 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
401 s->rregs[R_IVEC] = IVEC_HINOINT;
402 else
403 s->rregs[R_IVEC] = IVEC_LONOINT;
404 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
406 if (s->rxint)
407 set_rxint(s);
408 slavio_serial_update_irq(s);
411 static void slavio_serial_update_parameters(ChannelState *s)
413 int speed, parity, data_bits, stop_bits;
414 QEMUSerialSetParams ssp;
416 if (!s->chr || s->type != ser)
417 return;
419 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
420 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
421 parity = 'E';
422 else
423 parity = 'O';
424 } else {
425 parity = 'N';
427 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
428 stop_bits = 2;
429 else
430 stop_bits = 1;
431 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
432 case TXCTRL2_5BITS:
433 data_bits = 5;
434 break;
435 case TXCTRL2_7BITS:
436 data_bits = 7;
437 break;
438 case TXCTRL2_6BITS:
439 data_bits = 6;
440 break;
441 default:
442 case TXCTRL2_8BITS:
443 data_bits = 8;
444 break;
446 speed = 2457600 / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
447 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
448 case TXCTRL1_CLK1X:
449 break;
450 case TXCTRL1_CLK16X:
451 speed /= 16;
452 break;
453 case TXCTRL1_CLK32X:
454 speed /= 32;
455 break;
456 default:
457 case TXCTRL1_CLK64X:
458 speed /= 64;
459 break;
461 ssp.speed = speed;
462 ssp.parity = parity;
463 ssp.data_bits = data_bits;
464 ssp.stop_bits = stop_bits;
465 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
466 speed, parity, data_bits, stop_bits);
467 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
470 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
471 uint32_t val)
473 SerialState *serial = opaque;
474 ChannelState *s;
475 uint32_t saddr;
476 int newreg, channel;
478 val &= 0xff;
479 saddr = (addr & 3) >> 1;
480 channel = (addr & SERIAL_MAXADDR) >> 2;
481 s = &serial->chn[channel];
482 switch (saddr) {
483 case SERIAL_CTRL:
484 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
485 val & 0xff);
486 newreg = 0;
487 switch (s->reg) {
488 case W_CMD:
489 newreg = val & CMD_PTR_MASK;
490 val &= CMD_CMD_MASK;
491 switch (val) {
492 case CMD_HI:
493 newreg |= CMD_HI;
494 break;
495 case CMD_CLR_TXINT:
496 clr_txint(s);
497 break;
498 case CMD_CLR_IUS:
499 if (s->rxint_under_svc)
500 clr_rxint(s);
501 else if (s->txint_under_svc)
502 clr_txint(s);
503 break;
504 default:
505 break;
507 break;
508 case W_INTR ... W_RXCTRL:
509 case W_SYNC1 ... W_TXBUF:
510 case W_MISC1 ... W_CLOCK:
511 case W_MISC2 ... W_EXTINT:
512 s->wregs[s->reg] = val;
513 break;
514 case W_TXCTRL1:
515 case W_TXCTRL2:
516 s->wregs[s->reg] = val;
517 slavio_serial_update_parameters(s);
518 break;
519 case W_BRGLO:
520 case W_BRGHI:
521 s->wregs[s->reg] = val;
522 s->rregs[s->reg] = val;
523 slavio_serial_update_parameters(s);
524 break;
525 case W_MINTR:
526 switch (val & MINTR_RST_MASK) {
527 case 0:
528 default:
529 break;
530 case MINTR_RST_B:
531 slavio_serial_reset_chn(&serial->chn[0]);
532 return;
533 case MINTR_RST_A:
534 slavio_serial_reset_chn(&serial->chn[1]);
535 return;
536 case MINTR_RST_ALL:
537 slavio_serial_reset(serial);
538 return;
540 break;
541 default:
542 break;
544 if (s->reg == 0)
545 s->reg = newreg;
546 else
547 s->reg = 0;
548 break;
549 case SERIAL_DATA:
550 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
551 s->tx = val;
552 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
553 if (s->chr)
554 qemu_chr_write(s->chr, &s->tx, 1);
555 else if (s->type == kbd && !s->disabled) {
556 handle_kbd_command(s, val);
559 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
560 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
561 set_txint(s);
562 break;
563 default:
564 break;
568 static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
570 SerialState *serial = opaque;
571 ChannelState *s;
572 uint32_t saddr;
573 uint32_t ret;
574 int channel;
576 saddr = (addr & 3) >> 1;
577 channel = (addr & SERIAL_MAXADDR) >> 2;
578 s = &serial->chn[channel];
579 switch (saddr) {
580 case SERIAL_CTRL:
581 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
582 s->rregs[s->reg]);
583 ret = s->rregs[s->reg];
584 s->reg = 0;
585 return ret;
586 case SERIAL_DATA:
587 s->rregs[R_STATUS] &= ~STATUS_RXAV;
588 clr_rxint(s);
589 if (s->type == kbd || s->type == mouse)
590 ret = get_queue(s);
591 else
592 ret = s->rx;
593 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
594 if (s->chr)
595 qemu_chr_accept_input(s->chr);
596 return ret;
597 default:
598 break;
600 return 0;
603 static int serial_can_receive(void *opaque)
605 ChannelState *s = opaque;
606 int ret;
608 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
609 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
610 // char already available
611 ret = 0;
612 else
613 ret = 1;
614 return ret;
617 static void serial_receive_byte(ChannelState *s, int ch)
619 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
620 s->rregs[R_STATUS] |= STATUS_RXAV;
621 s->rx = ch;
622 set_rxint(s);
625 static void serial_receive_break(ChannelState *s)
627 s->rregs[R_STATUS] |= STATUS_BRK;
628 slavio_serial_update_irq(s);
631 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
633 ChannelState *s = opaque;
634 serial_receive_byte(s, buf[0]);
637 static void serial_event(void *opaque, int event)
639 ChannelState *s = opaque;
640 if (event == CHR_EVENT_BREAK)
641 serial_receive_break(s);
644 static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
645 slavio_serial_mem_readb,
646 NULL,
647 NULL,
650 static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
651 slavio_serial_mem_writeb,
652 NULL,
653 NULL,
656 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
658 uint32_t tmp = 0;
660 qemu_put_be32s(f, &tmp); /* unused, was IRQ. */
661 qemu_put_be32s(f, &s->reg);
662 qemu_put_be32s(f, &s->rxint);
663 qemu_put_be32s(f, &s->txint);
664 qemu_put_be32s(f, &s->rxint_under_svc);
665 qemu_put_be32s(f, &s->txint_under_svc);
666 qemu_put_8s(f, &s->rx);
667 qemu_put_8s(f, &s->tx);
668 qemu_put_buffer(f, s->wregs, SERIAL_REGS);
669 qemu_put_buffer(f, s->rregs, SERIAL_REGS);
672 static void slavio_serial_save(QEMUFile *f, void *opaque)
674 SerialState *s = opaque;
676 slavio_serial_save_chn(f, &s->chn[0]);
677 slavio_serial_save_chn(f, &s->chn[1]);
680 static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
682 uint32_t tmp;
684 if (version_id > 2)
685 return -EINVAL;
687 qemu_get_be32s(f, &tmp); /* unused */
688 qemu_get_be32s(f, &s->reg);
689 qemu_get_be32s(f, &s->rxint);
690 qemu_get_be32s(f, &s->txint);
691 if (version_id >= 2) {
692 qemu_get_be32s(f, &s->rxint_under_svc);
693 qemu_get_be32s(f, &s->txint_under_svc);
695 qemu_get_8s(f, &s->rx);
696 qemu_get_8s(f, &s->tx);
697 qemu_get_buffer(f, s->wregs, SERIAL_REGS);
698 qemu_get_buffer(f, s->rregs, SERIAL_REGS);
699 return 0;
702 static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
704 SerialState *s = opaque;
705 int ret;
707 ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
708 if (ret != 0)
709 return ret;
710 ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
711 return ret;
715 SerialState *slavio_serial_init(target_phys_addr_t base, qemu_irq irq,
716 CharDriverState *chr1, CharDriverState *chr2)
718 int slavio_serial_io_memory, i;
719 SerialState *s;
721 s = qemu_mallocz(sizeof(SerialState));
722 if (!s)
723 return NULL;
725 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
726 slavio_serial_mem_write,
728 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
730 s->chn[0].chr = chr1;
731 s->chn[1].chr = chr2;
732 s->chn[0].disabled = 0;
733 s->chn[1].disabled = 0;
735 for (i = 0; i < 2; i++) {
736 s->chn[i].irq = irq;
737 s->chn[i].chn = 1 - i;
738 s->chn[i].type = ser;
739 if (s->chn[i].chr) {
740 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
741 serial_receive1, serial_event, &s->chn[i]);
744 s->chn[0].otherchn = &s->chn[1];
745 s->chn[1].otherchn = &s->chn[0];
746 register_savevm("slavio_serial", base, 2, slavio_serial_save,
747 slavio_serial_load, s);
748 qemu_register_reset(slavio_serial_reset, s);
749 slavio_serial_reset(s);
750 return s;
753 static const uint8_t keycodes[128] = {
754 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
755 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
756 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
757 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
758 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
759 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
760 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
761 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
764 static const uint8_t e0_keycodes[128] = {
765 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
766 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
767 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
768 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
769 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
770 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
771 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
772 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
775 static void sunkbd_event(void *opaque, int ch)
777 ChannelState *s = opaque;
778 int release = ch & 0x80;
780 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
781 "press");
782 switch (ch) {
783 case 58: // Caps lock press
784 s->caps_lock_mode ^= 1;
785 if (s->caps_lock_mode == 2)
786 return; // Drop second press
787 break;
788 case 69: // Num lock press
789 s->num_lock_mode ^= 1;
790 if (s->num_lock_mode == 2)
791 return; // Drop second press
792 break;
793 case 186: // Caps lock release
794 s->caps_lock_mode ^= 2;
795 if (s->caps_lock_mode == 3)
796 return; // Drop first release
797 break;
798 case 197: // Num lock release
799 s->num_lock_mode ^= 2;
800 if (s->num_lock_mode == 3)
801 return; // Drop first release
802 break;
803 case 0xe0:
804 s->e0_mode = 1;
805 return;
806 default:
807 break;
809 if (s->e0_mode) {
810 s->e0_mode = 0;
811 ch = e0_keycodes[ch & 0x7f];
812 } else {
813 ch = keycodes[ch & 0x7f];
815 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
816 put_queue(s, ch | release);
819 static void handle_kbd_command(ChannelState *s, int val)
821 KBD_DPRINTF("Command %d\n", val);
822 if (s->led_mode) { // Ignore led byte
823 s->led_mode = 0;
824 return;
826 switch (val) {
827 case 1: // Reset, return type code
828 clear_queue(s);
829 put_queue(s, 0xff);
830 put_queue(s, 4); // Type 4
831 put_queue(s, 0x7f);
832 break;
833 case 0xe: // Set leds
834 s->led_mode = 1;
835 break;
836 case 7: // Query layout
837 case 0xf:
838 clear_queue(s);
839 put_queue(s, 0xfe);
840 put_queue(s, 0); // XXX, layout?
841 break;
842 default:
843 break;
847 static void sunmouse_event(void *opaque,
848 int dx, int dy, int dz, int buttons_state)
850 ChannelState *s = opaque;
851 int ch;
853 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
855 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
857 if (buttons_state & MOUSE_EVENT_LBUTTON)
858 ch ^= 0x4;
859 if (buttons_state & MOUSE_EVENT_MBUTTON)
860 ch ^= 0x2;
861 if (buttons_state & MOUSE_EVENT_RBUTTON)
862 ch ^= 0x1;
864 put_queue(s, ch);
866 ch = dx;
868 if (ch > 127)
869 ch=127;
870 else if (ch < -127)
871 ch=-127;
873 put_queue(s, ch & 0xff);
875 ch = -dy;
877 if (ch > 127)
878 ch=127;
879 else if (ch < -127)
880 ch=-127;
882 put_queue(s, ch & 0xff);
884 // MSC protocol specify two extra motion bytes
886 put_queue(s, 0);
887 put_queue(s, 0);
890 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
891 int disabled)
893 int slavio_serial_io_memory, i;
894 SerialState *s;
896 s = qemu_mallocz(sizeof(SerialState));
897 if (!s)
898 return;
899 for (i = 0; i < 2; i++) {
900 s->chn[i].irq = irq;
901 s->chn[i].chn = 1 - i;
902 s->chn[i].chr = NULL;
904 s->chn[0].otherchn = &s->chn[1];
905 s->chn[1].otherchn = &s->chn[0];
906 s->chn[0].type = mouse;
907 s->chn[1].type = kbd;
908 s->chn[0].disabled = disabled;
909 s->chn[1].disabled = disabled;
911 slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
912 slavio_serial_mem_write,
914 cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
916 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
917 "QEMU Sun Mouse");
918 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
919 register_savevm("slavio_serial_mouse", base, 2, slavio_serial_save,
920 slavio_serial_load, s);
921 qemu_register_reset(slavio_serial_reset, s);
922 slavio_serial_reset(s);