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