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