Annotation of qemu/hw/escc.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com