qemu/hw/input/ps2.c
<<
>>
Prefs
   1/*
   2 * QEMU PS/2 keyboard/mouse emulation
   3 *
   4 * Copyright (c) 2003 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "qemu/log.h"
  27#include "hw/input/ps2.h"
  28#include "migration/vmstate.h"
  29#include "ui/console.h"
  30#include "ui/input.h"
  31#include "sysemu/reset.h"
  32#include "sysemu/runstate.h"
  33
  34#include "trace.h"
  35
  36/* debug PC keyboard */
  37//#define DEBUG_KBD
  38
  39/* debug PC keyboard : only mouse */
  40//#define DEBUG_MOUSE
  41
  42/* Keyboard Commands */
  43#define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
  44#define KBD_CMD_ECHO            0xEE
  45#define KBD_CMD_SCANCODE        0xF0    /* Get/set scancode set */
  46#define KBD_CMD_GET_ID          0xF2    /* get keyboard ID */
  47#define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
  48#define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
  49#define KBD_CMD_RESET_DISABLE   0xF5    /* reset and disable scanning */
  50#define KBD_CMD_RESET_ENABLE    0xF6    /* reset and enable scanning */
  51#define KBD_CMD_RESET           0xFF    /* Reset */
  52
  53/* Keyboard Replies */
  54#define KBD_REPLY_POR           0xAA    /* Power on reset */
  55#define KBD_REPLY_ID            0xAB    /* Keyboard ID */
  56#define KBD_REPLY_ACK           0xFA    /* Command ACK */
  57#define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
  58
  59/* Mouse Commands */
  60#define AUX_SET_SCALE11         0xE6    /* Set 1:1 scaling */
  61#define AUX_SET_SCALE21         0xE7    /* Set 2:1 scaling */
  62#define AUX_SET_RES             0xE8    /* Set resolution */
  63#define AUX_GET_SCALE           0xE9    /* Get scaling factor */
  64#define AUX_SET_STREAM          0xEA    /* Set stream mode */
  65#define AUX_POLL                0xEB    /* Poll */
  66#define AUX_RESET_WRAP          0xEC    /* Reset wrap mode */
  67#define AUX_SET_WRAP            0xEE    /* Set wrap mode */
  68#define AUX_SET_REMOTE          0xF0    /* Set remote mode */
  69#define AUX_GET_TYPE            0xF2    /* Get type */
  70#define AUX_SET_SAMPLE          0xF3    /* Set sample rate */
  71#define AUX_ENABLE_DEV          0xF4    /* Enable aux device */
  72#define AUX_DISABLE_DEV         0xF5    /* Disable aux device */
  73#define AUX_SET_DEFAULT         0xF6
  74#define AUX_RESET               0xFF    /* Reset aux device */
  75#define AUX_ACK                 0xFA    /* Command byte ACK. */
  76
  77#define MOUSE_STATUS_REMOTE     0x40
  78#define MOUSE_STATUS_ENABLED    0x20
  79#define MOUSE_STATUS_SCALE21    0x10
  80
  81#define PS2_QUEUE_SIZE 16  /* Buffer size required by PS/2 protocol */
  82
  83/* Bits for 'modifiers' field in PS2KbdState */
  84#define MOD_CTRL_L  (1 << 0)
  85#define MOD_SHIFT_L (1 << 1)
  86#define MOD_ALT_L   (1 << 2)
  87#define MOD_CTRL_R  (1 << 3)
  88#define MOD_SHIFT_R (1 << 4)
  89#define MOD_ALT_R   (1 << 5)
  90
  91typedef struct {
  92    /* Keep the data array 256 bytes long, which compatibility
  93     with older qemu versions. */
  94    uint8_t data[256];
  95    int rptr, wptr, count;
  96} PS2Queue;
  97
  98struct PS2State {
  99    PS2Queue queue;
 100    int32_t write_cmd;
 101    void (*update_irq)(void *, int);
 102    void *update_arg;
 103};
 104
 105typedef struct {
 106    PS2State common;
 107    int scan_enabled;
 108    int translate;
 109    int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
 110    int ledstate;
 111    bool need_high_bit;
 112    unsigned int modifiers; /* bitmask of MOD_* constants above */
 113} PS2KbdState;
 114
 115typedef struct {
 116    PS2State common;
 117    uint8_t mouse_status;
 118    uint8_t mouse_resolution;
 119    uint8_t mouse_sample_rate;
 120    uint8_t mouse_wrap;
 121    uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
 122    uint8_t mouse_detect_state;
 123    int mouse_dx; /* current values, needed for 'poll' mode */
 124    int mouse_dy;
 125    int mouse_dz;
 126    uint8_t mouse_buttons;
 127} PS2MouseState;
 128
 129static uint8_t translate_table[256] = {
 130    0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
 131    0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
 132    0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
 133    0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
 134    0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
 135    0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
 136    0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
 137    0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
 138    0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
 139    0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
 140    0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
 141    0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
 142    0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
 143    0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
 144    0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
 145    0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
 146    0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
 147    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 148    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
 149    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 150    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 151    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 152    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
 153    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 154    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 155    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 156    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 157    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 158    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 159    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 160    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 161    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 162};
 163
 164static unsigned int ps2_modifier_bit(QKeyCode key)
 165{
 166    switch (key) {
 167    case Q_KEY_CODE_CTRL:
 168        return MOD_CTRL_L;
 169    case Q_KEY_CODE_CTRL_R:
 170        return MOD_CTRL_R;
 171    case Q_KEY_CODE_SHIFT:
 172        return MOD_SHIFT_L;
 173    case Q_KEY_CODE_SHIFT_R:
 174        return MOD_SHIFT_R;
 175    case Q_KEY_CODE_ALT:
 176        return MOD_ALT_L;
 177    case Q_KEY_CODE_ALT_R:
 178        return MOD_ALT_R;
 179    default:
 180        return 0;
 181    }
 182}
 183
 184static void ps2_reset_queue(PS2State *s)
 185{
 186    PS2Queue *q = &s->queue;
 187
 188    q->rptr = 0;
 189    q->wptr = 0;
 190    q->count = 0;
 191}
 192
 193void ps2_queue_noirq(PS2State *s, int b)
 194{
 195    PS2Queue *q = &s->queue;
 196
 197    if (q->count == PS2_QUEUE_SIZE) {
 198        return;
 199    }
 200
 201    q->data[q->wptr] = b;
 202    if (++q->wptr == PS2_QUEUE_SIZE)
 203        q->wptr = 0;
 204    q->count++;
 205}
 206
 207void ps2_raise_irq(PS2State *s)
 208{
 209    s->update_irq(s->update_arg, 1);
 210}
 211
 212void ps2_queue(PS2State *s, int b)
 213{
 214    ps2_queue_noirq(s, b);
 215    s->update_irq(s->update_arg, 1);
 216}
 217
 218void ps2_queue_2(PS2State *s, int b1, int b2)
 219{
 220    if (PS2_QUEUE_SIZE - s->queue.count < 2) {
 221        return;
 222    }
 223
 224    ps2_queue_noirq(s, b1);
 225    ps2_queue_noirq(s, b2);
 226    s->update_irq(s->update_arg, 1);
 227}
 228
 229void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
 230{
 231    if (PS2_QUEUE_SIZE - s->queue.count < 3) {
 232        return;
 233    }
 234
 235    ps2_queue_noirq(s, b1);
 236    ps2_queue_noirq(s, b2);
 237    ps2_queue_noirq(s, b3);
 238    s->update_irq(s->update_arg, 1);
 239}
 240
 241void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
 242{
 243    if (PS2_QUEUE_SIZE - s->queue.count < 4) {
 244        return;
 245    }
 246
 247    ps2_queue_noirq(s, b1);
 248    ps2_queue_noirq(s, b2);
 249    ps2_queue_noirq(s, b3);
 250    ps2_queue_noirq(s, b4);
 251    s->update_irq(s->update_arg, 1);
 252}
 253
 254/* keycode is the untranslated scancode in the current scancode set. */
 255static void ps2_put_keycode(void *opaque, int keycode)
 256{
 257    PS2KbdState *s = opaque;
 258
 259    trace_ps2_put_keycode(opaque, keycode);
 260    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 261
 262    if (s->translate) {
 263        if (keycode == 0xf0) {
 264            s->need_high_bit = true;
 265        } else if (s->need_high_bit) {
 266            ps2_queue(&s->common, translate_table[keycode] | 0x80);
 267            s->need_high_bit = false;
 268        } else {
 269            ps2_queue(&s->common, translate_table[keycode]);
 270        }
 271    } else {
 272        ps2_queue(&s->common, keycode);
 273    }
 274}
 275
 276static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
 277                               InputEvent *evt)
 278{
 279    PS2KbdState *s = (PS2KbdState *)dev;
 280    InputKeyEvent *key = evt->u.key.data;
 281    int qcode;
 282    uint16_t keycode = 0;
 283    int mod;
 284
 285    /* do not process events while disabled to prevent stream corruption */
 286    if (!s->scan_enabled) {
 287        return;
 288    }
 289
 290    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 291    assert(evt->type == INPUT_EVENT_KIND_KEY);
 292    qcode = qemu_input_key_value_to_qcode(key->key);
 293
 294    mod = ps2_modifier_bit(qcode);
 295    trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
 296    if (key->down) {
 297        s->modifiers |= mod;
 298    } else {
 299        s->modifiers &= ~mod;
 300    }
 301
 302    if (s->scancode_set == 1) {
 303        if (qcode == Q_KEY_CODE_PAUSE) {
 304            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 305                if (key->down) {
 306                    ps2_put_keycode(s, 0xe0);
 307                    ps2_put_keycode(s, 0x46);
 308                    ps2_put_keycode(s, 0xe0);
 309                    ps2_put_keycode(s, 0xc6);
 310                }
 311            } else {
 312                if (key->down) {
 313                    ps2_put_keycode(s, 0xe1);
 314                    ps2_put_keycode(s, 0x1d);
 315                    ps2_put_keycode(s, 0x45);
 316                    ps2_put_keycode(s, 0xe1);
 317                    ps2_put_keycode(s, 0x9d);
 318                    ps2_put_keycode(s, 0xc5);
 319                }
 320            }
 321        } else if (qcode == Q_KEY_CODE_PRINT) {
 322            if (s->modifiers & MOD_ALT_L) {
 323                if (key->down) {
 324                    ps2_put_keycode(s, 0xb8);
 325                    ps2_put_keycode(s, 0x38);
 326                    ps2_put_keycode(s, 0x54);
 327                } else {
 328                    ps2_put_keycode(s, 0xd4);
 329                    ps2_put_keycode(s, 0xb8);
 330                    ps2_put_keycode(s, 0x38);
 331                }
 332            } else if (s->modifiers & MOD_ALT_R) {
 333                if (key->down) {
 334                    ps2_put_keycode(s, 0xe0);
 335                    ps2_put_keycode(s, 0xb8);
 336                    ps2_put_keycode(s, 0xe0);
 337                    ps2_put_keycode(s, 0x38);
 338                    ps2_put_keycode(s, 0x54);
 339                } else {
 340                    ps2_put_keycode(s, 0xd4);
 341                    ps2_put_keycode(s, 0xe0);
 342                    ps2_put_keycode(s, 0xb8);
 343                    ps2_put_keycode(s, 0xe0);
 344                    ps2_put_keycode(s, 0x38);
 345                }
 346            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 347                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 348                if (key->down) {
 349                    ps2_put_keycode(s, 0xe0);
 350                    ps2_put_keycode(s, 0x37);
 351                } else {
 352                    ps2_put_keycode(s, 0xe0);
 353                    ps2_put_keycode(s, 0xb7);
 354                }
 355            } else {
 356                if (key->down) {
 357                    ps2_put_keycode(s, 0xe0);
 358                    ps2_put_keycode(s, 0x2a);
 359                    ps2_put_keycode(s, 0xe0);
 360                    ps2_put_keycode(s, 0x37);
 361                } else {
 362                    ps2_put_keycode(s, 0xe0);
 363                    ps2_put_keycode(s, 0xb7);
 364                    ps2_put_keycode(s, 0xe0);
 365                    ps2_put_keycode(s, 0xaa);
 366                }
 367            }
 368        } else {
 369            if (qcode < qemu_input_map_qcode_to_atset1_len)
 370                keycode = qemu_input_map_qcode_to_atset1[qcode];
 371            if (keycode) {
 372                if (keycode & 0xff00) {
 373                    ps2_put_keycode(s, keycode >> 8);
 374                }
 375                if (!key->down) {
 376                    keycode |= 0x80;
 377                }
 378                ps2_put_keycode(s, keycode & 0xff);
 379            } else {
 380                qemu_log_mask(LOG_UNIMP,
 381                              "ps2: ignoring key with qcode %d\n", qcode);
 382            }
 383        }
 384    } else if (s->scancode_set == 2) {
 385        if (qcode == Q_KEY_CODE_PAUSE) {
 386            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 387                if (key->down) {
 388                    ps2_put_keycode(s, 0xe0);
 389                    ps2_put_keycode(s, 0x7e);
 390                    ps2_put_keycode(s, 0xe0);
 391                    ps2_put_keycode(s, 0xf0);
 392                    ps2_put_keycode(s, 0x7e);
 393                }
 394            } else {
 395                if (key->down) {
 396                    ps2_put_keycode(s, 0xe1);
 397                    ps2_put_keycode(s, 0x14);
 398                    ps2_put_keycode(s, 0x77);
 399                    ps2_put_keycode(s, 0xe1);
 400                    ps2_put_keycode(s, 0xf0);
 401                    ps2_put_keycode(s, 0x14);
 402                    ps2_put_keycode(s, 0xf0);
 403                    ps2_put_keycode(s, 0x77);
 404                }
 405            }
 406        } else if (qcode == Q_KEY_CODE_PRINT) {
 407            if (s->modifiers & MOD_ALT_L) {
 408                if (key->down) {
 409                    ps2_put_keycode(s, 0xf0);
 410                    ps2_put_keycode(s, 0x11);
 411                    ps2_put_keycode(s, 0x11);
 412                    ps2_put_keycode(s, 0x84);
 413                } else {
 414                    ps2_put_keycode(s, 0xf0);
 415                    ps2_put_keycode(s, 0x84);
 416                    ps2_put_keycode(s, 0xf0);
 417                    ps2_put_keycode(s, 0x11);
 418                    ps2_put_keycode(s, 0x11);
 419                }
 420            } else if (s->modifiers & MOD_ALT_R) {
 421                if (key->down) {
 422                    ps2_put_keycode(s, 0xe0);
 423                    ps2_put_keycode(s, 0xf0);
 424                    ps2_put_keycode(s, 0x11);
 425                    ps2_put_keycode(s, 0xe0);
 426                    ps2_put_keycode(s, 0x11);
 427                    ps2_put_keycode(s, 0x84);
 428                } else {
 429                    ps2_put_keycode(s, 0xf0);
 430                    ps2_put_keycode(s, 0x84);
 431                    ps2_put_keycode(s, 0xe0);
 432                    ps2_put_keycode(s, 0xf0);
 433                    ps2_put_keycode(s, 0x11);
 434                    ps2_put_keycode(s, 0xe0);
 435                    ps2_put_keycode(s, 0x11);
 436                }
 437            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 438                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 439                if (key->down) {
 440                    ps2_put_keycode(s, 0xe0);
 441                    ps2_put_keycode(s, 0x7c);
 442                } else {
 443                    ps2_put_keycode(s, 0xe0);
 444                    ps2_put_keycode(s, 0xf0);
 445                    ps2_put_keycode(s, 0x7c);
 446                }
 447            } else {
 448                if (key->down) {
 449                    ps2_put_keycode(s, 0xe0);
 450                    ps2_put_keycode(s, 0x12);
 451                    ps2_put_keycode(s, 0xe0);
 452                    ps2_put_keycode(s, 0x7c);
 453                } else {
 454                    ps2_put_keycode(s, 0xe0);
 455                    ps2_put_keycode(s, 0xf0);
 456                    ps2_put_keycode(s, 0x7c);
 457                    ps2_put_keycode(s, 0xe0);
 458                    ps2_put_keycode(s, 0xf0);
 459                    ps2_put_keycode(s, 0x12);
 460                }
 461            }
 462        } else {
 463            if (qcode < qemu_input_map_qcode_to_atset2_len)
 464                keycode = qemu_input_map_qcode_to_atset2[qcode];
 465            if (keycode) {
 466                if (keycode & 0xff00) {
 467                    ps2_put_keycode(s, keycode >> 8);
 468                }
 469                if (!key->down) {
 470                    ps2_put_keycode(s, 0xf0);
 471                }
 472                ps2_put_keycode(s, keycode & 0xff);
 473            } else {
 474                qemu_log_mask(LOG_UNIMP,
 475                              "ps2: ignoring key with qcode %d\n", qcode);
 476            }
 477        }
 478    } else if (s->scancode_set == 3) {
 479        if (qcode < qemu_input_map_qcode_to_atset3_len)
 480            keycode = qemu_input_map_qcode_to_atset3[qcode];
 481        if (keycode) {
 482            /* FIXME: break code should be configured on a key by key basis */
 483            if (!key->down) {
 484                ps2_put_keycode(s, 0xf0);
 485            }
 486            ps2_put_keycode(s, keycode);
 487        } else {
 488            qemu_log_mask(LOG_UNIMP,
 489                          "ps2: ignoring key with qcode %d\n", qcode);
 490        }
 491    }
 492}
 493
 494uint32_t ps2_read_data(PS2State *s)
 495{
 496    PS2Queue *q;
 497    int val, index;
 498
 499    trace_ps2_read_data(s);
 500    q = &s->queue;
 501    if (q->count == 0) {
 502        /* NOTE: if no data left, we return the last keyboard one
 503           (needed for EMM386) */
 504        /* XXX: need a timer to do things correctly */
 505        index = q->rptr - 1;
 506        if (index < 0)
 507            index = PS2_QUEUE_SIZE - 1;
 508        val = q->data[index];
 509    } else {
 510        val = q->data[q->rptr];
 511        if (++q->rptr == PS2_QUEUE_SIZE)
 512            q->rptr = 0;
 513        q->count--;
 514        /* reading deasserts IRQ */
 515        s->update_irq(s->update_arg, 0);
 516        /* reassert IRQs if data left */
 517        s->update_irq(s->update_arg, q->count != 0);
 518    }
 519    return val;
 520}
 521
 522static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
 523{
 524    trace_ps2_set_ledstate(s, ledstate);
 525    s->ledstate = ledstate;
 526    kbd_put_ledstate(ledstate);
 527}
 528
 529static void ps2_reset_keyboard(PS2KbdState *s)
 530{
 531    trace_ps2_reset_keyboard(s);
 532    s->scan_enabled = 1;
 533    s->scancode_set = 2;
 534    ps2_reset_queue(&s->common);
 535    ps2_set_ledstate(s, 0);
 536}
 537
 538void ps2_write_keyboard(void *opaque, int val)
 539{
 540    PS2KbdState *s = (PS2KbdState *)opaque;
 541
 542    trace_ps2_write_keyboard(opaque, val);
 543    switch(s->common.write_cmd) {
 544    default:
 545    case -1:
 546        switch(val) {
 547        case 0x00:
 548            ps2_queue(&s->common, KBD_REPLY_ACK);
 549            break;
 550        case 0x05:
 551            ps2_queue(&s->common, KBD_REPLY_RESEND);
 552            break;
 553        case KBD_CMD_GET_ID:
 554            /* We emulate a MF2 AT keyboard here */
 555            if (s->translate)
 556                ps2_queue_3(&s->common,
 557                    KBD_REPLY_ACK,
 558                    KBD_REPLY_ID,
 559                    0x41);
 560            else
 561                ps2_queue_3(&s->common,
 562                    KBD_REPLY_ACK,
 563                    KBD_REPLY_ID,
 564                    0x83);
 565            break;
 566        case KBD_CMD_ECHO:
 567            ps2_queue(&s->common, KBD_CMD_ECHO);
 568            break;
 569        case KBD_CMD_ENABLE:
 570            s->scan_enabled = 1;
 571            ps2_queue(&s->common, KBD_REPLY_ACK);
 572            break;
 573        case KBD_CMD_SCANCODE:
 574        case KBD_CMD_SET_LEDS:
 575        case KBD_CMD_SET_RATE:
 576            s->common.write_cmd = val;
 577            ps2_queue(&s->common, KBD_REPLY_ACK);
 578            break;
 579        case KBD_CMD_RESET_DISABLE:
 580            ps2_reset_keyboard(s);
 581            s->scan_enabled = 0;
 582            ps2_queue(&s->common, KBD_REPLY_ACK);
 583            break;
 584        case KBD_CMD_RESET_ENABLE:
 585            ps2_reset_keyboard(s);
 586            s->scan_enabled = 1;
 587            ps2_queue(&s->common, KBD_REPLY_ACK);
 588            break;
 589        case KBD_CMD_RESET:
 590            ps2_reset_keyboard(s);
 591            ps2_queue_2(&s->common,
 592                KBD_REPLY_ACK,
 593                KBD_REPLY_POR);
 594            break;
 595        default:
 596            ps2_queue(&s->common, KBD_REPLY_RESEND);
 597            break;
 598        }
 599        break;
 600    case KBD_CMD_SCANCODE:
 601        if (val == 0) {
 602            if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
 603                ps2_queue(&s->common, KBD_REPLY_ACK);
 604                ps2_put_keycode(s, s->scancode_set);
 605            }
 606        } else if (val >= 1 && val <= 3) {
 607            s->scancode_set = val;
 608            ps2_queue(&s->common, KBD_REPLY_ACK);
 609        } else {
 610            ps2_queue(&s->common, KBD_REPLY_RESEND);
 611        }
 612        s->common.write_cmd = -1;
 613        break;
 614    case KBD_CMD_SET_LEDS:
 615        ps2_set_ledstate(s, val);
 616        ps2_queue(&s->common, KBD_REPLY_ACK);
 617        s->common.write_cmd = -1;
 618        break;
 619    case KBD_CMD_SET_RATE:
 620        ps2_queue(&s->common, KBD_REPLY_ACK);
 621        s->common.write_cmd = -1;
 622        break;
 623    }
 624}
 625
 626/* Set the scancode translation mode.
 627   0 = raw scancodes.
 628   1 = translated scancodes (used by qemu internally).  */
 629
 630void ps2_keyboard_set_translation(void *opaque, int mode)
 631{
 632    PS2KbdState *s = (PS2KbdState *)opaque;
 633    trace_ps2_keyboard_set_translation(opaque, mode);
 634    s->translate = mode;
 635}
 636
 637static int ps2_mouse_send_packet(PS2MouseState *s)
 638{
 639    const int needed = 3 + (s->mouse_type - 2);
 640    unsigned int b;
 641    int dx1, dy1, dz1;
 642
 643    if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
 644        return 0;
 645    }
 646
 647    dx1 = s->mouse_dx;
 648    dy1 = s->mouse_dy;
 649    dz1 = s->mouse_dz;
 650    /* XXX: increase range to 8 bits ? */
 651    if (dx1 > 127)
 652        dx1 = 127;
 653    else if (dx1 < -127)
 654        dx1 = -127;
 655    if (dy1 > 127)
 656        dy1 = 127;
 657    else if (dy1 < -127)
 658        dy1 = -127;
 659    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
 660    ps2_queue_noirq(&s->common, b);
 661    ps2_queue_noirq(&s->common, dx1 & 0xff);
 662    ps2_queue_noirq(&s->common, dy1 & 0xff);
 663    /* extra byte for IMPS/2 or IMEX */
 664    switch(s->mouse_type) {
 665    default:
 666        break;
 667    case 3:
 668        if (dz1 > 127)
 669            dz1 = 127;
 670        else if (dz1 < -127)
 671                dz1 = -127;
 672        ps2_queue_noirq(&s->common, dz1 & 0xff);
 673        break;
 674    case 4:
 675        if (dz1 > 7)
 676            dz1 = 7;
 677        else if (dz1 < -7)
 678            dz1 = -7;
 679        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
 680        ps2_queue_noirq(&s->common, b);
 681        break;
 682    }
 683
 684    ps2_raise_irq(&s->common);
 685
 686    trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
 687    /* update deltas */
 688    s->mouse_dx -= dx1;
 689    s->mouse_dy -= dy1;
 690    s->mouse_dz -= dz1;
 691
 692    return 1;
 693}
 694
 695static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
 696                            InputEvent *evt)
 697{
 698    static const int bmap[INPUT_BUTTON__MAX] = {
 699        [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
 700        [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
 701        [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
 702        [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
 703        [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
 704    };
 705    PS2MouseState *s = (PS2MouseState *)dev;
 706    InputMoveEvent *move;
 707    InputBtnEvent *btn;
 708
 709    /* check if deltas are recorded when disabled */
 710    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
 711        return;
 712
 713    switch (evt->type) {
 714    case INPUT_EVENT_KIND_REL:
 715        move = evt->u.rel.data;
 716        if (move->axis == INPUT_AXIS_X) {
 717            s->mouse_dx += move->value;
 718        } else if (move->axis == INPUT_AXIS_Y) {
 719            s->mouse_dy -= move->value;
 720        }
 721        break;
 722
 723    case INPUT_EVENT_KIND_BTN:
 724        btn = evt->u.btn.data;
 725        if (btn->down) {
 726            s->mouse_buttons |= bmap[btn->button];
 727            if (btn->button == INPUT_BUTTON_WHEEL_UP) {
 728                s->mouse_dz--;
 729            } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 730                s->mouse_dz++;
 731            }
 732        } else {
 733            s->mouse_buttons &= ~bmap[btn->button];
 734        }
 735        break;
 736
 737    default:
 738        /* keep gcc happy */
 739        break;
 740    }
 741}
 742
 743static void ps2_mouse_sync(DeviceState *dev)
 744{
 745    PS2MouseState *s = (PS2MouseState *)dev;
 746
 747    /* do not sync while disabled to prevent stream corruption */
 748    if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
 749        return;
 750    }
 751
 752    if (s->mouse_buttons) {
 753        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 754    }
 755    if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
 756        /* if not remote, send event. Multiple events are sent if
 757           too big deltas */
 758        while (ps2_mouse_send_packet(s)) {
 759            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
 760                break;
 761        }
 762    }
 763}
 764
 765void ps2_mouse_fake_event(void *opaque)
 766{
 767    PS2MouseState *s = opaque;
 768    trace_ps2_mouse_fake_event(opaque);
 769    s->mouse_dx++;
 770    ps2_mouse_sync(opaque);
 771}
 772
 773void ps2_write_mouse(void *opaque, int val)
 774{
 775    PS2MouseState *s = (PS2MouseState *)opaque;
 776
 777    trace_ps2_write_mouse(opaque, val);
 778#ifdef DEBUG_MOUSE
 779    printf("kbd: write mouse 0x%02x\n", val);
 780#endif
 781    switch(s->common.write_cmd) {
 782    default:
 783    case -1:
 784        /* mouse command */
 785        if (s->mouse_wrap) {
 786            if (val == AUX_RESET_WRAP) {
 787                s->mouse_wrap = 0;
 788                ps2_queue(&s->common, AUX_ACK);
 789                return;
 790            } else if (val != AUX_RESET) {
 791                ps2_queue(&s->common, val);
 792                return;
 793            }
 794        }
 795        switch(val) {
 796        case AUX_SET_SCALE11:
 797            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
 798            ps2_queue(&s->common, AUX_ACK);
 799            break;
 800        case AUX_SET_SCALE21:
 801            s->mouse_status |= MOUSE_STATUS_SCALE21;
 802            ps2_queue(&s->common, AUX_ACK);
 803            break;
 804        case AUX_SET_STREAM:
 805            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
 806            ps2_queue(&s->common, AUX_ACK);
 807            break;
 808        case AUX_SET_WRAP:
 809            s->mouse_wrap = 1;
 810            ps2_queue(&s->common, AUX_ACK);
 811            break;
 812        case AUX_SET_REMOTE:
 813            s->mouse_status |= MOUSE_STATUS_REMOTE;
 814            ps2_queue(&s->common, AUX_ACK);
 815            break;
 816        case AUX_GET_TYPE:
 817            ps2_queue_2(&s->common,
 818                AUX_ACK,
 819                s->mouse_type);
 820            break;
 821        case AUX_SET_RES:
 822        case AUX_SET_SAMPLE:
 823            s->common.write_cmd = val;
 824            ps2_queue(&s->common, AUX_ACK);
 825            break;
 826        case AUX_GET_SCALE:
 827            ps2_queue_4(&s->common,
 828                AUX_ACK,
 829                s->mouse_status,
 830                s->mouse_resolution,
 831                s->mouse_sample_rate);
 832            break;
 833        case AUX_POLL:
 834            ps2_queue(&s->common, AUX_ACK);
 835            ps2_mouse_send_packet(s);
 836            break;
 837        case AUX_ENABLE_DEV:
 838            s->mouse_status |= MOUSE_STATUS_ENABLED;
 839            ps2_queue(&s->common, AUX_ACK);
 840            break;
 841        case AUX_DISABLE_DEV:
 842            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
 843            ps2_queue(&s->common, AUX_ACK);
 844            break;
 845        case AUX_SET_DEFAULT:
 846            s->mouse_sample_rate = 100;
 847            s->mouse_resolution = 2;
 848            s->mouse_status = 0;
 849            ps2_queue(&s->common, AUX_ACK);
 850            break;
 851        case AUX_RESET:
 852            s->mouse_sample_rate = 100;
 853            s->mouse_resolution = 2;
 854            s->mouse_status = 0;
 855            s->mouse_type = 0;
 856            ps2_reset_queue(&s->common);
 857            ps2_queue_3(&s->common,
 858                AUX_ACK,
 859                0xaa,
 860                s->mouse_type);
 861            break;
 862        default:
 863            break;
 864        }
 865        break;
 866    case AUX_SET_SAMPLE:
 867        s->mouse_sample_rate = val;
 868        /* detect IMPS/2 or IMEX */
 869        switch(s->mouse_detect_state) {
 870        default:
 871        case 0:
 872            if (val == 200)
 873                s->mouse_detect_state = 1;
 874            break;
 875        case 1:
 876            if (val == 100)
 877                s->mouse_detect_state = 2;
 878            else if (val == 200)
 879                s->mouse_detect_state = 3;
 880            else
 881                s->mouse_detect_state = 0;
 882            break;
 883        case 2:
 884            if (val == 80)
 885                s->mouse_type = 3; /* IMPS/2 */
 886            s->mouse_detect_state = 0;
 887            break;
 888        case 3:
 889            if (val == 80)
 890                s->mouse_type = 4; /* IMEX */
 891            s->mouse_detect_state = 0;
 892            break;
 893        }
 894        ps2_queue(&s->common, AUX_ACK);
 895        s->common.write_cmd = -1;
 896        break;
 897    case AUX_SET_RES:
 898        s->mouse_resolution = val;
 899        ps2_queue(&s->common, AUX_ACK);
 900        s->common.write_cmd = -1;
 901        break;
 902    }
 903}
 904
 905static void ps2_common_reset(PS2State *s)
 906{
 907    s->write_cmd = -1;
 908    ps2_reset_queue(s);
 909    s->update_irq(s->update_arg, 0);
 910}
 911
 912static void ps2_common_post_load(PS2State *s)
 913{
 914    PS2Queue *q = &s->queue;
 915    uint8_t i, size;
 916    uint8_t tmp_data[PS2_QUEUE_SIZE];
 917
 918    /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
 919    size = q->count;
 920    if (q->count < 0) {
 921        size = 0;
 922    } else if (q->count > PS2_QUEUE_SIZE) {
 923        size = PS2_QUEUE_SIZE;
 924    }
 925
 926    /* move the queue elements to the start of data array */
 927    for (i = 0; i < size; i++) {
 928        if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
 929            q->rptr = 0;
 930        }
 931        tmp_data[i] = q->data[q->rptr++];
 932    }
 933    memcpy(q->data, tmp_data, size);
 934
 935    /* reset rptr/wptr/count */
 936    q->rptr = 0;
 937    q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
 938    q->count = size;
 939}
 940
 941static void ps2_kbd_reset(void *opaque)
 942{
 943    PS2KbdState *s = (PS2KbdState *) opaque;
 944
 945    trace_ps2_kbd_reset(opaque);
 946    ps2_common_reset(&s->common);
 947    s->scan_enabled = 1;
 948    s->translate = 0;
 949    s->scancode_set = 2;
 950    s->modifiers = 0;
 951}
 952
 953static void ps2_mouse_reset(void *opaque)
 954{
 955    PS2MouseState *s = (PS2MouseState *) opaque;
 956
 957    trace_ps2_mouse_reset(opaque);
 958    ps2_common_reset(&s->common);
 959    s->mouse_status = 0;
 960    s->mouse_resolution = 0;
 961    s->mouse_sample_rate = 0;
 962    s->mouse_wrap = 0;
 963    s->mouse_type = 0;
 964    s->mouse_detect_state = 0;
 965    s->mouse_dx = 0;
 966    s->mouse_dy = 0;
 967    s->mouse_dz = 0;
 968    s->mouse_buttons = 0;
 969}
 970
 971static const VMStateDescription vmstate_ps2_common = {
 972    .name = "PS2 Common State",
 973    .version_id = 3,
 974    .minimum_version_id = 2,
 975    .fields = (VMStateField[]) {
 976        VMSTATE_INT32(write_cmd, PS2State),
 977        VMSTATE_INT32(queue.rptr, PS2State),
 978        VMSTATE_INT32(queue.wptr, PS2State),
 979        VMSTATE_INT32(queue.count, PS2State),
 980        VMSTATE_BUFFER(queue.data, PS2State),
 981        VMSTATE_END_OF_LIST()
 982    }
 983};
 984
 985static bool ps2_keyboard_ledstate_needed(void *opaque)
 986{
 987    PS2KbdState *s = opaque;
 988
 989    return s->ledstate != 0; /* 0 is default state */
 990}
 991
 992static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
 993{
 994    PS2KbdState *s = opaque;
 995
 996    kbd_put_ledstate(s->ledstate);
 997    return 0;
 998}
 999
1000static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1001    .name = "ps2kbd/ledstate",
1002    .version_id = 3,
1003    .minimum_version_id = 2,
1004    .post_load = ps2_kbd_ledstate_post_load,
1005    .needed = ps2_keyboard_ledstate_needed,
1006    .fields = (VMStateField[]) {
1007        VMSTATE_INT32(ledstate, PS2KbdState),
1008        VMSTATE_END_OF_LIST()
1009    }
1010};
1011
1012static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1013{
1014    PS2KbdState *s = opaque;
1015    return s->need_high_bit != 0; /* 0 is the usual state */
1016}
1017
1018static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1019    .name = "ps2kbd/need_high_bit",
1020    .version_id = 1,
1021    .minimum_version_id = 1,
1022    .needed = ps2_keyboard_need_high_bit_needed,
1023    .fields = (VMStateField[]) {
1024        VMSTATE_BOOL(need_high_bit, PS2KbdState),
1025        VMSTATE_END_OF_LIST()
1026    }
1027};
1028
1029static int ps2_kbd_post_load(void* opaque, int version_id)
1030{
1031    PS2KbdState *s = (PS2KbdState*)opaque;
1032    PS2State *ps2 = &s->common;
1033
1034    if (version_id == 2)
1035        s->scancode_set=2;
1036
1037    ps2_common_post_load(ps2);
1038
1039    return 0;
1040}
1041
1042static int ps2_kbd_pre_save(void *opaque)
1043{
1044    PS2KbdState *s = (PS2KbdState *)opaque;
1045    PS2State *ps2 = &s->common;
1046
1047    ps2_common_post_load(ps2);
1048
1049    return 0;
1050}
1051
1052static const VMStateDescription vmstate_ps2_keyboard = {
1053    .name = "ps2kbd",
1054    .version_id = 3,
1055    .minimum_version_id = 2,
1056    .post_load = ps2_kbd_post_load,
1057    .pre_save = ps2_kbd_pre_save,
1058    .fields = (VMStateField[]) {
1059        VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1060        VMSTATE_INT32(scan_enabled, PS2KbdState),
1061        VMSTATE_INT32(translate, PS2KbdState),
1062        VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1063        VMSTATE_END_OF_LIST()
1064    },
1065    .subsections = (const VMStateDescription*[]) {
1066        &vmstate_ps2_keyboard_ledstate,
1067        &vmstate_ps2_keyboard_need_high_bit,
1068        NULL
1069    }
1070};
1071
1072static int ps2_mouse_post_load(void *opaque, int version_id)
1073{
1074    PS2MouseState *s = (PS2MouseState *)opaque;
1075    PS2State *ps2 = &s->common;
1076
1077    ps2_common_post_load(ps2);
1078
1079    return 0;
1080}
1081
1082static int ps2_mouse_pre_save(void *opaque)
1083{
1084    PS2MouseState *s = (PS2MouseState *)opaque;
1085    PS2State *ps2 = &s->common;
1086
1087    ps2_common_post_load(ps2);
1088
1089    return 0;
1090}
1091
1092static const VMStateDescription vmstate_ps2_mouse = {
1093    .name = "ps2mouse",
1094    .version_id = 2,
1095    .minimum_version_id = 2,
1096    .post_load = ps2_mouse_post_load,
1097    .pre_save = ps2_mouse_pre_save,
1098    .fields = (VMStateField[]) {
1099        VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1100        VMSTATE_UINT8(mouse_status, PS2MouseState),
1101        VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1102        VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1103        VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1104        VMSTATE_UINT8(mouse_type, PS2MouseState),
1105        VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1106        VMSTATE_INT32(mouse_dx, PS2MouseState),
1107        VMSTATE_INT32(mouse_dy, PS2MouseState),
1108        VMSTATE_INT32(mouse_dz, PS2MouseState),
1109        VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1110        VMSTATE_END_OF_LIST()
1111    }
1112};
1113
1114static QemuInputHandler ps2_keyboard_handler = {
1115    .name  = "QEMU PS/2 Keyboard",
1116    .mask  = INPUT_EVENT_MASK_KEY,
1117    .event = ps2_keyboard_event,
1118};
1119
1120void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1121{
1122    PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1123
1124    trace_ps2_kbd_init(s);
1125    s->common.update_irq = update_irq;
1126    s->common.update_arg = update_arg;
1127    s->scancode_set = 2;
1128    vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1129    qemu_input_handler_register((DeviceState *)s,
1130                                &ps2_keyboard_handler);
1131    qemu_register_reset(ps2_kbd_reset, s);
1132    return s;
1133}
1134
1135static QemuInputHandler ps2_mouse_handler = {
1136    .name  = "QEMU PS/2 Mouse",
1137    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1138    .event = ps2_mouse_event,
1139    .sync  = ps2_mouse_sync,
1140};
1141
1142void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1143{
1144    PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1145
1146    trace_ps2_mouse_init(s);
1147    s->common.update_irq = update_irq;
1148    s->common.update_arg = update_arg;
1149    vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1150    qemu_input_handler_register((DeviceState *)s,
1151                                &ps2_mouse_handler);
1152    qemu_register_reset(ps2_mouse_reset, s);
1153    return s;
1154}
1155