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