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