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