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