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/* Keyboard Commands */
  37#define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
  38#define KBD_CMD_ECHO            0xEE
  39#define KBD_CMD_SCANCODE        0xF0    /* Get/set scancode set */
  40#define KBD_CMD_GET_ID          0xF2    /* get keyboard ID */
  41#define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
  42#define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
  43#define KBD_CMD_RESET_DISABLE   0xF5    /* reset and disable scanning */
  44#define KBD_CMD_RESET_ENABLE    0xF6    /* reset and enable scanning */
  45#define KBD_CMD_RESET           0xFF    /* Reset */
  46#define KBD_CMD_SET_MAKE_BREAK  0xFC    /* Set Make and Break mode */
  47#define KBD_CMD_SET_TYPEMATIC   0xFA    /* Set Typematic Make and Break mode */
  48
  49/* Keyboard Replies */
  50#define KBD_REPLY_POR           0xAA    /* Power on reset */
  51#define KBD_REPLY_ID            0xAB    /* Keyboard ID */
  52#define KBD_REPLY_ACK           0xFA    /* Command ACK */
  53#define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
  54
  55/* Mouse Commands */
  56#define AUX_SET_SCALE11         0xE6    /* Set 1:1 scaling */
  57#define AUX_SET_SCALE21         0xE7    /* Set 2:1 scaling */
  58#define AUX_SET_RES             0xE8    /* Set resolution */
  59#define AUX_GET_SCALE           0xE9    /* Get scaling factor */
  60#define AUX_SET_STREAM          0xEA    /* Set stream mode */
  61#define AUX_POLL                0xEB    /* Poll */
  62#define AUX_RESET_WRAP          0xEC    /* Reset wrap mode */
  63#define AUX_SET_WRAP            0xEE    /* Set wrap mode */
  64#define AUX_SET_REMOTE          0xF0    /* Set remote mode */
  65#define AUX_GET_TYPE            0xF2    /* Get type */
  66#define AUX_SET_SAMPLE          0xF3    /* Set sample rate */
  67#define AUX_ENABLE_DEV          0xF4    /* Enable aux device */
  68#define AUX_DISABLE_DEV         0xF5    /* Disable aux device */
  69#define AUX_SET_DEFAULT         0xF6
  70#define AUX_RESET               0xFF    /* Reset aux device */
  71#define AUX_ACK                 0xFA    /* Command byte ACK. */
  72
  73#define MOUSE_STATUS_REMOTE     0x40
  74#define MOUSE_STATUS_ENABLED    0x20
  75#define MOUSE_STATUS_SCALE21    0x10
  76
  77/*
  78 * PS/2 buffer size. Keep 256 bytes for compatibility with
  79 * older QEMU versions.
  80 */
  81#define PS2_BUFFER_SIZE     256
  82#define PS2_QUEUE_SIZE      16  /* Queue size required by PS/2 protocol */
  83#define PS2_QUEUE_HEADROOM  8   /* Queue size for keyboard command replies */
  84
  85/* Bits for 'modifiers' field in PS2KbdState */
  86#define MOD_CTRL_L  (1 << 0)
  87#define MOD_SHIFT_L (1 << 1)
  88#define MOD_ALT_L   (1 << 2)
  89#define MOD_CTRL_R  (1 << 3)
  90#define MOD_SHIFT_R (1 << 4)
  91#define MOD_ALT_R   (1 << 5)
  92
  93typedef struct {
  94    uint8_t data[PS2_BUFFER_SIZE];
  95    int rptr, wptr, cwptr, 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->cwptr = -1;
 191    q->count = 0;
 192}
 193
 194int ps2_queue_empty(PS2State *s)
 195{
 196    return s->queue.count == 0;
 197}
 198
 199void ps2_queue_noirq(PS2State *s, int b)
 200{
 201    PS2Queue *q = &s->queue;
 202
 203    if (q->count >= PS2_QUEUE_SIZE) {
 204        return;
 205    }
 206
 207    q->data[q->wptr] = b;
 208    if (++q->wptr == PS2_BUFFER_SIZE) {
 209        q->wptr = 0;
 210    }
 211    q->count++;
 212}
 213
 214void ps2_raise_irq(PS2State *s)
 215{
 216    s->update_irq(s->update_arg, 1);
 217}
 218
 219void ps2_queue(PS2State *s, int b)
 220{
 221    if (PS2_QUEUE_SIZE - s->queue.count < 1) {
 222        return;
 223    }
 224
 225    ps2_queue_noirq(s, b);
 226    ps2_raise_irq(s);
 227}
 228
 229void ps2_queue_2(PS2State *s, int b1, int b2)
 230{
 231    if (PS2_QUEUE_SIZE - s->queue.count < 2) {
 232        return;
 233    }
 234
 235    ps2_queue_noirq(s, b1);
 236    ps2_queue_noirq(s, b2);
 237    ps2_raise_irq(s);
 238}
 239
 240void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
 241{
 242    if (PS2_QUEUE_SIZE - s->queue.count < 3) {
 243        return;
 244    }
 245
 246    ps2_queue_noirq(s, b1);
 247    ps2_queue_noirq(s, b2);
 248    ps2_queue_noirq(s, b3);
 249    ps2_raise_irq(s);
 250}
 251
 252void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
 253{
 254    if (PS2_QUEUE_SIZE - s->queue.count < 4) {
 255        return;
 256    }
 257
 258    ps2_queue_noirq(s, b1);
 259    ps2_queue_noirq(s, b2);
 260    ps2_queue_noirq(s, b3);
 261    ps2_queue_noirq(s, b4);
 262    ps2_raise_irq(s);
 263}
 264
 265static void ps2_cqueue_data(PS2Queue *q, int b)
 266{
 267    q->data[q->cwptr] = b;
 268    if (++q->cwptr >= PS2_BUFFER_SIZE) {
 269        q->cwptr = 0;
 270    }
 271    q->count++;
 272}
 273
 274static void ps2_cqueue_1(PS2State *s, int b1)
 275{
 276    PS2Queue *q = &s->queue;
 277
 278    q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1);
 279    q->cwptr = q->rptr;
 280    ps2_cqueue_data(q, b1);
 281    ps2_raise_irq(s);
 282}
 283
 284static void ps2_cqueue_2(PS2State *s, int b1, int b2)
 285{
 286    PS2Queue *q = &s->queue;
 287
 288    q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1);
 289    q->cwptr = q->rptr;
 290    ps2_cqueue_data(q, b1);
 291    ps2_cqueue_data(q, b2);
 292    ps2_raise_irq(s);
 293}
 294
 295static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3)
 296{
 297    PS2Queue *q = &s->queue;
 298
 299    q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1);
 300    q->cwptr = q->rptr;
 301    ps2_cqueue_data(q, b1);
 302    ps2_cqueue_data(q, b2);
 303    ps2_cqueue_data(q, b3);
 304    ps2_raise_irq(s);
 305}
 306
 307static void ps2_cqueue_reset(PS2State *s)
 308{
 309    PS2Queue *q = &s->queue;
 310    int ccount;
 311
 312    if (q->cwptr == -1) {
 313        return;
 314    }
 315
 316    ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
 317    q->count -= ccount;
 318    q->rptr = q->cwptr;
 319    q->cwptr = -1;
 320}
 321
 322/* keycode is the untranslated scancode in the current scancode set. */
 323static void ps2_put_keycode(void *opaque, int keycode)
 324{
 325    PS2KbdState *s = opaque;
 326
 327    trace_ps2_put_keycode(opaque, keycode);
 328    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 329
 330    if (s->translate) {
 331        if (keycode == 0xf0) {
 332            s->need_high_bit = true;
 333        } else if (s->need_high_bit) {
 334            ps2_queue(&s->common, translate_table[keycode] | 0x80);
 335            s->need_high_bit = false;
 336        } else {
 337            ps2_queue(&s->common, translate_table[keycode]);
 338        }
 339    } else {
 340        ps2_queue(&s->common, keycode);
 341    }
 342}
 343
 344static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
 345                               InputEvent *evt)
 346{
 347    PS2KbdState *s = (PS2KbdState *)dev;
 348    InputKeyEvent *key = evt->u.key.data;
 349    int qcode;
 350    uint16_t keycode = 0;
 351    int mod;
 352
 353    /* do not process events while disabled to prevent stream corruption */
 354    if (!s->scan_enabled) {
 355        return;
 356    }
 357
 358    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 359    assert(evt->type == INPUT_EVENT_KIND_KEY);
 360    qcode = qemu_input_key_value_to_qcode(key->key);
 361
 362    mod = ps2_modifier_bit(qcode);
 363    trace_ps2_keyboard_event(s, qcode, key->down, mod,
 364                             s->modifiers, s->scancode_set, s->translate);
 365    if (key->down) {
 366        s->modifiers |= mod;
 367    } else {
 368        s->modifiers &= ~mod;
 369    }
 370
 371    if (s->scancode_set == 1) {
 372        if (qcode == Q_KEY_CODE_PAUSE) {
 373            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 374                if (key->down) {
 375                    ps2_put_keycode(s, 0xe0);
 376                    ps2_put_keycode(s, 0x46);
 377                    ps2_put_keycode(s, 0xe0);
 378                    ps2_put_keycode(s, 0xc6);
 379                }
 380            } else {
 381                if (key->down) {
 382                    ps2_put_keycode(s, 0xe1);
 383                    ps2_put_keycode(s, 0x1d);
 384                    ps2_put_keycode(s, 0x45);
 385                    ps2_put_keycode(s, 0xe1);
 386                    ps2_put_keycode(s, 0x9d);
 387                    ps2_put_keycode(s, 0xc5);
 388                }
 389            }
 390        } else if (qcode == Q_KEY_CODE_PRINT) {
 391            if (s->modifiers & MOD_ALT_L) {
 392                if (key->down) {
 393                    ps2_put_keycode(s, 0xb8);
 394                    ps2_put_keycode(s, 0x38);
 395                    ps2_put_keycode(s, 0x54);
 396                } else {
 397                    ps2_put_keycode(s, 0xd4);
 398                    ps2_put_keycode(s, 0xb8);
 399                    ps2_put_keycode(s, 0x38);
 400                }
 401            } else if (s->modifiers & MOD_ALT_R) {
 402                if (key->down) {
 403                    ps2_put_keycode(s, 0xe0);
 404                    ps2_put_keycode(s, 0xb8);
 405                    ps2_put_keycode(s, 0xe0);
 406                    ps2_put_keycode(s, 0x38);
 407                    ps2_put_keycode(s, 0x54);
 408                } else {
 409                    ps2_put_keycode(s, 0xd4);
 410                    ps2_put_keycode(s, 0xe0);
 411                    ps2_put_keycode(s, 0xb8);
 412                    ps2_put_keycode(s, 0xe0);
 413                    ps2_put_keycode(s, 0x38);
 414                }
 415            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 416                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 417                if (key->down) {
 418                    ps2_put_keycode(s, 0xe0);
 419                    ps2_put_keycode(s, 0x37);
 420                } else {
 421                    ps2_put_keycode(s, 0xe0);
 422                    ps2_put_keycode(s, 0xb7);
 423                }
 424            } else {
 425                if (key->down) {
 426                    ps2_put_keycode(s, 0xe0);
 427                    ps2_put_keycode(s, 0x2a);
 428                    ps2_put_keycode(s, 0xe0);
 429                    ps2_put_keycode(s, 0x37);
 430                } else {
 431                    ps2_put_keycode(s, 0xe0);
 432                    ps2_put_keycode(s, 0xb7);
 433                    ps2_put_keycode(s, 0xe0);
 434                    ps2_put_keycode(s, 0xaa);
 435                }
 436            }
 437        } else {
 438            if (qcode < qemu_input_map_qcode_to_atset1_len)
 439                keycode = qemu_input_map_qcode_to_atset1[qcode];
 440            if (keycode) {
 441                if (keycode & 0xff00) {
 442                    ps2_put_keycode(s, keycode >> 8);
 443                }
 444                if (!key->down) {
 445                    keycode |= 0x80;
 446                }
 447                ps2_put_keycode(s, keycode & 0xff);
 448            } else {
 449                qemu_log_mask(LOG_UNIMP,
 450                              "ps2: ignoring key with qcode %d\n", qcode);
 451            }
 452        }
 453    } else if (s->scancode_set == 2) {
 454        if (qcode == Q_KEY_CODE_PAUSE) {
 455            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 456                if (key->down) {
 457                    ps2_put_keycode(s, 0xe0);
 458                    ps2_put_keycode(s, 0x7e);
 459                    ps2_put_keycode(s, 0xe0);
 460                    ps2_put_keycode(s, 0xf0);
 461                    ps2_put_keycode(s, 0x7e);
 462                }
 463            } else {
 464                if (key->down) {
 465                    ps2_put_keycode(s, 0xe1);
 466                    ps2_put_keycode(s, 0x14);
 467                    ps2_put_keycode(s, 0x77);
 468                    ps2_put_keycode(s, 0xe1);
 469                    ps2_put_keycode(s, 0xf0);
 470                    ps2_put_keycode(s, 0x14);
 471                    ps2_put_keycode(s, 0xf0);
 472                    ps2_put_keycode(s, 0x77);
 473                }
 474            }
 475        } else if (qcode == Q_KEY_CODE_PRINT) {
 476            if (s->modifiers & MOD_ALT_L) {
 477                if (key->down) {
 478                    ps2_put_keycode(s, 0xf0);
 479                    ps2_put_keycode(s, 0x11);
 480                    ps2_put_keycode(s, 0x11);
 481                    ps2_put_keycode(s, 0x84);
 482                } else {
 483                    ps2_put_keycode(s, 0xf0);
 484                    ps2_put_keycode(s, 0x84);
 485                    ps2_put_keycode(s, 0xf0);
 486                    ps2_put_keycode(s, 0x11);
 487                    ps2_put_keycode(s, 0x11);
 488                }
 489            } else if (s->modifiers & MOD_ALT_R) {
 490                if (key->down) {
 491                    ps2_put_keycode(s, 0xe0);
 492                    ps2_put_keycode(s, 0xf0);
 493                    ps2_put_keycode(s, 0x11);
 494                    ps2_put_keycode(s, 0xe0);
 495                    ps2_put_keycode(s, 0x11);
 496                    ps2_put_keycode(s, 0x84);
 497                } else {
 498                    ps2_put_keycode(s, 0xf0);
 499                    ps2_put_keycode(s, 0x84);
 500                    ps2_put_keycode(s, 0xe0);
 501                    ps2_put_keycode(s, 0xf0);
 502                    ps2_put_keycode(s, 0x11);
 503                    ps2_put_keycode(s, 0xe0);
 504                    ps2_put_keycode(s, 0x11);
 505                }
 506            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 507                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 508                if (key->down) {
 509                    ps2_put_keycode(s, 0xe0);
 510                    ps2_put_keycode(s, 0x7c);
 511                } else {
 512                    ps2_put_keycode(s, 0xe0);
 513                    ps2_put_keycode(s, 0xf0);
 514                    ps2_put_keycode(s, 0x7c);
 515                }
 516            } else {
 517                if (key->down) {
 518                    ps2_put_keycode(s, 0xe0);
 519                    ps2_put_keycode(s, 0x12);
 520                    ps2_put_keycode(s, 0xe0);
 521                    ps2_put_keycode(s, 0x7c);
 522                } else {
 523                    ps2_put_keycode(s, 0xe0);
 524                    ps2_put_keycode(s, 0xf0);
 525                    ps2_put_keycode(s, 0x7c);
 526                    ps2_put_keycode(s, 0xe0);
 527                    ps2_put_keycode(s, 0xf0);
 528                    ps2_put_keycode(s, 0x12);
 529                }
 530            }
 531        } else {
 532            if (qcode < qemu_input_map_qcode_to_atset2_len)
 533                keycode = qemu_input_map_qcode_to_atset2[qcode];
 534            if (keycode) {
 535                if (keycode & 0xff00) {
 536                    ps2_put_keycode(s, keycode >> 8);
 537                }
 538                if (!key->down) {
 539                    ps2_put_keycode(s, 0xf0);
 540                }
 541                ps2_put_keycode(s, keycode & 0xff);
 542            } else {
 543                qemu_log_mask(LOG_UNIMP,
 544                              "ps2: ignoring key with qcode %d\n", qcode);
 545            }
 546        }
 547    } else if (s->scancode_set == 3) {
 548        if (qcode < qemu_input_map_qcode_to_atset3_len)
 549            keycode = qemu_input_map_qcode_to_atset3[qcode];
 550        if (keycode) {
 551            /* FIXME: break code should be configured on a key by key basis */
 552            if (!key->down) {
 553                ps2_put_keycode(s, 0xf0);
 554            }
 555            ps2_put_keycode(s, keycode);
 556        } else {
 557            qemu_log_mask(LOG_UNIMP,
 558                          "ps2: ignoring key with qcode %d\n", qcode);
 559        }
 560    }
 561}
 562
 563uint32_t ps2_read_data(PS2State *s)
 564{
 565    PS2Queue *q;
 566    int val, index;
 567
 568    trace_ps2_read_data(s);
 569    q = &s->queue;
 570    if (q->count == 0) {
 571        /* NOTE: if no data left, we return the last keyboard one
 572           (needed for EMM386) */
 573        /* XXX: need a timer to do things correctly */
 574        index = q->rptr - 1;
 575        if (index < 0) {
 576            index = PS2_BUFFER_SIZE - 1;
 577        }
 578        val = q->data[index];
 579    } else {
 580        val = q->data[q->rptr];
 581        if (++q->rptr == PS2_BUFFER_SIZE) {
 582            q->rptr = 0;
 583        }
 584        q->count--;
 585        if (q->rptr == q->cwptr) {
 586            /* command reply queue is empty */
 587            q->cwptr = -1;
 588        }
 589        /* reading deasserts IRQ */
 590        s->update_irq(s->update_arg, 0);
 591        /* reassert IRQs if data left */
 592        if (q->count) {
 593            s->update_irq(s->update_arg, 1);
 594        }
 595    }
 596    return val;
 597}
 598
 599static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
 600{
 601    trace_ps2_set_ledstate(s, ledstate);
 602    s->ledstate = ledstate;
 603    kbd_put_ledstate(ledstate);
 604}
 605
 606static void ps2_reset_keyboard(PS2KbdState *s)
 607{
 608    trace_ps2_reset_keyboard(s);
 609    s->scan_enabled = 1;
 610    s->scancode_set = 2;
 611    ps2_reset_queue(&s->common);
 612    ps2_set_ledstate(s, 0);
 613}
 614
 615void ps2_write_keyboard(void *opaque, int val)
 616{
 617    PS2KbdState *s = (PS2KbdState *)opaque;
 618
 619    trace_ps2_write_keyboard(opaque, val);
 620    ps2_cqueue_reset(&s->common);
 621    switch(s->common.write_cmd) {
 622    default:
 623    case -1:
 624        switch(val) {
 625        case 0x00:
 626            ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 627            break;
 628        case 0x05:
 629            ps2_cqueue_1(&s->common, KBD_REPLY_RESEND);
 630            break;
 631        case KBD_CMD_GET_ID:
 632            /* We emulate a MF2 AT keyboard here */
 633            ps2_cqueue_3(&s->common, KBD_REPLY_ACK, KBD_REPLY_ID,
 634                s->translate ? 0x41 : 0x83);
 635            break;
 636        case KBD_CMD_ECHO:
 637            ps2_cqueue_1(&s->common, KBD_CMD_ECHO);
 638            break;
 639        case KBD_CMD_ENABLE:
 640            s->scan_enabled = 1;
 641            ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 642            break;
 643        case KBD_CMD_SCANCODE:
 644        case KBD_CMD_SET_LEDS:
 645        case KBD_CMD_SET_RATE:
 646        case KBD_CMD_SET_MAKE_BREAK:
 647            s->common.write_cmd = val;
 648            ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 649            break;
 650        case KBD_CMD_RESET_DISABLE:
 651            ps2_reset_keyboard(s);
 652            s->scan_enabled = 0;
 653            ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 654            break;
 655        case KBD_CMD_RESET_ENABLE:
 656            ps2_reset_keyboard(s);
 657            s->scan_enabled = 1;
 658            ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 659            break;
 660        case KBD_CMD_RESET:
 661            ps2_reset_keyboard(s);
 662            ps2_cqueue_2(&s->common,
 663                KBD_REPLY_ACK,
 664                KBD_REPLY_POR);
 665            break;
 666        case KBD_CMD_SET_TYPEMATIC:
 667            ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 668            break;
 669        default:
 670            ps2_cqueue_1(&s->common, KBD_REPLY_RESEND);
 671            break;
 672        }
 673        break;
 674    case KBD_CMD_SET_MAKE_BREAK:
 675        ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 676        s->common.write_cmd = -1;
 677        break;
 678    case KBD_CMD_SCANCODE:
 679        if (val == 0) {
 680            ps2_cqueue_2(&s->common, KBD_REPLY_ACK, s->translate ?
 681                translate_table[s->scancode_set] : s->scancode_set);
 682        } else if (val >= 1 && val <= 3) {
 683            s->scancode_set = val;
 684            ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 685        } else {
 686            ps2_cqueue_1(&s->common, KBD_REPLY_RESEND);
 687        }
 688        s->common.write_cmd = -1;
 689        break;
 690    case KBD_CMD_SET_LEDS:
 691        ps2_set_ledstate(s, val);
 692        ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 693        s->common.write_cmd = -1;
 694        break;
 695    case KBD_CMD_SET_RATE:
 696        ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
 697        s->common.write_cmd = -1;
 698        break;
 699    }
 700}
 701
 702/* Set the scancode translation mode.
 703   0 = raw scancodes.
 704   1 = translated scancodes (used by qemu internally).  */
 705
 706void ps2_keyboard_set_translation(void *opaque, int mode)
 707{
 708    PS2KbdState *s = (PS2KbdState *)opaque;
 709    trace_ps2_keyboard_set_translation(opaque, mode);
 710    s->translate = mode;
 711}
 712
 713static int ps2_mouse_send_packet(PS2MouseState *s)
 714{
 715    /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
 716    const int needed = s->mouse_type ? 4 : 3;
 717    unsigned int b;
 718    int dx1, dy1, dz1;
 719
 720    if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
 721        return 0;
 722    }
 723
 724    dx1 = s->mouse_dx;
 725    dy1 = s->mouse_dy;
 726    dz1 = s->mouse_dz;
 727    /* XXX: increase range to 8 bits ? */
 728    if (dx1 > 127)
 729        dx1 = 127;
 730    else if (dx1 < -127)
 731        dx1 = -127;
 732    if (dy1 > 127)
 733        dy1 = 127;
 734    else if (dy1 < -127)
 735        dy1 = -127;
 736    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
 737    ps2_queue_noirq(&s->common, b);
 738    ps2_queue_noirq(&s->common, dx1 & 0xff);
 739    ps2_queue_noirq(&s->common, dy1 & 0xff);
 740    /* extra byte for IMPS/2 or IMEX */
 741    switch(s->mouse_type) {
 742    default:
 743        break;
 744    case 3:
 745        if (dz1 > 127)
 746            dz1 = 127;
 747        else if (dz1 < -127)
 748                dz1 = -127;
 749        ps2_queue_noirq(&s->common, dz1 & 0xff);
 750        break;
 751    case 4:
 752        if (dz1 > 7)
 753            dz1 = 7;
 754        else if (dz1 < -7)
 755            dz1 = -7;
 756        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
 757        ps2_queue_noirq(&s->common, b);
 758        break;
 759    }
 760
 761    ps2_raise_irq(&s->common);
 762
 763    trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
 764    /* update deltas */
 765    s->mouse_dx -= dx1;
 766    s->mouse_dy -= dy1;
 767    s->mouse_dz -= dz1;
 768
 769    return 1;
 770}
 771
 772static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
 773                            InputEvent *evt)
 774{
 775    static const int bmap[INPUT_BUTTON__MAX] = {
 776        [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
 777        [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
 778        [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
 779        [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
 780        [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
 781    };
 782    PS2MouseState *s = (PS2MouseState *)dev;
 783    InputMoveEvent *move;
 784    InputBtnEvent *btn;
 785
 786    /* check if deltas are recorded when disabled */
 787    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
 788        return;
 789
 790    switch (evt->type) {
 791    case INPUT_EVENT_KIND_REL:
 792        move = evt->u.rel.data;
 793        if (move->axis == INPUT_AXIS_X) {
 794            s->mouse_dx += move->value;
 795        } else if (move->axis == INPUT_AXIS_Y) {
 796            s->mouse_dy -= move->value;
 797        }
 798        break;
 799
 800    case INPUT_EVENT_KIND_BTN:
 801        btn = evt->u.btn.data;
 802        if (btn->down) {
 803            s->mouse_buttons |= bmap[btn->button];
 804            if (btn->button == INPUT_BUTTON_WHEEL_UP) {
 805                s->mouse_dz--;
 806            } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 807                s->mouse_dz++;
 808            }
 809        } else {
 810            s->mouse_buttons &= ~bmap[btn->button];
 811        }
 812        break;
 813
 814    default:
 815        /* keep gcc happy */
 816        break;
 817    }
 818}
 819
 820static void ps2_mouse_sync(DeviceState *dev)
 821{
 822    PS2MouseState *s = (PS2MouseState *)dev;
 823
 824    /* do not sync while disabled to prevent stream corruption */
 825    if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
 826        return;
 827    }
 828
 829    if (s->mouse_buttons) {
 830        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 831    }
 832    if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
 833        /* if not remote, send event. Multiple events are sent if
 834           too big deltas */
 835        while (ps2_mouse_send_packet(s)) {
 836            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
 837                break;
 838        }
 839    }
 840}
 841
 842void ps2_mouse_fake_event(void *opaque)
 843{
 844    PS2MouseState *s = opaque;
 845    trace_ps2_mouse_fake_event(opaque);
 846    s->mouse_dx++;
 847    ps2_mouse_sync(opaque);
 848}
 849
 850void ps2_write_mouse(void *opaque, int val)
 851{
 852    PS2MouseState *s = (PS2MouseState *)opaque;
 853
 854    trace_ps2_write_mouse(opaque, val);
 855    switch(s->common.write_cmd) {
 856    default:
 857    case -1:
 858        /* mouse command */
 859        if (s->mouse_wrap) {
 860            if (val == AUX_RESET_WRAP) {
 861                s->mouse_wrap = 0;
 862                ps2_queue(&s->common, AUX_ACK);
 863                return;
 864            } else if (val != AUX_RESET) {
 865                ps2_queue(&s->common, val);
 866                return;
 867            }
 868        }
 869        switch(val) {
 870        case AUX_SET_SCALE11:
 871            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
 872            ps2_queue(&s->common, AUX_ACK);
 873            break;
 874        case AUX_SET_SCALE21:
 875            s->mouse_status |= MOUSE_STATUS_SCALE21;
 876            ps2_queue(&s->common, AUX_ACK);
 877            break;
 878        case AUX_SET_STREAM:
 879            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
 880            ps2_queue(&s->common, AUX_ACK);
 881            break;
 882        case AUX_SET_WRAP:
 883            s->mouse_wrap = 1;
 884            ps2_queue(&s->common, AUX_ACK);
 885            break;
 886        case AUX_SET_REMOTE:
 887            s->mouse_status |= MOUSE_STATUS_REMOTE;
 888            ps2_queue(&s->common, AUX_ACK);
 889            break;
 890        case AUX_GET_TYPE:
 891            ps2_queue_2(&s->common,
 892                AUX_ACK,
 893                s->mouse_type);
 894            break;
 895        case AUX_SET_RES:
 896        case AUX_SET_SAMPLE:
 897            s->common.write_cmd = val;
 898            ps2_queue(&s->common, AUX_ACK);
 899            break;
 900        case AUX_GET_SCALE:
 901            ps2_queue_4(&s->common,
 902                AUX_ACK,
 903                s->mouse_status,
 904                s->mouse_resolution,
 905                s->mouse_sample_rate);
 906            break;
 907        case AUX_POLL:
 908            ps2_queue(&s->common, AUX_ACK);
 909            ps2_mouse_send_packet(s);
 910            break;
 911        case AUX_ENABLE_DEV:
 912            s->mouse_status |= MOUSE_STATUS_ENABLED;
 913            ps2_queue(&s->common, AUX_ACK);
 914            break;
 915        case AUX_DISABLE_DEV:
 916            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
 917            ps2_queue(&s->common, AUX_ACK);
 918            break;
 919        case AUX_SET_DEFAULT:
 920            s->mouse_sample_rate = 100;
 921            s->mouse_resolution = 2;
 922            s->mouse_status = 0;
 923            ps2_queue(&s->common, AUX_ACK);
 924            break;
 925        case AUX_RESET:
 926            s->mouse_sample_rate = 100;
 927            s->mouse_resolution = 2;
 928            s->mouse_status = 0;
 929            s->mouse_type = 0;
 930            ps2_reset_queue(&s->common);
 931            ps2_queue_3(&s->common,
 932                AUX_ACK,
 933                0xaa,
 934                s->mouse_type);
 935            break;
 936        default:
 937            break;
 938        }
 939        break;
 940    case AUX_SET_SAMPLE:
 941        s->mouse_sample_rate = val;
 942        /* detect IMPS/2 or IMEX */
 943        switch(s->mouse_detect_state) {
 944        default:
 945        case 0:
 946            if (val == 200)
 947                s->mouse_detect_state = 1;
 948            break;
 949        case 1:
 950            if (val == 100)
 951                s->mouse_detect_state = 2;
 952            else if (val == 200)
 953                s->mouse_detect_state = 3;
 954            else
 955                s->mouse_detect_state = 0;
 956            break;
 957        case 2:
 958            if (val == 80)
 959                s->mouse_type = 3; /* IMPS/2 */
 960            s->mouse_detect_state = 0;
 961            break;
 962        case 3:
 963            if (val == 80)
 964                s->mouse_type = 4; /* IMEX */
 965            s->mouse_detect_state = 0;
 966            break;
 967        }
 968        ps2_queue(&s->common, AUX_ACK);
 969        s->common.write_cmd = -1;
 970        break;
 971    case AUX_SET_RES:
 972        s->mouse_resolution = val;
 973        ps2_queue(&s->common, AUX_ACK);
 974        s->common.write_cmd = -1;
 975        break;
 976    }
 977}
 978
 979static void ps2_common_reset(PS2State *s)
 980{
 981    s->write_cmd = -1;
 982    ps2_reset_queue(s);
 983    s->update_irq(s->update_arg, 0);
 984}
 985
 986static void ps2_common_post_load(PS2State *s)
 987{
 988    PS2Queue *q = &s->queue;
 989    int ccount = 0;
 990
 991    /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */
 992    if (q->cwptr != -1) {
 993        ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
 994        if (ccount > PS2_QUEUE_HEADROOM) {
 995            ccount = PS2_QUEUE_HEADROOM;
 996        }
 997    }
 998
 999    /* limit the scancode queue size to PS2_QUEUE_SIZE */
1000    if (q->count < ccount) {
1001        q->count = ccount;
1002    } else if (q->count > ccount + PS2_QUEUE_SIZE) {
1003        q->count = ccount + PS2_QUEUE_SIZE;
1004    }
1005
1006    /* sanitize rptr and recalculate wptr and cwptr */
1007    q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
1008    q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
1009    q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1;
1010}
1011
1012static void ps2_kbd_reset(void *opaque)
1013{
1014    PS2KbdState *s = (PS2KbdState *) opaque;
1015
1016    trace_ps2_kbd_reset(opaque);
1017    ps2_common_reset(&s->common);
1018    s->scan_enabled = 1;
1019    s->translate = 0;
1020    s->scancode_set = 2;
1021    s->modifiers = 0;
1022}
1023
1024static void ps2_mouse_reset(void *opaque)
1025{
1026    PS2MouseState *s = (PS2MouseState *) opaque;
1027
1028    trace_ps2_mouse_reset(opaque);
1029    ps2_common_reset(&s->common);
1030    s->mouse_status = 0;
1031    s->mouse_resolution = 0;
1032    s->mouse_sample_rate = 0;
1033    s->mouse_wrap = 0;
1034    s->mouse_type = 0;
1035    s->mouse_detect_state = 0;
1036    s->mouse_dx = 0;
1037    s->mouse_dy = 0;
1038    s->mouse_dz = 0;
1039    s->mouse_buttons = 0;
1040}
1041
1042static const VMStateDescription vmstate_ps2_common = {
1043    .name = "PS2 Common State",
1044    .version_id = 3,
1045    .minimum_version_id = 2,
1046    .fields = (VMStateField[]) {
1047        VMSTATE_INT32(write_cmd, PS2State),
1048        VMSTATE_INT32(queue.rptr, PS2State),
1049        VMSTATE_INT32(queue.wptr, PS2State),
1050        VMSTATE_INT32(queue.count, PS2State),
1051        VMSTATE_BUFFER(queue.data, PS2State),
1052        VMSTATE_END_OF_LIST()
1053    }
1054};
1055
1056static bool ps2_keyboard_ledstate_needed(void *opaque)
1057{
1058    PS2KbdState *s = opaque;
1059
1060    return s->ledstate != 0; /* 0 is default state */
1061}
1062
1063static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1064{
1065    PS2KbdState *s = opaque;
1066
1067    kbd_put_ledstate(s->ledstate);
1068    return 0;
1069}
1070
1071static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1072    .name = "ps2kbd/ledstate",
1073    .version_id = 3,
1074    .minimum_version_id = 2,
1075    .post_load = ps2_kbd_ledstate_post_load,
1076    .needed = ps2_keyboard_ledstate_needed,
1077    .fields = (VMStateField[]) {
1078        VMSTATE_INT32(ledstate, PS2KbdState),
1079        VMSTATE_END_OF_LIST()
1080    }
1081};
1082
1083static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1084{
1085    PS2KbdState *s = opaque;
1086    return s->need_high_bit != 0; /* 0 is the usual state */
1087}
1088
1089static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1090    .name = "ps2kbd/need_high_bit",
1091    .version_id = 1,
1092    .minimum_version_id = 1,
1093    .needed = ps2_keyboard_need_high_bit_needed,
1094    .fields = (VMStateField[]) {
1095        VMSTATE_BOOL(need_high_bit, PS2KbdState),
1096        VMSTATE_END_OF_LIST()
1097    }
1098};
1099
1100static bool ps2_keyboard_cqueue_needed(void *opaque)
1101{
1102    PS2KbdState *s = opaque;
1103
1104    return s->common.queue.cwptr != -1; /* the queue is mostly empty */
1105}
1106
1107static const VMStateDescription vmstate_ps2_keyboard_cqueue = {
1108    .name = "ps2kbd/command_reply_queue",
1109    .needed = ps2_keyboard_cqueue_needed,
1110    .fields = (VMStateField[]) {
1111        VMSTATE_INT32(common.queue.cwptr, PS2KbdState),
1112        VMSTATE_END_OF_LIST()
1113    }
1114};
1115
1116static int ps2_kbd_post_load(void* opaque, int version_id)
1117{
1118    PS2KbdState *s = (PS2KbdState*)opaque;
1119    PS2State *ps2 = &s->common;
1120
1121    if (version_id == 2)
1122        s->scancode_set=2;
1123
1124    ps2_common_post_load(ps2);
1125
1126    return 0;
1127}
1128
1129static const VMStateDescription vmstate_ps2_keyboard = {
1130    .name = "ps2kbd",
1131    .version_id = 3,
1132    .minimum_version_id = 2,
1133    .post_load = ps2_kbd_post_load,
1134    .fields = (VMStateField[]) {
1135        VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1136        VMSTATE_INT32(scan_enabled, PS2KbdState),
1137        VMSTATE_INT32(translate, PS2KbdState),
1138        VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1139        VMSTATE_END_OF_LIST()
1140    },
1141    .subsections = (const VMStateDescription*[]) {
1142        &vmstate_ps2_keyboard_ledstate,
1143        &vmstate_ps2_keyboard_need_high_bit,
1144        &vmstate_ps2_keyboard_cqueue,
1145        NULL
1146    }
1147};
1148
1149static int ps2_mouse_post_load(void *opaque, int version_id)
1150{
1151    PS2MouseState *s = (PS2MouseState *)opaque;
1152    PS2State *ps2 = &s->common;
1153
1154    ps2_common_post_load(ps2);
1155
1156    return 0;
1157}
1158
1159static const VMStateDescription vmstate_ps2_mouse = {
1160    .name = "ps2mouse",
1161    .version_id = 2,
1162    .minimum_version_id = 2,
1163    .post_load = ps2_mouse_post_load,
1164    .fields = (VMStateField[]) {
1165        VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1166        VMSTATE_UINT8(mouse_status, PS2MouseState),
1167        VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1168        VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1169        VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1170        VMSTATE_UINT8(mouse_type, PS2MouseState),
1171        VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1172        VMSTATE_INT32(mouse_dx, PS2MouseState),
1173        VMSTATE_INT32(mouse_dy, PS2MouseState),
1174        VMSTATE_INT32(mouse_dz, PS2MouseState),
1175        VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1176        VMSTATE_END_OF_LIST()
1177    }
1178};
1179
1180static QemuInputHandler ps2_keyboard_handler = {
1181    .name  = "QEMU PS/2 Keyboard",
1182    .mask  = INPUT_EVENT_MASK_KEY,
1183    .event = ps2_keyboard_event,
1184};
1185
1186void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1187{
1188    PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1189
1190    trace_ps2_kbd_init(s);
1191    s->common.update_irq = update_irq;
1192    s->common.update_arg = update_arg;
1193    s->scancode_set = 2;
1194    vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1195    qemu_input_handler_register((DeviceState *)s,
1196                                &ps2_keyboard_handler);
1197    qemu_register_reset(ps2_kbd_reset, s);
1198    return s;
1199}
1200
1201static QemuInputHandler ps2_mouse_handler = {
1202    .name  = "QEMU PS/2 Mouse",
1203    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1204    .event = ps2_mouse_event,
1205    .sync  = ps2_mouse_sync,
1206};
1207
1208void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1209{
1210    PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1211
1212    trace_ps2_mouse_init(s);
1213    s->common.update_irq = update_irq;
1214    s->common.update_arg = update_arg;
1215    vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1216    qemu_input_handler_register((DeviceState *)s,
1217                                &ps2_mouse_handler);
1218    qemu_register_reset(ps2_mouse_reset, s);
1219    return s;
1220}
1221