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