Fix cpuid KVM crash on i386 (Lubomir Rintel)
[sniper_test.git] / hw / escc.c
blob4c299ff6e4383db35cc6f8900cfff90bcccf2745
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.
24 #include "hw.h"
25 #include "escc.h"
26 #include "qemu-char.h"
27 #include "console.h"
29 /* debug serial */
30 //#define DEBUG_SERIAL
32 /* debug keyboard */
33 //#define DEBUG_KBD
35 /* debug mouse */
36 //#define DEBUG_MOUSE
39 * On Sparc32 this is the serial port, mouse and keyboard part of chip STP2001
40 * (Slave I/O), also produced as NCR89C105. See
41 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
43 * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
44 * mouse and keyboard ports don't implement all functions and they are
45 * only asynchronous. There is no DMA.
47 * Z85C30 is also used on PowerMacs. There are some small differences
48 * between Sparc version (sunzilog) and PowerMac (pmac):
49 * Offset between control and data registers
50 * There is some kind of lockup bug, but we can ignore it
51 * CTS is inverted
52 * DMA on pmac using DBDMA chip
53 * pmac can do IRDA and faster rates, sunzilog can only do 38400
54 * pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz
58 * Modifications:
59 * 2006-Aug-10 Igor Kovalenko : Renamed KBDQueue to SERIOQueue, implemented
60 * serial mouse queue.
61 * Implemented serial mouse protocol.
64 #ifdef DEBUG_SERIAL
65 #define SER_DPRINTF(fmt, args...) \
66 do { printf("SER: " fmt , ##args); } while (0)
67 #else
68 #define SER_DPRINTF(fmt, args...)
69 #endif
70 #ifdef DEBUG_KBD
71 #define KBD_DPRINTF(fmt, args...) \
72 do { printf("KBD: " fmt , ##args); } while (0)
73 #else
74 #define KBD_DPRINTF(fmt, args...)
75 #endif
76 #ifdef DEBUG_MOUSE
77 #define MS_DPRINTF(fmt, args...) \
78 do { printf("MSC: " fmt , ##args); } while (0)
79 #else
80 #define MS_DPRINTF(fmt, args...)
81 #endif
83 typedef enum {
84 chn_a, chn_b,
85 } chn_id_t;
87 #define CHN_C(s) ((s)->chn == chn_b? 'b' : 'a')
89 typedef enum {
90 ser, kbd, mouse,
91 } chn_type_t;
93 #define SERIO_QUEUE_SIZE 256
95 typedef struct {
96 uint8_t data[SERIO_QUEUE_SIZE];
97 int rptr, wptr, count;
98 } SERIOQueue;
100 #define SERIAL_REGS 16
101 typedef struct ChannelState {
102 qemu_irq irq;
103 uint32_t reg;
104 uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
105 chn_id_t chn; // this channel, A (base+4) or B (base+0)
106 chn_type_t type;
107 struct ChannelState *otherchn;
108 uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
109 SERIOQueue queue;
110 CharDriverState *chr;
111 int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
112 int disabled;
113 int clock;
114 } ChannelState;
116 struct SerialState {
117 struct ChannelState chn[2];
118 int it_shift;
121 #define SERIAL_CTRL 0
122 #define SERIAL_DATA 1
124 #define W_CMD 0
125 #define CMD_PTR_MASK 0x07
126 #define CMD_CMD_MASK 0x38
127 #define CMD_HI 0x08
128 #define CMD_CLR_TXINT 0x28
129 #define CMD_CLR_IUS 0x38
130 #define W_INTR 1
131 #define INTR_INTALL 0x01
132 #define INTR_TXINT 0x02
133 #define INTR_RXMODEMSK 0x18
134 #define INTR_RXINT1ST 0x08
135 #define INTR_RXINTALL 0x10
136 #define W_IVEC 2
137 #define W_RXCTRL 3
138 #define RXCTRL_RXEN 0x01
139 #define W_TXCTRL1 4
140 #define TXCTRL1_PAREN 0x01
141 #define TXCTRL1_PAREV 0x02
142 #define TXCTRL1_1STOP 0x04
143 #define TXCTRL1_1HSTOP 0x08
144 #define TXCTRL1_2STOP 0x0c
145 #define TXCTRL1_STPMSK 0x0c
146 #define TXCTRL1_CLK1X 0x00
147 #define TXCTRL1_CLK16X 0x40
148 #define TXCTRL1_CLK32X 0x80
149 #define TXCTRL1_CLK64X 0xc0
150 #define TXCTRL1_CLKMSK 0xc0
151 #define W_TXCTRL2 5
152 #define TXCTRL2_TXEN 0x08
153 #define TXCTRL2_BITMSK 0x60
154 #define TXCTRL2_5BITS 0x00
155 #define TXCTRL2_7BITS 0x20
156 #define TXCTRL2_6BITS 0x40
157 #define TXCTRL2_8BITS 0x60
158 #define W_SYNC1 6
159 #define W_SYNC2 7
160 #define W_TXBUF 8
161 #define W_MINTR 9
162 #define MINTR_STATUSHI 0x10
163 #define MINTR_RST_MASK 0xc0
164 #define MINTR_RST_B 0x40
165 #define MINTR_RST_A 0x80
166 #define MINTR_RST_ALL 0xc0
167 #define W_MISC1 10
168 #define W_CLOCK 11
169 #define CLOCK_TRXC 0x08
170 #define W_BRGLO 12
171 #define W_BRGHI 13
172 #define W_MISC2 14
173 #define MISC2_PLLDIS 0x30
174 #define W_EXTINT 15
175 #define EXTINT_DCD 0x08
176 #define EXTINT_SYNCINT 0x10
177 #define EXTINT_CTSINT 0x20
178 #define EXTINT_TXUNDRN 0x40
179 #define EXTINT_BRKINT 0x80
181 #define R_STATUS 0
182 #define STATUS_RXAV 0x01
183 #define STATUS_ZERO 0x02
184 #define STATUS_TXEMPTY 0x04
185 #define STATUS_DCD 0x08
186 #define STATUS_SYNC 0x10
187 #define STATUS_CTS 0x20
188 #define STATUS_TXUNDRN 0x40
189 #define STATUS_BRK 0x80
190 #define R_SPEC 1
191 #define SPEC_ALLSENT 0x01
192 #define SPEC_BITS8 0x06
193 #define R_IVEC 2
194 #define IVEC_TXINTB 0x00
195 #define IVEC_LONOINT 0x06
196 #define IVEC_LORXINTA 0x0c
197 #define IVEC_LORXINTB 0x04
198 #define IVEC_LOTXINTA 0x08
199 #define IVEC_HINOINT 0x60
200 #define IVEC_HIRXINTA 0x30
201 #define IVEC_HIRXINTB 0x20
202 #define IVEC_HITXINTA 0x10
203 #define R_INTR 3
204 #define INTR_EXTINTB 0x01
205 #define INTR_TXINTB 0x02
206 #define INTR_RXINTB 0x04
207 #define INTR_EXTINTA 0x08
208 #define INTR_TXINTA 0x10
209 #define INTR_RXINTA 0x20
210 #define R_IPEN 4
211 #define R_TXCTRL1 5
212 #define R_TXCTRL2 6
213 #define R_BC 7
214 #define R_RXBUF 8
215 #define R_RXCTRL 9
216 #define R_MISC 10
217 #define R_MISC1 11
218 #define R_BRGLO 12
219 #define R_BRGHI 13
220 #define R_MISC1I 14
221 #define R_EXTINT 15
223 static void handle_kbd_command(ChannelState *s, int val);
224 static int serial_can_receive(void *opaque);
225 static void serial_receive_byte(ChannelState *s, int ch);
227 static void clear_queue(void *opaque)
229 ChannelState *s = opaque;
230 SERIOQueue *q = &s->queue;
231 q->rptr = q->wptr = q->count = 0;
234 static void put_queue(void *opaque, int b)
236 ChannelState *s = opaque;
237 SERIOQueue *q = &s->queue;
239 SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
240 if (q->count >= SERIO_QUEUE_SIZE)
241 return;
242 q->data[q->wptr] = b;
243 if (++q->wptr == SERIO_QUEUE_SIZE)
244 q->wptr = 0;
245 q->count++;
246 serial_receive_byte(s, 0);
249 static uint32_t get_queue(void *opaque)
251 ChannelState *s = opaque;
252 SERIOQueue *q = &s->queue;
253 int val;
255 if (q->count == 0) {
256 return 0;
257 } else {
258 val = q->data[q->rptr];
259 if (++q->rptr == SERIO_QUEUE_SIZE)
260 q->rptr = 0;
261 q->count--;
263 SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
264 if (q->count > 0)
265 serial_receive_byte(s, 0);
266 return val;
269 static int escc_update_irq_chn(ChannelState *s)
271 if ((((s->wregs[W_INTR] & INTR_TXINT) && s->txint == 1) ||
272 // tx ints enabled, pending
273 ((((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINT1ST) ||
274 ((s->wregs[W_INTR] & INTR_RXMODEMSK) == INTR_RXINTALL)) &&
275 s->rxint == 1) || // rx ints enabled, pending
276 ((s->wregs[W_EXTINT] & EXTINT_BRKINT) &&
277 (s->rregs[R_STATUS] & STATUS_BRK)))) { // break int e&p
278 return 1;
280 return 0;
283 static void escc_update_irq(ChannelState *s)
285 int irq;
287 irq = escc_update_irq_chn(s);
288 irq |= escc_update_irq_chn(s->otherchn);
290 SER_DPRINTF("IRQ = %d\n", irq);
291 qemu_set_irq(s->irq, irq);
294 static void escc_reset_chn(ChannelState *s)
296 int i;
298 s->reg = 0;
299 for (i = 0; i < SERIAL_REGS; i++) {
300 s->rregs[i] = 0;
301 s->wregs[i] = 0;
303 s->wregs[W_TXCTRL1] = TXCTRL1_1STOP; // 1X divisor, 1 stop bit, no parity
304 s->wregs[W_MINTR] = MINTR_RST_ALL;
305 s->wregs[W_CLOCK] = CLOCK_TRXC; // Synch mode tx clock = TRxC
306 s->wregs[W_MISC2] = MISC2_PLLDIS; // PLL disabled
307 s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
308 EXTINT_TXUNDRN | EXTINT_BRKINT; // Enable most interrupts
309 if (s->disabled)
310 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
311 STATUS_CTS | STATUS_TXUNDRN;
312 else
313 s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
314 s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
316 s->rx = s->tx = 0;
317 s->rxint = s->txint = 0;
318 s->rxint_under_svc = s->txint_under_svc = 0;
319 s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
320 clear_queue(s);
323 static void escc_reset(void *opaque)
325 SerialState *s = opaque;
326 escc_reset_chn(&s->chn[0]);
327 escc_reset_chn(&s->chn[1]);
330 static inline void set_rxint(ChannelState *s)
332 s->rxint = 1;
333 if (!s->txint_under_svc) {
334 s->rxint_under_svc = 1;
335 if (s->chn == chn_a) {
336 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
337 s->otherchn->rregs[R_IVEC] = IVEC_HIRXINTA;
338 else
339 s->otherchn->rregs[R_IVEC] = IVEC_LORXINTA;
340 } else {
341 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
342 s->rregs[R_IVEC] = IVEC_HIRXINTB;
343 else
344 s->rregs[R_IVEC] = IVEC_LORXINTB;
347 if (s->chn == chn_a)
348 s->rregs[R_INTR] |= INTR_RXINTA;
349 else
350 s->otherchn->rregs[R_INTR] |= INTR_RXINTB;
351 escc_update_irq(s);
354 static inline void set_txint(ChannelState *s)
356 s->txint = 1;
357 if (!s->rxint_under_svc) {
358 s->txint_under_svc = 1;
359 if (s->chn == chn_a) {
360 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
361 s->otherchn->rregs[R_IVEC] = IVEC_HITXINTA;
362 else
363 s->otherchn->rregs[R_IVEC] = IVEC_LOTXINTA;
364 } else {
365 s->rregs[R_IVEC] = IVEC_TXINTB;
368 if (s->chn == chn_a)
369 s->rregs[R_INTR] |= INTR_TXINTA;
370 else
371 s->otherchn->rregs[R_INTR] |= INTR_TXINTB;
372 escc_update_irq(s);
375 static inline void clr_rxint(ChannelState *s)
377 s->rxint = 0;
378 s->rxint_under_svc = 0;
379 if (s->chn == chn_a) {
380 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
381 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
382 else
383 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
384 s->rregs[R_INTR] &= ~INTR_RXINTA;
385 } else {
386 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
387 s->rregs[R_IVEC] = IVEC_HINOINT;
388 else
389 s->rregs[R_IVEC] = IVEC_LONOINT;
390 s->otherchn->rregs[R_INTR] &= ~INTR_RXINTB;
392 if (s->txint)
393 set_txint(s);
394 escc_update_irq(s);
397 static inline void clr_txint(ChannelState *s)
399 s->txint = 0;
400 s->txint_under_svc = 0;
401 if (s->chn == chn_a) {
402 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
403 s->otherchn->rregs[R_IVEC] = IVEC_HINOINT;
404 else
405 s->otherchn->rregs[R_IVEC] = IVEC_LONOINT;
406 s->rregs[R_INTR] &= ~INTR_TXINTA;
407 } else {
408 if (s->wregs[W_MINTR] & MINTR_STATUSHI)
409 s->rregs[R_IVEC] = IVEC_HINOINT;
410 else
411 s->rregs[R_IVEC] = IVEC_LONOINT;
412 s->otherchn->rregs[R_INTR] &= ~INTR_TXINTB;
414 if (s->rxint)
415 set_rxint(s);
416 escc_update_irq(s);
419 static void escc_update_parameters(ChannelState *s)
421 int speed, parity, data_bits, stop_bits;
422 QEMUSerialSetParams ssp;
424 if (!s->chr || s->type != ser)
425 return;
427 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREN) {
428 if (s->wregs[W_TXCTRL1] & TXCTRL1_PAREV)
429 parity = 'E';
430 else
431 parity = 'O';
432 } else {
433 parity = 'N';
435 if ((s->wregs[W_TXCTRL1] & TXCTRL1_STPMSK) == TXCTRL1_2STOP)
436 stop_bits = 2;
437 else
438 stop_bits = 1;
439 switch (s->wregs[W_TXCTRL2] & TXCTRL2_BITMSK) {
440 case TXCTRL2_5BITS:
441 data_bits = 5;
442 break;
443 case TXCTRL2_7BITS:
444 data_bits = 7;
445 break;
446 case TXCTRL2_6BITS:
447 data_bits = 6;
448 break;
449 default:
450 case TXCTRL2_8BITS:
451 data_bits = 8;
452 break;
454 speed = s->clock / ((s->wregs[W_BRGLO] | (s->wregs[W_BRGHI] << 8)) + 2);
455 switch (s->wregs[W_TXCTRL1] & TXCTRL1_CLKMSK) {
456 case TXCTRL1_CLK1X:
457 break;
458 case TXCTRL1_CLK16X:
459 speed /= 16;
460 break;
461 case TXCTRL1_CLK32X:
462 speed /= 32;
463 break;
464 default:
465 case TXCTRL1_CLK64X:
466 speed /= 64;
467 break;
469 ssp.speed = speed;
470 ssp.parity = parity;
471 ssp.data_bits = data_bits;
472 ssp.stop_bits = stop_bits;
473 SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
474 speed, parity, data_bits, stop_bits);
475 qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
478 static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
480 SerialState *serial = opaque;
481 ChannelState *s;
482 uint32_t saddr;
483 int newreg, channel;
485 val &= 0xff;
486 saddr = (addr >> serial->it_shift) & 1;
487 channel = (addr >> (serial->it_shift + 1)) & 1;
488 s = &serial->chn[channel];
489 switch (saddr) {
490 case SERIAL_CTRL:
491 SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
492 val & 0xff);
493 newreg = 0;
494 switch (s->reg) {
495 case W_CMD:
496 newreg = val & CMD_PTR_MASK;
497 val &= CMD_CMD_MASK;
498 switch (val) {
499 case CMD_HI:
500 newreg |= CMD_HI;
501 break;
502 case CMD_CLR_TXINT:
503 clr_txint(s);
504 break;
505 case CMD_CLR_IUS:
506 if (s->rxint_under_svc)
507 clr_rxint(s);
508 else if (s->txint_under_svc)
509 clr_txint(s);
510 break;
511 default:
512 break;
514 break;
515 case W_INTR ... W_RXCTRL:
516 case W_SYNC1 ... W_TXBUF:
517 case W_MISC1 ... W_CLOCK:
518 case W_MISC2 ... W_EXTINT:
519 s->wregs[s->reg] = val;
520 break;
521 case W_TXCTRL1:
522 case W_TXCTRL2:
523 s->wregs[s->reg] = val;
524 escc_update_parameters(s);
525 break;
526 case W_BRGLO:
527 case W_BRGHI:
528 s->wregs[s->reg] = val;
529 s->rregs[s->reg] = val;
530 escc_update_parameters(s);
531 break;
532 case W_MINTR:
533 switch (val & MINTR_RST_MASK) {
534 case 0:
535 default:
536 break;
537 case MINTR_RST_B:
538 escc_reset_chn(&serial->chn[0]);
539 return;
540 case MINTR_RST_A:
541 escc_reset_chn(&serial->chn[1]);
542 return;
543 case MINTR_RST_ALL:
544 escc_reset(serial);
545 return;
547 break;
548 default:
549 break;
551 if (s->reg == 0)
552 s->reg = newreg;
553 else
554 s->reg = 0;
555 break;
556 case SERIAL_DATA:
557 SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
558 s->tx = val;
559 if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
560 if (s->chr)
561 qemu_chr_write(s->chr, &s->tx, 1);
562 else if (s->type == kbd && !s->disabled) {
563 handle_kbd_command(s, val);
566 s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty
567 s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent
568 set_txint(s);
569 break;
570 default:
571 break;
575 static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
577 SerialState *serial = opaque;
578 ChannelState *s;
579 uint32_t saddr;
580 uint32_t ret;
581 int channel;
583 saddr = (addr >> serial->it_shift) & 1;
584 channel = (addr >> (serial->it_shift + 1)) & 1;
585 s = &serial->chn[channel];
586 switch (saddr) {
587 case SERIAL_CTRL:
588 SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
589 s->rregs[s->reg]);
590 ret = s->rregs[s->reg];
591 s->reg = 0;
592 return ret;
593 case SERIAL_DATA:
594 s->rregs[R_STATUS] &= ~STATUS_RXAV;
595 clr_rxint(s);
596 if (s->type == kbd || s->type == mouse)
597 ret = get_queue(s);
598 else
599 ret = s->rx;
600 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
601 if (s->chr)
602 qemu_chr_accept_input(s->chr);
603 return ret;
604 default:
605 break;
607 return 0;
610 static int serial_can_receive(void *opaque)
612 ChannelState *s = opaque;
613 int ret;
615 if (((s->wregs[W_RXCTRL] & RXCTRL_RXEN) == 0) // Rx not enabled
616 || ((s->rregs[R_STATUS] & STATUS_RXAV) == STATUS_RXAV))
617 // char already available
618 ret = 0;
619 else
620 ret = 1;
621 return ret;
624 static void serial_receive_byte(ChannelState *s, int ch)
626 SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
627 s->rregs[R_STATUS] |= STATUS_RXAV;
628 s->rx = ch;
629 set_rxint(s);
632 static void serial_receive_break(ChannelState *s)
634 s->rregs[R_STATUS] |= STATUS_BRK;
635 escc_update_irq(s);
638 static void serial_receive1(void *opaque, const uint8_t *buf, int size)
640 ChannelState *s = opaque;
641 serial_receive_byte(s, buf[0]);
644 static void serial_event(void *opaque, int event)
646 ChannelState *s = opaque;
647 if (event == CHR_EVENT_BREAK)
648 serial_receive_break(s);
651 static CPUReadMemoryFunc *escc_mem_read[3] = {
652 escc_mem_readb,
653 NULL,
654 NULL,
657 static CPUWriteMemoryFunc *escc_mem_write[3] = {
658 escc_mem_writeb,
659 NULL,
660 NULL,
663 static void escc_save_chn(QEMUFile *f, ChannelState *s)
665 uint32_t tmp = 0;
667 qemu_put_be32s(f, &tmp); /* unused, was IRQ. */
668 qemu_put_be32s(f, &s->reg);
669 qemu_put_be32s(f, &s->rxint);
670 qemu_put_be32s(f, &s->txint);
671 qemu_put_be32s(f, &s->rxint_under_svc);
672 qemu_put_be32s(f, &s->txint_under_svc);
673 qemu_put_8s(f, &s->rx);
674 qemu_put_8s(f, &s->tx);
675 qemu_put_buffer(f, s->wregs, SERIAL_REGS);
676 qemu_put_buffer(f, s->rregs, SERIAL_REGS);
679 static void escc_save(QEMUFile *f, void *opaque)
681 SerialState *s = opaque;
683 escc_save_chn(f, &s->chn[0]);
684 escc_save_chn(f, &s->chn[1]);
687 static int escc_load_chn(QEMUFile *f, ChannelState *s, int version_id)
689 uint32_t tmp;
691 if (version_id > 2)
692 return -EINVAL;
694 qemu_get_be32s(f, &tmp); /* unused */
695 qemu_get_be32s(f, &s->reg);
696 qemu_get_be32s(f, &s->rxint);
697 qemu_get_be32s(f, &s->txint);
698 if (version_id >= 2) {
699 qemu_get_be32s(f, &s->rxint_under_svc);
700 qemu_get_be32s(f, &s->txint_under_svc);
702 qemu_get_8s(f, &s->rx);
703 qemu_get_8s(f, &s->tx);
704 qemu_get_buffer(f, s->wregs, SERIAL_REGS);
705 qemu_get_buffer(f, s->rregs, SERIAL_REGS);
706 return 0;
709 static int escc_load(QEMUFile *f, void *opaque, int version_id)
711 SerialState *s = opaque;
712 int ret;
714 ret = escc_load_chn(f, &s->chn[0], version_id);
715 if (ret != 0)
716 return ret;
717 ret = escc_load_chn(f, &s->chn[1], version_id);
718 return ret;
722 int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
723 CharDriverState *chrA, CharDriverState *chrB,
724 int clock, int it_shift)
726 int escc_io_memory, i;
727 SerialState *s;
729 s = qemu_mallocz(sizeof(SerialState));
731 escc_io_memory = cpu_register_io_memory(0, escc_mem_read,
732 escc_mem_write,
734 if (base)
735 cpu_register_physical_memory(base, ESCC_SIZE << it_shift,
736 escc_io_memory);
738 s->it_shift = it_shift;
739 s->chn[0].chr = chrB;
740 s->chn[1].chr = chrA;
741 s->chn[0].disabled = 0;
742 s->chn[1].disabled = 0;
743 s->chn[0].irq = irqB;
744 s->chn[1].irq = irqA;
746 for (i = 0; i < 2; i++) {
747 s->chn[i].chn = 1 - i;
748 s->chn[i].type = ser;
749 s->chn[i].clock = clock / 2;
750 if (s->chn[i].chr) {
751 qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
752 serial_receive1, serial_event, &s->chn[i]);
755 s->chn[0].otherchn = &s->chn[1];
756 s->chn[1].otherchn = &s->chn[0];
757 if (base)
758 register_savevm("escc", base, 2, escc_save, escc_load, s);
759 else
760 register_savevm("escc", -1, 2, escc_save, escc_load, s);
761 qemu_register_reset(escc_reset, s);
762 escc_reset(s);
763 return escc_io_memory;
766 static const uint8_t keycodes[128] = {
767 127, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 53,
768 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 89, 76, 77, 78,
769 79, 80, 81, 82, 83, 84, 85, 86, 87, 42, 99, 88, 100, 101, 102, 103,
770 104, 105, 106, 107, 108, 109, 110, 47, 19, 121, 119, 5, 6, 8, 10, 12,
771 14, 16, 17, 18, 7, 98, 23, 68, 69, 70, 71, 91, 92, 93, 125, 112,
772 113, 114, 94, 50, 0, 0, 124, 9, 11, 0, 0, 0, 0, 0, 0, 0,
773 90, 0, 46, 22, 13, 111, 52, 20, 96, 24, 28, 74, 27, 123, 44, 66,
774 0, 45, 2, 4, 48, 0, 0, 21, 0, 0, 0, 0, 0, 120, 122, 67,
777 static const uint8_t e0_keycodes[128] = {
778 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
779 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 76, 0, 0,
780 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
781 0, 0, 0, 0, 0, 109, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
782 0, 0, 0, 0, 0, 0, 0, 68, 69, 70, 0, 91, 0, 93, 0, 112,
783 113, 114, 94, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
784 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
785 1, 3, 25, 26, 49, 52, 72, 73, 97, 99, 111, 118, 120, 122, 67, 0,
788 static void sunkbd_event(void *opaque, int ch)
790 ChannelState *s = opaque;
791 int release = ch & 0x80;
793 KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
794 "press");
795 switch (ch) {
796 case 58: // Caps lock press
797 s->caps_lock_mode ^= 1;
798 if (s->caps_lock_mode == 2)
799 return; // Drop second press
800 break;
801 case 69: // Num lock press
802 s->num_lock_mode ^= 1;
803 if (s->num_lock_mode == 2)
804 return; // Drop second press
805 break;
806 case 186: // Caps lock release
807 s->caps_lock_mode ^= 2;
808 if (s->caps_lock_mode == 3)
809 return; // Drop first release
810 break;
811 case 197: // Num lock release
812 s->num_lock_mode ^= 2;
813 if (s->num_lock_mode == 3)
814 return; // Drop first release
815 break;
816 case 0xe0:
817 s->e0_mode = 1;
818 return;
819 default:
820 break;
822 if (s->e0_mode) {
823 s->e0_mode = 0;
824 ch = e0_keycodes[ch & 0x7f];
825 } else {
826 ch = keycodes[ch & 0x7f];
828 KBD_DPRINTF("Translated keycode %2.2x\n", ch);
829 put_queue(s, ch | release);
832 static void handle_kbd_command(ChannelState *s, int val)
834 KBD_DPRINTF("Command %d\n", val);
835 if (s->led_mode) { // Ignore led byte
836 s->led_mode = 0;
837 return;
839 switch (val) {
840 case 1: // Reset, return type code
841 clear_queue(s);
842 put_queue(s, 0xff);
843 put_queue(s, 4); // Type 4
844 put_queue(s, 0x7f);
845 break;
846 case 0xe: // Set leds
847 s->led_mode = 1;
848 break;
849 case 7: // Query layout
850 case 0xf:
851 clear_queue(s);
852 put_queue(s, 0xfe);
853 put_queue(s, 0); // XXX, layout?
854 break;
855 default:
856 break;
860 static void sunmouse_event(void *opaque,
861 int dx, int dy, int dz, int buttons_state)
863 ChannelState *s = opaque;
864 int ch;
866 MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
868 ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
870 if (buttons_state & MOUSE_EVENT_LBUTTON)
871 ch ^= 0x4;
872 if (buttons_state & MOUSE_EVENT_MBUTTON)
873 ch ^= 0x2;
874 if (buttons_state & MOUSE_EVENT_RBUTTON)
875 ch ^= 0x1;
877 put_queue(s, ch);
879 ch = dx;
881 if (ch > 127)
882 ch=127;
883 else if (ch < -127)
884 ch=-127;
886 put_queue(s, ch & 0xff);
888 ch = -dy;
890 if (ch > 127)
891 ch=127;
892 else if (ch < -127)
893 ch=-127;
895 put_queue(s, ch & 0xff);
897 // MSC protocol specify two extra motion bytes
899 put_queue(s, 0);
900 put_queue(s, 0);
903 void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
904 int disabled, int clock, int it_shift)
906 int slavio_serial_io_memory, i;
907 SerialState *s;
909 s = qemu_mallocz(sizeof(SerialState));
911 s->it_shift = it_shift;
912 for (i = 0; i < 2; i++) {
913 s->chn[i].irq = irq;
914 s->chn[i].chn = 1 - i;
915 s->chn[i].chr = NULL;
916 s->chn[i].clock = clock / 2;
918 s->chn[0].otherchn = &s->chn[1];
919 s->chn[1].otherchn = &s->chn[0];
920 s->chn[0].type = mouse;
921 s->chn[1].type = kbd;
922 s->chn[0].disabled = disabled;
923 s->chn[1].disabled = disabled;
925 slavio_serial_io_memory = cpu_register_io_memory(0, escc_mem_read,
926 escc_mem_write,
928 cpu_register_physical_memory(base, ESCC_SIZE << it_shift,
929 slavio_serial_io_memory);
931 qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
932 "QEMU Sun Mouse");
933 qemu_add_kbd_event_handler(sunkbd_event, &s->chn[1]);
934 register_savevm("slavio_serial_mouse", base, 2, escc_save, escc_load, s);
935 qemu_register_reset(escc_reset, s);
936 escc_reset(s);