kvm: Simplify cpu_synchronize_state()
[qemu/mdroth.git] / hw / escc.c
blobae3b802743f7be31e5b88d9c634a14d9b5b5c3ff
1 /*
2 * QEMU ESCC (Z8030/Z8530/Z85C30/SCC/ESCC) 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.
25 #include "hw.h"
26 #include "sysbus.h"
27 #include "escc.h"
28 #include "qemu-char.h"
29 #include "console.h"
31 /* debug serial */
32 //#define DEBUG_SERIAL
34 /* debug keyboard */
35 //#define DEBUG_KBD
37 /* debug mouse */
38 //#define DEBUG_MOUSE
41 * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001
42 * (Slave I/O), also produced as NCR89C105. See
43 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
45 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
46 * mouse and keyboard ports don't implement all functions and they are
47 * only asynchronous. There is no DMA.
49 * Z85C30 is also used on PowerMacs. There are some small differences
50 * between Sparc version (sunzilog) and PowerMac (pmac):
51 * Offset between control and data registers
52 * There is some kind of lockup bug, but we can ignore it
53 * CTS is inverted
54 * DMA on pmac using DBDMA chip
55 * pmac can do IRDA and faster rates, sunzilog can only do 38400
56 * pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz
60 * Modifications:
61 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
62 * serial mouse queue.
63 * Implemented serial mouse protocol.
66 #ifdef DEBUG_SERIAL
67 #define SER_DPRINTF(fmt, ...) \
68 do { printf("SER: " fmt , ## __VA_ARGS__); } while (0)
69 #else
70 #define SER_DPRINTF(fmt, ...)
71 #endif
72 #ifdef DEBUG_KBD
73 #define KBD_DPRINTF(fmt, ...) \
74 do { printf("KBD: " fmt , ## __VA_ARGS__); } while (0)
75 #else
76 #define KBD_DPRINTF(fmt, ...)
77 #endif
78 #ifdef DEBUG_MOUSE
79 #define MS_DPRINTF(fmt, ...) \
80 do { printf("MSC: " fmt , ## __VA_ARGS__); } while (0)
81 #else
82 #define MS_DPRINTF(fmt, ...)
83 #endif
85 typedef enum {
86 chn_a, chn_b,
87 } chn_id_t;
89 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
91 typedef enum {
92 ser, kbd, mouse,
93 } chn_type_t;
95 #define SERIO_QUEUE_SIZE 256
97 typedef struct {
98 uint8_t data[SERIO_QUEUE_SIZE];
99 int rptr, wptr, count;
100 } SERIOQueue;
102 #define SERIAL_REGS 16
103 typedef struct ChannelState {
104 qemu_irq irq;
105 uint32_t reg;
106 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
107 chn_id_t chn; // this channel, A (base+4) or B (base+0)
108 chn_type_t type;
109 struct ChannelState *otherchn;
110 uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
111 SERIOQueue queue;
112 CharDriverState *chr;
113 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
114 int disabled;
115 int clock;
116 } ChannelState;
118 struct SerialState {
119 SysBusDevice busdev;
120 struct ChannelState chn[2];
121 uint32_t it_shift;
122 int mmio_index;
123 uint32_t disabled;
124 uint32_t frequency;
127 #define SERIAL_CTRL 0
128 #define SERIAL_DATA 1
130 #define W_CMD 0
131 #define CMD_PTR_MASK 0x07
132 #define CMD_CMD_MASK 0x38
133 #define CMD_HI 0x08
134 #define CMD_CLR_TXINT 0x28
135 #define CMD_CLR_IUS 0x38
136 #define W_INTR 1
137 #define INTR_INTALL 0x01
138 #define INTR_TXINT 0x02
139 #define INTR_RXMODEMSK 0x18
140 #define INTR_RXINT1ST 0x08
141 #define INTR_RXINTALL 0x10
142 #define W_IVEC 2
143 #define W_RXCTRL 3
144 #define RXCTRL_RXEN 0x01
145 #define W_TXCTRL1 4
146 #define TXCTRL1_PAREN 0x01
147 #define TXCTRL1_PAREV 0x02
148 #define TXCTRL1_1STOP 0x04
149 #define TXCTRL1_1HSTOP 0x08
150 #define TXCTRL1_2STOP 0x0c
151 #define TXCTRL1_STPMSK 0x0c
152 #define TXCTRL1_CLK1X 0x00
153 #define TXCTRL1_CLK16X 0x40
154 #define TXCTRL1_CLK32X 0x80
155 #define TXCTRL1_CLK64X 0xc0
156 #define TXCTRL1_CLKMSK 0xc0
157 #define W_TXCTRL2 5
158 #define TXCTRL2_TXEN 0x08
159 #define TXCTRL2_BITMSK 0x60
160 #define TXCTRL2_5BITS 0x00
161 #define TXCTRL2_7BITS 0x20
162 #define TXCTRL2_6BITS 0x40
163 #define TXCTRL2_8BITS 0x60
164 #define W_SYNC1 6
165 #define W_SYNC2 7
166 #define W_TXBUF 8
167 #define W_MINTR 9
168 #define MINTR_STATUSHI 0x10
169 #define MINTR_RST_MASK 0xc0
170 #define MINTR_RST_B 0x40
171 #define MINTR_RST_A 0x80
172 #define MINTR_RST_ALL 0xc0
173 #define W_MISC1 10
174 #define W_CLOCK 11
175 #define CLOCK_TRXC 0x08
176 #define W_BRGLO 12
177 #define W_BRGHI 13
178 #define W_MISC2 14
179 #define MISC2_PLLDIS 0x30
180 #define W_EXTINT 15
181 #define EXTINT_DCD 0x08
182 #define EXTINT_SYNCINT 0x10
183 #define EXTINT_CTSINT 0x20
184 #define EXTINT_TXUNDRN 0x40
185 #define EXTINT_BRKINT 0x80
187 #define R_STATUS 0
188 #define STATUS_RXAV 0x01
189 #define STATUS_ZERO 0x02
190 #define STATUS_TXEMPTY 0x04
191 #define STATUS_DCD 0x08
192 #define STATUS_SYNC 0x10
193 #define STATUS_CTS 0x20
194 #define STATUS_TXUNDRN 0x40
195 #define STATUS_BRK 0x80
196 #define R_SPEC 1
197 #define SPEC_ALLSENT 0x01
198 #define SPEC_BITS8 0x06
199 #define R_IVEC 2
200 #define IVEC_TXINTB 0x00
201 #define IVEC_LONOINT 0x06
202 #define IVEC_LORXINTA 0x0c
203 #define IVEC_LORXINTB 0x04
204 #define IVEC_LOTXINTA 0x08
205 #define IVEC_HINOINT 0x60
206 #define IVEC_HIRXINTA 0x30
207 #define IVEC_HIRXINTB 0x20
208 #define IVEC_HITXINTA 0x10
209 #define R_INTR 3
210 #define INTR_EXTINTB 0x01
211 #define INTR_TXINTB 0x02
212 #define INTR_RXINTB 0x04
213 #define INTR_EXTINTA 0x08
214 #define INTR_TXINTA 0x10
215 #define INTR_RXINTA 0x20
216 #define R_IPEN 4
217 #define R_TXCTRL1 5
218 #define R_TXCTRL2 6
219 #define R_BC 7
220 #define R_RXBUF 8
221 #define R_RXCTRL 9
222 #define R_MISC 10
223 #define R_MISC1 11
224 #define R_BRGLO 12
225 #define R_BRGHI 13
226 #define R_MISC1I 14
227 #define R_EXTINT 15
229 static void handle_kbd_command(ChannelState *s, int val);
230 static int serial_can_receive(void *opaque);
231 static void serial_receive_byte(ChannelState *s, int ch);
233 static void clear_queue(void *opaque)
235 ChannelState *s = opaque;
236 SERIOQueue *q = &s->queue;
237 q->rptr = q->wptr = q->count = 0;
240 static void put_queue(void *opaque, int b)
242 ChannelState *s = opaque;
243 SERIOQueue *q = &s->queue;
245 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
246 if (q->count >= SERIO_QUEUE_SIZE)
247 return;
248 q->data[q->wptr] = b;
249 if (++q->wptr == SERIO_QUEUE_SIZE)
250 q->wptr = 0;
251 q->count++;
252 serial_receive_byte(s, 0);
255 static uint32_t get_queue(void *opaque)
257 ChannelState *s = opaque;
258 SERIOQueue *q = &s->queue;
259 int val;
261 if (q->count == 0) {
262 return 0;
263 } else {
264 val = q->data[q->rptr];
265 if (++q->rptr == SERIO_QUEUE_SIZE)
266 q->rptr = 0;
267 q->count--;
269 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
270 if (q->count > 0)
271 serial_receive_byte(s, 0);
272 return val;
275 static int escc_update_irq_chn(ChannelState *s)
277 if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
278 // tx ints enabled, pending
279 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
280 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
281 s->rxint == 1) || // rx ints enabled, pending
282 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
283 (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
284 return 1;
286 return 0;
289 static void escc_update_irq(ChannelState *s)
291 int irq;
293 irq = escc_update_irq_chn(s);
294 irq |= escc_update_irq_chn(s->otherchn);
296 SER_DPRINTF("IRQ = %d\n", irq);
297 qemu_set_irq(s->irq, irq);
300 static void escc_reset_chn(ChannelState *s)
302 int i;
304 s->reg = 0;
305 for (i = 0; i < SERIAL_REGS; i++) {
306 s->rregs[i] = 0;
307 s->wregs[i] = 0;
309 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
310 s->wregs[W_MINTR] = MINTR_RST_ALL;
311 s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
312 s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
313 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
314 EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
315 if (s->disabled)
316 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
317 STATUS_CTS | STATUS_TXUNDRN;
318 else
319 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
320 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
322 s->rx = s->tx = 0;
323 s->rxint = s->txint = 0;
324 s->rxint_under_svc = s->txint_under_svc = 0;
325 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
326 clear_queue(s);
329 static void escc_reset(void *opaque)
331 SerialState *s = opaque;
332 escc_reset_chn(&s->chn[0]);
333 escc_reset_chn(&s->chn[1]);
336 static inline void set_rxint(ChannelState *s)
338 s->rxint = 1;
339 if (!s->txint_under_svc) {
340 s->rxint_under_svc = 1;
341 if (s->chn == chn_a) {
342 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
343 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
344 else
345 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
346 } else {
347 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
348 s->rregs[R_IVEC] = IVEC_HIRXINTB;
349 else
350 s->rregs[R_IVEC] = IVEC_LORXINTB;
353 if (s->chn == chn_a)
354 s->rregs[R_INTR] |= INTR_RXINTA;
355 else
356 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
357 escc_update_irq(s);
360 static inline void set_txint(ChannelState *s)
362 s->txint = 1;
363 if (!s->rxint_under_svc) {
364 s->txint_under_svc = 1;
365 if (s->chn == chn_a) {
366 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
367 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
368 else
369 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
370 } else {
371 s->rregs[R_IVEC] = IVEC_TXINTB;
374 if (s->chn == chn_a)
375 s->rregs[R_INTR] |= INTR_TXINTA;
376 else
377 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
378 escc_update_irq(s);
381 static inline void clr_rxint(ChannelState *s)
383 s->rxint = 0;
384 s->rxint_under_svc = 0;
385 if (s->chn == chn_a) {
386 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
387 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
388 else
389 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
390 s->rregs[R_INTR] &= ~INTR_RXINTA;
391 } else {
392 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
393 s->rregs[R_IVEC] = IVEC_HINOINT;
394 else
395 s->rregs[R_IVEC] = IVEC_LONOINT;
396 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
398 if (s->txint)
399 set_txint(s);
400 escc_update_irq(s);
403 static inline void clr_txint(ChannelState *s)
405 s->txint = 0;
406 s->txint_under_svc = 0;
407 if (s->chn == chn_a) {
408 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
409 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
410 else
411 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
412 s->rregs[R_INTR] &= ~INTR_TXINTA;
413 } else {
414 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
415 s->rregs[R_IVEC] = IVEC_HINOINT;
416 else
417 s->rregs[R_IVEC] = IVEC_LONOINT;
418 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
420 if (s->rxint)
421 set_rxint(s);
422 escc_update_irq(s);
425 static void escc_update_parameters(ChannelState *s)
427 int speed, parity, data_bits, stop_bits;
428 QEMUSerialSetParams ssp;
430 if (!s->chr || s->type != ser)
431 return;
433 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
434 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
435 parity = 'E';
436 else
437 parity = 'O';
438 } else {
439 parity = 'N';
441 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
442 stop_bits = 2;
443 else
444 stop_bits = 1;
445 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
446 case TXCTRL2_5BITS:
447 data_bits = 5;
448 break;
449 case TXCTRL2_7BITS:
450 data_bits = 7;
451 break;
452 case TXCTRL2_6BITS:
453 data_bits = 6;
454 break;
455 default:
456 case TXCTRL2_8BITS:
457 data_bits = 8;
458 break;
460 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
461 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
462 case TXCTRL1_CLK1X:
463 break;
464 case TXCTRL1_CLK16X:
465 speed /= 16;
466 break;
467 case TXCTRL1_CLK32X:
468 speed /= 32;
469 break;
470 default:
471 case TXCTRL1_CLK64X:
472 speed /= 64;
473 break;
475 ssp.speed = speed;
476 ssp.parity = parity;
477 ssp.data_bits = data_bits;
478 ssp.stop_bits = stop_bits;
479 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
480 speed, parity, data_bits, stop_bits);
481 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
484 static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
486 SerialState *serial = opaque;
487 ChannelState *s;
488 uint32_t saddr;
489 int newreg, channel;
491 val &= 0xff;
492 saddr = (addr >> serial->it_shift) & 1;
493 channel = (addr >> (serial->it_shift + 1)) & 1;
494 s = &serial->chn[channel];
495 switch (saddr) {
496 case SERIAL_CTRL:
497 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
498 val & 0xff);
499 newreg = 0;
500 switch (s->reg) {
501 case W_CMD:
502 newreg = val & CMD_PTR_MASK;
503 val &= CMD_CMD_MASK;
504 switch (val) {
505 case CMD_HI:
506 newreg |= CMD_HI;
507 break;
508 case CMD_CLR_TXINT:
509 clr_txint(s);
510 break;
511 case CMD_CLR_IUS:
512 if (s->rxint_under_svc)
513 clr_rxint(s);
514 else if (s->txint_under_svc)
515 clr_txint(s);
516 break;
517 default:
518 break;
520 break;
521 case W_INTR ... W_RXCTRL:
522 case W_SYNC1 ... W_TXBUF:
523 case W_MISC1 ... W_CLOCK:
524 case W_MISC2 ... W_EXTINT:
525 s->wregs[s->reg] = val;
526 break;
527 case W_TXCTRL1:
528 case W_TXCTRL2:
529 s->wregs[s->reg] = val;
530 escc_update_parameters(s);
531 break;
532 case W_BRGLO:
533 case W_BRGHI:
534 s->wregs[s->reg] = val;
535 s->rregs[s->reg] = val;
536 escc_update_parameters(s);
537 break;
538 case W_MINTR:
539 switch (val & MINTR_RST_MASK) {
540 case 0:
541 default:
542 break;
543 case MINTR_RST_B:
544 escc_reset_chn(&serial->chn[0]);
545 return;
546 case MINTR_RST_A:
547 escc_reset_chn(&serial->chn[1]);
548 return;
549 case MINTR_RST_ALL:
550 escc_reset(serial);
551 return;
553 break;
554 default:
555 break;
557 if (s->reg == 0)
558 s->reg = newreg;
559 else
560 s->reg = 0;
561 break;
562 case SERIAL_DATA:
563 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
564 s->tx = val;
565 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
566 if (s->chr)
567 qemu_chr_write(s->chr, &s->tx, 1);
568 else if (s->type == kbd && !s->disabled) {
569 handle_kbd_command(s, val);
572 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
573 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
574 set_txint(s);
575 break;
576 default:
577 break;
581 static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
583 SerialState *serial = opaque;
584 ChannelState *s;
585 uint32_t saddr;
586 uint32_t ret;
587 int channel;
589 saddr = (addr >> serial->it_shift) & 1;
590 channel = (addr >> (serial->it_shift + 1)) & 1;
591 s = &serial->chn[channel];
592 switch (saddr) {
593 case SERIAL_CTRL:
594 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
595 s->rregs[s->reg]);
596 ret = s->rregs[s->reg];
597 s->reg = 0;
598 return ret;
599 case SERIAL_DATA:
600 s->rregs[R_STATUS] &= ~STATUS_RXAV;
601 clr_rxint(s);
602 if (s->type == kbd || s->type == mouse)
603 ret = get_queue(s);
604 else
605 ret = s->rx;
606 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
607 if (s->chr)
608 qemu_chr_accept_input(s->chr);
609 return ret;
610 default:
611 break;
613 return 0;
616 static int serial_can_receive(void *opaque)
618 ChannelState *s = opaque;
619 int ret;
621 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
622 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
623 // char already available
624 ret = 0;
625 else
626 ret = 1;
627 return ret;
630 static void serial_receive_byte(ChannelState *s, int ch)
632 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
633 s->rregs[R_STATUS] |= STATUS_RXAV;
634 s->rx = ch;
635 set_rxint(s);
638 static void serial_receive_break(ChannelState *s)
640 s->rregs[R_STATUS] |= STATUS_BRK;
641 escc_update_irq(s);
644 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
646 ChannelState *s = opaque;
647 serial_receive_byte(s, buf[0]);
650 static void serial_event(void *opaque, int event)
652 ChannelState *s = opaque;
653 if (event == CHR_EVENT_BREAK)
654 serial_receive_break(s);
657 static CPUReadMemoryFunc * const escc_mem_read[3] = {
658 escc_mem_readb,
659 NULL,
660 NULL,
663 static CPUWriteMemoryFunc * const escc_mem_write[3] = {
664 escc_mem_writeb,
665 NULL,
666 NULL,
669 static void escc_save_chn(QEMUFile *f, ChannelState *s)
671 uint32_t tmp = 0;
673 qemu_put_be32s(f, &tmp); /* unused, was IRQ. */
674 qemu_put_be32s(f, &s->reg);
675 qemu_put_be32s(f, &s->rxint);
676 qemu_put_be32s(f, &s->txint);
677 qemu_put_be32s(f, &s->rxint_under_svc);
678 qemu_put_be32s(f, &s->txint_under_svc);
679 qemu_put_8s(f, &s->rx);
680 qemu_put_8s(f, &s->tx);
681 qemu_put_buffer(f, s->wregs, SERIAL_REGS);
682 qemu_put_buffer(f, s->rregs, SERIAL_REGS);
685 static void escc_save(QEMUFile *f, void *opaque)
687 SerialState *s = opaque;
689 escc_save_chn(f, &s->chn[0]);
690 escc_save_chn(f, &s->chn[1]);
693 static int escc_load_chn(QEMUFile *f, ChannelState *s, int version_id)
695 uint32_t tmp;
697 if (version_id > 2)
698 return -EINVAL;
700 qemu_get_be32s(f, &tmp); /* unused */
701 qemu_get_be32s(f, &s->reg);
702 qemu_get_be32s(f, &s->rxint);
703 qemu_get_be32s(f, &s->txint);
704 if (version_id >= 2) {
705 qemu_get_be32s(f, &s->rxint_under_svc);
706 qemu_get_be32s(f, &s->txint_under_svc);
708 qemu_get_8s(f, &s->rx);
709 qemu_get_8s(f, &s->tx);
710 qemu_get_buffer(f, s->wregs, SERIAL_REGS);
711 qemu_get_buffer(f, s->rregs, SERIAL_REGS);
712 return 0;
715 static int escc_load(QEMUFile *f, void *opaque, int version_id)
717 SerialState *s = opaque;
718 int ret;
720 ret = escc_load_chn(f, &s->chn[0], version_id);
721 if (ret != 0)
722 return ret;
723 ret = escc_load_chn(f, &s->chn[1], version_id);
724 return ret;
728 int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
729 CharDriverState *chrA, CharDriverState *chrB,
730 int clock, int it_shift)
732 DeviceState *dev;
733 SysBusDevice *s;
734 SerialState *d;
736 dev = qdev_create(NULL, "escc");
737 qdev_prop_set_uint32(dev, "disabled", 0);
738 qdev_prop_set_uint32(dev, "frequency", clock);
739 qdev_prop_set_uint32(dev, "it_shift", it_shift);
740 qdev_prop_set_chr(dev, "chrB", chrB);
741 qdev_prop_set_chr(dev, "chrA", chrA);
742 qdev_prop_set_uint32(dev, "chnBtype", ser);
743 qdev_prop_set_uint32(dev, "chnAtype", ser);
744 qdev_init(dev);
745 s = sysbus_from_qdev(dev);
746 sysbus_connect_irq(s, 0, irqA);
747 sysbus_connect_irq(s, 1, irqB);
748 if (base) {
749 sysbus_mmio_map(s, 0, base);
752 d = FROM_SYSBUS(SerialState, s);
753 return d->mmio_index;
756 static const uint8_t keycodes[128] = {
757 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
758 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
759 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
760 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
761 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
762 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
763 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
764 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
767 static const uint8_t e0_keycodes[128] = {
768 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
770 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
771 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
772 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
773 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
774 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
775 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
778 static void sunkbd_event(void *opaque, int ch)
780 ChannelState *s = opaque;
781 int release = ch & 0x80;
783 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
784 "press");
785 switch (ch) {
786 case 58: // Caps lock press
787 s->caps_lock_mode ^= 1;
788 if (s->caps_lock_mode == 2)
789 return; // Drop second press
790 break;
791 case 69: // Num lock press
792 s->num_lock_mode ^= 1;
793 if (s->num_lock_mode == 2)
794 return; // Drop second press
795 break;
796 case 186: // Caps lock release
797 s->caps_lock_mode ^= 2;
798 if (s->caps_lock_mode == 3)
799 return; // Drop first release
800 break;
801 case 197: // Num lock release
802 s->num_lock_mode ^= 2;
803 if (s->num_lock_mode == 3)
804 return; // Drop first release
805 break;
806 case 0xe0:
807 s->e0_mode = 1;
808 return;
809 default:
810 break;
812 if (s->e0_mode) {
813 s->e0_mode = 0;
814 ch = e0_keycodes[ch & 0x7f];
815 } else {
816 ch = keycodes[ch & 0x7f];
818 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
819 put_queue(s, ch | release);
822 static void handle_kbd_command(ChannelState *s, int val)
824 KBD_DPRINTF("Command %d\n", val);
825 if (s->led_mode) { // Ignore led byte
826 s->led_mode = 0;
827 return;
829 switch (val) {
830 case 1: // Reset, return type code
831 clear_queue(s);
832 put_queue(s, 0xff);
833 put_queue(s, 4); // Type 4
834 put_queue(s, 0x7f);
835 break;
836 case 0xe: // Set leds
837 s->led_mode = 1;
838 break;
839 case 7: // Query layout
840 case 0xf:
841 clear_queue(s);
842 put_queue(s, 0xfe);
843 put_queue(s, 0); // XXX, layout?
844 break;
845 default:
846 break;
850 static void sunmouse_event(void *opaque,
851 int dx, int dy, int dz, int buttons_state)
853 ChannelState *s = opaque;
854 int ch;
856 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
858 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
860 if (buttons_state & MOUSE_EVENT_LBUTTON)
861 ch ^= 0x4;
862 if (buttons_state & MOUSE_EVENT_MBUTTON)
863 ch ^= 0x2;
864 if (buttons_state & MOUSE_EVENT_RBUTTON)
865 ch ^= 0x1;
867 put_queue(s, ch);
869 ch = dx;
871 if (ch > 127)
872 ch=127;
873 else if (ch < -127)
874 ch=-127;
876 put_queue(s, ch & 0xff);
878 ch = -dy;
880 if (ch > 127)
881 ch=127;
882 else if (ch < -127)
883 ch=-127;
885 put_queue(s, ch & 0xff);
887 // MSC protocol specify two extra motion bytes
889 put_queue(s, 0);
890 put_queue(s, 0);
893 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
894 int disabled, int clock, int it_shift)
896 DeviceState *dev;
897 SysBusDevice *s;
899 dev = qdev_create(NULL, "escc");
900 qdev_prop_set_uint32(dev, "disabled", disabled);
901 qdev_prop_set_uint32(dev, "frequency", clock);
902 qdev_prop_set_uint32(dev, "it_shift", it_shift);
903 qdev_prop_set_chr(dev, "chrB", NULL);
904 qdev_prop_set_chr(dev, "chrA", NULL);
905 qdev_prop_set_uint32(dev, "chnBtype", mouse);
906 qdev_prop_set_uint32(dev, "chnAtype", kbd);
907 qdev_init(dev);
908 s = sysbus_from_qdev(dev);
909 sysbus_connect_irq(s, 0, irq);
910 sysbus_connect_irq(s, 1, irq);
911 sysbus_mmio_map(s, 0, base);
914 static void escc_init1(SysBusDevice *dev)
916 SerialState *s = FROM_SYSBUS(SerialState, dev);
917 int io;
918 unsigned int i;
920 s->chn[0].disabled = s->disabled;
921 s->chn[1].disabled = s->disabled;
922 for (i = 0; i < 2; i++) {
923 sysbus_init_irq(dev, &s->chn[i].irq);
924 s->chn[i].chn = 1 - i;
925 s->chn[i].clock = s->frequency / 2;
926 if (s->chn[i].chr) {
927 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
928 serial_receive1, serial_event, &s->chn[i]);
931 s->chn[0].otherchn = &s->chn[1];
932 s->chn[1].otherchn = &s->chn[0];
934 io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s);
935 sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io);
936 s->mmio_index = io;
938 if (s->chn[0].type == mouse) {
939 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
940 "QEMU Sun Mouse");
942 if (s->chn[1].type == kbd) {
943 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
945 register_savevm("escc", -1, 2, escc_save, escc_load, s);
946 qemu_register_reset(escc_reset, s);
947 escc_reset(s);
950 static SysBusDeviceInfo escc_info = {
951 .init = escc_init1,
952 .qdev.name = "escc",
953 .qdev.size = sizeof(SerialState),
954 .qdev.props = (Property[]) {
955 DEFINE_PROP_UINT32("frequency", SerialState, frequency, 0),
956 DEFINE_PROP_UINT32("it_shift", SerialState, it_shift, 0),
957 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
958 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
959 DEFINE_PROP_UINT32("chnBtype", SerialState, chn[0].type, 0),
960 DEFINE_PROP_UINT32("chnAtype", SerialState, chn[1].type, 0),
961 DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
962 DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
963 DEFINE_PROP_END_OF_LIST(),
967 static void escc_register_devices(void)
969 sysbus_register_withprop(&escc_info);
972 device_init(escc_register_devices)