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