Python-lang gdb script to extract x86_64 guest vmcore from qemu coredump
[qemu/cris-port.git] / hw / char / escc.c
blob6397f6f282232a56608c481780f0378bb35a40d9
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/hw.h"
26 #include "hw/sysbus.h"
27 #include "hw/char/escc.h"
28 #include "sysemu/char.h"
29 #include "ui/console.h"
30 #include "trace.h"
33 * Chipset docs:
34 * "Z80C30/Z85C30/Z80230/Z85230/Z85233 SCC/ESCC User Manual",
35 * http://www.zilog.com/docs/serial/scc_escc_um.pdf
37 * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001
38 * (Slave I/O), also produced as NCR89C105. See
39 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
41 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
42 * mouse and keyboard ports don't implement all functions and they are
43 * only asynchronous. There is no DMA.
45 * Z85C30 is also used on PowerMacs. There are some small differences
46 * between Sparc version (sunzilog) and PowerMac (pmac):
47 * Offset between control and data registers
48 * There is some kind of lockup bug, but we can ignore it
49 * CTS is inverted
50 * DMA on pmac using DBDMA chip
51 * pmac can do IRDA and faster rates, sunzilog can only do 38400
52 * pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz
56 * Modifications:
57 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
58 * serial mouse queue.
59 * Implemented serial mouse protocol.
61 * 2010-May-23 Artyom Tarasenko: Reworked IUS logic
64 typedef enum {
65 chn_a, chn_b,
66 } ChnID;
68 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
70 typedef enum {
71 ser, kbd, mouse,
72 } ChnType;
74 #define SERIO_QUEUE_SIZE 256
76 typedef struct {
77 uint8_t data[SERIO_QUEUE_SIZE];
78 int rptr, wptr, count;
79 } SERIOQueue;
81 #define SERIAL_REGS 16
82 typedef struct ChannelState {
83 qemu_irq irq;
84 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
85 struct ChannelState *otherchn;
86 uint32_t reg;
87 uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
88 SERIOQueue queue;
89 CharDriverState *chr;
90 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
91 int disabled;
92 int clock;
93 uint32_t vmstate_dummy;
94 ChnID chn; // this channel, A (base+4) or B (base+0)
95 ChnType type;
96 uint8_t rx, tx;
97 } ChannelState;
99 #define ESCC(obj) OBJECT_CHECK(ESCCState, (obj), TYPE_ESCC)
101 typedef struct ESCCState {
102 SysBusDevice parent_obj;
104 struct ChannelState chn[2];
105 uint32_t it_shift;
106 MemoryRegion mmio;
107 uint32_t disabled;
108 uint32_t frequency;
109 } ESCCState;
111 #define SERIAL_CTRL 0
112 #define SERIAL_DATA 1
114 #define W_CMD 0
115 #define CMD_PTR_MASK 0x07
116 #define CMD_CMD_MASK 0x38
117 #define CMD_HI 0x08
118 #define CMD_CLR_TXINT 0x28
119 #define CMD_CLR_IUS 0x38
120 #define W_INTR 1
121 #define INTR_INTALL 0x01
122 #define INTR_TXINT 0x02
123 #define INTR_RXMODEMSK 0x18
124 #define INTR_RXINT1ST 0x08
125 #define INTR_RXINTALL 0x10
126 #define W_IVEC 2
127 #define W_RXCTRL 3
128 #define RXCTRL_RXEN 0x01
129 #define W_TXCTRL1 4
130 #define TXCTRL1_PAREN 0x01
131 #define TXCTRL1_PAREV 0x02
132 #define TXCTRL1_1STOP 0x04
133 #define TXCTRL1_1HSTOP 0x08
134 #define TXCTRL1_2STOP 0x0c
135 #define TXCTRL1_STPMSK 0x0c
136 #define TXCTRL1_CLK1X 0x00
137 #define TXCTRL1_CLK16X 0x40
138 #define TXCTRL1_CLK32X 0x80
139 #define TXCTRL1_CLK64X 0xc0
140 #define TXCTRL1_CLKMSK 0xc0
141 #define W_TXCTRL2 5
142 #define TXCTRL2_TXEN 0x08
143 #define TXCTRL2_BITMSK 0x60
144 #define TXCTRL2_5BITS 0x00
145 #define TXCTRL2_7BITS 0x20
146 #define TXCTRL2_6BITS 0x40
147 #define TXCTRL2_8BITS 0x60
148 #define W_SYNC1 6
149 #define W_SYNC2 7
150 #define W_TXBUF 8
151 #define W_MINTR 9
152 #define MINTR_STATUSHI 0x10
153 #define MINTR_RST_MASK 0xc0
154 #define MINTR_RST_B 0x40
155 #define MINTR_RST_A 0x80
156 #define MINTR_RST_ALL 0xc0
157 #define W_MISC1 10
158 #define W_CLOCK 11
159 #define CLOCK_TRXC 0x08
160 #define W_BRGLO 12
161 #define W_BRGHI 13
162 #define W_MISC2 14
163 #define MISC2_PLLDIS 0x30
164 #define W_EXTINT 15
165 #define EXTINT_DCD 0x08
166 #define EXTINT_SYNCINT 0x10
167 #define EXTINT_CTSINT 0x20
168 #define EXTINT_TXUNDRN 0x40
169 #define EXTINT_BRKINT 0x80
171 #define R_STATUS 0
172 #define STATUS_RXAV 0x01
173 #define STATUS_ZERO 0x02
174 #define STATUS_TXEMPTY 0x04
175 #define STATUS_DCD 0x08
176 #define STATUS_SYNC 0x10
177 #define STATUS_CTS 0x20
178 #define STATUS_TXUNDRN 0x40
179 #define STATUS_BRK 0x80
180 #define R_SPEC 1
181 #define SPEC_ALLSENT 0x01
182 #define SPEC_BITS8 0x06
183 #define R_IVEC 2
184 #define IVEC_TXINTB 0x00
185 #define IVEC_LONOINT 0x06
186 #define IVEC_LORXINTA 0x0c
187 #define IVEC_LORXINTB 0x04
188 #define IVEC_LOTXINTA 0x08
189 #define IVEC_HINOINT 0x60
190 #define IVEC_HIRXINTA 0x30
191 #define IVEC_HIRXINTB 0x20
192 #define IVEC_HITXINTA 0x10
193 #define R_INTR 3
194 #define INTR_EXTINTB 0x01
195 #define INTR_TXINTB 0x02
196 #define INTR_RXINTB 0x04
197 #define INTR_EXTINTA 0x08
198 #define INTR_TXINTA 0x10
199 #define INTR_RXINTA 0x20
200 #define R_IPEN 4
201 #define R_TXCTRL1 5
202 #define R_TXCTRL2 6
203 #define R_BC 7
204 #define R_RXBUF 8
205 #define R_RXCTRL 9
206 #define R_MISC 10
207 #define R_MISC1 11
208 #define R_BRGLO 12
209 #define R_BRGHI 13
210 #define R_MISC1I 14
211 #define R_EXTINT 15
213 static void handle_kbd_command(ChannelState *s, int val);
214 static int serial_can_receive(void *opaque);
215 static void serial_receive_byte(ChannelState *s, int ch);
217 static void clear_queue(void *opaque)
219 ChannelState *s = opaque;
220 SERIOQueue *q = &s->queue;
221 q->rptr = q->wptr = q->count = 0;
224 static void put_queue(void *opaque, int b)
226 ChannelState *s = opaque;
227 SERIOQueue *q = &s->queue;
229 trace_escc_put_queue(CHN_C(s), b);
230 if (q->count >= SERIO_QUEUE_SIZE)
231 return;
232 q->data[q->wptr] = b;
233 if (++q->wptr == SERIO_QUEUE_SIZE)
234 q->wptr = 0;
235 q->count++;
236 serial_receive_byte(s, 0);
239 static uint32_t get_queue(void *opaque)
241 ChannelState *s = opaque;
242 SERIOQueue *q = &s->queue;
243 int val;
245 if (q->count == 0) {
246 return 0;
247 } else {
248 val = q->data[q->rptr];
249 if (++q->rptr == SERIO_QUEUE_SIZE)
250 q->rptr = 0;
251 q->count--;
253 trace_escc_get_queue(CHN_C(s), val);
254 if (q->count > 0)
255 serial_receive_byte(s, 0);
256 return val;
259 static int escc_update_irq_chn(ChannelState *s)
261 if ((((s->wregs[W_INTR] & INTR_TXINT) && (s->txint == 1)) ||
262 // tx ints enabled, pending
263 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
264 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
265 s->rxint == 1) || // rx ints enabled, pending
266 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
267 (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
268 return 1;
270 return 0;
273 static void escc_update_irq(ChannelState *s)
275 int irq;
277 irq = escc_update_irq_chn(s);
278 irq |= escc_update_irq_chn(s->otherchn);
280 trace_escc_update_irq(irq);
281 qemu_set_irq(s->irq, irq);
284 static void escc_reset_chn(ChannelState *s)
286 int i;
288 s->reg = 0;
289 for (i = 0; i < SERIAL_REGS; i++) {
290 s->rregs[i] = 0;
291 s->wregs[i] = 0;
293 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
294 s->wregs[W_MINTR] = MINTR_RST_ALL;
295 s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
296 s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
297 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
298 EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
299 if (s->disabled)
300 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
301 STATUS_CTS | STATUS_TXUNDRN;
302 else
303 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
304 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
306 s->rx = s->tx = 0;
307 s->rxint = s->txint = 0;
308 s->rxint_under_svc = s->txint_under_svc = 0;
309 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
310 clear_queue(s);
313 static void escc_reset(DeviceState *d)
315 ESCCState *s = ESCC(d);
317 escc_reset_chn(&s->chn[0]);
318 escc_reset_chn(&s->chn[1]);
321 static inline void set_rxint(ChannelState *s)
323 s->rxint = 1;
324 /* XXX: missing daisy chainnig: chn_b rx should have a lower priority
325 than chn_a rx/tx/special_condition service*/
326 s->rxint_under_svc = 1;
327 if (s->chn == chn_a) {
328 s->rregs[R_INTR] |= INTR_RXINTA;
329 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
330 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
331 else
332 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
333 } else {
334 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
335 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
336 s->rregs[R_IVEC] = IVEC_HIRXINTB;
337 else
338 s->rregs[R_IVEC] = IVEC_LORXINTB;
340 escc_update_irq(s);
343 static inline void set_txint(ChannelState *s)
345 s->txint = 1;
346 if (!s->rxint_under_svc) {
347 s->txint_under_svc = 1;
348 if (s->chn == chn_a) {
349 if (s->wregs[W_INTR] & INTR_TXINT) {
350 s->rregs[R_INTR] |= INTR_TXINTA;
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;
358 if (s->wregs[W_INTR] & INTR_TXINT) {
359 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
362 escc_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 escc_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 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
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 escc_update_irq(s);
411 static void escc_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 = s->clock / ((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 trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
466 qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
469 static void escc_mem_write(void *opaque, hwaddr addr,
470 uint64_t val, unsigned size)
472 ESCCState *serial = opaque;
473 ChannelState *s;
474 uint32_t saddr;
475 int newreg, channel;
477 val &= 0xff;
478 saddr = (addr >> serial->it_shift) & 1;
479 channel = (addr >> (serial->it_shift + 1)) & 1;
480 s = &serial->chn[channel];
481 switch (saddr) {
482 case SERIAL_CTRL:
483 trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
484 newreg = 0;
485 switch (s->reg) {
486 case W_CMD:
487 newreg = val & CMD_PTR_MASK;
488 val &= CMD_CMD_MASK;
489 switch (val) {
490 case CMD_HI:
491 newreg |= CMD_HI;
492 break;
493 case CMD_CLR_TXINT:
494 clr_txint(s);
495 break;
496 case CMD_CLR_IUS:
497 if (s->rxint_under_svc) {
498 s->rxint_under_svc = 0;
499 if (s->txint) {
500 set_txint(s);
502 } else if (s->txint_under_svc) {
503 s->txint_under_svc = 0;
505 escc_update_irq(s);
506 break;
507 default:
508 break;
510 break;
511 case W_INTR ... W_RXCTRL:
512 case W_SYNC1 ... W_TXBUF:
513 case W_MISC1 ... W_CLOCK:
514 case W_MISC2 ... W_EXTINT:
515 s->wregs[s->reg] = val;
516 break;
517 case W_TXCTRL1:
518 case W_TXCTRL2:
519 s->wregs[s->reg] = val;
520 escc_update_parameters(s);
521 break;
522 case W_BRGLO:
523 case W_BRGHI:
524 s->wregs[s->reg] = val;
525 s->rregs[s->reg] = val;
526 escc_update_parameters(s);
527 break;
528 case W_MINTR:
529 switch (val & MINTR_RST_MASK) {
530 case 0:
531 default:
532 break;
533 case MINTR_RST_B:
534 escc_reset_chn(&serial->chn[0]);
535 return;
536 case MINTR_RST_A:
537 escc_reset_chn(&serial->chn[1]);
538 return;
539 case MINTR_RST_ALL:
540 escc_reset(DEVICE(serial));
541 return;
543 break;
544 default:
545 break;
547 if (s->reg == 0)
548 s->reg = newreg;
549 else
550 s->reg = 0;
551 break;
552 case SERIAL_DATA:
553 trace_escc_mem_writeb_data(CHN_C(s), val);
554 s->tx = val;
555 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
556 if (s->chr)
557 qemu_chr_fe_write(s->chr, &s->tx, 1);
558 else if (s->type == kbd && !s->disabled) {
559 handle_kbd_command(s, val);
562 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
563 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
564 set_txint(s);
565 break;
566 default:
567 break;
571 static uint64_t escc_mem_read(void *opaque, hwaddr addr,
572 unsigned size)
574 ESCCState *serial = opaque;
575 ChannelState *s;
576 uint32_t saddr;
577 uint32_t ret;
578 int channel;
580 saddr = (addr >> serial->it_shift) & 1;
581 channel = (addr >> (serial->it_shift + 1)) & 1;
582 s = &serial->chn[channel];
583 switch (saddr) {
584 case SERIAL_CTRL:
585 trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
586 ret = s->rregs[s->reg];
587 s->reg = 0;
588 return ret;
589 case SERIAL_DATA:
590 s->rregs[R_STATUS] &= ~STATUS_RXAV;
591 clr_rxint(s);
592 if (s->type == kbd || s->type == mouse)
593 ret = get_queue(s);
594 else
595 ret = s->rx;
596 trace_escc_mem_readb_data(CHN_C(s), ret);
597 if (s->chr)
598 qemu_chr_accept_input(s->chr);
599 return ret;
600 default:
601 break;
603 return 0;
606 static const MemoryRegionOps escc_mem_ops = {
607 .read = escc_mem_read,
608 .write = escc_mem_write,
609 .endianness = DEVICE_NATIVE_ENDIAN,
610 .valid = {
611 .min_access_size = 1,
612 .max_access_size = 1,
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 trace_escc_serial_receive_byte(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 const VMStateDescription vmstate_escc_chn = {
658 .name ="escc_chn",
659 .version_id = 2,
660 .minimum_version_id = 1,
661 .minimum_version_id_old = 1,
662 .fields = (VMStateField []) {
663 VMSTATE_UINT32(vmstate_dummy, ChannelState),
664 VMSTATE_UINT32(reg, ChannelState),
665 VMSTATE_UINT32(rxint, ChannelState),
666 VMSTATE_UINT32(txint, ChannelState),
667 VMSTATE_UINT32(rxint_under_svc, ChannelState),
668 VMSTATE_UINT32(txint_under_svc, ChannelState),
669 VMSTATE_UINT8(rx, ChannelState),
670 VMSTATE_UINT8(tx, ChannelState),
671 VMSTATE_BUFFER(wregs, ChannelState),
672 VMSTATE_BUFFER(rregs, ChannelState),
673 VMSTATE_END_OF_LIST()
677 static const VMStateDescription vmstate_escc = {
678 .name ="escc",
679 .version_id = 2,
680 .minimum_version_id = 1,
681 .minimum_version_id_old = 1,
682 .fields = (VMStateField []) {
683 VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
684 ChannelState),
685 VMSTATE_END_OF_LIST()
689 MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
690 CharDriverState *chrA, CharDriverState *chrB,
691 int clock, int it_shift)
693 DeviceState *dev;
694 SysBusDevice *s;
695 ESCCState *d;
697 dev = qdev_create(NULL, TYPE_ESCC);
698 qdev_prop_set_uint32(dev, "disabled", 0);
699 qdev_prop_set_uint32(dev, "frequency", clock);
700 qdev_prop_set_uint32(dev, "it_shift", it_shift);
701 qdev_prop_set_chr(dev, "chrB", chrB);
702 qdev_prop_set_chr(dev, "chrA", chrA);
703 qdev_prop_set_uint32(dev, "chnBtype", ser);
704 qdev_prop_set_uint32(dev, "chnAtype", ser);
705 qdev_init_nofail(dev);
706 s = SYS_BUS_DEVICE(dev);
707 sysbus_connect_irq(s, 0, irqB);
708 sysbus_connect_irq(s, 1, irqA);
709 if (base) {
710 sysbus_mmio_map(s, 0, base);
713 d = ESCC(s);
714 return &d->mmio;
717 static const uint8_t keycodes[128] = {
718 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
719 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
720 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
721 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
722 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
723 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
724 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
725 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
728 static const uint8_t e0_keycodes[128] = {
729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
730 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
732 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
733 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
734 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
735 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
736 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
739 static void sunkbd_event(void *opaque, int ch)
741 ChannelState *s = opaque;
742 int release = ch & 0x80;
744 trace_escc_sunkbd_event_in(ch);
745 switch (ch) {
746 case 58: // Caps lock press
747 s->caps_lock_mode ^= 1;
748 if (s->caps_lock_mode == 2)
749 return; // Drop second press
750 break;
751 case 69: // Num lock press
752 s->num_lock_mode ^= 1;
753 if (s->num_lock_mode == 2)
754 return; // Drop second press
755 break;
756 case 186: // Caps lock release
757 s->caps_lock_mode ^= 2;
758 if (s->caps_lock_mode == 3)
759 return; // Drop first release
760 break;
761 case 197: // Num lock release
762 s->num_lock_mode ^= 2;
763 if (s->num_lock_mode == 3)
764 return; // Drop first release
765 break;
766 case 0xe0:
767 s->e0_mode = 1;
768 return;
769 default:
770 break;
772 if (s->e0_mode) {
773 s->e0_mode = 0;
774 ch = e0_keycodes[ch & 0x7f];
775 } else {
776 ch = keycodes[ch & 0x7f];
778 trace_escc_sunkbd_event_out(ch);
779 put_queue(s, ch | release);
782 static void handle_kbd_command(ChannelState *s, int val)
784 trace_escc_kbd_command(val);
785 if (s->led_mode) { // Ignore led byte
786 s->led_mode = 0;
787 return;
789 switch (val) {
790 case 1: // Reset, return type code
791 clear_queue(s);
792 put_queue(s, 0xff);
793 put_queue(s, 4); // Type 4
794 put_queue(s, 0x7f);
795 break;
796 case 0xe: // Set leds
797 s->led_mode = 1;
798 break;
799 case 7: // Query layout
800 case 0xf:
801 clear_queue(s);
802 put_queue(s, 0xfe);
803 put_queue(s, 0); // XXX, layout?
804 break;
805 default:
806 break;
810 static void sunmouse_event(void *opaque,
811 int dx, int dy, int dz, int buttons_state)
813 ChannelState *s = opaque;
814 int ch;
816 trace_escc_sunmouse_event(dx, dy, buttons_state);
817 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
819 if (buttons_state & MOUSE_EVENT_LBUTTON)
820 ch ^= 0x4;
821 if (buttons_state & MOUSE_EVENT_MBUTTON)
822 ch ^= 0x2;
823 if (buttons_state & MOUSE_EVENT_RBUTTON)
824 ch ^= 0x1;
826 put_queue(s, ch);
828 ch = dx;
830 if (ch > 127)
831 ch = 127;
832 else if (ch < -127)
833 ch = -127;
835 put_queue(s, ch & 0xff);
837 ch = -dy;
839 if (ch > 127)
840 ch = 127;
841 else if (ch < -127)
842 ch = -127;
844 put_queue(s, ch & 0xff);
846 // MSC protocol specify two extra motion bytes
848 put_queue(s, 0);
849 put_queue(s, 0);
852 void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
853 int disabled, int clock, int it_shift)
855 DeviceState *dev;
856 SysBusDevice *s;
858 dev = qdev_create(NULL, TYPE_ESCC);
859 qdev_prop_set_uint32(dev, "disabled", disabled);
860 qdev_prop_set_uint32(dev, "frequency", clock);
861 qdev_prop_set_uint32(dev, "it_shift", it_shift);
862 qdev_prop_set_chr(dev, "chrB", NULL);
863 qdev_prop_set_chr(dev, "chrA", NULL);
864 qdev_prop_set_uint32(dev, "chnBtype", mouse);
865 qdev_prop_set_uint32(dev, "chnAtype", kbd);
866 qdev_init_nofail(dev);
867 s = SYS_BUS_DEVICE(dev);
868 sysbus_connect_irq(s, 0, irq);
869 sysbus_connect_irq(s, 1, irq);
870 sysbus_mmio_map(s, 0, base);
873 static int escc_init1(SysBusDevice *dev)
875 ESCCState *s = ESCC(dev);
876 unsigned int i;
878 s->chn[0].disabled = s->disabled;
879 s->chn[1].disabled = s->disabled;
880 for (i = 0; i < 2; i++) {
881 sysbus_init_irq(dev, &s->chn[i].irq);
882 s->chn[i].chn = 1 - i;
883 s->chn[i].clock = s->frequency / 2;
884 if (s->chn[i].chr) {
885 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
886 serial_receive1, serial_event, &s->chn[i]);
889 s->chn[0].otherchn = &s->chn[1];
890 s->chn[1].otherchn = &s->chn[0];
892 memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
893 ESCC_SIZE << s->it_shift);
894 sysbus_init_mmio(dev, &s->mmio);
896 if (s->chn[0].type == mouse) {
897 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
898 "QEMU Sun Mouse");
900 if (s->chn[1].type == kbd) {
901 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
904 return 0;
907 static Property escc_properties[] = {
908 DEFINE_PROP_UINT32("frequency", ESCCState, frequency, 0),
909 DEFINE_PROP_UINT32("it_shift", ESCCState, it_shift, 0),
910 DEFINE_PROP_UINT32("disabled", ESCCState, disabled, 0),
911 DEFINE_PROP_UINT32("chnBtype", ESCCState, chn[0].type, 0),
912 DEFINE_PROP_UINT32("chnAtype", ESCCState, chn[1].type, 0),
913 DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr),
914 DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr),
915 DEFINE_PROP_END_OF_LIST(),
918 static void escc_class_init(ObjectClass *klass, void *data)
920 DeviceClass *dc = DEVICE_CLASS(klass);
921 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
923 k->init = escc_init1;
924 dc->reset = escc_reset;
925 dc->vmsd = &vmstate_escc;
926 dc->props = escc_properties;
929 static const TypeInfo escc_info = {
930 .name = TYPE_ESCC,
931 .parent = TYPE_SYS_BUS_DEVICE,
932 .instance_size = sizeof(ESCCState),
933 .class_init = escc_class_init,
936 static void escc_register_types(void)
938 type_register_static(&escc_info);
941 type_init(escc_register_types)