scsi: update comment on the standards revision
[qemu/aliguori-queue.git] / hw / escc.c
blob6d2fd36b11629499f525972bb6a7c2477e21d6bb
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.
70 #ifdef DEBUG_SERIAL
71 #define SER_DPRINTF(fmt, ...) \
72 do { printf("SER: " fmt , ## __VA_ARGS__); } while (0)
73 #else
74 #define SER_DPRINTF(fmt, ...)
75 #endif
76 #ifdef DEBUG_KBD
77 #define KBD_DPRINTF(fmt, ...) \
78 do { printf("KBD: " fmt , ## __VA_ARGS__); } while (0)
79 #else
80 #define KBD_DPRINTF(fmt, ...)
81 #endif
82 #ifdef DEBUG_MOUSE
83 #define MS_DPRINTF(fmt, ...) \
84 do { printf("MSC: " fmt , ## __VA_ARGS__); } while (0)
85 #else
86 #define MS_DPRINTF(fmt, ...)
87 #endif
89 typedef enum {
90 chn_a, chn_b,
91 } ChnID;
93 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
95 typedef enum {
96 ser, kbd, mouse,
97 } ChnType;
99 #define SERIO_QUEUE_SIZE 256
101 typedef struct {
102 uint8_t data[SERIO_QUEUE_SIZE];
103 int rptr, wptr, count;
104 } SERIOQueue;
106 #define SERIAL_REGS 16
107 typedef struct ChannelState {
108 qemu_irq irq;
109 uint32_t reg;
110 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
111 ChnID chn; // this channel, A (base+4) or B (base+0)
112 ChnType type;
113 struct ChannelState *otherchn;
114 uint8_t rx, tx, 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 } ChannelState;
123 struct SerialState {
124 SysBusDevice busdev;
125 struct ChannelState chn[2];
126 uint32_t it_shift;
127 int mmio_index;
128 uint32_t disabled;
129 uint32_t frequency;
132 #define SERIAL_CTRL 0
133 #define SERIAL_DATA 1
135 #define W_CMD 0
136 #define CMD_PTR_MASK 0x07
137 #define CMD_CMD_MASK 0x38
138 #define CMD_HI 0x08
139 #define CMD_CLR_TXINT 0x28
140 #define CMD_CLR_IUS 0x38
141 #define W_INTR 1
142 #define INTR_INTALL 0x01
143 #define INTR_TXINT 0x02
144 #define INTR_RXMODEMSK 0x18
145 #define INTR_RXINT1ST 0x08
146 #define INTR_RXINTALL 0x10
147 #define W_IVEC 2
148 #define W_RXCTRL 3
149 #define RXCTRL_RXEN 0x01
150 #define W_TXCTRL1 4
151 #define TXCTRL1_PAREN 0x01
152 #define TXCTRL1_PAREV 0x02
153 #define TXCTRL1_1STOP 0x04
154 #define TXCTRL1_1HSTOP 0x08
155 #define TXCTRL1_2STOP 0x0c
156 #define TXCTRL1_STPMSK 0x0c
157 #define TXCTRL1_CLK1X 0x00
158 #define TXCTRL1_CLK16X 0x40
159 #define TXCTRL1_CLK32X 0x80
160 #define TXCTRL1_CLK64X 0xc0
161 #define TXCTRL1_CLKMSK 0xc0
162 #define W_TXCTRL2 5
163 #define TXCTRL2_TXEN 0x08
164 #define TXCTRL2_BITMSK 0x60
165 #define TXCTRL2_5BITS 0x00
166 #define TXCTRL2_7BITS 0x20
167 #define TXCTRL2_6BITS 0x40
168 #define TXCTRL2_8BITS 0x60
169 #define W_SYNC1 6
170 #define W_SYNC2 7
171 #define W_TXBUF 8
172 #define W_MINTR 9
173 #define MINTR_STATUSHI 0x10
174 #define MINTR_RST_MASK 0xc0
175 #define MINTR_RST_B 0x40
176 #define MINTR_RST_A 0x80
177 #define MINTR_RST_ALL 0xc0
178 #define W_MISC1 10
179 #define W_CLOCK 11
180 #define CLOCK_TRXC 0x08
181 #define W_BRGLO 12
182 #define W_BRGHI 13
183 #define W_MISC2 14
184 #define MISC2_PLLDIS 0x30
185 #define W_EXTINT 15
186 #define EXTINT_DCD 0x08
187 #define EXTINT_SYNCINT 0x10
188 #define EXTINT_CTSINT 0x20
189 #define EXTINT_TXUNDRN 0x40
190 #define EXTINT_BRKINT 0x80
192 #define R_STATUS 0
193 #define STATUS_RXAV 0x01
194 #define STATUS_ZERO 0x02
195 #define STATUS_TXEMPTY 0x04
196 #define STATUS_DCD 0x08
197 #define STATUS_SYNC 0x10
198 #define STATUS_CTS 0x20
199 #define STATUS_TXUNDRN 0x40
200 #define STATUS_BRK 0x80
201 #define R_SPEC 1
202 #define SPEC_ALLSENT 0x01
203 #define SPEC_BITS8 0x06
204 #define R_IVEC 2
205 #define IVEC_TXINTB 0x00
206 #define IVEC_LONOINT 0x06
207 #define IVEC_LORXINTA 0x0c
208 #define IVEC_LORXINTB 0x04
209 #define IVEC_LOTXINTA 0x08
210 #define IVEC_HINOINT 0x60
211 #define IVEC_HIRXINTA 0x30
212 #define IVEC_HIRXINTB 0x20
213 #define IVEC_HITXINTA 0x10
214 #define R_INTR 3
215 #define INTR_EXTINTB 0x01
216 #define INTR_TXINTB 0x02
217 #define INTR_RXINTB 0x04
218 #define INTR_EXTINTA 0x08
219 #define INTR_TXINTA 0x10
220 #define INTR_RXINTA 0x20
221 #define R_IPEN 4
222 #define R_TXCTRL1 5
223 #define R_TXCTRL2 6
224 #define R_BC 7
225 #define R_RXBUF 8
226 #define R_RXCTRL 9
227 #define R_MISC 10
228 #define R_MISC1 11
229 #define R_BRGLO 12
230 #define R_BRGHI 13
231 #define R_MISC1I 14
232 #define R_EXTINT 15
234 static void handle_kbd_command(ChannelState *s, int val);
235 static int serial_can_receive(void *opaque);
236 static void serial_receive_byte(ChannelState *s, int ch);
238 static void clear_queue(void *opaque)
240 ChannelState *s = opaque;
241 SERIOQueue *q = &s->queue;
242 q->rptr = q->wptr = q->count = 0;
245 static void put_queue(void *opaque, int b)
247 ChannelState *s = opaque;
248 SERIOQueue *q = &s->queue;
250 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
251 if (q->count >= SERIO_QUEUE_SIZE)
252 return;
253 q->data[q->wptr] = b;
254 if (++q->wptr == SERIO_QUEUE_SIZE)
255 q->wptr = 0;
256 q->count++;
257 serial_receive_byte(s, 0);
260 static uint32_t get_queue(void *opaque)
262 ChannelState *s = opaque;
263 SERIOQueue *q = &s->queue;
264 int val;
266 if (q->count == 0) {
267 return 0;
268 } else {
269 val = q->data[q->rptr];
270 if (++q->rptr == SERIO_QUEUE_SIZE)
271 q->rptr = 0;
272 q->count--;
274 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
275 if (q->count > 0)
276 serial_receive_byte(s, 0);
277 return val;
280 static int escc_update_irq_chn(ChannelState *s)
282 if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
283 // tx ints enabled, pending
284 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
285 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
286 s->rxint == 1) || // rx ints enabled, pending
287 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
288 (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
289 return 1;
291 return 0;
294 static void escc_update_irq(ChannelState *s)
296 int irq;
298 irq = escc_update_irq_chn(s);
299 irq |= escc_update_irq_chn(s->otherchn);
301 SER_DPRINTF("IRQ = %d\n", irq);
302 qemu_set_irq(s->irq, irq);
305 static void escc_reset_chn(ChannelState *s)
307 int i;
309 s->reg = 0;
310 for (i = 0; i < SERIAL_REGS; i++) {
311 s->rregs[i] = 0;
312 s->wregs[i] = 0;
314 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
315 s->wregs[W_MINTR] = MINTR_RST_ALL;
316 s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
317 s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
318 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
319 EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
320 if (s->disabled)
321 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
322 STATUS_CTS | STATUS_TXUNDRN;
323 else
324 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
325 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
327 s->rx = s->tx = 0;
328 s->rxint = s->txint = 0;
329 s->rxint_under_svc = s->txint_under_svc = 0;
330 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
331 clear_queue(s);
334 static void escc_reset(DeviceState *d)
336 SerialState *s = container_of(d, SerialState, busdev.qdev);
338 escc_reset_chn(&s->chn[0]);
339 escc_reset_chn(&s->chn[1]);
342 static inline void set_rxint(ChannelState *s)
344 s->rxint = 1;
345 if (!s->txint_under_svc) {
346 s->rxint_under_svc = 1;
347 if (s->chn == chn_a) {
348 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
349 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
350 else
351 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
352 } else {
353 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
354 s->rregs[R_IVEC] = IVEC_HIRXINTB;
355 else
356 s->rregs[R_IVEC] = IVEC_LORXINTB;
359 if (s->chn == chn_a)
360 s->rregs[R_INTR] |= INTR_RXINTA;
361 else
362 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
363 escc_update_irq(s);
366 static inline void set_txint(ChannelState *s)
368 s->txint = 1;
369 if (!s->rxint_under_svc) {
370 s->txint_under_svc = 1;
371 if (s->chn == chn_a) {
372 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
373 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
374 else
375 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
376 } else {
377 s->rregs[R_IVEC] = IVEC_TXINTB;
380 if (s->chn == chn_a)
381 s->rregs[R_INTR] |= INTR_TXINTA;
382 else
383 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
384 escc_update_irq(s);
387 static inline void clr_rxint(ChannelState *s)
389 s->rxint = 0;
390 s->rxint_under_svc = 0;
391 if (s->chn == chn_a) {
392 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
393 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
394 else
395 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
396 s->rregs[R_INTR] &= ~INTR_RXINTA;
397 } else {
398 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
399 s->rregs[R_IVEC] = IVEC_HINOINT;
400 else
401 s->rregs[R_IVEC] = IVEC_LONOINT;
402 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
404 if (s->txint)
405 set_txint(s);
406 escc_update_irq(s);
409 static inline void clr_txint(ChannelState *s)
411 s->txint = 0;
412 s->txint_under_svc = 0;
413 if (s->chn == chn_a) {
414 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
415 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
416 else
417 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
418 s->rregs[R_INTR] &= ~INTR_TXINTA;
419 } else {
420 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
421 s->rregs[R_IVEC] = IVEC_HINOINT;
422 else
423 s->rregs[R_IVEC] = IVEC_LONOINT;
424 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
426 if (s->rxint)
427 set_rxint(s);
428 escc_update_irq(s);
431 static void escc_update_parameters(ChannelState *s)
433 int speed, parity, data_bits, stop_bits;
434 QEMUSerialSetParams ssp;
436 if (!s->chr || s->type != ser)
437 return;
439 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
440 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
441 parity = 'E';
442 else
443 parity = 'O';
444 } else {
445 parity = 'N';
447 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
448 stop_bits = 2;
449 else
450 stop_bits = 1;
451 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
452 case TXCTRL2_5BITS:
453 data_bits = 5;
454 break;
455 case TXCTRL2_7BITS:
456 data_bits = 7;
457 break;
458 case TXCTRL2_6BITS:
459 data_bits = 6;
460 break;
461 default:
462 case TXCTRL2_8BITS:
463 data_bits = 8;
464 break;
466 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
467 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
468 case TXCTRL1_CLK1X:
469 break;
470 case TXCTRL1_CLK16X:
471 speed /= 16;
472 break;
473 case TXCTRL1_CLK32X:
474 speed /= 32;
475 break;
476 default:
477 case TXCTRL1_CLK64X:
478 speed /= 64;
479 break;
481 ssp.speed = speed;
482 ssp.parity = parity;
483 ssp.data_bits = data_bits;
484 ssp.stop_bits = stop_bits;
485 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
486 speed, parity, data_bits, stop_bits);
487 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
490 static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
492 SerialState *serial = opaque;
493 ChannelState *s;
494 uint32_t saddr;
495 int newreg, channel;
497 val &= 0xff;
498 saddr = (addr >> serial->it_shift) & 1;
499 channel = (addr >> (serial->it_shift + 1)) & 1;
500 s = &serial->chn[channel];
501 switch (saddr) {
502 case SERIAL_CTRL:
503 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
504 val & 0xff);
505 newreg = 0;
506 switch (s->reg) {
507 case W_CMD:
508 newreg = val & CMD_PTR_MASK;
509 val &= CMD_CMD_MASK;
510 switch (val) {
511 case CMD_HI:
512 newreg |= CMD_HI;
513 break;
514 case CMD_CLR_TXINT:
515 clr_txint(s);
516 break;
517 case CMD_CLR_IUS:
518 if (s->rxint_under_svc)
519 clr_rxint(s);
520 else if (s->txint_under_svc)
521 clr_txint(s);
522 break;
523 default:
524 break;
526 break;
527 case W_INTR ... W_RXCTRL:
528 case W_SYNC1 ... W_TXBUF:
529 case W_MISC1 ... W_CLOCK:
530 case W_MISC2 ... W_EXTINT:
531 s->wregs[s->reg] = val;
532 break;
533 case W_TXCTRL1:
534 case W_TXCTRL2:
535 s->wregs[s->reg] = val;
536 escc_update_parameters(s);
537 break;
538 case W_BRGLO:
539 case W_BRGHI:
540 s->wregs[s->reg] = val;
541 s->rregs[s->reg] = val;
542 escc_update_parameters(s);
543 break;
544 case W_MINTR:
545 switch (val & MINTR_RST_MASK) {
546 case 0:
547 default:
548 break;
549 case MINTR_RST_B:
550 escc_reset_chn(&serial->chn[0]);
551 return;
552 case MINTR_RST_A:
553 escc_reset_chn(&serial->chn[1]);
554 return;
555 case MINTR_RST_ALL:
556 escc_reset(&serial->busdev.qdev);
557 return;
559 break;
560 default:
561 break;
563 if (s->reg == 0)
564 s->reg = newreg;
565 else
566 s->reg = 0;
567 break;
568 case SERIAL_DATA:
569 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
570 s->tx = val;
571 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
572 if (s->chr)
573 qemu_chr_write(s->chr, &s->tx, 1);
574 else if (s->type == kbd && !s->disabled) {
575 handle_kbd_command(s, val);
578 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
579 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
580 set_txint(s);
581 break;
582 default:
583 break;
587 static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
589 SerialState *serial = opaque;
590 ChannelState *s;
591 uint32_t saddr;
592 uint32_t ret;
593 int channel;
595 saddr = (addr >> serial->it_shift) & 1;
596 channel = (addr >> (serial->it_shift + 1)) & 1;
597 s = &serial->chn[channel];
598 switch (saddr) {
599 case SERIAL_CTRL:
600 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
601 s->rregs[s->reg]);
602 ret = s->rregs[s->reg];
603 s->reg = 0;
604 return ret;
605 case SERIAL_DATA:
606 s->rregs[R_STATUS] &= ~STATUS_RXAV;
607 clr_rxint(s);
608 if (s->type == kbd || s->type == mouse)
609 ret = get_queue(s);
610 else
611 ret = s->rx;
612 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
613 if (s->chr)
614 qemu_chr_accept_input(s->chr);
615 return ret;
616 default:
617 break;
619 return 0;
622 static int serial_can_receive(void *opaque)
624 ChannelState *s = opaque;
625 int ret;
627 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
628 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
629 // char already available
630 ret = 0;
631 else
632 ret = 1;
633 return ret;
636 static void serial_receive_byte(ChannelState *s, int ch)
638 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
639 s->rregs[R_STATUS] |= STATUS_RXAV;
640 s->rx = ch;
641 set_rxint(s);
644 static void serial_receive_break(ChannelState *s)
646 s->rregs[R_STATUS] |= STATUS_BRK;
647 escc_update_irq(s);
650 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
652 ChannelState *s = opaque;
653 serial_receive_byte(s, buf[0]);
656 static void serial_event(void *opaque, int event)
658 ChannelState *s = opaque;
659 if (event == CHR_EVENT_BREAK)
660 serial_receive_break(s);
663 static CPUReadMemoryFunc * const escc_mem_read[3] = {
664 escc_mem_readb,
665 NULL,
666 NULL,
669 static CPUWriteMemoryFunc * const escc_mem_write[3] = {
670 escc_mem_writeb,
671 NULL,
672 NULL,
675 static const VMStateDescription vmstate_escc_chn = {
676 .name ="escc_chn",
677 .version_id = 2,
678 .minimum_version_id = 1,
679 .minimum_version_id_old = 1,
680 .fields = (VMStateField []) {
681 VMSTATE_UINT32(vmstate_dummy, ChannelState),
682 VMSTATE_UINT32(reg, ChannelState),
683 VMSTATE_UINT32(rxint, ChannelState),
684 VMSTATE_UINT32(txint, ChannelState),
685 VMSTATE_UINT32(rxint_under_svc, ChannelState),
686 VMSTATE_UINT32(txint_under_svc, ChannelState),
687 VMSTATE_UINT8(rx, ChannelState),
688 VMSTATE_UINT8(tx, ChannelState),
689 VMSTATE_BUFFER(wregs, ChannelState),
690 VMSTATE_BUFFER(rregs, ChannelState),
691 VMSTATE_END_OF_LIST()
695 static const VMStateDescription vmstate_escc = {
696 .name ="escc",
697 .version_id = 2,
698 .minimum_version_id = 1,
699 .minimum_version_id_old = 1,
700 .fields = (VMStateField []) {
701 VMSTATE_STRUCT_ARRAY(chn, SerialState, 2, 2, vmstate_escc_chn,
702 ChannelState),
703 VMSTATE_END_OF_LIST()
707 int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
708 CharDriverState *chrA, CharDriverState *chrB,
709 int clock, int it_shift)
711 DeviceState *dev;
712 SysBusDevice *s;
713 SerialState *d;
715 dev = qdev_create(NULL, "escc");
716 qdev_prop_set_uint32(dev, "disabled", 0);
717 qdev_prop_set_uint32(dev, "frequency", clock);
718 qdev_prop_set_uint32(dev, "it_shift", it_shift);
719 qdev_prop_set_chr(dev, "chrB", chrB);
720 qdev_prop_set_chr(dev, "chrA", chrA);
721 qdev_prop_set_uint32(dev, "chnBtype", ser);
722 qdev_prop_set_uint32(dev, "chnAtype", ser);
723 qdev_init_nofail(dev);
724 s = sysbus_from_qdev(dev);
725 sysbus_connect_irq(s, 0, irqB);
726 sysbus_connect_irq(s, 1, irqA);
727 if (base) {
728 sysbus_mmio_map(s, 0, base);
731 d = FROM_SYSBUS(SerialState, s);
732 return d->mmio_index;
735 static const uint8_t keycodes[128] = {
736 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
737 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
738 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
739 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
740 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
741 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
742 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
743 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
746 static const uint8_t e0_keycodes[128] = {
747 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
748 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
750 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
751 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
752 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
753 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
754 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
757 static void sunkbd_event(void *opaque, int ch)
759 ChannelState *s = opaque;
760 int release = ch & 0x80;
762 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
763 "press");
764 switch (ch) {
765 case 58: // Caps lock press
766 s->caps_lock_mode ^= 1;
767 if (s->caps_lock_mode == 2)
768 return; // Drop second press
769 break;
770 case 69: // Num lock press
771 s->num_lock_mode ^= 1;
772 if (s->num_lock_mode == 2)
773 return; // Drop second press
774 break;
775 case 186: // Caps lock release
776 s->caps_lock_mode ^= 2;
777 if (s->caps_lock_mode == 3)
778 return; // Drop first release
779 break;
780 case 197: // Num lock release
781 s->num_lock_mode ^= 2;
782 if (s->num_lock_mode == 3)
783 return; // Drop first release
784 break;
785 case 0xe0:
786 s->e0_mode = 1;
787 return;
788 default:
789 break;
791 if (s->e0_mode) {
792 s->e0_mode = 0;
793 ch = e0_keycodes[ch & 0x7f];
794 } else {
795 ch = keycodes[ch & 0x7f];
797 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
798 put_queue(s, ch | release);
801 static void handle_kbd_command(ChannelState *s, int val)
803 KBD_DPRINTF("Command %d\n", val);
804 if (s->led_mode) { // Ignore led byte
805 s->led_mode = 0;
806 return;
808 switch (val) {
809 case 1: // Reset, return type code
810 clear_queue(s);
811 put_queue(s, 0xff);
812 put_queue(s, 4); // Type 4
813 put_queue(s, 0x7f);
814 break;
815 case 0xe: // Set leds
816 s->led_mode = 1;
817 break;
818 case 7: // Query layout
819 case 0xf:
820 clear_queue(s);
821 put_queue(s, 0xfe);
822 put_queue(s, 0); // XXX, layout?
823 break;
824 default:
825 break;
829 static void sunmouse_event(void *opaque,
830 int dx, int dy, int dz, int buttons_state)
832 ChannelState *s = opaque;
833 int ch;
835 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
837 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
839 if (buttons_state & MOUSE_EVENT_LBUTTON)
840 ch ^= 0x4;
841 if (buttons_state & MOUSE_EVENT_MBUTTON)
842 ch ^= 0x2;
843 if (buttons_state & MOUSE_EVENT_RBUTTON)
844 ch ^= 0x1;
846 put_queue(s, ch);
848 ch = dx;
850 if (ch > 127)
851 ch = 127;
852 else if (ch < -127)
853 ch = -127;
855 put_queue(s, ch & 0xff);
857 ch = -dy;
859 if (ch > 127)
860 ch = 127;
861 else if (ch < -127)
862 ch = -127;
864 put_queue(s, ch & 0xff);
866 // MSC protocol specify two extra motion bytes
868 put_queue(s, 0);
869 put_queue(s, 0);
872 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
873 int disabled, int clock, int it_shift)
875 DeviceState *dev;
876 SysBusDevice *s;
878 dev = qdev_create(NULL, "escc");
879 qdev_prop_set_uint32(dev, "disabled", disabled);
880 qdev_prop_set_uint32(dev, "frequency", clock);
881 qdev_prop_set_uint32(dev, "it_shift", it_shift);
882 qdev_prop_set_chr(dev, "chrB", NULL);
883 qdev_prop_set_chr(dev, "chrA", NULL);
884 qdev_prop_set_uint32(dev, "chnBtype", mouse);
885 qdev_prop_set_uint32(dev, "chnAtype", kbd);
886 qdev_init_nofail(dev);
887 s = sysbus_from_qdev(dev);
888 sysbus_connect_irq(s, 0, irq);
889 sysbus_connect_irq(s, 1, irq);
890 sysbus_mmio_map(s, 0, base);
893 static int escc_init1(SysBusDevice *dev)
895 SerialState *s = FROM_SYSBUS(SerialState, dev);
896 int io;
897 unsigned int i;
899 s->chn[0].disabled = s->disabled;
900 s->chn[1].disabled = s->disabled;
901 for (i = 0; i < 2; i++) {
902 sysbus_init_irq(dev, &s->chn[i].irq);
903 s->chn[i].chn = 1 - i;
904 s->chn[i].clock = s->frequency / 2;
905 if (s->chn[i].chr) {
906 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
907 serial_receive1, serial_event, &s->chn[i]);
910 s->chn[0].otherchn = &s->chn[1];
911 s->chn[1].otherchn = &s->chn[0];
913 io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s);
914 sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io);
915 s->mmio_index = io;
917 if (s->chn[0].type == mouse) {
918 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
919 "QEMU Sun Mouse");
921 if (s->chn[1].type == kbd) {
922 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
925 return 0;
928 static SysBusDeviceInfo escc_info = {
929 .init = escc_init1,
930 .qdev.name = "escc",
931 .qdev.size = sizeof(SerialState),
932 .qdev.vmsd = &vmstate_escc,
933 .qdev.reset = escc_reset,
934 .qdev.props = (Property[]) {
935 DEFINE_PROP_UINT32("frequency", SerialState, frequency, 0),
936 DEFINE_PROP_UINT32("it_shift", SerialState, it_shift, 0),
937 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
938 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
939 DEFINE_PROP_UINT32("chnBtype", SerialState, chn[0].type, 0),
940 DEFINE_PROP_UINT32("chnAtype", SerialState, chn[1].type, 0),
941 DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
942 DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
943 DEFINE_PROP_END_OF_LIST(),
947 static void escc_register_devices(void)
949 sysbus_register_withprop(&escc_info);
952 device_init(escc_register_devices)