escc: avoid structure holes spotted by pahole
[qemu/mdroth.git] / hw / escc.c
blobffcd746e00c56395897d749e5bad258f9d9386e5
1 /*
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
22 * THE SOFTWARE.
25 #include "hw.h"
26 #include "sysbus.h"
27 #include "escc.h"
28 #include "qemu-char.h"
29 #include "console.h"
31 /* debug serial */
32 //#define DEBUG_SERIAL
34 /* debug keyboard */
35 //#define DEBUG_KBD
37 /* debug mouse */
38 //#define DEBUG_MOUSE
41 * Chipset docs:
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
57 * CTS is inverted
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
64 * Modifications:
65 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
66 * serial mouse queue.
67 * Implemented serial mouse protocol.
69 * 2010-May-23 Artyom Tarasenko: Reworked IUS logic
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
91 typedef enum {
92 chn_a, chn_b,
93 } ChnID;
95 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
97 typedef enum {
98 ser, kbd, mouse,
99 } ChnType;
101 #define SERIO_QUEUE_SIZE 256
103 typedef struct {
104 uint8_t data[SERIO_QUEUE_SIZE];
105 int rptr, wptr, count;
106 } SERIOQueue;
108 #define SERIAL_REGS 16
109 typedef struct ChannelState {
110 qemu_irq irq;
111 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
112 struct ChannelState *otherchn;
113 uint32_t reg;
114 uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
115 SERIOQueue queue;
116 CharDriverState *chr;
117 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
118 int disabled;
119 int clock;
120 uint32_t vmstate_dummy;
121 ChnID chn; // this channel, A (base+4) or B (base+0)
122 ChnType type;
123 uint8_t rx, tx;
124 } ChannelState;
126 struct SerialState {
127 SysBusDevice busdev;
128 struct ChannelState chn[2];
129 uint32_t it_shift;
130 MemoryRegion mmio;
131 uint32_t disabled;
132 uint32_t frequency;
135 #define SERIAL_CTRL 0
136 #define SERIAL_DATA 1
138 #define W_CMD 0
139 #define CMD_PTR_MASK 0x07
140 #define CMD_CMD_MASK 0x38
141 #define CMD_HI 0x08
142 #define CMD_CLR_TXINT 0x28
143 #define CMD_CLR_IUS 0x38
144 #define W_INTR 1
145 #define INTR_INTALL 0x01
146 #define INTR_TXINT 0x02
147 #define INTR_RXMODEMSK 0x18
148 #define INTR_RXINT1ST 0x08
149 #define INTR_RXINTALL 0x10
150 #define W_IVEC 2
151 #define W_RXCTRL 3
152 #define RXCTRL_RXEN 0x01
153 #define W_TXCTRL1 4
154 #define TXCTRL1_PAREN 0x01
155 #define TXCTRL1_PAREV 0x02
156 #define TXCTRL1_1STOP 0x04
157 #define TXCTRL1_1HSTOP 0x08
158 #define TXCTRL1_2STOP 0x0c
159 #define TXCTRL1_STPMSK 0x0c
160 #define TXCTRL1_CLK1X 0x00
161 #define TXCTRL1_CLK16X 0x40
162 #define TXCTRL1_CLK32X 0x80
163 #define TXCTRL1_CLK64X 0xc0
164 #define TXCTRL1_CLKMSK 0xc0
165 #define W_TXCTRL2 5
166 #define TXCTRL2_TXEN 0x08
167 #define TXCTRL2_BITMSK 0x60
168 #define TXCTRL2_5BITS 0x00
169 #define TXCTRL2_7BITS 0x20
170 #define TXCTRL2_6BITS 0x40
171 #define TXCTRL2_8BITS 0x60
172 #define W_SYNC1 6
173 #define W_SYNC2 7
174 #define W_TXBUF 8
175 #define W_MINTR 9
176 #define MINTR_STATUSHI 0x10
177 #define MINTR_RST_MASK 0xc0
178 #define MINTR_RST_B 0x40
179 #define MINTR_RST_A 0x80
180 #define MINTR_RST_ALL 0xc0
181 #define W_MISC1 10
182 #define W_CLOCK 11
183 #define CLOCK_TRXC 0x08
184 #define W_BRGLO 12
185 #define W_BRGHI 13
186 #define W_MISC2 14
187 #define MISC2_PLLDIS 0x30
188 #define W_EXTINT 15
189 #define EXTINT_DCD 0x08
190 #define EXTINT_SYNCINT 0x10
191 #define EXTINT_CTSINT 0x20
192 #define EXTINT_TXUNDRN 0x40
193 #define EXTINT_BRKINT 0x80
195 #define R_STATUS 0
196 #define STATUS_RXAV 0x01
197 #define STATUS_ZERO 0x02
198 #define STATUS_TXEMPTY 0x04
199 #define STATUS_DCD 0x08
200 #define STATUS_SYNC 0x10
201 #define STATUS_CTS 0x20
202 #define STATUS_TXUNDRN 0x40
203 #define STATUS_BRK 0x80
204 #define R_SPEC 1
205 #define SPEC_ALLSENT 0x01
206 #define SPEC_BITS8 0x06
207 #define R_IVEC 2
208 #define IVEC_TXINTB 0x00
209 #define IVEC_LONOINT 0x06
210 #define IVEC_LORXINTA 0x0c
211 #define IVEC_LORXINTB 0x04
212 #define IVEC_LOTXINTA 0x08
213 #define IVEC_HINOINT 0x60
214 #define IVEC_HIRXINTA 0x30
215 #define IVEC_HIRXINTB 0x20
216 #define IVEC_HITXINTA 0x10
217 #define R_INTR 3
218 #define INTR_EXTINTB 0x01
219 #define INTR_TXINTB 0x02
220 #define INTR_RXINTB 0x04
221 #define INTR_EXTINTA 0x08
222 #define INTR_TXINTA 0x10
223 #define INTR_RXINTA 0x20
224 #define R_IPEN 4
225 #define R_TXCTRL1 5
226 #define R_TXCTRL2 6
227 #define R_BC 7
228 #define R_RXBUF 8
229 #define R_RXCTRL 9
230 #define R_MISC 10
231 #define R_MISC1 11
232 #define R_BRGLO 12
233 #define R_BRGHI 13
234 #define R_MISC1I 14
235 #define R_EXTINT 15
237 static void handle_kbd_command(ChannelState *s, int val);
238 static int serial_can_receive(void *opaque);
239 static void serial_receive_byte(ChannelState *s, int ch);
241 static void clear_queue(void *opaque)
243 ChannelState *s = opaque;
244 SERIOQueue *q = &s->queue;
245 q->rptr = q->wptr = q->count = 0;
248 static void put_queue(void *opaque, int b)
250 ChannelState *s = opaque;
251 SERIOQueue *q = &s->queue;
253 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
254 if (q->count >= SERIO_QUEUE_SIZE)
255 return;
256 q->data[q->wptr] = b;
257 if (++q->wptr == SERIO_QUEUE_SIZE)
258 q->wptr = 0;
259 q->count++;
260 serial_receive_byte(s, 0);
263 static uint32_t get_queue(void *opaque)
265 ChannelState *s = opaque;
266 SERIOQueue *q = &s->queue;
267 int val;
269 if (q->count == 0) {
270 return 0;
271 } else {
272 val = q->data[q->rptr];
273 if (++q->rptr == SERIO_QUEUE_SIZE)
274 q->rptr = 0;
275 q->count--;
277 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
278 if (q->count > 0)
279 serial_receive_byte(s, 0);
280 return val;
283 static int escc_update_irq_chn(ChannelState *s)
285 if ((((s->wregs[W_INTR] & INTR_TXINT) && (s->txint == 1)) ||
286 // tx ints enabled, pending
287 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
288 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
289 s->rxint == 1) || // rx ints enabled, pending
290 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
291 (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
292 return 1;
294 return 0;
297 static void escc_update_irq(ChannelState *s)
299 int irq;
301 irq = escc_update_irq_chn(s);
302 irq |= escc_update_irq_chn(s->otherchn);
304 SER_DPRINTF("IRQ = %d\n", irq);
305 qemu_set_irq(s->irq, irq);
308 static void escc_reset_chn(ChannelState *s)
310 int i;
312 s->reg = 0;
313 for (i = 0; i < SERIAL_REGS; i++) {
314 s->rregs[i] = 0;
315 s->wregs[i] = 0;
317 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
318 s->wregs[W_MINTR] = MINTR_RST_ALL;
319 s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
320 s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
321 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
322 EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
323 if (s->disabled)
324 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
325 STATUS_CTS | STATUS_TXUNDRN;
326 else
327 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
328 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
330 s->rx = s->tx = 0;
331 s->rxint = s->txint = 0;
332 s->rxint_under_svc = s->txint_under_svc = 0;
333 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
334 clear_queue(s);
337 static void escc_reset(DeviceState *d)
339 SerialState *s = container_of(d, SerialState, busdev.qdev);
341 escc_reset_chn(&s->chn[0]);
342 escc_reset_chn(&s->chn[1]);
345 static inline void set_rxint(ChannelState *s)
347 s->rxint = 1;
348 /* XXX: missing daisy chainnig: chn_b rx should have a lower priority
349 than chn_a rx/tx/special_condition service*/
350 s->rxint_under_svc = 1;
351 if (s->chn == chn_a) {
352 s->rregs[R_INTR] |= INTR_RXINTA;
353 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
354 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
355 else
356 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
357 } else {
358 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
359 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
360 s->rregs[R_IVEC] = IVEC_HIRXINTB;
361 else
362 s->rregs[R_IVEC] = IVEC_LORXINTB;
364 escc_update_irq(s);
367 static inline void set_txint(ChannelState *s)
369 s->txint = 1;
370 if (!s->rxint_under_svc) {
371 s->txint_under_svc = 1;
372 if (s->chn == chn_a) {
373 if (s->wregs[W_INTR] & INTR_TXINT) {
374 s->rregs[R_INTR] |= INTR_TXINTA;
376 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
377 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
378 else
379 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
380 } else {
381 s->rregs[R_IVEC] = IVEC_TXINTB;
382 if (s->wregs[W_INTR] & INTR_TXINT) {
383 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
386 escc_update_irq(s);
390 static inline void clr_rxint(ChannelState *s)
392 s->rxint = 0;
393 s->rxint_under_svc = 0;
394 if (s->chn == chn_a) {
395 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
396 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
397 else
398 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
399 s->rregs[R_INTR] &= ~INTR_RXINTA;
400 } else {
401 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
402 s->rregs[R_IVEC] = IVEC_HINOINT;
403 else
404 s->rregs[R_IVEC] = IVEC_LONOINT;
405 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
407 if (s->txint)
408 set_txint(s);
409 escc_update_irq(s);
412 static inline void clr_txint(ChannelState *s)
414 s->txint = 0;
415 s->txint_under_svc = 0;
416 if (s->chn == chn_a) {
417 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
418 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
419 else
420 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
421 s->rregs[R_INTR] &= ~INTR_TXINTA;
422 } else {
423 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
424 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
425 s->rregs[R_IVEC] = IVEC_HINOINT;
426 else
427 s->rregs[R_IVEC] = IVEC_LONOINT;
428 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
430 if (s->rxint)
431 set_rxint(s);
432 escc_update_irq(s);
435 static void escc_update_parameters(ChannelState *s)
437 int speed, parity, data_bits, stop_bits;
438 QEMUSerialSetParams ssp;
440 if (!s->chr || s->type != ser)
441 return;
443 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
444 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
445 parity = 'E';
446 else
447 parity = 'O';
448 } else {
449 parity = 'N';
451 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
452 stop_bits = 2;
453 else
454 stop_bits = 1;
455 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
456 case TXCTRL2_5BITS:
457 data_bits = 5;
458 break;
459 case TXCTRL2_7BITS:
460 data_bits = 7;
461 break;
462 case TXCTRL2_6BITS:
463 data_bits = 6;
464 break;
465 default:
466 case TXCTRL2_8BITS:
467 data_bits = 8;
468 break;
470 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
471 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
472 case TXCTRL1_CLK1X:
473 break;
474 case TXCTRL1_CLK16X:
475 speed /= 16;
476 break;
477 case TXCTRL1_CLK32X:
478 speed /= 32;
479 break;
480 default:
481 case TXCTRL1_CLK64X:
482 speed /= 64;
483 break;
485 ssp.speed = speed;
486 ssp.parity = parity;
487 ssp.data_bits = data_bits;
488 ssp.stop_bits = stop_bits;
489 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
490 speed, parity, data_bits, stop_bits);
491 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
494 static void escc_mem_write(void *opaque, target_phys_addr_t addr,
495 uint64_t val, unsigned size)
497 SerialState *serial = opaque;
498 ChannelState *s;
499 uint32_t saddr;
500 int newreg, channel;
502 val &= 0xff;
503 saddr = (addr >> serial->it_shift) & 1;
504 channel = (addr >> (serial->it_shift + 1)) & 1;
505 s = &serial->chn[channel];
506 switch (saddr) {
507 case SERIAL_CTRL:
508 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
509 val & 0xff);
510 newreg = 0;
511 switch (s->reg) {
512 case W_CMD:
513 newreg = val & CMD_PTR_MASK;
514 val &= CMD_CMD_MASK;
515 switch (val) {
516 case CMD_HI:
517 newreg |= CMD_HI;
518 break;
519 case CMD_CLR_TXINT:
520 clr_txint(s);
521 break;
522 case CMD_CLR_IUS:
523 if (s->rxint_under_svc) {
524 s->rxint_under_svc = 0;
525 if (s->txint) {
526 set_txint(s);
528 } else if (s->txint_under_svc) {
529 s->txint_under_svc = 0;
531 escc_update_irq(s);
532 break;
533 default:
534 break;
536 break;
537 case W_INTR ... W_RXCTRL:
538 case W_SYNC1 ... W_TXBUF:
539 case W_MISC1 ... W_CLOCK:
540 case W_MISC2 ... W_EXTINT:
541 s->wregs[s->reg] = val;
542 break;
543 case W_TXCTRL1:
544 case W_TXCTRL2:
545 s->wregs[s->reg] = val;
546 escc_update_parameters(s);
547 break;
548 case W_BRGLO:
549 case W_BRGHI:
550 s->wregs[s->reg] = val;
551 s->rregs[s->reg] = val;
552 escc_update_parameters(s);
553 break;
554 case W_MINTR:
555 switch (val & MINTR_RST_MASK) {
556 case 0:
557 default:
558 break;
559 case MINTR_RST_B:
560 escc_reset_chn(&serial->chn[0]);
561 return;
562 case MINTR_RST_A:
563 escc_reset_chn(&serial->chn[1]);
564 return;
565 case MINTR_RST_ALL:
566 escc_reset(&serial->busdev.qdev);
567 return;
569 break;
570 default:
571 break;
573 if (s->reg == 0)
574 s->reg = newreg;
575 else
576 s->reg = 0;
577 break;
578 case SERIAL_DATA:
579 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
580 s->tx = val;
581 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
582 if (s->chr)
583 qemu_chr_write(s->chr, &s->tx, 1);
584 else if (s->type == kbd && !s->disabled) {
585 handle_kbd_command(s, val);
588 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
589 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
590 set_txint(s);
591 break;
592 default:
593 break;
597 static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
598 unsigned size)
600 SerialState *serial = opaque;
601 ChannelState *s;
602 uint32_t saddr;
603 uint32_t ret;
604 int channel;
606 saddr = (addr >> serial->it_shift) & 1;
607 channel = (addr >> (serial->it_shift + 1)) & 1;
608 s = &serial->chn[channel];
609 switch (saddr) {
610 case SERIAL_CTRL:
611 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
612 s->rregs[s->reg]);
613 ret = s->rregs[s->reg];
614 s->reg = 0;
615 return ret;
616 case SERIAL_DATA:
617 s->rregs[R_STATUS] &= ~STATUS_RXAV;
618 clr_rxint(s);
619 if (s->type == kbd || s->type == mouse)
620 ret = get_queue(s);
621 else
622 ret = s->rx;
623 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
624 if (s->chr)
625 qemu_chr_accept_input(s->chr);
626 return ret;
627 default:
628 break;
630 return 0;
633 static const MemoryRegionOps escc_mem_ops = {
634 .read = escc_mem_read,
635 .write = escc_mem_write,
636 .endianness = DEVICE_NATIVE_ENDIAN,
637 .valid = {
638 .min_access_size = 1,
639 .max_access_size = 1,
643 static int serial_can_receive(void *opaque)
645 ChannelState *s = opaque;
646 int ret;
648 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
649 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
650 // char already available
651 ret = 0;
652 else
653 ret = 1;
654 return ret;
657 static void serial_receive_byte(ChannelState *s, int ch)
659 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
660 s->rregs[R_STATUS] |= STATUS_RXAV;
661 s->rx = ch;
662 set_rxint(s);
665 static void serial_receive_break(ChannelState *s)
667 s->rregs[R_STATUS] |= STATUS_BRK;
668 escc_update_irq(s);
671 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
673 ChannelState *s = opaque;
674 serial_receive_byte(s, buf[0]);
677 static void serial_event(void *opaque, int event)
679 ChannelState *s = opaque;
680 if (event == CHR_EVENT_BREAK)
681 serial_receive_break(s);
684 static const VMStateDescription vmstate_escc_chn = {
685 .name ="escc_chn",
686 .version_id = 2,
687 .minimum_version_id = 1,
688 .minimum_version_id_old = 1,
689 .fields = (VMStateField []) {
690 VMSTATE_UINT32(vmstate_dummy, ChannelState),
691 VMSTATE_UINT32(reg, ChannelState),
692 VMSTATE_UINT32(rxint, ChannelState),
693 VMSTATE_UINT32(txint, ChannelState),
694 VMSTATE_UINT32(rxint_under_svc, ChannelState),
695 VMSTATE_UINT32(txint_under_svc, ChannelState),
696 VMSTATE_UINT8(rx, ChannelState),
697 VMSTATE_UINT8(tx, ChannelState),
698 VMSTATE_BUFFER(wregs, ChannelState),
699 VMSTATE_BUFFER(rregs, ChannelState),
700 VMSTATE_END_OF_LIST()
704 static const VMStateDescription vmstate_escc = {
705 .name ="escc",
706 .version_id = 2,
707 .minimum_version_id = 1,
708 .minimum_version_id_old = 1,
709 .fields = (VMStateField []) {
710 VMSTATE_STRUCT_ARRAY(chn, SerialState, 2, 2, vmstate_escc_chn,
711 ChannelState),
712 VMSTATE_END_OF_LIST()
716 MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
717 CharDriverState *chrA, CharDriverState *chrB,
718 int clock, int it_shift)
720 DeviceState *dev;
721 SysBusDevice *s;
722 SerialState *d;
724 dev = qdev_create(NULL, "escc");
725 qdev_prop_set_uint32(dev, "disabled", 0);
726 qdev_prop_set_uint32(dev, "frequency", clock);
727 qdev_prop_set_uint32(dev, "it_shift", it_shift);
728 qdev_prop_set_chr(dev, "chrB", chrB);
729 qdev_prop_set_chr(dev, "chrA", chrA);
730 qdev_prop_set_uint32(dev, "chnBtype", ser);
731 qdev_prop_set_uint32(dev, "chnAtype", ser);
732 qdev_init_nofail(dev);
733 s = sysbus_from_qdev(dev);
734 sysbus_connect_irq(s, 0, irqB);
735 sysbus_connect_irq(s, 1, irqA);
736 if (base) {
737 sysbus_mmio_map(s, 0, base);
740 d = FROM_SYSBUS(SerialState, s);
741 return &d->mmio;
744 static const uint8_t keycodes[128] = {
745 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
746 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
747 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
748 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
749 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
750 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
751 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
752 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
755 static const uint8_t e0_keycodes[128] = {
756 0, 0, 0, 0, 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, 90, 76, 0, 0,
758 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
759 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
760 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
761 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
762 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
763 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
766 static void sunkbd_event(void *opaque, int ch)
768 ChannelState *s = opaque;
769 int release = ch & 0x80;
771 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
772 "press");
773 switch (ch) {
774 case 58: // Caps lock press
775 s->caps_lock_mode ^= 1;
776 if (s->caps_lock_mode == 2)
777 return; // Drop second press
778 break;
779 case 69: // Num lock press
780 s->num_lock_mode ^= 1;
781 if (s->num_lock_mode == 2)
782 return; // Drop second press
783 break;
784 case 186: // Caps lock release
785 s->caps_lock_mode ^= 2;
786 if (s->caps_lock_mode == 3)
787 return; // Drop first release
788 break;
789 case 197: // Num lock release
790 s->num_lock_mode ^= 2;
791 if (s->num_lock_mode == 3)
792 return; // Drop first release
793 break;
794 case 0xe0:
795 s->e0_mode = 1;
796 return;
797 default:
798 break;
800 if (s->e0_mode) {
801 s->e0_mode = 0;
802 ch = e0_keycodes[ch & 0x7f];
803 } else {
804 ch = keycodes[ch & 0x7f];
806 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
807 put_queue(s, ch | release);
810 static void handle_kbd_command(ChannelState *s, int val)
812 KBD_DPRINTF("Command %d\n", val);
813 if (s->led_mode) { // Ignore led byte
814 s->led_mode = 0;
815 return;
817 switch (val) {
818 case 1: // Reset, return type code
819 clear_queue(s);
820 put_queue(s, 0xff);
821 put_queue(s, 4); // Type 4
822 put_queue(s, 0x7f);
823 break;
824 case 0xe: // Set leds
825 s->led_mode = 1;
826 break;
827 case 7: // Query layout
828 case 0xf:
829 clear_queue(s);
830 put_queue(s, 0xfe);
831 put_queue(s, 0); // XXX, layout?
832 break;
833 default:
834 break;
838 static void sunmouse_event(void *opaque,
839 int dx, int dy, int dz, int buttons_state)
841 ChannelState *s = opaque;
842 int ch;
844 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
846 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
848 if (buttons_state & MOUSE_EVENT_LBUTTON)
849 ch ^= 0x4;
850 if (buttons_state & MOUSE_EVENT_MBUTTON)
851 ch ^= 0x2;
852 if (buttons_state & MOUSE_EVENT_RBUTTON)
853 ch ^= 0x1;
855 put_queue(s, ch);
857 ch = dx;
859 if (ch > 127)
860 ch = 127;
861 else if (ch < -127)
862 ch = -127;
864 put_queue(s, ch & 0xff);
866 ch = -dy;
868 if (ch > 127)
869 ch = 127;
870 else if (ch < -127)
871 ch = -127;
873 put_queue(s, ch & 0xff);
875 // MSC protocol specify two extra motion bytes
877 put_queue(s, 0);
878 put_queue(s, 0);
881 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
882 int disabled, int clock, int it_shift)
884 DeviceState *dev;
885 SysBusDevice *s;
887 dev = qdev_create(NULL, "escc");
888 qdev_prop_set_uint32(dev, "disabled", disabled);
889 qdev_prop_set_uint32(dev, "frequency", clock);
890 qdev_prop_set_uint32(dev, "it_shift", it_shift);
891 qdev_prop_set_chr(dev, "chrB", NULL);
892 qdev_prop_set_chr(dev, "chrA", NULL);
893 qdev_prop_set_uint32(dev, "chnBtype", mouse);
894 qdev_prop_set_uint32(dev, "chnAtype", kbd);
895 qdev_init_nofail(dev);
896 s = sysbus_from_qdev(dev);
897 sysbus_connect_irq(s, 0, irq);
898 sysbus_connect_irq(s, 1, irq);
899 sysbus_mmio_map(s, 0, base);
902 static int escc_init1(SysBusDevice *dev)
904 SerialState *s = FROM_SYSBUS(SerialState, dev);
905 unsigned int i;
907 s->chn[0].disabled = s->disabled;
908 s->chn[1].disabled = s->disabled;
909 for (i = 0; i < 2; i++) {
910 sysbus_init_irq(dev, &s->chn[i].irq);
911 s->chn[i].chn = 1 - i;
912 s->chn[i].clock = s->frequency / 2;
913 if (s->chn[i].chr) {
914 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
915 serial_receive1, serial_event, &s->chn[i]);
918 s->chn[0].otherchn = &s->chn[1];
919 s->chn[1].otherchn = &s->chn[0];
921 memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc",
922 ESCC_SIZE << s->it_shift);
923 sysbus_init_mmio_region(dev, &s->mmio);
925 if (s->chn[0].type == mouse) {
926 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
927 "QEMU Sun Mouse");
929 if (s->chn[1].type == kbd) {
930 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
933 return 0;
936 static SysBusDeviceInfo escc_info = {
937 .init = escc_init1,
938 .qdev.name = "escc",
939 .qdev.size = sizeof(SerialState),
940 .qdev.vmsd = &vmstate_escc,
941 .qdev.reset = escc_reset,
942 .qdev.props = (Property[]) {
943 DEFINE_PROP_UINT32("frequency", SerialState, frequency, 0),
944 DEFINE_PROP_UINT32("it_shift", SerialState, it_shift, 0),
945 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
946 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
947 DEFINE_PROP_UINT32("chnBtype", SerialState, chn[0].type, 0),
948 DEFINE_PROP_UINT32("chnAtype", SerialState, chn[1].type, 0),
949 DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
950 DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
951 DEFINE_PROP_END_OF_LIST(),
955 static void escc_register_devices(void)
957 sysbus_register_withprop(&escc_info);
960 device_init(escc_register_devices)