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 CharDriverState *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 (!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 (s->chr)
560 qemu_chr_fe_write(s->chr, &s->tx, 1);
561 else if (s->type == kbd && !s->disabled) {
562 handle_kbd_command(s, val);
563 }
564 }
565 s->rregs[R_STATUS] |= STATUS_TXEMPTY;
566 s->rregs[R_SPEC] |= SPEC_ALLSENT;
567 set_txint(s);
568 break;
569 default:
570 break;
571 }
572}
573
574static uint64_t escc_mem_read(void *opaque, hwaddr addr,
575 unsigned size)
576{
577 ESCCState *serial = opaque;
578 ChannelState *s;
579 uint32_t saddr;
580 uint32_t ret;
581 int channel;
582
583 saddr = (addr >> serial->it_shift) & 1;
584 channel = (addr >> (serial->it_shift + 1)) & 1;
585 s = &serial->chn[channel];
586 switch (saddr) {
587 case SERIAL_CTRL:
588 trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
589 ret = s->rregs[s->reg];
590 s->reg = 0;
591 return ret;
592 case SERIAL_DATA:
593 s->rregs[R_STATUS] &= ~STATUS_RXAV;
594 clr_rxint(s);
595 if (s->type == kbd || s->type == mouse)
596 ret = get_queue(s);
597 else
598 ret = s->rx;
599 trace_escc_mem_readb_data(CHN_C(s), ret);
600 if (s->chr)
601 qemu_chr_accept_input(s->chr);
602 return ret;
603 default:
604 break;
605 }
606 return 0;
607}
608
609static const MemoryRegionOps escc_mem_ops = {
610 .read = escc_mem_read,
611 .write = escc_mem_write,
612 .endianness = DEVICE_NATIVE_ENDIAN,
613 .valid = {
614 .min_access_size = 1,
615 .max_access_size = 1,
616 },
617};
618
619static int serial_can_receive(void *opaque)
620{
621 ChannelState *s = opaque;
622 int ret;
623
624 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0)
625 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
626
627 ret = 0;
628 else
629 ret = 1;
630 return ret;
631}
632
633static void serial_receive_byte(ChannelState *s, int ch)
634{
635 trace_escc_serial_receive_byte(CHN_C(s), ch);
636 s->rregs[R_STATUS] |= STATUS_RXAV;
637 s->rx = ch;
638 set_rxint(s);
639}
640
641static void serial_receive_break(ChannelState *s)
642{
643 s->rregs[R_STATUS] |= STATUS_BRK;
644 escc_update_irq(s);
645}
646
647static void serial_receive1(void *opaque, const uint8_t *buf, int size)
648{
649 ChannelState *s = opaque;
650 serial_receive_byte(s, buf[0]);
651}
652
653static void serial_event(void *opaque, int event)
654{
655 ChannelState *s = opaque;
656 if (event == CHR_EVENT_BREAK)
657 serial_receive_break(s);
658}
659
660static const VMStateDescription vmstate_escc_chn = {
661 .name ="escc_chn",
662 .version_id = 2,
663 .minimum_version_id = 1,
664 .fields = (VMStateField[]) {
665 VMSTATE_UINT32(vmstate_dummy, ChannelState),
666 VMSTATE_UINT32(reg, ChannelState),
667 VMSTATE_UINT32(rxint, ChannelState),
668 VMSTATE_UINT32(txint, ChannelState),
669 VMSTATE_UINT32(rxint_under_svc, ChannelState),
670 VMSTATE_UINT32(txint_under_svc, ChannelState),
671 VMSTATE_UINT8(rx, ChannelState),
672 VMSTATE_UINT8(tx, ChannelState),
673 VMSTATE_BUFFER(wregs, ChannelState),
674 VMSTATE_BUFFER(rregs, ChannelState),
675 VMSTATE_END_OF_LIST()
676 }
677};
678
679static const VMStateDescription vmstate_escc = {
680 .name ="escc",
681 .version_id = 2,
682 .minimum_version_id = 1,
683 .fields = (VMStateField[]) {
684 VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
685 ChannelState),
686 VMSTATE_END_OF_LIST()
687 }
688};
689
690MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
691 CharDriverState *chrA, CharDriverState *chrB,
692 int clock, int it_shift)
693{
694 DeviceState *dev;
695 SysBusDevice *s;
696 ESCCState *d;
697
698 dev = qdev_create(NULL, TYPE_ESCC);
699 qdev_prop_set_uint32(dev, "disabled", 0);
700 qdev_prop_set_uint32(dev, "frequency", clock);
701 qdev_prop_set_uint32(dev, "it_shift", it_shift);
702 qdev_prop_set_chr(dev, "chrB", chrB);
703 qdev_prop_set_chr(dev, "chrA", chrA);
704 qdev_prop_set_uint32(dev, "chnBtype", ser);
705 qdev_prop_set_uint32(dev, "chnAtype", ser);
706 qdev_init_nofail(dev);
707 s = SYS_BUS_DEVICE(dev);
708 sysbus_connect_irq(s, 0, irqB);
709 sysbus_connect_irq(s, 1, irqA);
710 if (base) {
711 sysbus_mmio_map(s, 0, base);
712 }
713
714 d = ESCC(s);
715 return &d->mmio;
716}
717
718static const uint8_t qcode_to_keycode[Q_KEY_CODE__MAX] = {
719 [Q_KEY_CODE_SHIFT] = 99,
720 [Q_KEY_CODE_SHIFT_R] = 110,
721 [Q_KEY_CODE_ALT] = 19,
722 [Q_KEY_CODE_ALT_R] = 13,
723 [Q_KEY_CODE_ALTGR] = 13,
724 [Q_KEY_CODE_CTRL] = 76,
725 [Q_KEY_CODE_CTRL_R] = 76,
726 [Q_KEY_CODE_ESC] = 29,
727 [Q_KEY_CODE_1] = 30,
728 [Q_KEY_CODE_2] = 31,
729 [Q_KEY_CODE_3] = 32,
730 [Q_KEY_CODE_4] = 33,
731 [Q_KEY_CODE_5] = 34,
732 [Q_KEY_CODE_6] = 35,
733 [Q_KEY_CODE_7] = 36,
734 [Q_KEY_CODE_8] = 37,
735 [Q_KEY_CODE_9] = 38,
736 [Q_KEY_CODE_0] = 39,
737 [Q_KEY_CODE_MINUS] = 40,
738 [Q_KEY_CODE_EQUAL] = 41,
739 [Q_KEY_CODE_BACKSPACE] = 43,
740 [Q_KEY_CODE_TAB] = 53,
741 [Q_KEY_CODE_Q] = 54,
742 [Q_KEY_CODE_W] = 55,
743 [Q_KEY_CODE_E] = 56,
744 [Q_KEY_CODE_R] = 57,
745 [Q_KEY_CODE_T] = 58,
746 [Q_KEY_CODE_Y] = 59,
747 [Q_KEY_CODE_U] = 60,
748 [Q_KEY_CODE_I] = 61,
749 [Q_KEY_CODE_O] = 62,
750 [Q_KEY_CODE_P] = 63,
751 [Q_KEY_CODE_BRACKET_LEFT] = 64,
752 [Q_KEY_CODE_BRACKET_RIGHT] = 65,
753 [Q_KEY_CODE_RET] = 89,
754 [Q_KEY_CODE_A] = 77,
755 [Q_KEY_CODE_S] = 78,
756 [Q_KEY_CODE_D] = 79,
757 [Q_KEY_CODE_F] = 80,
758 [Q_KEY_CODE_G] = 81,
759 [Q_KEY_CODE_H] = 82,
760 [Q_KEY_CODE_J] = 83,
761 [Q_KEY_CODE_K] = 84,
762 [Q_KEY_CODE_L] = 85,
763 [Q_KEY_CODE_SEMICOLON] = 86,
764 [Q_KEY_CODE_APOSTROPHE] = 87,
765 [Q_KEY_CODE_GRAVE_ACCENT] = 42,
766 [Q_KEY_CODE_BACKSLASH] = 88,
767 [Q_KEY_CODE_Z] = 100,
768 [Q_KEY_CODE_X] = 101,
769 [Q_KEY_CODE_C] = 102,
770 [Q_KEY_CODE_V] = 103,
771 [Q_KEY_CODE_B] = 104,
772 [Q_KEY_CODE_N] = 105,
773 [Q_KEY_CODE_M] = 106,
774 [Q_KEY_CODE_COMMA] = 107,
775 [Q_KEY_CODE_DOT] = 108,
776 [Q_KEY_CODE_SLASH] = 109,
777 [Q_KEY_CODE_ASTERISK] = 47,
778 [Q_KEY_CODE_SPC] = 121,
779 [Q_KEY_CODE_CAPS_LOCK] = 119,
780 [Q_KEY_CODE_F1] = 5,
781 [Q_KEY_CODE_F2] = 6,
782 [Q_KEY_CODE_F3] = 8,
783 [Q_KEY_CODE_F4] = 10,
784 [Q_KEY_CODE_F5] = 12,
785 [Q_KEY_CODE_F6] = 14,
786 [Q_KEY_CODE_F7] = 16,
787 [Q_KEY_CODE_F8] = 17,
788 [Q_KEY_CODE_F9] = 18,
789 [Q_KEY_CODE_F10] = 7,
790 [Q_KEY_CODE_NUM_LOCK] = 98,
791 [Q_KEY_CODE_SCROLL_LOCK] = 23,
792 [Q_KEY_CODE_KP_DIVIDE] = 46,
793 [Q_KEY_CODE_KP_MULTIPLY] = 47,
794 [Q_KEY_CODE_KP_SUBTRACT] = 71,
795 [Q_KEY_CODE_KP_ADD] = 125,
796 [Q_KEY_CODE_KP_ENTER] = 90,
797 [Q_KEY_CODE_KP_DECIMAL] = 50,
798 [Q_KEY_CODE_KP_0] = 94,
799 [Q_KEY_CODE_KP_1] = 112,
800 [Q_KEY_CODE_KP_2] = 113,
801 [Q_KEY_CODE_KP_3] = 114,
802 [Q_KEY_CODE_KP_4] = 91,
803 [Q_KEY_CODE_KP_5] = 92,
804 [Q_KEY_CODE_KP_6] = 93,
805 [Q_KEY_CODE_KP_7] = 68,
806 [Q_KEY_CODE_KP_8] = 69,
807 [Q_KEY_CODE_KP_9] = 70,
808 [Q_KEY_CODE_LESS] = 124,
809 [Q_KEY_CODE_F11] = 9,
810 [Q_KEY_CODE_F12] = 11,
811 [Q_KEY_CODE_HOME] = 52,
812 [Q_KEY_CODE_PGUP] = 96,
813 [Q_KEY_CODE_PGDN] = 123,
814 [Q_KEY_CODE_END] = 74,
815 [Q_KEY_CODE_LEFT] = 24,
816 [Q_KEY_CODE_UP] = 20,
817 [Q_KEY_CODE_DOWN] = 27,
818 [Q_KEY_CODE_RIGHT] = 28,
819 [Q_KEY_CODE_INSERT] = 44,
820 [Q_KEY_CODE_DELETE] = 66,
821 [Q_KEY_CODE_STOP] = 1,
822 [Q_KEY_CODE_AGAIN] = 3,
823 [Q_KEY_CODE_PROPS] = 25,
824 [Q_KEY_CODE_UNDO] = 26,
825 [Q_KEY_CODE_FRONT] = 49,
826 [Q_KEY_CODE_COPY] = 51,
827 [Q_KEY_CODE_OPEN] = 72,
828 [Q_KEY_CODE_PASTE] = 73,
829 [Q_KEY_CODE_FIND] = 95,
830 [Q_KEY_CODE_CUT] = 97,
831 [Q_KEY_CODE_LF] = 111,
832 [Q_KEY_CODE_HELP] = 118,
833 [Q_KEY_CODE_META_L] = 120,
834 [Q_KEY_CODE_META_R] = 122,
835 [Q_KEY_CODE_COMPOSE] = 67,
836 [Q_KEY_CODE_PRINT] = 22,
837 [Q_KEY_CODE_SYSRQ] = 21,
838};
839
840static void sunkbd_handle_event(DeviceState *dev, QemuConsole *src,
841 InputEvent *evt)
842{
843 ChannelState *s = (ChannelState *)dev;
844 int qcode, keycode;
845 InputKeyEvent *key;
846
847 assert(evt->type == INPUT_EVENT_KIND_KEY);
848 key = evt->u.key.data;
849 qcode = qemu_input_key_value_to_qcode(key->key);
850 trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode],
851 key->down);
852
853 if (qcode == Q_KEY_CODE_CAPS_LOCK) {
854 if (key->down) {
855 s->caps_lock_mode ^= 1;
856 if (s->caps_lock_mode == 2) {
857 return;
858 }
859 } else {
860 s->caps_lock_mode ^= 2;
861 if (s->caps_lock_mode == 3) {
862 return;
863 }
864 }
865 }
866
867 if (qcode == Q_KEY_CODE_NUM_LOCK) {
868 if (key->down) {
869 s->num_lock_mode ^= 1;
870 if (s->num_lock_mode == 2) {
871 return;
872 }
873 } else {
874 s->num_lock_mode ^= 2;
875 if (s->num_lock_mode == 3) {
876 return;
877 }
878 }
879 }
880
881 keycode = qcode_to_keycode[qcode];
882 if (!key->down) {
883 keycode |= 0x80;
884 }
885 trace_escc_sunkbd_event_out(keycode);
886 put_queue(s, keycode);
887}
888
889static QemuInputHandler sunkbd_handler = {
890 .name = "sun keyboard",
891 .mask = INPUT_EVENT_MASK_KEY,
892 .event = sunkbd_handle_event,
893};
894
895static void handle_kbd_command(ChannelState *s, int val)
896{
897 trace_escc_kbd_command(val);
898 if (s->led_mode) {
899 s->led_mode = 0;
900 return;
901 }
902 switch (val) {
903 case 1:
904 clear_queue(s);
905 put_queue(s, 0xff);
906 put_queue(s, 4);
907 put_queue(s, 0x7f);
908 break;
909 case 0xe:
910 s->led_mode = 1;
911 break;
912 case 7:
913 case 0xf:
914 clear_queue(s);
915 put_queue(s, 0xfe);
916 put_queue(s, 0x21);
917 break;
918 default:
919 break;
920 }
921}
922
923static void sunmouse_event(void *opaque,
924 int dx, int dy, int dz, int buttons_state)
925{
926 ChannelState *s = opaque;
927 int ch;
928
929 trace_escc_sunmouse_event(dx, dy, buttons_state);
930 ch = 0x80 | 0x7;
931
932 if (buttons_state & MOUSE_EVENT_LBUTTON)
933 ch ^= 0x4;
934 if (buttons_state & MOUSE_EVENT_MBUTTON)
935 ch ^= 0x2;
936 if (buttons_state & MOUSE_EVENT_RBUTTON)
937 ch ^= 0x1;
938
939 put_queue(s, ch);
940
941 ch = dx;
942
943 if (ch > 127)
944 ch = 127;
945 else if (ch < -127)
946 ch = -127;
947
948 put_queue(s, ch & 0xff);
949
950 ch = -dy;
951
952 if (ch > 127)
953 ch = 127;
954 else if (ch < -127)
955 ch = -127;
956
957 put_queue(s, ch & 0xff);
958
959
960
961 put_queue(s, 0);
962 put_queue(s, 0);
963}
964
965void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
966 int disabled, int clock, int it_shift)
967{
968 DeviceState *dev;
969 SysBusDevice *s;
970
971 dev = qdev_create(NULL, TYPE_ESCC);
972 qdev_prop_set_uint32(dev, "disabled", disabled);
973 qdev_prop_set_uint32(dev, "frequency", clock);
974 qdev_prop_set_uint32(dev, "it_shift", it_shift);
975 qdev_prop_set_chr(dev, "chrB", NULL);
976 qdev_prop_set_chr(dev, "chrA", NULL);
977 qdev_prop_set_uint32(dev, "chnBtype", mouse);
978 qdev_prop_set_uint32(dev, "chnAtype", kbd);
979 qdev_init_nofail(dev);
980 s = SYS_BUS_DEVICE(dev);
981 sysbus_connect_irq(s, 0, irq);
982 sysbus_connect_irq(s, 1, irq);
983 sysbus_mmio_map(s, 0, base);
984}
985
986static int escc_init1(SysBusDevice *dev)
987{
988 ESCCState *s = ESCC(dev);
989 unsigned int i;
990
991 s->chn[0].disabled = s->disabled;
992 s->chn[1].disabled = s->disabled;
993 for (i = 0; i < 2; i++) {
994 sysbus_init_irq(dev, &s->chn[i].irq);
995 s->chn[i].chn = 1 - i;
996 s->chn[i].clock = s->frequency / 2;
997 if (s->chn[i].chr) {
998 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
999 serial_receive1, serial_event, &s->chn[i]);
1000 }
1001 }
1002 s->chn[0].otherchn = &s->chn[1];
1003 s->chn[1].otherchn = &s->chn[0];
1004
1005 memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
1006 ESCC_SIZE << s->it_shift);
1007 sysbus_init_mmio(dev, &s->mmio);
1008
1009 if (s->chn[0].type == mouse) {
1010 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
1011 "QEMU Sun Mouse");
1012 }
1013 if (s->chn[1].type == kbd) {
1014 s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
1015 &sunkbd_handler);
1016 }
1017
1018 return 0;
1019}
1020
1021static Property escc_properties[] = {
1022 DEFINE_PROP_UINT32("frequency", ESCCState, frequency, 0),
1023 DEFINE_PROP_UINT32("it_shift", ESCCState, it_shift, 0),
1024 DEFINE_PROP_UINT32("disabled", ESCCState, disabled, 0),
1025 DEFINE_PROP_UINT32("chnBtype", ESCCState, chn[0].type, 0),
1026 DEFINE_PROP_UINT32("chnAtype", ESCCState, chn[1].type, 0),
1027 DEFINE_PROP_CHR("chrB", ESCCState, chn[0].chr),
1028 DEFINE_PROP_CHR("chrA", ESCCState, chn[1].chr),
1029 DEFINE_PROP_END_OF_LIST(),
1030};
1031
1032static void escc_class_init(ObjectClass *klass, void *data)
1033{
1034 DeviceClass *dc = DEVICE_CLASS(klass);
1035 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1036
1037 k->init = escc_init1;
1038 dc->reset = escc_reset;
1039 dc->vmsd = &vmstate_escc;
1040 dc->props = escc_properties;
1041 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1042}
1043
1044static const TypeInfo escc_info = {
1045 .name = TYPE_ESCC,
1046 .parent = TYPE_SYS_BUS_DEVICE,
1047 .instance_size = sizeof(ESCCState),
1048 .class_init = escc_class_init,
1049};
1050
1051static void escc_register_types(void)
1052{
1053 type_register_static(&escc_info);
1054}
1055
1056type_init(escc_register_types)
1057