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