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