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
28 #include "qemu-char.h"
32 //#define DEBUG_SERIAL
42 * "Z80C30/Z85C30/Z80230/Z85230/Z85233 SCC/ESCC User Manual",
43 * http://www.zilog.com/docs/serial/scc_escc_um.pdf
45 * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001
46 * (Slave I/O), also produced as NCR89C105. See
47 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
49 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
50 * mouse and keyboard ports don't implement all functions and they are
51 * only asynchronous. There is no DMA.
53 * Z85C30 is also used on PowerMacs. There are some small differences
54 * between Sparc version (sunzilog) and PowerMac (pmac):
55 * Offset between control and data registers
56 * There is some kind of lockup bug, but we can ignore it
58 * DMA on pmac using DBDMA chip
59 * pmac can do IRDA and faster rates, sunzilog can only do 38400
60 * pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz
65 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
67 * Implemented serial mouse protocol.
69 * 2010-May-23 Artyom Tarasenko: Reworked IUS logic
73 #define SER_DPRINTF(fmt, ...) \
74 do { printf("SER: " fmt , ## __VA_ARGS__); } while (0)
76 #define SER_DPRINTF(fmt, ...)
79 #define KBD_DPRINTF(fmt, ...) \
80 do { printf("KBD: " fmt , ## __VA_ARGS__); } while (0)
82 #define KBD_DPRINTF(fmt, ...)
85 #define MS_DPRINTF(fmt, ...) \
86 do { printf("MSC: " fmt , ## __VA_ARGS__); } while (0)
88 #define MS_DPRINTF(fmt, ...)
95 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
101 #define SERIO_QUEUE_SIZE 256
104 uint8_t data
[SERIO_QUEUE_SIZE
];
105 int rptr
, wptr
, count
;
108 #define SERIAL_REGS 16
109 typedef struct ChannelState
{
112 uint32_t rxint
, txint
, rxint_under_svc
, txint_under_svc
;
113 ChnID chn
; // this channel, A (base+4) or B (base+0)
115 struct ChannelState
*otherchn
;
116 uint8_t rx
, tx
, wregs
[SERIAL_REGS
], rregs
[SERIAL_REGS
];
118 CharDriverState
*chr
;
119 int e0_mode
, led_mode
, caps_lock_mode
, num_lock_mode
;
122 uint32_t vmstate_dummy
;
127 struct ChannelState chn
[2];
134 #define SERIAL_CTRL 0
135 #define SERIAL_DATA 1
138 #define CMD_PTR_MASK 0x07
139 #define CMD_CMD_MASK 0x38
141 #define CMD_CLR_TXINT 0x28
142 #define CMD_CLR_IUS 0x38
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
151 #define RXCTRL_RXEN 0x01
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
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
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
182 #define CLOCK_TRXC 0x08
186 #define MISC2_PLLDIS 0x30
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
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
204 #define SPEC_ALLSENT 0x01
205 #define SPEC_BITS8 0x06
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
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
236 static void handle_kbd_command(ChannelState
*s
, int val
);
237 static int serial_can_receive(void *opaque
);
238 static void serial_receive_byte(ChannelState
*s
, int ch
);
240 static void clear_queue(void *opaque
)
242 ChannelState
*s
= opaque
;
243 SERIOQueue
*q
= &s
->queue
;
244 q
->rptr
= q
->wptr
= q
->count
= 0;
247 static void put_queue(void *opaque
, int b
)
249 ChannelState
*s
= opaque
;
250 SERIOQueue
*q
= &s
->queue
;
252 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s
), b
);
253 if (q
->count
>= SERIO_QUEUE_SIZE
)
255 q
->data
[q
->wptr
] = b
;
256 if (++q
->wptr
== SERIO_QUEUE_SIZE
)
259 serial_receive_byte(s
, 0);
262 static uint32_t get_queue(void *opaque
)
264 ChannelState
*s
= opaque
;
265 SERIOQueue
*q
= &s
->queue
;
271 val
= q
->data
[q
->rptr
];
272 if (++q
->rptr
== SERIO_QUEUE_SIZE
)
276 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s
), val
);
278 serial_receive_byte(s
, 0);
282 static int escc_update_irq_chn(ChannelState
*s
)
284 if ((((s
->wregs
[W_INTR
] & INTR_TXINT
) && (s
->txint
== 1)) ||
285 // tx ints enabled, pending
286 ((((s
->wregs
[W_INTR
] & INTR_RXMODEMSK
) == INTR_RXINT1ST
) ||
287 ((s
->wregs
[W_INTR
] & INTR_RXMODEMSK
) == INTR_RXINTALL
)) &&
288 s
->rxint
== 1) || // rx ints enabled, pending
289 ((s
->wregs
[W_EXTINT
] & EXTINT_BRKINT
) &&
290 (s
->rregs
[R_STATUS
] & STATUS_BRK
)))) { // break int e&p
296 static void escc_update_irq(ChannelState
*s
)
300 irq
= escc_update_irq_chn(s
);
301 irq
|= escc_update_irq_chn(s
->otherchn
);
303 SER_DPRINTF("IRQ = %d\n", irq
);
304 qemu_set_irq(s
->irq
, irq
);
307 static void escc_reset_chn(ChannelState
*s
)
312 for (i
= 0; i
< SERIAL_REGS
; i
++) {
316 s
->wregs
[W_TXCTRL1
] = TXCTRL1_1STOP
; // 1X divisor, 1 stop bit, no parity
317 s
->wregs
[W_MINTR
] = MINTR_RST_ALL
;
318 s
->wregs
[W_CLOCK
] = CLOCK_TRXC
; // Synch mode tx clock = TRxC
319 s
->wregs
[W_MISC2
] = MISC2_PLLDIS
; // PLL disabled
320 s
->wregs
[W_EXTINT
] = EXTINT_DCD
| EXTINT_SYNCINT
| EXTINT_CTSINT
|
321 EXTINT_TXUNDRN
| EXTINT_BRKINT
; // Enable most interrupts
323 s
->rregs
[R_STATUS
] = STATUS_TXEMPTY
| STATUS_DCD
| STATUS_SYNC
|
324 STATUS_CTS
| STATUS_TXUNDRN
;
326 s
->rregs
[R_STATUS
] = STATUS_TXEMPTY
| STATUS_TXUNDRN
;
327 s
->rregs
[R_SPEC
] = SPEC_BITS8
| SPEC_ALLSENT
;
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;
336 static void escc_reset(DeviceState
*d
)
338 SerialState
*s
= container_of(d
, SerialState
, busdev
.qdev
);
340 escc_reset_chn(&s
->chn
[0]);
341 escc_reset_chn(&s
->chn
[1]);
344 static inline void set_rxint(ChannelState
*s
)
347 /* XXX: missing daisy chainnig: chn_b rx should have a lower priority
348 than chn_a rx/tx/special_condition service*/
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
;
355 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LORXINTA
;
357 s
->otherchn
->rregs
[R_INTR
] |= INTR_RXINTB
;
358 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
359 s
->rregs
[R_IVEC
] = IVEC_HIRXINTB
;
361 s
->rregs
[R_IVEC
] = IVEC_LORXINTB
;
366 static inline void set_txint(ChannelState
*s
)
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
;
376 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LOTXINTA
;
378 s
->rregs
[R_IVEC
] = IVEC_TXINTB
;
379 s
->otherchn
->rregs
[R_INTR
] |= INTR_TXINTB
;
385 static inline void clr_rxint(ChannelState
*s
)
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
;
393 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LONOINT
;
394 s
->rregs
[R_INTR
] &= ~INTR_RXINTA
;
396 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
397 s
->rregs
[R_IVEC
] = IVEC_HINOINT
;
399 s
->rregs
[R_IVEC
] = IVEC_LONOINT
;
400 s
->otherchn
->rregs
[R_INTR
] &= ~INTR_RXINTB
;
407 static inline void clr_txint(ChannelState
*s
)
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
;
415 s
->otherchn
->rregs
[R_IVEC
] = IVEC_LONOINT
;
416 s
->rregs
[R_INTR
] &= ~INTR_TXINTA
;
418 s
->otherchn
->rregs
[R_INTR
] &= ~INTR_TXINTB
;
419 if (s
->wregs
[W_MINTR
] & MINTR_STATUSHI
)
420 s
->rregs
[R_IVEC
] = IVEC_HINOINT
;
422 s
->rregs
[R_IVEC
] = IVEC_LONOINT
;
423 s
->otherchn
->rregs
[R_INTR
] &= ~INTR_TXINTB
;
430 static void escc_update_parameters(ChannelState
*s
)
432 int speed
, parity
, data_bits
, stop_bits
;
433 QEMUSerialSetParams ssp
;
435 if (!s
->chr
|| s
->type
!= ser
)
438 if (s
->wregs
[W_TXCTRL1
] & TXCTRL1_PAREN
) {
439 if (s
->wregs
[W_TXCTRL1
] & TXCTRL1_PAREV
)
446 if ((s
->wregs
[W_TXCTRL1
] & TXCTRL1_STPMSK
) == TXCTRL1_2STOP
)
450 switch (s
->wregs
[W_TXCTRL2
] & TXCTRL2_BITMSK
) {
465 speed
= s
->clock
/ ((s
->wregs
[W_BRGLO
] | (s
->wregs
[W_BRGHI
] << 8)) + 2);
466 switch (s
->wregs
[W_TXCTRL1
] & TXCTRL1_CLKMSK
) {
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
);
489 static void escc_mem_writeb(void *opaque
, target_phys_addr_t addr
, uint32_t val
)
491 SerialState
*serial
= opaque
;
497 saddr
= (addr
>> serial
->it_shift
) & 1;
498 channel
= (addr
>> (serial
->it_shift
+ 1)) & 1;
499 s
= &serial
->chn
[channel
];
502 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s
), s
->reg
,
507 newreg
= val
& CMD_PTR_MASK
;
517 if (s
->rxint_under_svc
) {
518 s
->rxint_under_svc
= 0;
522 } else if (s
->txint_under_svc
) {
523 s
->txint_under_svc
= 0;
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
;
539 s
->wregs
[s
->reg
] = val
;
540 escc_update_parameters(s
);
544 s
->wregs
[s
->reg
] = val
;
545 s
->rregs
[s
->reg
] = val
;
546 escc_update_parameters(s
);
549 switch (val
& MINTR_RST_MASK
) {
554 escc_reset_chn(&serial
->chn
[0]);
557 escc_reset_chn(&serial
->chn
[1]);
560 escc_reset(&serial
->busdev
.qdev
);
573 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s
), val
);
575 if (s
->wregs
[W_TXCTRL2
] & TXCTRL2_TXEN
) { // tx enabled
577 qemu_chr_write(s
->chr
, &s
->tx
, 1);
578 else if (s
->type
== kbd
&& !s
->disabled
) {
579 handle_kbd_command(s
, val
);
582 s
->rregs
[R_STATUS
] |= STATUS_TXEMPTY
; // Tx buffer empty
583 s
->rregs
[R_SPEC
] |= SPEC_ALLSENT
; // All sent
591 static uint32_t escc_mem_readb(void *opaque
, target_phys_addr_t addr
)
593 SerialState
*serial
= opaque
;
599 saddr
= (addr
>> serial
->it_shift
) & 1;
600 channel
= (addr
>> (serial
->it_shift
+ 1)) & 1;
601 s
= &serial
->chn
[channel
];
604 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s
), s
->reg
,
606 ret
= s
->rregs
[s
->reg
];
610 s
->rregs
[R_STATUS
] &= ~STATUS_RXAV
;
612 if (s
->type
== kbd
|| s
->type
== mouse
)
616 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s
), ret
);
618 qemu_chr_accept_input(s
->chr
);
626 static int serial_can_receive(void *opaque
)
628 ChannelState
*s
= opaque
;
631 if (((s
->wregs
[W_RXCTRL
] & RXCTRL_RXEN
) == 0) // Rx not enabled
632 || ((s
->rregs
[R_STATUS
] & STATUS_RXAV
) == STATUS_RXAV
))
633 // char already available
640 static void serial_receive_byte(ChannelState
*s
, int ch
)
642 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s
), ch
);
643 s
->rregs
[R_STATUS
] |= STATUS_RXAV
;
648 static void serial_receive_break(ChannelState
*s
)
650 s
->rregs
[R_STATUS
] |= STATUS_BRK
;
654 static void serial_receive1(void *opaque
, const uint8_t *buf
, int size
)
656 ChannelState
*s
= opaque
;
657 serial_receive_byte(s
, buf
[0]);
660 static void serial_event(void *opaque
, int event
)
662 ChannelState
*s
= opaque
;
663 if (event
== CHR_EVENT_BREAK
)
664 serial_receive_break(s
);
667 static CPUReadMemoryFunc
* const escc_mem_read
[3] = {
673 static CPUWriteMemoryFunc
* const escc_mem_write
[3] = {
679 static const VMStateDescription vmstate_escc_chn
= {
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()
699 static const VMStateDescription vmstate_escc
= {
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
,
707 VMSTATE_END_OF_LIST()
711 int escc_init(target_phys_addr_t base
, qemu_irq irqA
, qemu_irq irqB
,
712 CharDriverState
*chrA
, CharDriverState
*chrB
,
713 int clock
, int it_shift
)
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
);
732 sysbus_mmio_map(s
, 0, base
);
735 d
= FROM_SYSBUS(SerialState
, s
);
736 return d
->mmio_index
;
739 static 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,
750 static 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,
761 static void sunkbd_event(void *opaque
, int ch
)
763 ChannelState
*s
= opaque
;
764 int release
= ch
& 0x80;
766 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch
, release
? "release" :
769 case 58: // Caps lock press
770 s
->caps_lock_mode
^= 1;
771 if (s
->caps_lock_mode
== 2)
772 return; // Drop second press
774 case 69: // Num lock press
775 s
->num_lock_mode
^= 1;
776 if (s
->num_lock_mode
== 2)
777 return; // Drop second press
779 case 186: // Caps lock release
780 s
->caps_lock_mode
^= 2;
781 if (s
->caps_lock_mode
== 3)
782 return; // Drop first release
784 case 197: // Num lock release
785 s
->num_lock_mode
^= 2;
786 if (s
->num_lock_mode
== 3)
787 return; // Drop first release
797 ch
= e0_keycodes
[ch
& 0x7f];
799 ch
= keycodes
[ch
& 0x7f];
801 KBD_DPRINTF("Translated keycode %2.2x\n", ch
);
802 put_queue(s
, ch
| release
);
805 static void handle_kbd_command(ChannelState
*s
, int val
)
807 KBD_DPRINTF("Command %d\n", val
);
808 if (s
->led_mode
) { // Ignore led byte
813 case 1: // Reset, return type code
816 put_queue(s
, 4); // Type 4
819 case 0xe: // Set leds
822 case 7: // Query layout
826 put_queue(s
, 0); // XXX, layout?
833 static void sunmouse_event(void *opaque
,
834 int dx
, int dy
, int dz
, int buttons_state
)
836 ChannelState
*s
= opaque
;
839 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx
, dy
, buttons_state
);
841 ch
= 0x80 | 0x7; /* protocol start byte, no buttons pressed */
843 if (buttons_state
& MOUSE_EVENT_LBUTTON
)
845 if (buttons_state
& MOUSE_EVENT_MBUTTON
)
847 if (buttons_state
& MOUSE_EVENT_RBUTTON
)
859 put_queue(s
, ch
& 0xff);
868 put_queue(s
, ch
& 0xff);
870 // MSC protocol specify two extra motion bytes
876 void slavio_serial_ms_kbd_init(target_phys_addr_t base
, qemu_irq irq
,
877 int disabled
, int clock
, int it_shift
)
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
);
897 static int escc_init1(SysBusDevice
*dev
)
899 SerialState
*s
= FROM_SYSBUS(SerialState
, dev
);
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;
910 qemu_chr_add_handlers(s
->chn
[i
].chr
, serial_can_receive
,
911 serial_receive1
, serial_event
, &s
->chn
[i
]);
914 s
->chn
[0].otherchn
= &s
->chn
[1];
915 s
->chn
[1].otherchn
= &s
->chn
[0];
917 io
= cpu_register_io_memory(escc_mem_read
, escc_mem_write
, s
);
918 sysbus_init_mmio(dev
, ESCC_SIZE
<< s
->it_shift
, io
);
921 if (s
->chn
[0].type
== mouse
) {
922 qemu_add_mouse_event_handler(sunmouse_event
, &s
->chn
[0], 0,
925 if (s
->chn
[1].type
== kbd
) {
926 qemu_add_kbd_event_handler(sunkbd_event
, &s
->chn
[1]);
932 static SysBusDeviceInfo escc_info
= {
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(),
951 static void escc_register_devices(void)
953 sysbus_register_withprop(&escc_info
);
956 device_init(escc_register_devices
)