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