scsi-disk: no need to call scsi_req_data on a short read
[qemu.git] / hw / escc.c
blobbea5873a02cddc55be2b699d51bcdc61ca9e6159
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 reg;
112 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
113 ChnID chn; // this channel, A (base+4) or B (base+0)
114 ChnType type;
115 struct ChannelState *otherchn;
116 uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
117 SERIOQueue queue;
118 CharDriverState *chr;
119 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
120 int disabled;
121 int clock;
122 uint32_t vmstate_dummy;
123 } ChannelState;
125 struct SerialState {
126 SysBusDevice busdev;
127 struct ChannelState chn[2];
128 uint32_t it_shift;
129 MemoryRegion mmio;
130 uint32_t disabled;
131 uint32_t frequency;
134 #define SERIAL_CTRL 0
135 #define SERIAL_DATA 1
137 #define W_CMD 0
138 #define CMD_PTR_MASK 0x07
139 #define CMD_CMD_MASK 0x38
140 #define CMD_HI 0x08
141 #define CMD_CLR_TXINT 0x28
142 #define CMD_CLR_IUS 0x38
143 #define W_INTR 1
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
149 #define W_IVEC 2
150 #define W_RXCTRL 3
151 #define RXCTRL_RXEN 0x01
152 #define W_TXCTRL1 4
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
164 #define W_TXCTRL2 5
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
171 #define W_SYNC1 6
172 #define W_SYNC2 7
173 #define W_TXBUF 8
174 #define W_MINTR 9
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
180 #define W_MISC1 10
181 #define W_CLOCK 11
182 #define CLOCK_TRXC 0x08
183 #define W_BRGLO 12
184 #define W_BRGHI 13
185 #define W_MISC2 14
186 #define MISC2_PLLDIS 0x30
187 #define W_EXTINT 15
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
194 #define R_STATUS 0
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
203 #define R_SPEC 1
204 #define SPEC_ALLSENT 0x01
205 #define SPEC_BITS8 0x06
206 #define R_IVEC 2
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
216 #define R_INTR 3
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
223 #define R_IPEN 4
224 #define R_TXCTRL1 5
225 #define R_TXCTRL2 6
226 #define R_BC 7
227 #define R_RXBUF 8
228 #define R_RXCTRL 9
229 #define R_MISC 10
230 #define R_MISC1 11
231 #define R_BRGLO 12
232 #define R_BRGHI 13
233 #define R_MISC1I 14
234 #define R_EXTINT 15
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)
254 return;
255 q->data[q->wptr] = b;
256 if (++q->wptr == SERIO_QUEUE_SIZE)
257 q->wptr = 0;
258 q->count++;
259 serial_receive_byte(s, 0);
262 static uint32_t get_queue(void *opaque)
264 ChannelState *s = opaque;
265 SERIOQueue *q = &s->queue;
266 int val;
268 if (q->count == 0) {
269 return 0;
270 } else {
271 val = q->data[q->rptr];
272 if (++q->rptr == SERIO_QUEUE_SIZE)
273 q->rptr = 0;
274 q->count--;
276 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
277 if (q->count > 0)
278 serial_receive_byte(s, 0);
279 return val;
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
291 return 1;
293 return 0;
296 static void escc_update_irq(ChannelState *s)
298 int irq;
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)
309 int i;
311 s->reg = 0;
312 for (i = 0; i < SERIAL_REGS; i++) {
313 s->rregs[i] = 0;
314 s->wregs[i] = 0;
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
322 if (s->disabled)
323 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
324 STATUS_CTS | STATUS_TXUNDRN;
325 else
326 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
327 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
329 s->rx = s->tx = 0;
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;
333 clear_queue(s);
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)
346 s->rxint = 1;
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;
354 else
355 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
356 } else {
357 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
358 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
359 s->rregs[R_IVEC] = IVEC_HIRXINTB;
360 else
361 s->rregs[R_IVEC] = IVEC_LORXINTB;
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_INTR] & INTR_TXINT) {
373 s->rregs[R_INTR] |= INTR_TXINTA;
375 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
376 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
377 else
378 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
379 } else {
380 s->rregs[R_IVEC] = IVEC_TXINTB;
381 if (s->wregs[W_INTR] & INTR_TXINT) {
382 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
385 escc_update_irq(s);
389 static inline void clr_rxint(ChannelState *s)
391 s->rxint = 0;
392 s->rxint_under_svc = 0;
393 if (s->chn == chn_a) {
394 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
395 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
396 else
397 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
398 s->rregs[R_INTR] &= ~INTR_RXINTA;
399 } else {
400 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
401 s->rregs[R_IVEC] = IVEC_HINOINT;
402 else
403 s->rregs[R_IVEC] = IVEC_LONOINT;
404 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
406 if (s->txint)
407 set_txint(s);
408 escc_update_irq(s);
411 static inline void clr_txint(ChannelState *s)
413 s->txint = 0;
414 s->txint_under_svc = 0;
415 if (s->chn == chn_a) {
416 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
417 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
418 else
419 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
420 s->rregs[R_INTR] &= ~INTR_TXINTA;
421 } else {
422 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
423 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
424 s->rregs[R_IVEC] = IVEC_HINOINT;
425 else
426 s->rregs[R_IVEC] = IVEC_LONOINT;
427 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
429 if (s->rxint)
430 set_rxint(s);
431 escc_update_irq(s);
434 static void escc_update_parameters(ChannelState *s)
436 int speed, parity, data_bits, stop_bits;
437 QEMUSerialSetParams ssp;
439 if (!s->chr || s->type != ser)
440 return;
442 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
443 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
444 parity = 'E';
445 else
446 parity = 'O';
447 } else {
448 parity = 'N';
450 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
451 stop_bits = 2;
452 else
453 stop_bits = 1;
454 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
455 case TXCTRL2_5BITS:
456 data_bits = 5;
457 break;
458 case TXCTRL2_7BITS:
459 data_bits = 7;
460 break;
461 case TXCTRL2_6BITS:
462 data_bits = 6;
463 break;
464 default:
465 case TXCTRL2_8BITS:
466 data_bits = 8;
467 break;
469 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
470 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
471 case TXCTRL1_CLK1X:
472 break;
473 case TXCTRL1_CLK16X:
474 speed /= 16;
475 break;
476 case TXCTRL1_CLK32X:
477 speed /= 32;
478 break;
479 default:
480 case TXCTRL1_CLK64X:
481 speed /= 64;
482 break;
484 ssp.speed = speed;
485 ssp.parity = parity;
486 ssp.data_bits = data_bits;
487 ssp.stop_bits = stop_bits;
488 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
489 speed, parity, data_bits, stop_bits);
490 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
493 static void escc_mem_write(void *opaque, target_phys_addr_t addr,
494 uint64_t val, unsigned size)
496 SerialState *serial = opaque;
497 ChannelState *s;
498 uint32_t saddr;
499 int newreg, channel;
501 val &= 0xff;
502 saddr = (addr >> serial->it_shift) & 1;
503 channel = (addr >> (serial->it_shift + 1)) & 1;
504 s = &serial->chn[channel];
505 switch (saddr) {
506 case SERIAL_CTRL:
507 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
508 val & 0xff);
509 newreg = 0;
510 switch (s->reg) {
511 case W_CMD:
512 newreg = val & CMD_PTR_MASK;
513 val &= CMD_CMD_MASK;
514 switch (val) {
515 case CMD_HI:
516 newreg |= CMD_HI;
517 break;
518 case CMD_CLR_TXINT:
519 clr_txint(s);
520 break;
521 case CMD_CLR_IUS:
522 if (s->rxint_under_svc) {
523 s->rxint_under_svc = 0;
524 if (s->txint) {
525 set_txint(s);
527 } else if (s->txint_under_svc) {
528 s->txint_under_svc = 0;
530 escc_update_irq(s);
531 break;
532 default:
533 break;
535 break;
536 case W_INTR ... W_RXCTRL:
537 case W_SYNC1 ... W_TXBUF:
538 case W_MISC1 ... W_CLOCK:
539 case W_MISC2 ... W_EXTINT:
540 s->wregs[s->reg] = val;
541 break;
542 case W_TXCTRL1:
543 case W_TXCTRL2:
544 s->wregs[s->reg] = val;
545 escc_update_parameters(s);
546 break;
547 case W_BRGLO:
548 case W_BRGHI:
549 s->wregs[s->reg] = val;
550 s->rregs[s->reg] = val;
551 escc_update_parameters(s);
552 break;
553 case W_MINTR:
554 switch (val & MINTR_RST_MASK) {
555 case 0:
556 default:
557 break;
558 case MINTR_RST_B:
559 escc_reset_chn(&serial->chn[0]);
560 return;
561 case MINTR_RST_A:
562 escc_reset_chn(&serial->chn[1]);
563 return;
564 case MINTR_RST_ALL:
565 escc_reset(&serial->busdev.qdev);
566 return;
568 break;
569 default:
570 break;
572 if (s->reg == 0)
573 s->reg = newreg;
574 else
575 s->reg = 0;
576 break;
577 case SERIAL_DATA:
578 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
579 s->tx = val;
580 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
581 if (s->chr)
582 qemu_chr_write(s->chr, &s->tx, 1);
583 else if (s->type == kbd && !s->disabled) {
584 handle_kbd_command(s, val);
587 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
588 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
589 set_txint(s);
590 break;
591 default:
592 break;
596 static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
597 unsigned size)
599 SerialState *serial = opaque;
600 ChannelState *s;
601 uint32_t saddr;
602 uint32_t ret;
603 int channel;
605 saddr = (addr >> serial->it_shift) & 1;
606 channel = (addr >> (serial->it_shift + 1)) & 1;
607 s = &serial->chn[channel];
608 switch (saddr) {
609 case SERIAL_CTRL:
610 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
611 s->rregs[s->reg]);
612 ret = s->rregs[s->reg];
613 s->reg = 0;
614 return ret;
615 case SERIAL_DATA:
616 s->rregs[R_STATUS] &= ~STATUS_RXAV;
617 clr_rxint(s);
618 if (s->type == kbd || s->type == mouse)
619 ret = get_queue(s);
620 else
621 ret = s->rx;
622 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
623 if (s->chr)
624 qemu_chr_accept_input(s->chr);
625 return ret;
626 default:
627 break;
629 return 0;
632 static const MemoryRegionOps escc_mem_ops = {
633 .read = escc_mem_read,
634 .write = escc_mem_write,
635 .endianness = DEVICE_NATIVE_ENDIAN,
636 .valid = {
637 .min_access_size = 1,
638 .max_access_size = 1,
642 static int serial_can_receive(void *opaque)
644 ChannelState *s = opaque;
645 int ret;
647 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
648 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
649 // char already available
650 ret = 0;
651 else
652 ret = 1;
653 return ret;
656 static void serial_receive_byte(ChannelState *s, int ch)
658 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
659 s->rregs[R_STATUS] |= STATUS_RXAV;
660 s->rx = ch;
661 set_rxint(s);
664 static void serial_receive_break(ChannelState *s)
666 s->rregs[R_STATUS] |= STATUS_BRK;
667 escc_update_irq(s);
670 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
672 ChannelState *s = opaque;
673 serial_receive_byte(s, buf[0]);
676 static void serial_event(void *opaque, int event)
678 ChannelState *s = opaque;
679 if (event == CHR_EVENT_BREAK)
680 serial_receive_break(s);
683 static const VMStateDescription vmstate_escc_chn = {
684 .name ="escc_chn",
685 .version_id = 2,
686 .minimum_version_id = 1,
687 .minimum_version_id_old = 1,
688 .fields = (VMStateField []) {
689 VMSTATE_UINT32(vmstate_dummy, ChannelState),
690 VMSTATE_UINT32(reg, ChannelState),
691 VMSTATE_UINT32(rxint, ChannelState),
692 VMSTATE_UINT32(txint, ChannelState),
693 VMSTATE_UINT32(rxint_under_svc, ChannelState),
694 VMSTATE_UINT32(txint_under_svc, ChannelState),
695 VMSTATE_UINT8(rx, ChannelState),
696 VMSTATE_UINT8(tx, ChannelState),
697 VMSTATE_BUFFER(wregs, ChannelState),
698 VMSTATE_BUFFER(rregs, ChannelState),
699 VMSTATE_END_OF_LIST()
703 static const VMStateDescription vmstate_escc = {
704 .name ="escc",
705 .version_id = 2,
706 .minimum_version_id = 1,
707 .minimum_version_id_old = 1,
708 .fields = (VMStateField []) {
709 VMSTATE_STRUCT_ARRAY(chn, SerialState, 2, 2, vmstate_escc_chn,
710 ChannelState),
711 VMSTATE_END_OF_LIST()
715 MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
716 CharDriverState *chrA, CharDriverState *chrB,
717 int clock, int it_shift)
719 DeviceState *dev;
720 SysBusDevice *s;
721 SerialState *d;
723 dev = qdev_create(NULL, "escc");
724 qdev_prop_set_uint32(dev, "disabled", 0);
725 qdev_prop_set_uint32(dev, "frequency", clock);
726 qdev_prop_set_uint32(dev, "it_shift", it_shift);
727 qdev_prop_set_chr(dev, "chrB", chrB);
728 qdev_prop_set_chr(dev, "chrA", chrA);
729 qdev_prop_set_uint32(dev, "chnBtype", ser);
730 qdev_prop_set_uint32(dev, "chnAtype", ser);
731 qdev_init_nofail(dev);
732 s = sysbus_from_qdev(dev);
733 sysbus_connect_irq(s, 0, irqB);
734 sysbus_connect_irq(s, 1, irqA);
735 if (base) {
736 sysbus_mmio_map(s, 0, base);
739 d = FROM_SYSBUS(SerialState, s);
740 return &d->mmio;
743 static const uint8_t keycodes[128] = {
744 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
745 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
746 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
747 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
748 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
749 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
750 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
751 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
754 static const uint8_t e0_keycodes[128] = {
755 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
756 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
757 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
758 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
759 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
760 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
761 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
762 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
765 static void sunkbd_event(void *opaque, int ch)
767 ChannelState *s = opaque;
768 int release = ch & 0x80;
770 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
771 "press");
772 switch (ch) {
773 case 58: // Caps lock press
774 s->caps_lock_mode ^= 1;
775 if (s->caps_lock_mode == 2)
776 return; // Drop second press
777 break;
778 case 69: // Num lock press
779 s->num_lock_mode ^= 1;
780 if (s->num_lock_mode == 2)
781 return; // Drop second press
782 break;
783 case 186: // Caps lock release
784 s->caps_lock_mode ^= 2;
785 if (s->caps_lock_mode == 3)
786 return; // Drop first release
787 break;
788 case 197: // Num lock release
789 s->num_lock_mode ^= 2;
790 if (s->num_lock_mode == 3)
791 return; // Drop first release
792 break;
793 case 0xe0:
794 s->e0_mode = 1;
795 return;
796 default:
797 break;
799 if (s->e0_mode) {
800 s->e0_mode = 0;
801 ch = e0_keycodes[ch & 0x7f];
802 } else {
803 ch = keycodes[ch & 0x7f];
805 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
806 put_queue(s, ch | release);
809 static void handle_kbd_command(ChannelState *s, int val)
811 KBD_DPRINTF("Command %d\n", val);
812 if (s->led_mode) { // Ignore led byte
813 s->led_mode = 0;
814 return;
816 switch (val) {
817 case 1: // Reset, return type code
818 clear_queue(s);
819 put_queue(s, 0xff);
820 put_queue(s, 4); // Type 4
821 put_queue(s, 0x7f);
822 break;
823 case 0xe: // Set leds
824 s->led_mode = 1;
825 break;
826 case 7: // Query layout
827 case 0xf:
828 clear_queue(s);
829 put_queue(s, 0xfe);
830 put_queue(s, 0); // XXX, layout?
831 break;
832 default:
833 break;
837 static void sunmouse_event(void *opaque,
838 int dx, int dy, int dz, int buttons_state)
840 ChannelState *s = opaque;
841 int ch;
843 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
845 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
847 if (buttons_state & MOUSE_EVENT_LBUTTON)
848 ch ^= 0x4;
849 if (buttons_state & MOUSE_EVENT_MBUTTON)
850 ch ^= 0x2;
851 if (buttons_state & MOUSE_EVENT_RBUTTON)
852 ch ^= 0x1;
854 put_queue(s, ch);
856 ch = dx;
858 if (ch > 127)
859 ch = 127;
860 else if (ch < -127)
861 ch = -127;
863 put_queue(s, ch & 0xff);
865 ch = -dy;
867 if (ch > 127)
868 ch = 127;
869 else if (ch < -127)
870 ch = -127;
872 put_queue(s, ch & 0xff);
874 // MSC protocol specify two extra motion bytes
876 put_queue(s, 0);
877 put_queue(s, 0);
880 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
881 int disabled, int clock, int it_shift)
883 DeviceState *dev;
884 SysBusDevice *s;
886 dev = qdev_create(NULL, "escc");
887 qdev_prop_set_uint32(dev, "disabled", disabled);
888 qdev_prop_set_uint32(dev, "frequency", clock);
889 qdev_prop_set_uint32(dev, "it_shift", it_shift);
890 qdev_prop_set_chr(dev, "chrB", NULL);
891 qdev_prop_set_chr(dev, "chrA", NULL);
892 qdev_prop_set_uint32(dev, "chnBtype", mouse);
893 qdev_prop_set_uint32(dev, "chnAtype", kbd);
894 qdev_init_nofail(dev);
895 s = sysbus_from_qdev(dev);
896 sysbus_connect_irq(s, 0, irq);
897 sysbus_connect_irq(s, 1, irq);
898 sysbus_mmio_map(s, 0, base);
901 static int escc_init1(SysBusDevice *dev)
903 SerialState *s = FROM_SYSBUS(SerialState, dev);
904 unsigned int i;
906 s->chn[0].disabled = s->disabled;
907 s->chn[1].disabled = s->disabled;
908 for (i = 0; i < 2; i++) {
909 sysbus_init_irq(dev, &s->chn[i].irq);
910 s->chn[i].chn = 1 - i;
911 s->chn[i].clock = s->frequency / 2;
912 if (s->chn[i].chr) {
913 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
914 serial_receive1, serial_event, &s->chn[i]);
917 s->chn[0].otherchn = &s->chn[1];
918 s->chn[1].otherchn = &s->chn[0];
920 memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc",
921 ESCC_SIZE << s->it_shift);
922 sysbus_init_mmio_region(dev, &s->mmio);
924 if (s->chn[0].type == mouse) {
925 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
926 "QEMU Sun Mouse");
928 if (s->chn[1].type == kbd) {
929 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
932 return 0;
935 static SysBusDeviceInfo escc_info = {
936 .init = escc_init1,
937 .qdev.name = "escc",
938 .qdev.size = sizeof(SerialState),
939 .qdev.vmsd = &vmstate_escc,
940 .qdev.reset = escc_reset,
941 .qdev.props = (Property[]) {
942 DEFINE_PROP_UINT32("frequency", SerialState, frequency, 0),
943 DEFINE_PROP_UINT32("it_shift", SerialState, it_shift, 0),
944 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
945 DEFINE_PROP_UINT32("disabled", SerialState, disabled, 0),
946 DEFINE_PROP_UINT32("chnBtype", SerialState, chn[0].type, 0),
947 DEFINE_PROP_UINT32("chnAtype", SerialState, chn[1].type, 0),
948 DEFINE_PROP_CHR("chrB", SerialState, chn[0].chr),
949 DEFINE_PROP_CHR("chrA", SerialState, chn[1].chr),
950 DEFINE_PROP_END_OF_LIST(),
954 static void escc_register_devices(void)
956 sysbus_register_withprop(&escc_info);
959 device_init(escc_register_devices)