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