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