2 * QEMU ESCC (Z8030/Z8530/Z85C30/SCC/ESCC) serial port emulation
4 * Copyright (c) 2003-2005 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 #include "hw/sysbus.h"
28 #include "char/char.h"
29 #include "ui/console.h"
34 * "Z80C30/Z85C30/Z80230/Z85230/Z85233 SCC/ESCC User Manual",
35 * http://www.zilog.com/docs/serial/scc_escc_um.pdf
37 * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001
38 * (Slave I/O), also produced as NCR89C105. See
39 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
41 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
42 * mouse and keyboard ports don't implement all functions and they are
43 * only asynchronous. There is no DMA.
45 * Z85C30 is also used on PowerMacs. There are some small differences
46 * between Sparc version (sunzilog) and PowerMac (pmac):
47 * Offset between control and data registers
48 * There is some kind of lockup bug, but we can ignore it
50 * DMA on pmac using DBDMA chip
51 * pmac can do IRDA and faster rates, sunzilog can only do 38400
52 * pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz
57 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
59 * Implemented serial mouse protocol.
61 * 2010-May-23 Artyom Tarasenko: Reworked IUS logic
68 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
74 #define SERIO_QUEUE_SIZE 256
77 uint8_t data
[SERIO_QUEUE_SIZE
];
78 int rptr
, wptr
, count
;
81 #define SERIAL_REGS 16
82 typedef struct ChannelState
{
84 uint32_t rxint
, txint
, rxint_under_svc
, txint_under_svc
;
85 struct ChannelState
*otherchn
;
87 uint8_t wregs
[SERIAL_REGS
], rregs
[SERIAL_REGS
];
90 int e0_mode
, led_mode
, caps_lock_mode
, num_lock_mode
;
93 uint32_t vmstate_dummy
;
94 ChnID chn
; // this channel, A (base+4) or B (base+0)
101 struct ChannelState chn
[2];
108 #define SERIAL_CTRL 0
109 #define SERIAL_DATA 1
112 #define CMD_PTR_MASK 0x07
113 #define CMD_CMD_MASK 0x38
115 #define CMD_CLR_TXINT 0x28
116 #define CMD_CLR_IUS 0x38
118 #define INTR_INTALL 0x01
119 #define INTR_TXINT 0x02
120 #define INTR_RXMODEMSK 0x18
121 #define INTR_RXINT1ST 0x08
122 #define INTR_RXINTALL 0x10
125 #define RXCTRL_RXEN 0x01
127 #define TXCTRL1_PAREN 0x01
128 #define TXCTRL1_PAREV 0x02
129 #define TXCTRL1_1STOP 0x04
130 #define TXCTRL1_1HSTOP 0x08
131 #define TXCTRL1_2STOP 0x0c
132 #define TXCTRL1_STPMSK 0x0c
133 #define TXCTRL1_CLK1X 0x00
134 #define TXCTRL1_CLK16X 0x40
135 #define TXCTRL1_CLK32X 0x80
136 #define TXCTRL1_CLK64X 0xc0
137 #define TXCTRL1_CLKMSK 0xc0
139 #define TXCTRL2_TXEN 0x08
140 #define TXCTRL2_BITMSK 0x60
141 #define TXCTRL2_5BITS 0x00
142 #define TXCTRL2_7BITS 0x20
143 #define TXCTRL2_6BITS 0x40
144 #define TXCTRL2_8BITS 0x60
149 #define MINTR_STATUSHI 0x10
150 #define MINTR_RST_MASK 0xc0
151 #define MINTR_RST_B 0x40
152 #define MINTR_RST_A 0x80
153 #define MINTR_RST_ALL 0xc0
156 #define CLOCK_TRXC 0x08
160 #define MISC2_PLLDIS 0x30
162 #define EXTINT_DCD 0x08
163 #define EXTINT_SYNCINT 0x10
164 #define EXTINT_CTSINT 0x20
165 #define EXTINT_TXUNDRN 0x40
166 #define EXTINT_BRKINT 0x80
169 #define STATUS_RXAV 0x01
170 #define STATUS_ZERO 0x02
171 #define STATUS_TXEMPTY 0x04
172 #define STATUS_DCD 0x08
173 #define STATUS_SYNC 0x10
174 #define STATUS_CTS 0x20
175 #define STATUS_TXUNDRN 0x40
176 #define STATUS_BRK 0x80
178 #define SPEC_ALLSENT 0x01
179 #define SPEC_BITS8 0x06
181 #define IVEC_TXINTB 0x00
182 #define IVEC_LONOINT 0x06
183 #define IVEC_LORXINTA 0x0c
184 #define IVEC_LORXINTB 0x04
185 #define IVEC_LOTXINTA 0x08
186 #define IVEC_HINOINT 0x60
187 #define IVEC_HIRXINTA 0x30
188 #define IVEC_HIRXINTB 0x20
189 #define IVEC_HITXINTA 0x10
191 #define INTR_EXTINTB 0x01
192 #define INTR_TXINTB 0x02
193 #define INTR_RXINTB 0x04
194 #define INTR_EXTINTA 0x08
195 #define INTR_TXINTA 0x10
196 #define INTR_RXINTA 0x20
210 static void handle_kbd_command(ChannelState
*s
, int val
);
211 static int serial_can_receive(void *opaque
);
212 static void serial_receive_byte(ChannelState
*s
, int ch
);
214 static void clear_queue(void *opaque
)
216 ChannelState
*s
= opaque
;
217 SERIOQueue
*q
= &s
->queue
;
218 q
->rptr
= q
->wptr
= q
->count
= 0;
221 static void put_queue(void *opaque
, int b
)
223 ChannelState
*s
= opaque
;
224 SERIOQueue
*q
= &s
->queue
;
226 trace_escc_put_queue(CHN_C(s
), b
);
227 if (q
->count
>= SERIO_QUEUE_SIZE
)
229 q
->data
[q
->wptr
] = b
;
230 if (++q
->wptr
== SERIO_QUEUE_SIZE
)
233 serial_receive_byte(s
, 0);
236 static uint32_t get_queue(void *opaque
)
238 ChannelState
*s
= opaque
;
239 SERIOQueue
*q
= &s
->queue
;
245 val
= q
->data
[q
->rptr
];
246 if (++q
->rptr
== SERIO_QUEUE_SIZE
)
250 trace_escc_get_queue(CHN_C(s
), val
);
252 serial_receive_byte(s
, 0);
256 static int escc_update_irq_chn(ChannelState
*s
)
258 if ((((s
->wregs
[W_INTR
] & INTR_TXINT
) && (s
->txint
== 1)) ||
259 // tx ints enabled, pending
260 ((((s
->wregs
[W_INTR
] & INTR_RXMODEMSK
) == INTR_RXINT1ST
) ||
261 ((s
->wregs
[W_INTR
] & INTR_RXMODEMSK
) == INTR_RXINTALL
)) &&
262 s
->rxint
== 1) || // rx ints enabled, pending
263 ((s
->wregs
[W_EXTINT
] & EXTINT_BRKINT
) &&
264 (s
->rregs
[R_STATUS
] & STATUS_BRK
)))) { // break int e&p
270 static void escc_update_irq(ChannelState
*s
)
274 irq
= escc_update_irq_chn(s
);
275 irq
|= escc_update_irq_chn(s
->otherchn
);
277 trace_escc_update_irq(irq
);
278 qemu_set_irq(s
->irq
, irq
);
281 static void escc_reset_chn(ChannelState
*s
)
286 for (i
= 0; i
< SERIAL_REGS
; i
++) {
290 s
->wregs
[W_TXCTRL1
] = TXCTRL1_1STOP
; // 1X divisor, 1 stop bit, no parity
291 s
->wregs
[W_MINTR
] = MINTR_RST_ALL
;
292 s
->wregs
[W_CLOCK
] = CLOCK_TRXC
; // Synch mode tx clock = TRxC
293 s
->wregs
[W_MISC2
] = MISC2_PLLDIS
; // PLL disabled
294 s
->wregs
[W_EXTINT
] = EXTINT_DCD
| EXTINT_SYNCINT
| EXTINT_CTSINT
|
295 EXTINT_TXUNDRN
| EXTINT_BRKINT
; // Enable most interrupts
297 s
->rregs
[R_STATUS
] = STATUS_TXEMPTY
| STATUS_DCD
| STATUS_SYNC
|
298 STATUS_CTS
| STATUS_TXUNDRN
;
300 s
->rregs
[R_STATUS
] = STATUS_TXEMPTY
| STATUS_TXUNDRN
;
301 s
->rregs
[R_SPEC
] = SPEC_BITS8
| SPEC_ALLSENT
;
304 s
->rxint
= s
->txint
= 0;
305 s
->rxint_under_svc
= s
->txint_under_svc
= 0;
306 s
->e0_mode
= s
->led_mode
= s
->caps_lock_mode
= s
->num_lock_mode
= 0;
310 static void escc_reset(DeviceState
*d
)
312 SerialState
*s
= container_of(d
, SerialState
, busdev
.qdev
);
314 escc_reset_chn(&s
->chn
[0]);
315 escc_reset_chn(&s
->chn
[1]);
318 static inline void set_rxint(ChannelState
*s
)
321 /* XXX: missing daisy chainnig: chn_b rx should have a lower priority
322 than chn_a rx/tx/special_condition service*/
323 s
->rxint_under_svc
= 1;
324 if (s
->chn
== chn_a
) {
325 s
->rregs
[R_INTR
] |= INTR_RXINTA
;
326 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
327 s
->otherchn
->rregs
[R_IVEC
] = IVEC_HIRXINTA
;
329 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LORXINTA
;
331 s
->otherchn
->rregs
[R_INTR
] |= INTR_RXINTB
;
332 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
333 s
->rregs
[R_IVEC
] = IVEC_HIRXINTB
;
335 s
->rregs
[R_IVEC
] = IVEC_LORXINTB
;
340 static inline void set_txint(ChannelState
*s
)
343 if (!s
->rxint_under_svc
) {
344 s
->txint_under_svc
= 1;
345 if (s
->chn
== chn_a
) {
346 if (s
->wregs
[W_INTR
] & INTR_TXINT
) {
347 s
->rregs
[R_INTR
] |= INTR_TXINTA
;
349 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
350 s
->otherchn
->rregs
[R_IVEC
] = IVEC_HITXINTA
;
352 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LOTXINTA
;
354 s
->rregs
[R_IVEC
] = IVEC_TXINTB
;
355 if (s
->wregs
[W_INTR
] & INTR_TXINT
) {
356 s
->otherchn
->rregs
[R_INTR
] |= INTR_TXINTB
;
363 static inline void clr_rxint(ChannelState
*s
)
366 s
->rxint_under_svc
= 0;
367 if (s
->chn
== chn_a
) {
368 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
369 s
->otherchn
->rregs
[R_IVEC
] = IVEC_HINOINT
;
371 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LONOINT
;
372 s
->rregs
[R_INTR
] &= ~INTR_RXINTA
;
374 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
375 s
->rregs
[R_IVEC
] = IVEC_HINOINT
;
377 s
->rregs
[R_IVEC
] = IVEC_LONOINT
;
378 s
->otherchn
->rregs
[R_INTR
] &= ~INTR_RXINTB
;
385 static inline void clr_txint(ChannelState
*s
)
388 s
->txint_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
;
393 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LONOINT
;
394 s
->rregs
[R_INTR
] &= ~INTR_TXINTA
;
396 s
->otherchn
->rregs
[R_INTR
] &= ~INTR_TXINTB
;
397 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
398 s
->rregs
[R_IVEC
] = IVEC_HINOINT
;
400 s
->rregs
[R_IVEC
] = IVEC_LONOINT
;
401 s
->otherchn
->rregs
[R_INTR
] &= ~INTR_TXINTB
;
408 static void escc_update_parameters(ChannelState
*s
)
410 int speed
, parity
, data_bits
, stop_bits
;
411 QEMUSerialSetParams ssp
;
413 if (!s
->chr
|| s
->type
!= ser
)
416 if (s
->wregs
[W_TXCTRL1
] & TXCTRL1_PAREN
) {
417 if (s
->wregs
[W_TXCTRL1
] & TXCTRL1_PAREV
)
424 if ((s
->wregs
[W_TXCTRL1
] & TXCTRL1_STPMSK
) == TXCTRL1_2STOP
)
428 switch (s
->wregs
[W_TXCTRL2
] & TXCTRL2_BITMSK
) {
443 speed
= s
->clock
/ ((s
->wregs
[W_BRGLO
] | (s
->wregs
[W_BRGHI
] << 8)) + 2);
444 switch (s
->wregs
[W_TXCTRL1
] & TXCTRL1_CLKMSK
) {
460 ssp
.data_bits
= data_bits
;
461 ssp
.stop_bits
= stop_bits
;
462 trace_escc_update_parameters(CHN_C(s
), speed
, parity
, data_bits
, stop_bits
);
463 qemu_chr_fe_ioctl(s
->chr
, CHR_IOCTL_SERIAL_SET_PARAMS
, &ssp
);
466 static void escc_mem_write(void *opaque
, hwaddr addr
,
467 uint64_t val
, unsigned size
)
469 SerialState
*serial
= opaque
;
475 saddr
= (addr
>> serial
->it_shift
) & 1;
476 channel
= (addr
>> (serial
->it_shift
+ 1)) & 1;
477 s
= &serial
->chn
[channel
];
480 trace_escc_mem_writeb_ctrl(CHN_C(s
), s
->reg
, val
& 0xff);
484 newreg
= val
& CMD_PTR_MASK
;
494 if (s
->rxint_under_svc
) {
495 s
->rxint_under_svc
= 0;
499 } else if (s
->txint_under_svc
) {
500 s
->txint_under_svc
= 0;
508 case W_INTR
... W_RXCTRL
:
509 case W_SYNC1
... W_TXBUF
:
510 case W_MISC1
... W_CLOCK
:
511 case W_MISC2
... W_EXTINT
:
512 s
->wregs
[s
->reg
] = val
;
516 s
->wregs
[s
->reg
] = val
;
517 escc_update_parameters(s
);
521 s
->wregs
[s
->reg
] = val
;
522 s
->rregs
[s
->reg
] = val
;
523 escc_update_parameters(s
);
526 switch (val
& MINTR_RST_MASK
) {
531 escc_reset_chn(&serial
->chn
[0]);
534 escc_reset_chn(&serial
->chn
[1]);
537 escc_reset(&serial
->busdev
.qdev
);
550 trace_escc_mem_writeb_data(CHN_C(s
), val
);
552 if (s
->wregs
[W_TXCTRL2
] & TXCTRL2_TXEN
) { // tx enabled
554 qemu_chr_fe_write(s
->chr
, &s
->tx
, 1);
555 else if (s
->type
== kbd
&& !s
->disabled
) {
556 handle_kbd_command(s
, val
);
559 s
->rregs
[R_STATUS
] |= STATUS_TXEMPTY
; // Tx buffer empty
560 s
->rregs
[R_SPEC
] |= SPEC_ALLSENT
; // All sent
568 static uint64_t escc_mem_read(void *opaque
, hwaddr addr
,
571 SerialState
*serial
= opaque
;
577 saddr
= (addr
>> serial
->it_shift
) & 1;
578 channel
= (addr
>> (serial
->it_shift
+ 1)) & 1;
579 s
= &serial
->chn
[channel
];
582 trace_escc_mem_readb_ctrl(CHN_C(s
), s
->reg
, s
->rregs
[s
->reg
]);
583 ret
= s
->rregs
[s
->reg
];
587 s
->rregs
[R_STATUS
] &= ~STATUS_RXAV
;
589 if (s
->type
== kbd
|| s
->type
== mouse
)
593 trace_escc_mem_readb_data(CHN_C(s
), ret
);
595 qemu_chr_accept_input(s
->chr
);
603 static const MemoryRegionOps escc_mem_ops
= {
604 .read
= escc_mem_read
,
605 .write
= escc_mem_write
,
606 .endianness
= DEVICE_NATIVE_ENDIAN
,
608 .min_access_size
= 1,
609 .max_access_size
= 1,
613 static int serial_can_receive(void *opaque
)
615 ChannelState
*s
= opaque
;
618 if (((s
->wregs
[W_RXCTRL
] & RXCTRL_RXEN
) == 0) // Rx not enabled
619 || ((s
->rregs
[R_STATUS
] & STATUS_RXAV
) == STATUS_RXAV
))
620 // char already available
627 static void serial_receive_byte(ChannelState
*s
, int ch
)
629 trace_escc_serial_receive_byte(CHN_C(s
), ch
);
630 s
->rregs
[R_STATUS
] |= STATUS_RXAV
;
635 static void serial_receive_break(ChannelState
*s
)
637 s
->rregs
[R_STATUS
] |= STATUS_BRK
;
641 static void serial_receive1(void *opaque
, const uint8_t *buf
, int size
)
643 ChannelState
*s
= opaque
;
644 serial_receive_byte(s
, buf
[0]);
647 static void serial_event(void *opaque
, int event
)
649 ChannelState
*s
= opaque
;
650 if (event
== CHR_EVENT_BREAK
)
651 serial_receive_break(s
);
654 static const VMStateDescription vmstate_escc_chn
= {
657 .minimum_version_id
= 1,
658 .minimum_version_id_old
= 1,
659 .fields
= (VMStateField
[]) {
660 VMSTATE_UINT32(vmstate_dummy
, ChannelState
),
661 VMSTATE_UINT32(reg
, ChannelState
),
662 VMSTATE_UINT32(rxint
, ChannelState
),
663 VMSTATE_UINT32(txint
, ChannelState
),
664 VMSTATE_UINT32(rxint_under_svc
, ChannelState
),
665 VMSTATE_UINT32(txint_under_svc
, ChannelState
),
666 VMSTATE_UINT8(rx
, ChannelState
),
667 VMSTATE_UINT8(tx
, ChannelState
),
668 VMSTATE_BUFFER(wregs
, ChannelState
),
669 VMSTATE_BUFFER(rregs
, ChannelState
),
670 VMSTATE_END_OF_LIST()
674 static const VMStateDescription vmstate_escc
= {
677 .minimum_version_id
= 1,
678 .minimum_version_id_old
= 1,
679 .fields
= (VMStateField
[]) {
680 VMSTATE_STRUCT_ARRAY(chn
, SerialState
, 2, 2, vmstate_escc_chn
,
682 VMSTATE_END_OF_LIST()
686 MemoryRegion
*escc_init(hwaddr base
, qemu_irq irqA
, qemu_irq irqB
,
687 CharDriverState
*chrA
, CharDriverState
*chrB
,
688 int clock
, int it_shift
)
694 dev
= qdev_create(NULL
, "escc");
695 qdev_prop_set_uint32(dev
, "disabled", 0);
696 qdev_prop_set_uint32(dev
, "frequency", clock
);
697 qdev_prop_set_uint32(dev
, "it_shift", it_shift
);
698 qdev_prop_set_chr(dev
, "chrB", chrB
);
699 qdev_prop_set_chr(dev
, "chrA", chrA
);
700 qdev_prop_set_uint32(dev
, "chnBtype", ser
);
701 qdev_prop_set_uint32(dev
, "chnAtype", ser
);
702 qdev_init_nofail(dev
);
703 s
= SYS_BUS_DEVICE(dev
);
704 sysbus_connect_irq(s
, 0, irqB
);
705 sysbus_connect_irq(s
, 1, irqA
);
707 sysbus_mmio_map(s
, 0, base
);
710 d
= FROM_SYSBUS(SerialState
, s
);
714 static const uint8_t keycodes
[128] = {
715 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
716 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
717 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
718 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
719 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
720 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
721 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
722 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
725 static const uint8_t e0_keycodes
[128] = {
726 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
728 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
729 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
730 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
731 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
732 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
733 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
736 static void sunkbd_event(void *opaque
, int ch
)
738 ChannelState
*s
= opaque
;
739 int release
= ch
& 0x80;
741 trace_escc_sunkbd_event_in(ch
);
743 case 58: // Caps lock press
744 s
->caps_lock_mode
^= 1;
745 if (s
->caps_lock_mode
== 2)
746 return; // Drop second press
748 case 69: // Num lock press
749 s
->num_lock_mode
^= 1;
750 if (s
->num_lock_mode
== 2)
751 return; // Drop second press
753 case 186: // Caps lock release
754 s
->caps_lock_mode
^= 2;
755 if (s
->caps_lock_mode
== 3)
756 return; // Drop first release
758 case 197: // Num lock release
759 s
->num_lock_mode
^= 2;
760 if (s
->num_lock_mode
== 3)
761 return; // Drop first release
771 ch
= e0_keycodes
[ch
& 0x7f];
773 ch
= keycodes
[ch
& 0x7f];
775 trace_escc_sunkbd_event_out(ch
);
776 put_queue(s
, ch
| release
);
779 static void handle_kbd_command(ChannelState
*s
, int val
)
781 trace_escc_kbd_command(val
);
782 if (s
->led_mode
) { // Ignore led byte
787 case 1: // Reset, return type code
790 put_queue(s
, 4); // Type 4
793 case 0xe: // Set leds
796 case 7: // Query layout
800 put_queue(s
, 0); // XXX, layout?
807 static void sunmouse_event(void *opaque
,
808 int dx
, int dy
, int dz
, int buttons_state
)
810 ChannelState
*s
= opaque
;
813 trace_escc_sunmouse_event(dx
, dy
, buttons_state
);
814 ch
= 0x80 | 0x7; /* protocol start byte, no buttons pressed */
816 if (buttons_state
& MOUSE_EVENT_LBUTTON
)
818 if (buttons_state
& MOUSE_EVENT_MBUTTON
)
820 if (buttons_state
& MOUSE_EVENT_RBUTTON
)
832 put_queue(s
, ch
& 0xff);
841 put_queue(s
, ch
& 0xff);
843 // MSC protocol specify two extra motion bytes
849 void slavio_serial_ms_kbd_init(hwaddr base
, qemu_irq irq
,
850 int disabled
, int clock
, int it_shift
)
855 dev
= qdev_create(NULL
, "escc");
856 qdev_prop_set_uint32(dev
, "disabled", disabled
);
857 qdev_prop_set_uint32(dev
, "frequency", clock
);
858 qdev_prop_set_uint32(dev
, "it_shift", it_shift
);
859 qdev_prop_set_chr(dev
, "chrB", NULL
);
860 qdev_prop_set_chr(dev
, "chrA", NULL
);
861 qdev_prop_set_uint32(dev
, "chnBtype", mouse
);
862 qdev_prop_set_uint32(dev
, "chnAtype", kbd
);
863 qdev_init_nofail(dev
);
864 s
= SYS_BUS_DEVICE(dev
);
865 sysbus_connect_irq(s
, 0, irq
);
866 sysbus_connect_irq(s
, 1, irq
);
867 sysbus_mmio_map(s
, 0, base
);
870 static int escc_init1(SysBusDevice
*dev
)
872 SerialState
*s
= FROM_SYSBUS(SerialState
, dev
);
875 s
->chn
[0].disabled
= s
->disabled
;
876 s
->chn
[1].disabled
= s
->disabled
;
877 for (i
= 0; i
< 2; i
++) {
878 sysbus_init_irq(dev
, &s
->chn
[i
].irq
);
879 s
->chn
[i
].chn
= 1 - i
;
880 s
->chn
[i
].clock
= s
->frequency
/ 2;
882 qemu_chr_add_handlers(s
->chn
[i
].chr
, serial_can_receive
,
883 serial_receive1
, serial_event
, &s
->chn
[i
]);
886 s
->chn
[0].otherchn
= &s
->chn
[1];
887 s
->chn
[1].otherchn
= &s
->chn
[0];
889 memory_region_init_io(&s
->mmio
, &escc_mem_ops
, s
, "escc",
890 ESCC_SIZE
<< s
->it_shift
);
891 sysbus_init_mmio(dev
, &s
->mmio
);
893 if (s
->chn
[0].type
== mouse
) {
894 qemu_add_mouse_event_handler(sunmouse_event
, &s
->chn
[0], 0,
897 if (s
->chn
[1].type
== kbd
) {
898 qemu_add_kbd_event_handler(sunkbd_event
, &s
->chn
[1]);
904 static Property escc_properties
[] = {
905 DEFINE_PROP_UINT32("frequency", SerialState
, frequency
, 0),
906 DEFINE_PROP_UINT32("it_shift", SerialState
, it_shift
, 0),
907 DEFINE_PROP_UINT32("disabled", SerialState
, disabled
, 0),
908 DEFINE_PROP_UINT32("chnBtype", SerialState
, chn
[0].type
, 0),
909 DEFINE_PROP_UINT32("chnAtype", SerialState
, chn
[1].type
, 0),
910 DEFINE_PROP_CHR("chrB", SerialState
, chn
[0].chr
),
911 DEFINE_PROP_CHR("chrA", SerialState
, chn
[1].chr
),
912 DEFINE_PROP_END_OF_LIST(),
915 static void escc_class_init(ObjectClass
*klass
, void *data
)
917 DeviceClass
*dc
= DEVICE_CLASS(klass
);
918 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
920 k
->init
= escc_init1
;
921 dc
->reset
= escc_reset
;
922 dc
->vmsd
= &vmstate_escc
;
923 dc
->props
= escc_properties
;
926 static const TypeInfo escc_info
= {
928 .parent
= TYPE_SYS_BUS_DEVICE
,
929 .instance_size
= sizeof(SerialState
),
930 .class_init
= escc_class_init
,
933 static void escc_register_types(void)
935 type_register_static(&escc_info
);
938 type_init(escc_register_types
)