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 "sysemu/char.h"
30#include "ui/console.h"
31#include "ui/input.h"
32#include "trace.h"
33
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
66typedef enum {
67 chn_a, chn_b,
68} ChnID;
69
70#define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
71
72typedef enum {
73 ser, kbd, mouse,
74} ChnType;
75
76#define SERIO_QUEUE_SIZE 256
77
78typedef struct {
79 uint8_t data[SERIO_QUEUE_SIZE];
80 int rptr, wptr, count;
81} SERIOQueue;
82
83#define SERIAL_REGS 16
84typedef struct ChannelState {
85 qemu_irq irq;
86 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
87 struct ChannelState *otherchn;
88 uint32_t reg;
89 uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
90 SERIOQueue queue;
91 CharBackend chr;
92 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
93 int disabled;
94 int clock;
95 uint32_t vmstate_dummy;
96 ChnID chn;
97 ChnType type;
98 uint8_t rx, tx;
99 QemuInputHandlerState *hs;
100} ChannelState;
101
102#define ESCC(obj) OBJECT_CHECK(ESCCState, (obj), TYPE_ESCC)
103
104typedef struct ESCCState {
105 SysBusDevice parent_obj;
106
107 struct ChannelState chn[2];
108 uint32_t it_shift;
109 MemoryRegion mmio;
110 uint32_t disabled;
111 uint32_t frequency;
112} ESCCState;
113
114#define SERIAL_CTRL 0
115#define SERIAL_DATA 1
116
117#define W_CMD 0
118#define CMD_PTR_MASK 0x07
119#define CMD_CMD_MASK 0x38
120#define CMD_HI 0x08
121#define CMD_CLR_TXINT 0x28
122#define CMD_CLR_IUS 0x38
123#define W_INTR 1
124#define INTR_INTALL 0x01
125#define INTR_TXINT 0x02
126#define INTR_RXMODEMSK 0x18
127#define INTR_RXINT1ST 0x08
128#define INTR_RXINTALL 0x10
129#define W_IVEC 2
130#define W_RXCTRL 3
131#define RXCTRL_RXEN 0x01
132#define W_TXCTRL1 4
133#define TXCTRL1_PAREN 0x01
134#define TXCTRL1_PAREV 0x02
135#define TXCTRL1_1STOP 0x04
136#define TXCTRL1_1HSTOP 0x08
137#define TXCTRL1_2STOP 0x0c
138#define TXCTRL1_STPMSK 0x0c
139#define TXCTRL1_CLK1X 0x00
140#define TXCTRL1_CLK16X 0x40
141#define TXCTRL1_CLK32X 0x80
142#define TXCTRL1_CLK64X 0xc0
143#define TXCTRL1_CLKMSK 0xc0
144#define W_TXCTRL2 5
145#define TXCTRL2_TXEN 0x08
146#define TXCTRL2_BITMSK 0x60
147#define TXCTRL2_5BITS 0x00
148#define TXCTRL2_7BITS 0x20
149#define TXCTRL2_6BITS 0x40
150#define TXCTRL2_8BITS 0x60
151#define W_SYNC1 6
152#define W_SYNC2 7
153#define W_TXBUF 8
154#define W_MINTR 9
155#define MINTR_STATUSHI 0x10
156#define MINTR_RST_MASK 0xc0
157#define MINTR_RST_B 0x40
158#define MINTR_RST_A 0x80
159#define MINTR_RST_ALL 0xc0
160#define W_MISC1 10
161#define W_CLOCK 11
162#define CLOCK_TRXC 0x08
163#define W_BRGLO 12
164#define W_BRGHI 13
165#define W_MISC2 14
166#define MISC2_PLLDIS 0x30
167#define W_EXTINT 15
168#define EXTINT_DCD 0x08
169#define EXTINT_SYNCINT 0x10
170#define EXTINT_CTSINT 0x20
171#define EXTINT_TXUNDRN 0x40
172#define EXTINT_BRKINT 0x80
173
174#define R_STATUS 0
175#define STATUS_RXAV 0x01
176#define STATUS_ZERO 0x02
177#define STATUS_TXEMPTY 0x04
178#define STATUS_DCD 0x08
179#define STATUS_SYNC 0x10
180#define STATUS_CTS 0x20
181#define STATUS_TXUNDRN 0x40
182#define STATUS_BRK 0x80
183#define R_SPEC 1
184#define SPEC_ALLSENT 0x01
185#define SPEC_BITS8 0x06
186#define R_IVEC 2
187#define IVEC_TXINTB 0x00
188#define IVEC_LONOINT 0x06
189#define IVEC_LORXINTA 0x0c
190#define IVEC_LORXINTB 0x04
191#define IVEC_LOTXINTA 0x08
192#define IVEC_HINOINT 0x60
193#define IVEC_HIRXINTA 0x30
194#define IVEC_HIRXINTB 0x20
195#define IVEC_HITXINTA 0x10
196#define R_INTR 3
197#define INTR_EXTINTB 0x01
198#define INTR_TXINTB 0x02
199#define INTR_RXINTB 0x04
200#define INTR_EXTINTA 0x08
201#define INTR_TXINTA 0x10
202#define INTR_RXINTA 0x20
203#define R_IPEN 4
204#define R_TXCTRL1 5
205#define R_TXCTRL2 6
206#define R_BC 7
207#define R_RXBUF 8
208#define R_RXCTRL 9
209#define R_MISC 10
210#define R_MISC1 11
211#define R_BRGLO 12
212#define R_BRGHI 13
213#define R_MISC1I 14
214#define R_EXTINT 15
215
216static void handle_kbd_command(ChannelState *s, int val);
217static int serial_can_receive(void *opaque);
218static void serial_receive_byte(ChannelState *s, int ch);
219
220static void clear_queue(void *opaque)
221{
222 ChannelState *s = opaque;
223 SERIOQueue *q = &s->queue;
224 q->rptr = q->wptr = q->count = 0;
225}
226
227static void put_queue(void *opaque, int b)
228{
229 ChannelState *s = opaque;
230 SERIOQueue *q = &s->queue;
231
232 trace_escc_put_queue(CHN_C(s), b);
233 if (q->count >= SERIO_QUEUE_SIZE)
234 return;
235 q->data[q->wptr] = b;
236 if (++q->wptr == SERIO_QUEUE_SIZE)
237 q->wptr = 0;
238 q->count++;
239 serial_receive_byte(s, 0);
240}
241
242static uint32_t get_queue(void *opaque)
243{
244 ChannelState *s = opaque;
245 SERIOQueue *q = &s->queue;
246 int val;
247
248 if (q->count == 0) {
249 return 0;
250 } else {
251 val = q->data[q->rptr];
252 if (++q->rptr == SERIO_QUEUE_SIZE)
253 q->rptr = 0;
254 q->count--;
255 }
256 trace_escc_get_queue(CHN_C(s), val);
257 if (q->count > 0)
258 serial_receive_byte(s, 0);
259 return val;
260}
261
262static int escc_update_irq_chn(ChannelState *s)
263{
264 if ((((s->wregs[W_INTR] & INTR_TXINT) && (s->txint == 1)) ||
265
266 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
267 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
268 s->rxint == 1) ||
269 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
270 (s->rregs[R_STATUS] & STATUS_BRK)))) {
271 return 1;
272 }
273 return 0;
274}
275
276static void escc_update_irq(ChannelState *s)
277{
278 int irq;
279
280 irq = escc_update_irq_chn(s);
281 irq |= escc_update_irq_chn(s->otherchn);
282
283 trace_escc_update_irq(irq);
284 qemu_set_irq(s->irq, irq);
285}
286
287static void escc_reset_chn(ChannelState *s)
288{
289 int i;
290
291 s->reg = 0;
292 for (i = 0; i < SERIAL_REGS; i++) {
293 s->rregs[i] = 0;
294 s->wregs[i] = 0;
295 }
296 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP;
297 s->wregs[W_MINTR] = MINTR_RST_ALL;
298 s->wregs[W_CLOCK] = CLOCK_TRXC;
299 s->wregs[W_MISC2] = MISC2_PLLDIS;
300 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
301 EXTINT_TXUNDRN | EXTINT_BRKINT;
302 if (s->disabled)
303 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
304 STATUS_CTS | STATUS_TXUNDRN;
305 else
306 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
307 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
308
309 s->rx = s->tx = 0;
310 s->rxint = s->txint = 0;
311 s->rxint_under_svc = s->txint_under_svc = 0;
312 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
313 clear_queue(s);
314}
315
316static void escc_reset(DeviceState *d)
317{
318 ESCCState *s = ESCC(d);
319
320 escc_reset_chn(&s->chn[0]);
321 escc_reset_chn(&s->chn[1]);
322}
323
324static inline void set_rxint(ChannelState *s)
325{
326 s->rxint = 1;
327
328
329 s->rxint_under_svc = 1;
330 if (s->chn == chn_a) {
331 s->rregs[R_INTR] |= INTR_RXINTA;
332 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
333 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
334 else
335 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
336 } else {
337 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
338 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
339 s->rregs[R_IVEC] = IVEC_HIRXINTB;
340 else
341 s->rregs[R_IVEC] = IVEC_LORXINTB;
342 }
343 escc_update_irq(s);
344}
345
346static inline void set_txint(ChannelState *s)
347{
348 s->txint = 1;
349 if (!s->rxint_under_svc) {
350 s->txint_under_svc = 1;
351 if (s->chn == chn_a) {
352 if (s->wregs[W_INTR] & INTR_TXINT) {
353 s->rregs[R_INTR] |= INTR_TXINTA;
354 }
355 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
356 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
357 else
358 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
359 } else {
360 s->rregs[R_IVEC] = IVEC_TXINTB;
361 if (s->wregs[W_INTR] & INTR_TXINT) {
362 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
363 }
364 }
365 escc_update_irq(s);
366 }
367}
368
369static inline void clr_rxint(ChannelState *s)
370{
371 s->rxint = 0;
372 s->rxint_under_svc = 0;
373 if (s->chn == chn_a) {
374 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
375 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
376 else
377 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
378 s->rregs[R_INTR] &= ~INTR_RXINTA;
379 } else {
380 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
381 s->rregs[R_IVEC] = IVEC_HINOINT;
382 else
383 s->rregs[R_IVEC] = IVEC_LONOINT;
384 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
385 }
386 if (s->txint)
387 set_txint(s);
388 escc_update_irq(s);
389}
390
391static inline void clr_txint(ChannelState *s)
392{
393 s->txint = 0;
394 s->txint_under_svc = 0;
395 if (s->chn == chn_a) {
396 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
397 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
398 else
399 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
400 s->rregs[R_INTR] &= ~INTR_TXINTA;
401 } else {
402 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
403 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
404 s->rregs[R_IVEC] = IVEC_HINOINT;
405 else
406 s->rregs[R_IVEC] = IVEC_LONOINT;
407 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
408 }
409 if (s->rxint)
410 set_rxint(s);
411 escc_update_irq(s);
412}
413
414static void escc_update_parameters(ChannelState *s)
415{
416 int speed, parity, data_bits, stop_bits;
417 QEMUSerialSetParams ssp;
418
419 if (!qemu_chr_fe_get_driver(&s->chr) || s->type != ser)
420 return;
421
422 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
423 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
424 parity = 'E';
425 else
426 parity = 'O';
427 } else {
428 parity = 'N';
429 }
430 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
431 stop_bits = 2;
432 else
433 stop_bits = 1;
434 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
435 case TXCTRL2_5BITS:
436 data_bits = 5;
437 break;
438 case TXCTRL2_7BITS:
439 data_bits = 7;
440 break;
441 case TXCTRL2_6BITS:
442 data_bits = 6;
443 break;
444 default:
445 case TXCTRL2_8BITS:
446 data_bits = 8;
447 break;
448 }
449 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
450 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
451 case TXCTRL1_CLK1X:
452 break;
453 case TXCTRL1_CLK16X:
454 speed /= 16;
455 break;
456 case TXCTRL1_CLK32X:
457 speed /= 32;
458 break;
459 default:
460 case TXCTRL1_CLK64X:
461 speed /= 64;
462 break;
463 }
464 ssp.speed = speed;
465 ssp.parity = parity;
466 ssp.data_bits = data_bits;
467 ssp.stop_bits = stop_bits;
468 trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
469 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
470}
471
472static void escc_mem_write(void *opaque, hwaddr addr,
473 uint64_t val, unsigned size)
474{
475 ESCCState *serial = opaque;
476 ChannelState *s;
477 uint32_t saddr;
478 int newreg, channel;
479
480 val &= 0xff;
481 saddr = (addr >> serial->it_shift) & 1;
482 channel = (addr >> (serial->it_shift + 1)) & 1;
483 s = &serial->chn[channel];
484 switch (saddr) {
485 case SERIAL_CTRL:
486 trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
487 newreg = 0;
488 switch (s->reg) {
489 case W_CMD:
490 newreg = val & CMD_PTR_MASK;
491 val &= CMD_CMD_MASK;
492 switch (val) {
493 case CMD_HI:
494 newreg |= CMD_HI;
495 break;
496 case CMD_CLR_TXINT:
497 clr_txint(s);
498 break;
499 case CMD_CLR_IUS:
500 if (s->rxint_under_svc) {
501 s->rxint_under_svc = 0;
502 if (s->txint) {
503 set_txint(s);
504 }
505 } else if (s->txint_under_svc) {
506 s->txint_under_svc = 0;
507 }
508 escc_update_irq(s);
509 break;
510 default:
511 break;
512 }
513 break;
514 case W_INTR ... W_RXCTRL:
515 case W_SYNC1 ... W_TXBUF:
516 case W_MISC1 ... W_CLOCK:
517 case W_MISC2 ... W_EXTINT:
518 s->wregs[s->reg] = val;
519 break;
520 case W_TXCTRL1:
521 case W_TXCTRL2:
522 s->wregs[s->reg] = val;
523 escc_update_parameters(s);
524 break;
525 case W_BRGLO:
526 case W_BRGHI:
527 s->wregs[s->reg] = val;
528 s->rregs[s->reg] = val;
529 escc_update_parameters(s);
530 break;
531 case W_MINTR:
532 switch (val & MINTR_RST_MASK) {
533 case 0:
534 default:
535 break;
536 case MINTR_RST_B:
537 escc_reset_chn(&serial->chn[0]);
538 return;
539 case MINTR_RST_A:
540 escc_reset_chn(&serial->chn[1]);
541 return;
542 case MINTR_RST_ALL:
543 escc_reset(DEVICE(serial));
544 return;
545 }
546 break;
547 default:
548 break;
549 }
550 if (s->reg == 0)
551 s->reg = newreg;
552 else
553 s->reg = 0;
554 break;
555 case SERIAL_DATA:
556 trace_escc_mem_writeb_data(CHN_C(s), val);
557 s->tx = val;
558 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) {
559 if (qemu_chr_fe_get_driver(&s->chr)) {
560
561
562 qemu_chr_fe_write_all(&s->chr, &s->tx, 1);
563 } else if (s->type == kbd && !s->disabled) {
564 handle_kbd_command(s, val);
565 }
566 }
567 s->rregs[R_STATUS] |= STATUS_TXEMPTY;
568 s->rregs[R_SPEC] |= SPEC_ALLSENT;
569 set_txint(s);
570 break;
571 default:
572 break;
573 }
574}
575
576static uint64_t escc_mem_read(void *opaque, hwaddr addr,
577 unsigned size)
578{
579 ESCCState *serial = opaque;
580 ChannelState *s;
581 uint32_t saddr;
582 uint32_t ret;
583 int channel;
584
585 saddr = (addr >> serial->it_shift) & 1;
586 channel = (addr >> (serial->it_shift + 1)) & 1;
587 s = &serial->chn[channel];
588 switch (saddr) {
589 case SERIAL_CTRL:
590 trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
591 ret = s->rregs[s->reg];
592 s->reg = 0;
593 return ret;
594 case SERIAL_DATA:
595 s->rregs[R_STATUS] &= ~STATUS_RXAV;
596 clr_rxint(s);
597 if (s->type == kbd || s->type == mouse)
598 ret = get_queue(s);
599 else
600 ret = s->rx;
601 trace_escc_mem_readb_data(CHN_C(s), ret);
602 qemu_chr_fe_accept_input(&s->chr);
603 return ret;
604 default:
605 break;
606 }
607 return 0;
608}
609
610static const MemoryRegionOps escc_mem_ops = {
611 .read = escc_mem_read,
612 .write = escc_mem_write,
613 .endianness = DEVICE_NATIVE_ENDIAN,
614 .valid = {
615 .min_access_size = 1,
616 .max_access_size = 1,
617 },
618};
619
620static int serial_can_receive(void *opaque)
621{
622 ChannelState *s = opaque;
623 int ret;
624
625 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0)
626 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
627
628 ret = 0;
629 else
630 ret = 1;
631 return ret;
632}
633
634static void serial_receive_byte(ChannelState *s, int ch)
635{
636 trace_escc_serial_receive_byte(CHN_C(s), ch);
637 s->rregs[R_STATUS] |= STATUS_RXAV;
638 s->rx = ch;
639 set_rxint(s);
640}
641
642static void serial_receive_break(ChannelState *s)
643{
644 s->rregs[R_STATUS] |= STATUS_BRK;
645 escc_update_irq(s);
646}
647
648static void serial_receive1(void *opaque, const uint8_t *buf, int size)
649{
650 ChannelState *s = opaque;
651 serial_receive_byte(s, buf[0]);
652}
653
654static void serial_event(void *opaque, int event)
655{
656 ChannelState *s = opaque;
657 if (event == CHR_EVENT_BREAK)
658 serial_receive_break(s);
659}
660
661static const VMStateDescription vmstate_escc_chn = {
662 .name ="escc_chn",
663 .version_id = 2,
664 .minimum_version_id = 1,
665 .fields = (VMStateField[]) {
666 VMSTATE_UINT32(vmstate_dummy, ChannelState),
667 VMSTATE_UINT32(reg, ChannelState),
668 VMSTATE_UINT32(rxint, ChannelState),
669 VMSTATE_UINT32(txint, ChannelState),
670 VMSTATE_UINT32(rxint_under_svc, ChannelState),
671 VMSTATE_UINT32(txint_under_svc, ChannelState),
672 VMSTATE_UINT8(rx, ChannelState),
673 VMSTATE_UINT8(tx, ChannelState),
674 VMSTATE_BUFFER(wregs, ChannelState),
675 VMSTATE_BUFFER(rregs, ChannelState),
676 VMSTATE_END_OF_LIST()
677 }
678};
679
680static const VMStateDescription vmstate_escc = {
681 .name ="escc",
682 .version_id = 2,
683 .minimum_version_id = 1,
684 .fields = (VMStateField[]) {
685 VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
686 ChannelState),
687 VMSTATE_END_OF_LIST()
688 }
689};
690
691MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
692 CharDriverState *chrA, CharDriverState *chrB,
693 int clock, int it_shift)
694{
695 DeviceState *dev;
696 SysBusDevice *s;
697 ESCCState *d;
698
699 dev = qdev_create(NULL, TYPE_ESCC);
700 qdev_prop_set_uint32(dev, "disabled", 0);
701 qdev_prop_set_uint32(dev, "frequency", clock);
702 qdev_prop_set_uint32(dev, "it_shift", it_shift);
703 qdev_prop_set_chr(dev, "chrB", chrB);
704 qdev_prop_set_chr(dev, "chrA", chrA);
705 qdev_prop_set_uint32(dev, "chnBtype", ser);
706 qdev_prop_set_uint32(dev, "chnAtype", ser);
707 qdev_init_nofail(dev);
708 s = SYS_BUS_DEVICE(dev);
709 sysbus_connect_irq(s, 0, irqB);
710 sysbus_connect_irq(s, 1, irqA);
711 if (base) {
712 sysbus_mmio_map(s, 0, base);
713 }
714
715 d = ESCC(s);
716 return &d->mmio;
717}
718
719static const uint8_t qcode_to_keycode[Q_KEY_CODE__MAX] = {
720 [Q_KEY_CODE_SHIFT] = 99,
721 [Q_KEY_CODE_SHIFT_R] = 110,
722 [Q_KEY_CODE_ALT] = 19,
723 [Q_KEY_CODE_ALT_R] = 13,
724 [Q_KEY_CODE_ALTGR] = 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_get_driver(&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,
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