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