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