1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "hw/irq.h"
27#include "hw/qdev-properties.h"
28#include "hw/qdev-properties-system.h"
29#include "hw/sysbus.h"
30#include "migration/vmstate.h"
31#include "qemu/module.h"
32#include "hw/char/escc.h"
33#include "ui/console.h"
34#include "trace.h"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75#define CHN_C(s) ((s)->chn == escc_chn_b ? 'b' : 'a')
76
77#define SERIAL_CTRL 0
78#define SERIAL_DATA 1
79
80#define W_CMD 0
81#define CMD_PTR_MASK 0x07
82#define CMD_CMD_MASK 0x38
83#define CMD_HI 0x08
84#define CMD_CLR_TXINT 0x28
85#define CMD_CLR_IUS 0x38
86#define W_INTR 1
87#define INTR_INTALL 0x01
88#define INTR_TXINT 0x02
89#define INTR_PAR_SPEC 0x04
90#define INTR_RXMODEMSK 0x18
91#define INTR_RXINT1ST 0x08
92#define INTR_RXINTALL 0x10
93#define INTR_WTRQ_TXRX 0x20
94#define W_IVEC 2
95#define W_RXCTRL 3
96#define RXCTRL_RXEN 0x01
97#define RXCTRL_HUNT 0x10
98#define W_TXCTRL1 4
99#define TXCTRL1_PAREN 0x01
100#define TXCTRL1_PAREV 0x02
101#define TXCTRL1_1STOP 0x04
102#define TXCTRL1_1HSTOP 0x08
103#define TXCTRL1_2STOP 0x0c
104#define TXCTRL1_STPMSK 0x0c
105#define TXCTRL1_CLK1X 0x00
106#define TXCTRL1_CLK16X 0x40
107#define TXCTRL1_CLK32X 0x80
108#define TXCTRL1_CLK64X 0xc0
109#define TXCTRL1_CLKMSK 0xc0
110#define W_TXCTRL2 5
111#define TXCTRL2_TXCRC 0x01
112#define TXCTRL2_TXEN 0x08
113#define TXCTRL2_BITMSK 0x60
114#define TXCTRL2_5BITS 0x00
115#define TXCTRL2_7BITS 0x20
116#define TXCTRL2_6BITS 0x40
117#define TXCTRL2_8BITS 0x60
118#define W_SYNC1 6
119#define W_SYNC2 7
120#define W_TXBUF 8
121#define W_MINTR 9
122#define MINTR_VIS 0x01
123#define MINTR_NV 0x02
124#define MINTR_STATUSHI 0x10
125#define MINTR_SOFTIACK 0x20
126#define MINTR_RST_MASK 0xc0
127#define MINTR_RST_B 0x40
128#define MINTR_RST_A 0x80
129#define MINTR_RST_ALL 0xc0
130#define W_MISC1 10
131#define MISC1_ENC_MASK 0x60
132#define W_CLOCK 11
133#define CLOCK_TRXC 0x08
134#define W_BRGLO 12
135#define W_BRGHI 13
136#define W_MISC2 14
137#define MISC2_BRG_EN 0x01
138#define MISC2_BRG_SRC 0x02
139#define MISC2_LCL_LOOP 0x10
140#define MISC2_PLLCMD0 0x20
141#define MISC2_PLLCMD1 0x40
142#define MISC2_PLLCMD2 0x80
143#define W_EXTINT 15
144#define EXTINT_DCD 0x08
145#define EXTINT_SYNCINT 0x10
146#define EXTINT_CTSINT 0x20
147#define EXTINT_TXUNDRN 0x40
148#define EXTINT_BRKINT 0x80
149
150#define R_STATUS 0
151#define STATUS_RXAV 0x01
152#define STATUS_ZERO 0x02
153#define STATUS_TXEMPTY 0x04
154#define STATUS_DCD 0x08
155#define STATUS_SYNC 0x10
156#define STATUS_CTS 0x20
157#define STATUS_TXUNDRN 0x40
158#define STATUS_BRK 0x80
159#define R_SPEC 1
160#define SPEC_ALLSENT 0x01
161#define SPEC_BITS8 0x06
162#define R_IVEC 2
163#define IVEC_TXINTB 0x00
164#define IVEC_LONOINT 0x06
165#define IVEC_LORXINTA 0x0c
166#define IVEC_LORXINTB 0x04
167#define IVEC_LOTXINTA 0x08
168#define IVEC_HINOINT 0x60
169#define IVEC_HIRXINTA 0x30
170#define IVEC_HIRXINTB 0x20
171#define IVEC_HITXINTA 0x10
172#define R_INTR 3
173#define INTR_EXTINTB 0x01
174#define INTR_TXINTB 0x02
175#define INTR_RXINTB 0x04
176#define INTR_EXTINTA 0x08
177#define INTR_TXINTA 0x10
178#define INTR_RXINTA 0x20
179#define R_IPEN 4
180#define R_TXCTRL1 5
181#define R_TXCTRL2 6
182#define R_BC 7
183#define R_RXBUF 8
184#define R_RXCTRL 9
185#define R_MISC 10
186#define MISC_2CLKMISS 0x40
187#define R_MISC1 11
188#define R_BRGLO 12
189#define R_BRGHI 13
190#define R_MISC1I 14
191#define R_EXTINT 15
192
193static void handle_kbd_command(ESCCChannelState *s, int val);
194static int serial_can_receive(void *opaque);
195static void serial_receive_byte(ESCCChannelState *s, int ch);
196
197static int reg_shift(ESCCState *s)
198{
199 return s->bit_swap ? s->it_shift + 1 : s->it_shift;
200}
201
202static int chn_shift(ESCCState *s)
203{
204 return s->bit_swap ? s->it_shift : s->it_shift + 1;
205}
206
207static void clear_queue(void *opaque)
208{
209 ESCCChannelState *s = opaque;
210 ESCCSERIOQueue *q = &s->queue;
211 q->rptr = q->wptr = q->count = 0;
212}
213
214static void put_queue(void *opaque, int b)
215{
216 ESCCChannelState *s = opaque;
217 ESCCSERIOQueue *q = &s->queue;
218
219 trace_escc_put_queue(CHN_C(s), b);
220 if (q->count >= ESCC_SERIO_QUEUE_SIZE) {
221 return;
222 }
223 q->data[q->wptr] = b;
224 if (++q->wptr == ESCC_SERIO_QUEUE_SIZE) {
225 q->wptr = 0;
226 }
227 q->count++;
228 serial_receive_byte(s, 0);
229}
230
231static uint32_t get_queue(void *opaque)
232{
233 ESCCChannelState *s = opaque;
234 ESCCSERIOQueue *q = &s->queue;
235 int val;
236
237 if (q->count == 0) {
238 return 0;
239 } else {
240 val = q->data[q->rptr];
241 if (++q->rptr == ESCC_SERIO_QUEUE_SIZE) {
242 q->rptr = 0;
243 }
244 q->count--;
245 }
246 trace_escc_get_queue(CHN_C(s), val);
247 if (q->count > 0) {
248 serial_receive_byte(s, 0);
249 }
250 return val;
251}
252
253static int escc_update_irq_chn(ESCCChannelState *s)
254{
255 if ((((s->wregs[W_INTR] & INTR_TXINT) && (s->txint == 1)) ||
256
257 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
258 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
259 s->rxint == 1) ||
260
261 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
262 (s->rregs[R_STATUS] & STATUS_BRK)))) {
263
264 return 1;
265 }
266 return 0;
267}
268
269static void escc_update_irq(ESCCChannelState *s)
270{
271 int irq;
272
273 irq = escc_update_irq_chn(s);
274 irq |= escc_update_irq_chn(s->otherchn);
275
276 trace_escc_update_irq(irq);
277 qemu_set_irq(s->irq, irq);
278}
279
280static void escc_reset_chn(ESCCChannelState *s)
281{
282 s->reg = 0;
283 s->rx = s->tx = 0;
284 s->rxint = s->txint = 0;
285 s->rxint_under_svc = s->txint_under_svc = 0;
286 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
287 clear_queue(s);
288}
289
290static void escc_soft_reset_chn(ESCCChannelState *s)
291{
292 escc_reset_chn(s);
293
294 s->wregs[W_CMD] = 0;
295 s->wregs[W_INTR] &= INTR_PAR_SPEC | INTR_WTRQ_TXRX;
296 s->wregs[W_RXCTRL] &= ~RXCTRL_RXEN;
297
298 s->wregs[W_TXCTRL1] |= TXCTRL1_1STOP;
299 s->wregs[W_TXCTRL2] &= TXCTRL2_TXCRC | TXCTRL2_8BITS;
300 s->wregs[W_MINTR] &= ~MINTR_SOFTIACK;
301 s->wregs[W_MISC1] &= MISC1_ENC_MASK;
302
303 s->wregs[W_MISC2] &= MISC2_BRG_EN | MISC2_BRG_SRC |
304 MISC2_PLLCMD1 | MISC2_PLLCMD2;
305 s->wregs[W_MISC2] |= MISC2_PLLCMD0;
306
307 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
308 EXTINT_TXUNDRN | EXTINT_BRKINT;
309
310 s->rregs[R_STATUS] &= STATUS_DCD | STATUS_SYNC | STATUS_CTS | STATUS_BRK;
311 s->rregs[R_STATUS] |= STATUS_TXEMPTY | STATUS_TXUNDRN;
312 if (s->disabled) {
313 s->rregs[R_STATUS] |= STATUS_DCD | STATUS_SYNC | STATUS_CTS;
314 }
315 s->rregs[R_SPEC] &= SPEC_ALLSENT;
316 s->rregs[R_SPEC] |= SPEC_BITS8;
317 s->rregs[R_INTR] = 0;
318 s->rregs[R_MISC] &= MISC_2CLKMISS;
319}
320
321static void escc_hard_reset_chn(ESCCChannelState *s)
322{
323 escc_soft_reset_chn(s);
324
325
326
327
328
329
330 s->wregs[W_MINTR] &= MINTR_VIS | MINTR_NV;
331 s->wregs[W_MINTR] |= MINTR_RST_B | MINTR_RST_A;
332 s->wregs[W_MISC1] = 0;
333 s->wregs[W_CLOCK] = CLOCK_TRXC;
334 s->wregs[W_MISC2] &= MISC2_PLLCMD1 | MISC2_PLLCMD2;
335 s->wregs[W_MISC2] |= MISC2_LCL_LOOP | MISC2_PLLCMD0;
336}
337
338static void escc_reset(DeviceState *d)
339{
340 ESCCState *s = ESCC(d);
341 int i, j;
342
343 for (i = 0; i < 2; i++) {
344 ESCCChannelState *cs = &s->chn[i];
345
346
347
348
349
350
351
352
353 for (j = 0; j < ESCC_SERIAL_REGS; j++) {
354 cs->rregs[j] = 0;
355 cs->wregs[j] = 0;
356 }
357
358
359
360
361
362
363
364
365
366 cs->rregs[R_STATUS] |= STATUS_TXEMPTY;
367
368 escc_reset_chn(cs);
369 }
370}
371
372static inline void set_rxint(ESCCChannelState *s)
373{
374 s->rxint = 1;
375
376
377
378
379 s->rxint_under_svc = 1;
380 if (s->chn == escc_chn_a) {
381 s->rregs[R_INTR] |= INTR_RXINTA;
382 if (s->wregs[W_MINTR] & MINTR_STATUSHI) {
383 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
384 } else {
385 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
386 }
387 } else {
388 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
389 if (s->wregs[W_MINTR] & MINTR_STATUSHI) {
390 s->rregs[R_IVEC] = IVEC_HIRXINTB;
391 } else {
392 s->rregs[R_IVEC] = IVEC_LORXINTB;
393 }
394 }
395 escc_update_irq(s);
396}
397
398static inline void set_txint(ESCCChannelState *s)
399{
400 s->txint = 1;
401 if (!s->rxint_under_svc) {
402 s->txint_under_svc = 1;
403 if (s->chn == escc_chn_a) {
404 if (s->wregs[W_INTR] & INTR_TXINT) {
405 s->rregs[R_INTR] |= INTR_TXINTA;
406 }
407 if (s->wregs[W_MINTR] & MINTR_STATUSHI) {
408 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
409 } else {
410 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
411 }
412 } else {
413 s->rregs[R_IVEC] = IVEC_TXINTB;
414 if (s->wregs[W_INTR] & INTR_TXINT) {
415 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
416 }
417 }
418 escc_update_irq(s);
419 }
420}
421
422static inline void clr_rxint(ESCCChannelState *s)
423{
424 s->rxint = 0;
425 s->rxint_under_svc = 0;
426 if (s->chn == escc_chn_a) {
427 if (s->wregs[W_MINTR] & MINTR_STATUSHI) {
428 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
429 } else {
430 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
431 }
432 s->rregs[R_INTR] &= ~INTR_RXINTA;
433 } else {
434 if (s->wregs[W_MINTR] & MINTR_STATUSHI) {
435 s->rregs[R_IVEC] = IVEC_HINOINT;
436 } else {
437 s->rregs[R_IVEC] = IVEC_LONOINT;
438 }
439 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
440 }
441 if (s->txint) {
442 set_txint(s);
443 }
444 escc_update_irq(s);
445}
446
447static inline void clr_txint(ESCCChannelState *s)
448{
449 s->txint = 0;
450 s->txint_under_svc = 0;
451 if (s->chn == escc_chn_a) {
452 if (s->wregs[W_MINTR] & MINTR_STATUSHI) {
453 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
454 } else {
455 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
456 }
457 s->rregs[R_INTR] &= ~INTR_TXINTA;
458 } else {
459 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
460 if (s->wregs[W_MINTR] & MINTR_STATUSHI) {
461 s->rregs[R_IVEC] = IVEC_HINOINT;
462 } else {
463 s->rregs[R_IVEC] = IVEC_LONOINT;
464 }
465 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
466 }
467 if (s->rxint) {
468 set_rxint(s);
469 }
470 escc_update_irq(s);
471}
472
473static void escc_update_parameters(ESCCChannelState *s)
474{
475 int speed, parity, data_bits, stop_bits;
476 QEMUSerialSetParams ssp;
477
478 if (!qemu_chr_fe_backend_connected(&s->chr) || s->type != escc_serial) {
479 return;
480 }
481
482 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
483 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV) {
484 parity = 'E';
485 } else {
486 parity = 'O';
487 }
488 } else {
489 parity = 'N';
490 }
491 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP) {
492 stop_bits = 2;
493 } else {
494 stop_bits = 1;
495 }
496 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
497 case TXCTRL2_5BITS:
498 data_bits = 5;
499 break;
500 case TXCTRL2_7BITS:
501 data_bits = 7;
502 break;
503 case TXCTRL2_6BITS:
504 data_bits = 6;
505 break;
506 default:
507 case TXCTRL2_8BITS:
508 data_bits = 8;
509 break;
510 }
511 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
512 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
513 case TXCTRL1_CLK1X:
514 break;
515 case TXCTRL1_CLK16X:
516 speed /= 16;
517 break;
518 case TXCTRL1_CLK32X:
519 speed /= 32;
520 break;
521 default:
522 case TXCTRL1_CLK64X:
523 speed /= 64;
524 break;
525 }
526 ssp.speed = speed;
527 ssp.parity = parity;
528 ssp.data_bits = data_bits;
529 ssp.stop_bits = stop_bits;
530 trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
531 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
532}
533
534static void escc_mem_write(void *opaque, hwaddr addr,
535 uint64_t val, unsigned size)
536{
537 ESCCState *serial = opaque;
538 ESCCChannelState *s;
539 uint32_t saddr;
540 int newreg, channel;
541
542 val &= 0xff;
543 saddr = (addr >> reg_shift(serial)) & 1;
544 channel = (addr >> chn_shift(serial)) & 1;
545 s = &serial->chn[channel];
546 switch (saddr) {
547 case SERIAL_CTRL:
548 trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
549 newreg = 0;
550 switch (s->reg) {
551 case W_CMD:
552 newreg = val & CMD_PTR_MASK;
553 val &= CMD_CMD_MASK;
554 switch (val) {
555 case CMD_HI:
556 newreg |= CMD_HI;
557 break;
558 case CMD_CLR_TXINT:
559 clr_txint(s);
560 break;
561 case CMD_CLR_IUS:
562 if (s->rxint_under_svc) {
563 s->rxint_under_svc = 0;
564 if (s->txint) {
565 set_txint(s);
566 }
567 } else if (s->txint_under_svc) {
568 s->txint_under_svc = 0;
569 }
570 escc_update_irq(s);
571 break;
572 default:
573 break;
574 }
575 break;
576 case W_RXCTRL:
577 s->wregs[s->reg] = val;
578 if (val & RXCTRL_HUNT) {
579 s->rregs[R_STATUS] |= STATUS_SYNC;
580 }
581 break;
582 case W_INTR ... W_IVEC:
583 case W_SYNC1 ... W_TXBUF:
584 case W_MISC1 ... W_CLOCK:
585 case W_MISC2 ... W_EXTINT:
586 s->wregs[s->reg] = val;
587 break;
588 case W_TXCTRL1:
589 s->wregs[s->reg] = val;
590
591
592
593
594
595
596
597
598
599
600 s->rregs[R_SPEC] |= SPEC_ALLSENT;
601 escc_update_parameters(s);
602 break;
603 case W_TXCTRL2:
604 s->wregs[s->reg] = val;
605 escc_update_parameters(s);
606 break;
607 case W_BRGLO:
608 case W_BRGHI:
609 s->wregs[s->reg] = val;
610 s->rregs[s->reg] = val;
611 escc_update_parameters(s);
612 break;
613 case W_MINTR:
614 switch (val & MINTR_RST_MASK) {
615 case 0:
616 default:
617 break;
618 case MINTR_RST_B:
619 trace_escc_soft_reset_chn(CHN_C(&serial->chn[0]));
620 escc_soft_reset_chn(&serial->chn[0]);
621 return;
622 case MINTR_RST_A:
623 trace_escc_soft_reset_chn(CHN_C(&serial->chn[1]));
624 escc_soft_reset_chn(&serial->chn[1]);
625 return;
626 case MINTR_RST_ALL:
627 trace_escc_hard_reset();
628 escc_hard_reset_chn(&serial->chn[0]);
629 escc_hard_reset_chn(&serial->chn[1]);
630 return;
631 }
632 break;
633 default:
634 break;
635 }
636 if (s->reg == 0) {
637 s->reg = newreg;
638 } else {
639 s->reg = 0;
640 }
641 break;
642 case SERIAL_DATA:
643 trace_escc_mem_writeb_data(CHN_C(s), val);
644
645
646
647
648
649 s->txint = 0;
650 escc_update_irq(s);
651 s->tx = val;
652 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) {
653 if (qemu_chr_fe_backend_connected(&s->chr)) {
654
655
656
657
658 qemu_chr_fe_write_all(&s->chr, &s->tx, 1);
659 } else if (s->type == escc_kbd && !s->disabled) {
660 handle_kbd_command(s, val);
661 }
662 }
663 s->rregs[R_STATUS] |= STATUS_TXEMPTY;
664 s->rregs[R_SPEC] |= SPEC_ALLSENT;
665 set_txint(s);
666 break;
667 default:
668 break;
669 }
670}
671
672static uint64_t escc_mem_read(void *opaque, hwaddr addr,
673 unsigned size)
674{
675 ESCCState *serial = opaque;
676 ESCCChannelState *s;
677 uint32_t saddr;
678 uint32_t ret;
679 int channel;
680
681 saddr = (addr >> reg_shift(serial)) & 1;
682 channel = (addr >> chn_shift(serial)) & 1;
683 s = &serial->chn[channel];
684 switch (saddr) {
685 case SERIAL_CTRL:
686 trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
687 ret = s->rregs[s->reg];
688 s->reg = 0;
689 return ret;
690 case SERIAL_DATA:
691 s->rregs[R_STATUS] &= ~STATUS_RXAV;
692 clr_rxint(s);
693 if (s->type == escc_kbd || s->type == escc_mouse) {
694 ret = get_queue(s);
695 } else {
696 ret = s->rx;
697 }
698 trace_escc_mem_readb_data(CHN_C(s), ret);
699 qemu_chr_fe_accept_input(&s->chr);
700 return ret;
701 default:
702 break;
703 }
704 return 0;
705}
706
707static const MemoryRegionOps escc_mem_ops = {
708 .read = escc_mem_read,
709 .write = escc_mem_write,
710 .endianness = DEVICE_NATIVE_ENDIAN,
711 .valid = {
712 .min_access_size = 1,
713 .max_access_size = 1,
714 },
715};
716
717static int serial_can_receive(void *opaque)
718{
719 ESCCChannelState *s = opaque;
720 int ret;
721
722 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0)
723 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV)) {
724
725 ret = 0;
726 } else {
727 ret = 1;
728 }
729 return ret;
730}
731
732static void serial_receive_byte(ESCCChannelState *s, int ch)
733{
734 trace_escc_serial_receive_byte(CHN_C(s), ch);
735 s->rregs[R_STATUS] |= STATUS_RXAV;
736 s->rx = ch;
737 set_rxint(s);
738}
739
740static void serial_receive_break(ESCCChannelState *s)
741{
742 s->rregs[R_STATUS] |= STATUS_BRK;
743 escc_update_irq(s);
744}
745
746static void serial_receive1(void *opaque, const uint8_t *buf, int size)
747{
748 ESCCChannelState *s = opaque;
749 serial_receive_byte(s, buf[0]);
750}
751
752static void serial_event(void *opaque, QEMUChrEvent event)
753{
754 ESCCChannelState *s = opaque;
755 if (event == CHR_EVENT_BREAK) {
756 serial_receive_break(s);
757 }
758}
759
760static const VMStateDescription vmstate_escc_chn = {
761 .name = "escc_chn",
762 .version_id = 2,
763 .minimum_version_id = 1,
764 .fields = (VMStateField[]) {
765 VMSTATE_UINT32(vmstate_dummy, ESCCChannelState),
766 VMSTATE_UINT32(reg, ESCCChannelState),
767 VMSTATE_UINT32(rxint, ESCCChannelState),
768 VMSTATE_UINT32(txint, ESCCChannelState),
769 VMSTATE_UINT32(rxint_under_svc, ESCCChannelState),
770 VMSTATE_UINT32(txint_under_svc, ESCCChannelState),
771 VMSTATE_UINT8(rx, ESCCChannelState),
772 VMSTATE_UINT8(tx, ESCCChannelState),
773 VMSTATE_BUFFER(wregs, ESCCChannelState),
774 VMSTATE_BUFFER(rregs, ESCCChannelState),
775 VMSTATE_END_OF_LIST()
776 }
777};
778
779static const VMStateDescription vmstate_escc = {
780 .name = "escc",
781 .version_id = 2,
782 .minimum_version_id = 1,
783 .fields = (VMStateField[]) {
784 VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
785 ESCCChannelState),
786 VMSTATE_END_OF_LIST()
787 }
788};
789
790static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
791 InputEvent *evt)
792{
793 ESCCChannelState *s = (ESCCChannelState *)dev;
794 int qcode, keycode;
795 InputKeyEvent *key;
796
797 assert(evt->type == INPUT_EVENT_KIND_KEY);
798 key = evt->u.key.data;
799 qcode = qemu_input_key_value_to_qcode(key->key);
800 trace_escc_sunkbd_event_in(qcode, QKeyCode_str(qcode),
801 key->down);
802
803 if (qcode == Q_KEY_CODE_CAPS_LOCK) {
804 if (key->down) {
805 s->caps_lock_mode ^= 1;
806 if (s->caps_lock_mode == 2) {
807 return;
808 }
809 } else {
810 s->caps_lock_mode ^= 2;
811 if (s->caps_lock_mode == 3) {
812 return;
813 }
814 }
815 }
816
817 if (qcode == Q_KEY_CODE_NUM_LOCK) {
818 if (key->down) {
819 s->num_lock_mode ^= 1;
820 if (s->num_lock_mode == 2) {
821 return;
822 }
823 } else {
824 s->num_lock_mode ^= 2;
825 if (s->num_lock_mode == 3) {
826 return;
827 }
828 }
829 }
830
831 if (qcode > qemu_input_map_qcode_to_sun_len) {
832 return;
833 }
834
835 keycode = qemu_input_map_qcode_to_sun[qcode];
836 if (!key->down) {
837 keycode |= 0x80;
838 }
839 trace_escc_sunkbd_event_out(keycode);
840 put_queue(s, keycode);
841}
842
843static QemuInputHandler sunkbd_handler = {
844 .name = "sun keyboard",
845 .mask = INPUT_EVENT_MASK_KEY,
846 .event = sunkbd_handle_event,
847};
848
849static void handle_kbd_command(ESCCChannelState *s, int val)
850{
851 trace_escc_kbd_command(val);
852 if (s->led_mode) {
853 s->led_mode = 0;
854 return;
855 }
856 switch (val) {
857 case 1:
858 clear_queue(s);
859 put_queue(s, 0xff);
860 put_queue(s, 4);
861 put_queue(s, 0x7f);
862 break;
863 case 0xe:
864 s->led_mode = 1;
865 break;
866 case 7:
867 case 0xf:
868 clear_queue(s);
869 put_queue(s, 0xfe);
870 put_queue(s, 0x21);
871 break;
872 default:
873 break;
874 }
875}
876
877static void sunmouse_event(void *opaque,
878 int dx, int dy, int dz, int buttons_state)
879{
880 ESCCChannelState *s = opaque;
881 int ch;
882
883 trace_escc_sunmouse_event(dx, dy, buttons_state);
884 ch = 0x80 | 0x7;
885
886 if (buttons_state & MOUSE_EVENT_LBUTTON) {
887 ch ^= 0x4;
888 }
889 if (buttons_state & MOUSE_EVENT_MBUTTON) {
890 ch ^= 0x2;
891 }
892 if (buttons_state & MOUSE_EVENT_RBUTTON) {
893 ch ^= 0x1;
894 }
895
896 put_queue(s, ch);
897
898 ch = dx;
899
900 if (ch > 127) {
901 ch = 127;
902 } else if (ch < -127) {
903 ch = -127;
904 }
905
906 put_queue(s, ch & 0xff);
907
908 ch = -dy;
909
910 if (ch > 127) {
911 ch = 127;
912 } else if (ch < -127) {
913 ch = -127;
914 }
915
916 put_queue(s, ch & 0xff);
917
918
919
920 put_queue(s, 0);
921 put_queue(s, 0);
922}
923
924static void escc_init1(Object *obj)
925{
926 ESCCState *s = ESCC(obj);
927 SysBusDevice *dev = SYS_BUS_DEVICE(obj);
928 unsigned int i;
929
930 for (i = 0; i < 2; i++) {
931 sysbus_init_irq(dev, &s->chn[i].irq);
932 s->chn[i].chn = 1 - i;
933 }
934 s->chn[0].otherchn = &s->chn[1];
935 s->chn[1].otherchn = &s->chn[0];
936
937 sysbus_init_mmio(dev, &s->mmio);
938}
939
940static void escc_realize(DeviceState *dev, Error **errp)
941{
942 ESCCState *s = ESCC(dev);
943 unsigned int i;
944
945 s->chn[0].disabled = s->disabled;
946 s->chn[1].disabled = s->disabled;
947
948 memory_region_init_io(&s->mmio, OBJECT(dev), &escc_mem_ops, s, "escc",
949 ESCC_SIZE << s->it_shift);
950
951 for (i = 0; i < 2; i++) {
952 if (qemu_chr_fe_backend_connected(&s->chn[i].chr)) {
953 s->chn[i].clock = s->frequency / 2;
954 qemu_chr_fe_set_handlers(&s->chn[i].chr, serial_can_receive,
955 serial_receive1, serial_event, NULL,
956 &s->chn[i], NULL, true);
957 }
958 }
959
960 if (s->chn[0].type == escc_mouse) {
961 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
962 "QEMU Sun Mouse");
963 }
964 if (s->chn[1].type == escc_kbd) {
965 s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
966 &sunkbd_handler);
967 }
968}
969
970static Property escc_properties[] = {
971 DEFINE_PROP_UINT32("frequency", ESCCState, frequency, 0),
972 DEFINE_PROP_UINT32("it_shift", ESCCState, it_shift, 0),
973 DEFINE_PROP_BOOL("bit_swap", ESCCState, bit_swap, false),
974 DEFINE_PROP_UINT32("disabled", ESCCState, disabled, 0),
975 DEFINE_PROP_UINT32("chnBtype", ESCCState, chn[0].type, 0),
976 DEFINE_PROP_UINT32("chnAtype", ESCCState, chn[1].type, 0),
977 DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr),
978 DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr),
979 DEFINE_PROP_END_OF_LIST(),
980};
981
982static void escc_class_init(ObjectClass *klass, void *data)
983{
984 DeviceClass *dc = DEVICE_CLASS(klass);
985
986 dc->reset = escc_reset;
987 dc->realize = escc_realize;
988 dc->vmsd = &vmstate_escc;
989 device_class_set_props(dc, escc_properties);
990 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
991}
992
993static const TypeInfo escc_info = {
994 .name = TYPE_ESCC,
995 .parent = TYPE_SYS_BUS_DEVICE,
996 .instance_size = sizeof(ESCCState),
997 .instance_init = escc_init1,
998 .class_init = escc_class_init,
999};
1000
1001static void escc_register_types(void)
1002{
1003 type_register_static(&escc_info);
1004}
1005
1006type_init(escc_register_types)
1007