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