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/irq.h"
  28#include "hw/sysbus.h"
  29#include "hw/input/ps2.h"
  30#include "migration/vmstate.h"
  31#include "ui/console.h"
  32#include "ui/input.h"
  33#include "sysemu/reset.h"
  34#include "sysemu/runstate.h"
  35#include "qapi/error.h"
  36
  37#include "trace.h"
  38
  39/* Keyboard Commands */
  40#define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
  41#define KBD_CMD_ECHO            0xEE
  42#define KBD_CMD_SCANCODE        0xF0    /* Get/set scancode set */
  43#define KBD_CMD_GET_ID          0xF2    /* get keyboard ID */
  44#define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
  45#define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
  46#define KBD_CMD_RESET_DISABLE   0xF5    /* reset and disable scanning */
  47#define KBD_CMD_RESET_ENABLE    0xF6    /* reset and enable scanning */
  48#define KBD_CMD_RESET           0xFF    /* Reset */
  49#define KBD_CMD_SET_MAKE_BREAK  0xFC    /* Set Make and Break mode */
  50#define KBD_CMD_SET_TYPEMATIC   0xFA    /* Set Typematic Make and Break mode */
  51
  52/* Keyboard Replies */
  53#define KBD_REPLY_POR       0xAA    /* Power on reset */
  54#define KBD_REPLY_ID        0xAB    /* Keyboard ID */
  55#define KBD_REPLY_ACK       0xFA    /* Command ACK */
  56#define KBD_REPLY_RESEND    0xFE    /* Command NACK, send the cmd again */
  57
  58/* Mouse Commands */
  59#define AUX_SET_SCALE11     0xE6    /* Set 1:1 scaling */
  60#define AUX_SET_SCALE21     0xE7    /* Set 2:1 scaling */
  61#define AUX_SET_RES         0xE8    /* Set resolution */
  62#define AUX_GET_SCALE       0xE9    /* Get scaling factor */
  63#define AUX_SET_STREAM      0xEA    /* Set stream mode */
  64#define AUX_POLL            0xEB    /* Poll */
  65#define AUX_RESET_WRAP      0xEC    /* Reset wrap mode */
  66#define AUX_SET_WRAP        0xEE    /* Set wrap mode */
  67#define AUX_SET_REMOTE      0xF0    /* Set remote mode */
  68#define AUX_GET_TYPE        0xF2    /* Get type */
  69#define AUX_SET_SAMPLE      0xF3    /* Set sample rate */
  70#define AUX_ENABLE_DEV      0xF4    /* Enable aux device */
  71#define AUX_DISABLE_DEV     0xF5    /* Disable aux device */
  72#define AUX_SET_DEFAULT     0xF6
  73#define AUX_RESET           0xFF    /* Reset aux device */
  74#define AUX_ACK             0xFA    /* Command byte ACK. */
  75
  76#define MOUSE_STATUS_REMOTE     0x40
  77#define MOUSE_STATUS_ENABLED    0x20
  78#define MOUSE_STATUS_SCALE21    0x10
  79
  80#define PS2_QUEUE_SIZE      16  /* Queue size required by PS/2 protocol */
  81#define PS2_QUEUE_HEADROOM  8   /* Queue size for keyboard command replies */
  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
  91static uint8_t translate_table[256] = {
  92    0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
  93    0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
  94    0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
  95    0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
  96    0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
  97    0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
  98    0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
  99    0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
 100    0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
 101    0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
 102    0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
 103    0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
 104    0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
 105    0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
 106    0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
 107    0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
 108    0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
 109    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 110    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
 111    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 112    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 113    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 114    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
 115    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 116    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 117    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 118    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 119    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 120    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 121    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 122    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 123    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 124};
 125
 126static unsigned int ps2_modifier_bit(QKeyCode key)
 127{
 128    switch (key) {
 129    case Q_KEY_CODE_CTRL:
 130        return MOD_CTRL_L;
 131    case Q_KEY_CODE_CTRL_R:
 132        return MOD_CTRL_R;
 133    case Q_KEY_CODE_SHIFT:
 134        return MOD_SHIFT_L;
 135    case Q_KEY_CODE_SHIFT_R:
 136        return MOD_SHIFT_R;
 137    case Q_KEY_CODE_ALT:
 138        return MOD_ALT_L;
 139    case Q_KEY_CODE_ALT_R:
 140        return MOD_ALT_R;
 141    default:
 142        return 0;
 143    }
 144}
 145
 146static void ps2_reset_queue(PS2State *s)
 147{
 148    PS2Queue *q = &s->queue;
 149
 150    q->rptr = 0;
 151    q->wptr = 0;
 152    q->cwptr = -1;
 153    q->count = 0;
 154}
 155
 156int ps2_queue_empty(PS2State *s)
 157{
 158    return s->queue.count == 0;
 159}
 160
 161void ps2_queue_noirq(PS2State *s, int b)
 162{
 163    PS2Queue *q = &s->queue;
 164
 165    if (q->count >= PS2_QUEUE_SIZE) {
 166        return;
 167    }
 168
 169    q->data[q->wptr] = b;
 170    if (++q->wptr == PS2_BUFFER_SIZE) {
 171        q->wptr = 0;
 172    }
 173    q->count++;
 174}
 175
 176static void ps2_raise_irq(PS2State *s)
 177{
 178    qemu_set_irq(s->irq, 1);
 179}
 180
 181static void ps2_lower_irq(PS2State *s)
 182{
 183    qemu_set_irq(s->irq, 0);
 184}
 185
 186void ps2_queue(PS2State *s, int b)
 187{
 188    if (PS2_QUEUE_SIZE - s->queue.count < 1) {
 189        return;
 190    }
 191
 192    ps2_queue_noirq(s, b);
 193    ps2_raise_irq(s);
 194}
 195
 196void ps2_queue_2(PS2State *s, int b1, int b2)
 197{
 198    if (PS2_QUEUE_SIZE - s->queue.count < 2) {
 199        return;
 200    }
 201
 202    ps2_queue_noirq(s, b1);
 203    ps2_queue_noirq(s, b2);
 204    ps2_raise_irq(s);
 205}
 206
 207void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
 208{
 209    if (PS2_QUEUE_SIZE - s->queue.count < 3) {
 210        return;
 211    }
 212
 213    ps2_queue_noirq(s, b1);
 214    ps2_queue_noirq(s, b2);
 215    ps2_queue_noirq(s, b3);
 216    ps2_raise_irq(s);
 217}
 218
 219void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
 220{
 221    if (PS2_QUEUE_SIZE - s->queue.count < 4) {
 222        return;
 223    }
 224
 225    ps2_queue_noirq(s, b1);
 226    ps2_queue_noirq(s, b2);
 227    ps2_queue_noirq(s, b3);
 228    ps2_queue_noirq(s, b4);
 229    ps2_raise_irq(s);
 230}
 231
 232static void ps2_cqueue_data(PS2Queue *q, int b)
 233{
 234    q->data[q->cwptr] = b;
 235    if (++q->cwptr >= PS2_BUFFER_SIZE) {
 236        q->cwptr = 0;
 237    }
 238    q->count++;
 239}
 240
 241static void ps2_cqueue_1(PS2State *s, int b1)
 242{
 243    PS2Queue *q = &s->queue;
 244
 245    q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1);
 246    q->cwptr = q->rptr;
 247    ps2_cqueue_data(q, b1);
 248    ps2_raise_irq(s);
 249}
 250
 251static void ps2_cqueue_2(PS2State *s, int b1, int b2)
 252{
 253    PS2Queue *q = &s->queue;
 254
 255    q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1);
 256    q->cwptr = q->rptr;
 257    ps2_cqueue_data(q, b1);
 258    ps2_cqueue_data(q, b2);
 259    ps2_raise_irq(s);
 260}
 261
 262static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3)
 263{
 264    PS2Queue *q = &s->queue;
 265
 266    q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1);
 267    q->cwptr = q->rptr;
 268    ps2_cqueue_data(q, b1);
 269    ps2_cqueue_data(q, b2);
 270    ps2_cqueue_data(q, b3);
 271    ps2_raise_irq(s);
 272}
 273
 274static void ps2_cqueue_reset(PS2State *s)
 275{
 276    PS2Queue *q = &s->queue;
 277    int ccount;
 278
 279    if (q->cwptr == -1) {
 280        return;
 281    }
 282
 283    ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
 284    q->count -= ccount;
 285    q->rptr = q->cwptr;
 286    q->cwptr = -1;
 287}
 288
 289/* keycode is the untranslated scancode in the current scancode set. */
 290static void ps2_put_keycode(void *opaque, int keycode)
 291{
 292    PS2KbdState *s = opaque;
 293    PS2State *ps = PS2_DEVICE(s);
 294
 295    trace_ps2_put_keycode(opaque, keycode);
 296    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 297
 298    if (s->translate) {
 299        if (keycode == 0xf0) {
 300            s->need_high_bit = true;
 301        } else if (s->need_high_bit) {
 302            ps2_queue(ps, translate_table[keycode] | 0x80);
 303            s->need_high_bit = false;
 304        } else {
 305            ps2_queue(ps, translate_table[keycode]);
 306        }
 307    } else {
 308        ps2_queue(ps, keycode);
 309    }
 310}
 311
 312static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
 313                               InputEvent *evt)
 314{
 315    PS2KbdState *s = (PS2KbdState *)dev;
 316    InputKeyEvent *key = evt->u.key.data;
 317    int qcode;
 318    uint16_t keycode = 0;
 319    int mod;
 320
 321    /* do not process events while disabled to prevent stream corruption */
 322    if (!s->scan_enabled) {
 323        return;
 324    }
 325
 326    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 327    assert(evt->type == INPUT_EVENT_KIND_KEY);
 328    qcode = qemu_input_key_value_to_qcode(key->key);
 329
 330    mod = ps2_modifier_bit(qcode);
 331    trace_ps2_keyboard_event(s, qcode, key->down, mod,
 332                             s->modifiers, s->scancode_set, s->translate);
 333    if (key->down) {
 334        s->modifiers |= mod;
 335    } else {
 336        s->modifiers &= ~mod;
 337    }
 338
 339    if (s->scancode_set == 1) {
 340        if (qcode == Q_KEY_CODE_PAUSE) {
 341            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 342                if (key->down) {
 343                    ps2_put_keycode(s, 0xe0);
 344                    ps2_put_keycode(s, 0x46);
 345                    ps2_put_keycode(s, 0xe0);
 346                    ps2_put_keycode(s, 0xc6);
 347                }
 348            } else {
 349                if (key->down) {
 350                    ps2_put_keycode(s, 0xe1);
 351                    ps2_put_keycode(s, 0x1d);
 352                    ps2_put_keycode(s, 0x45);
 353                    ps2_put_keycode(s, 0xe1);
 354                    ps2_put_keycode(s, 0x9d);
 355                    ps2_put_keycode(s, 0xc5);
 356                }
 357            }
 358        } else if (qcode == Q_KEY_CODE_PRINT) {
 359            if (s->modifiers & MOD_ALT_L) {
 360                if (key->down) {
 361                    ps2_put_keycode(s, 0xb8);
 362                    ps2_put_keycode(s, 0x38);
 363                    ps2_put_keycode(s, 0x54);
 364                } else {
 365                    ps2_put_keycode(s, 0xd4);
 366                    ps2_put_keycode(s, 0xb8);
 367                    ps2_put_keycode(s, 0x38);
 368                }
 369            } else if (s->modifiers & MOD_ALT_R) {
 370                if (key->down) {
 371                    ps2_put_keycode(s, 0xe0);
 372                    ps2_put_keycode(s, 0xb8);
 373                    ps2_put_keycode(s, 0xe0);
 374                    ps2_put_keycode(s, 0x38);
 375                    ps2_put_keycode(s, 0x54);
 376                } else {
 377                    ps2_put_keycode(s, 0xd4);
 378                    ps2_put_keycode(s, 0xe0);
 379                    ps2_put_keycode(s, 0xb8);
 380                    ps2_put_keycode(s, 0xe0);
 381                    ps2_put_keycode(s, 0x38);
 382                }
 383            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 384                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 385                if (key->down) {
 386                    ps2_put_keycode(s, 0xe0);
 387                    ps2_put_keycode(s, 0x37);
 388                } else {
 389                    ps2_put_keycode(s, 0xe0);
 390                    ps2_put_keycode(s, 0xb7);
 391                }
 392            } else {
 393                if (key->down) {
 394                    ps2_put_keycode(s, 0xe0);
 395                    ps2_put_keycode(s, 0x2a);
 396                    ps2_put_keycode(s, 0xe0);
 397                    ps2_put_keycode(s, 0x37);
 398                } else {
 399                    ps2_put_keycode(s, 0xe0);
 400                    ps2_put_keycode(s, 0xb7);
 401                    ps2_put_keycode(s, 0xe0);
 402                    ps2_put_keycode(s, 0xaa);
 403                }
 404            }
 405        } else if ((qcode == Q_KEY_CODE_LANG1 || qcode == Q_KEY_CODE_LANG2)
 406                   && !key->down) {
 407            /* Ignore release for these keys */
 408        } else {
 409            if (qcode < qemu_input_map_qcode_to_atset1_len) {
 410                keycode = qemu_input_map_qcode_to_atset1[qcode];
 411            }
 412            if (keycode) {
 413                if (keycode & 0xff00) {
 414                    ps2_put_keycode(s, keycode >> 8);
 415                }
 416                if (!key->down) {
 417                    keycode |= 0x80;
 418                }
 419                ps2_put_keycode(s, keycode & 0xff);
 420            } else {
 421                qemu_log_mask(LOG_UNIMP,
 422                              "ps2: ignoring key with qcode %d\n", qcode);
 423            }
 424        }
 425    } else if (s->scancode_set == 2) {
 426        if (qcode == Q_KEY_CODE_PAUSE) {
 427            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 428                if (key->down) {
 429                    ps2_put_keycode(s, 0xe0);
 430                    ps2_put_keycode(s, 0x7e);
 431                    ps2_put_keycode(s, 0xe0);
 432                    ps2_put_keycode(s, 0xf0);
 433                    ps2_put_keycode(s, 0x7e);
 434                }
 435            } else {
 436                if (key->down) {
 437                    ps2_put_keycode(s, 0xe1);
 438                    ps2_put_keycode(s, 0x14);
 439                    ps2_put_keycode(s, 0x77);
 440                    ps2_put_keycode(s, 0xe1);
 441                    ps2_put_keycode(s, 0xf0);
 442                    ps2_put_keycode(s, 0x14);
 443                    ps2_put_keycode(s, 0xf0);
 444                    ps2_put_keycode(s, 0x77);
 445                }
 446            }
 447        } else if (qcode == Q_KEY_CODE_PRINT) {
 448            if (s->modifiers & MOD_ALT_L) {
 449                if (key->down) {
 450                    ps2_put_keycode(s, 0xf0);
 451                    ps2_put_keycode(s, 0x11);
 452                    ps2_put_keycode(s, 0x11);
 453                    ps2_put_keycode(s, 0x84);
 454                } else {
 455                    ps2_put_keycode(s, 0xf0);
 456                    ps2_put_keycode(s, 0x84);
 457                    ps2_put_keycode(s, 0xf0);
 458                    ps2_put_keycode(s, 0x11);
 459                    ps2_put_keycode(s, 0x11);
 460                }
 461            } else if (s->modifiers & MOD_ALT_R) {
 462                if (key->down) {
 463                    ps2_put_keycode(s, 0xe0);
 464                    ps2_put_keycode(s, 0xf0);
 465                    ps2_put_keycode(s, 0x11);
 466                    ps2_put_keycode(s, 0xe0);
 467                    ps2_put_keycode(s, 0x11);
 468                    ps2_put_keycode(s, 0x84);
 469                } else {
 470                    ps2_put_keycode(s, 0xf0);
 471                    ps2_put_keycode(s, 0x84);
 472                    ps2_put_keycode(s, 0xe0);
 473                    ps2_put_keycode(s, 0xf0);
 474                    ps2_put_keycode(s, 0x11);
 475                    ps2_put_keycode(s, 0xe0);
 476                    ps2_put_keycode(s, 0x11);
 477                }
 478            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 479                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 480                if (key->down) {
 481                    ps2_put_keycode(s, 0xe0);
 482                    ps2_put_keycode(s, 0x7c);
 483                } else {
 484                    ps2_put_keycode(s, 0xe0);
 485                    ps2_put_keycode(s, 0xf0);
 486                    ps2_put_keycode(s, 0x7c);
 487                }
 488            } else {
 489                if (key->down) {
 490                    ps2_put_keycode(s, 0xe0);
 491                    ps2_put_keycode(s, 0x12);
 492                    ps2_put_keycode(s, 0xe0);
 493                    ps2_put_keycode(s, 0x7c);
 494                } else {
 495                    ps2_put_keycode(s, 0xe0);
 496                    ps2_put_keycode(s, 0xf0);
 497                    ps2_put_keycode(s, 0x7c);
 498                    ps2_put_keycode(s, 0xe0);
 499                    ps2_put_keycode(s, 0xf0);
 500                    ps2_put_keycode(s, 0x12);
 501                }
 502            }
 503        } else if ((qcode == Q_KEY_CODE_LANG1 || qcode == Q_KEY_CODE_LANG2) &&
 504                   !key->down) {
 505            /* Ignore release for these keys */
 506        } else {
 507            if (qcode < qemu_input_map_qcode_to_atset2_len) {
 508                keycode = qemu_input_map_qcode_to_atset2[qcode];
 509            }
 510            if (keycode) {
 511                if (keycode & 0xff00) {
 512                    ps2_put_keycode(s, keycode >> 8);
 513                }
 514                if (!key->down) {
 515                    ps2_put_keycode(s, 0xf0);
 516                }
 517                ps2_put_keycode(s, keycode & 0xff);
 518            } else {
 519                qemu_log_mask(LOG_UNIMP,
 520                              "ps2: ignoring key with qcode %d\n", qcode);
 521            }
 522        }
 523    } else if (s->scancode_set == 3) {
 524        if (qcode < qemu_input_map_qcode_to_atset3_len) {
 525            keycode = qemu_input_map_qcode_to_atset3[qcode];
 526        }
 527        if (keycode) {
 528            /* FIXME: break code should be configured on a key by key basis */
 529            if (!key->down) {
 530                ps2_put_keycode(s, 0xf0);
 531            }
 532            ps2_put_keycode(s, keycode);
 533        } else {
 534            qemu_log_mask(LOG_UNIMP,
 535                          "ps2: ignoring key with qcode %d\n", qcode);
 536        }
 537    }
 538}
 539
 540uint32_t ps2_read_data(PS2State *s)
 541{
 542    PS2Queue *q;
 543    int val, index;
 544
 545    trace_ps2_read_data(s);
 546    q = &s->queue;
 547    if (q->count == 0) {
 548        /*
 549         * NOTE: if no data left, we return the last keyboard one
 550         * (needed for EMM386)
 551         */
 552        /* XXX: need a timer to do things correctly */
 553        index = q->rptr - 1;
 554        if (index < 0) {
 555            index = PS2_BUFFER_SIZE - 1;
 556        }
 557        val = q->data[index];
 558    } else {
 559        val = q->data[q->rptr];
 560        if (++q->rptr == PS2_BUFFER_SIZE) {
 561            q->rptr = 0;
 562        }
 563        q->count--;
 564        if (q->rptr == q->cwptr) {
 565            /* command reply queue is empty */
 566            q->cwptr = -1;
 567        }
 568        /* reading deasserts IRQ */
 569        ps2_lower_irq(s);
 570        /* reassert IRQs if data left */
 571        if (q->count) {
 572            ps2_raise_irq(s);
 573        }
 574    }
 575    return val;
 576}
 577
 578static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
 579{
 580    trace_ps2_set_ledstate(s, ledstate);
 581    s->ledstate = ledstate;
 582    kbd_put_ledstate(ledstate);
 583}
 584
 585static void ps2_reset_keyboard(PS2KbdState *s)
 586{
 587    PS2State *ps2 = PS2_DEVICE(s);
 588
 589    trace_ps2_reset_keyboard(s);
 590    s->scan_enabled = 1;
 591    s->scancode_set = 2;
 592    ps2_reset_queue(ps2);
 593    ps2_set_ledstate(s, 0);
 594}
 595
 596void ps2_write_keyboard(PS2KbdState *s, int val)
 597{
 598    PS2State *ps2 = PS2_DEVICE(s);
 599
 600    trace_ps2_write_keyboard(s, val);
 601    ps2_cqueue_reset(ps2);
 602    switch (ps2->write_cmd) {
 603    default:
 604    case -1:
 605        switch (val) {
 606        case 0x00:
 607            ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 608            break;
 609        case 0x05:
 610            ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
 611            break;
 612        case KBD_CMD_GET_ID:
 613            /* We emulate a MF2 AT keyboard here */
 614            ps2_cqueue_3(ps2, KBD_REPLY_ACK, KBD_REPLY_ID,
 615                         s->translate ? 0x41 : 0x83);
 616            break;
 617        case KBD_CMD_ECHO:
 618            ps2_cqueue_1(ps2, KBD_CMD_ECHO);
 619            break;
 620        case KBD_CMD_ENABLE:
 621            s->scan_enabled = 1;
 622            ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 623            break;
 624        case KBD_CMD_SCANCODE:
 625        case KBD_CMD_SET_LEDS:
 626        case KBD_CMD_SET_RATE:
 627        case KBD_CMD_SET_MAKE_BREAK:
 628            ps2->write_cmd = val;
 629            ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 630            break;
 631        case KBD_CMD_RESET_DISABLE:
 632            ps2_reset_keyboard(s);
 633            s->scan_enabled = 0;
 634            ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 635            break;
 636        case KBD_CMD_RESET_ENABLE:
 637            ps2_reset_keyboard(s);
 638            s->scan_enabled = 1;
 639            ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 640            break;
 641        case KBD_CMD_RESET:
 642            ps2_reset_keyboard(s);
 643            ps2_cqueue_2(ps2,
 644                         KBD_REPLY_ACK,
 645                         KBD_REPLY_POR);
 646            break;
 647        case KBD_CMD_SET_TYPEMATIC:
 648            ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 649            break;
 650        default:
 651            ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
 652            break;
 653        }
 654        break;
 655    case KBD_CMD_SET_MAKE_BREAK:
 656        ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 657        ps2->write_cmd = -1;
 658        break;
 659    case KBD_CMD_SCANCODE:
 660        if (val == 0) {
 661            ps2_cqueue_2(ps2, KBD_REPLY_ACK, s->translate ?
 662                translate_table[s->scancode_set] : s->scancode_set);
 663        } else if (val >= 1 && val <= 3) {
 664            s->scancode_set = val;
 665            ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 666        } else {
 667            ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
 668        }
 669        ps2->write_cmd = -1;
 670        break;
 671    case KBD_CMD_SET_LEDS:
 672        ps2_set_ledstate(s, val);
 673        ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 674        ps2->write_cmd = -1;
 675        break;
 676    case KBD_CMD_SET_RATE:
 677        ps2_cqueue_1(ps2, KBD_REPLY_ACK);
 678        ps2->write_cmd = -1;
 679        break;
 680    }
 681}
 682
 683/*
 684 * Set the scancode translation mode.
 685 * 0 = raw scancodes.
 686 * 1 = translated scancodes (used by qemu internally).
 687 */
 688
 689void ps2_keyboard_set_translation(PS2KbdState *s, int mode)
 690{
 691    trace_ps2_keyboard_set_translation(s, mode);
 692    s->translate = mode;
 693}
 694
 695static int ps2_mouse_send_packet(PS2MouseState *s)
 696{
 697    PS2State *ps2 = PS2_DEVICE(s);
 698    /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
 699    const int needed = s->mouse_type ? 4 : 3;
 700    unsigned int b;
 701    int dx1, dy1, dz1, dw1;
 702
 703    if (PS2_QUEUE_SIZE - ps2->queue.count < needed) {
 704        return 0;
 705    }
 706
 707    dx1 = s->mouse_dx;
 708    dy1 = s->mouse_dy;
 709    dz1 = s->mouse_dz;
 710    dw1 = s->mouse_dw;
 711    /* XXX: increase range to 8 bits ? */
 712    if (dx1 > 127) {
 713        dx1 = 127;
 714    } else if (dx1 < -127) {
 715        dx1 = -127;
 716    }
 717    if (dy1 > 127) {
 718        dy1 = 127;
 719    } else if (dy1 < -127) {
 720        dy1 = -127;
 721    }
 722    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
 723    ps2_queue_noirq(ps2, b);
 724    ps2_queue_noirq(ps2, dx1 & 0xff);
 725    ps2_queue_noirq(ps2, dy1 & 0xff);
 726    /* extra byte for IMPS/2 or IMEX */
 727    switch (s->mouse_type) {
 728    default:
 729        /* Just ignore the wheels if not supported */
 730        s->mouse_dz = 0;
 731        s->mouse_dw = 0;
 732        break;
 733    case 3:
 734        if (dz1 > 127) {
 735            dz1 = 127;
 736        } else if (dz1 < -127) {
 737            dz1 = -127;
 738        }
 739        ps2_queue_noirq(ps2, dz1 & 0xff);
 740        s->mouse_dz -= dz1;
 741        s->mouse_dw = 0;
 742        break;
 743    case 4:
 744        /*
 745         * This matches what the Linux kernel expects for exps/2 in
 746         * drivers/input/mouse/psmouse-base.c. Note, if you happen to
 747         * press/release the 4th or 5th buttons at the same moment as a
 748         * horizontal wheel scroll, those button presses will get lost. I'm not
 749         * sure what to do about that, since by this point we don't know
 750         * whether those buttons actually changed state.
 751         */
 752        if (dw1 != 0) {
 753            if (dw1 > 31) {
 754                dw1 = 31;
 755            } else if (dw1 < -31) {
 756                dw1 = -31;
 757            }
 758
 759            /*
 760             * linux kernel expects first 6 bits to represent the value
 761             * for horizontal scroll
 762             */
 763            b = (dw1 & 0x3f) | 0x40;
 764            s->mouse_dw -= dw1;
 765        } else {
 766            if (dz1 > 7) {
 767                dz1 = 7;
 768            } else if (dz1 < -7) {
 769                dz1 = -7;
 770            }
 771
 772            b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
 773            s->mouse_dz -= dz1;
 774        }
 775        ps2_queue_noirq(ps2, b);
 776        break;
 777    }
 778
 779    ps2_raise_irq(ps2);
 780
 781    trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
 782    /* update deltas */
 783    s->mouse_dx -= dx1;
 784    s->mouse_dy -= dy1;
 785
 786    return 1;
 787}
 788
 789static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
 790                            InputEvent *evt)
 791{
 792    static const int bmap[INPUT_BUTTON__MAX] = {
 793        [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
 794        [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
 795        [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
 796        [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
 797        [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
 798    };
 799    PS2MouseState *s = (PS2MouseState *)dev;
 800    InputMoveEvent *move;
 801    InputBtnEvent *btn;
 802
 803    /* check if deltas are recorded when disabled */
 804    if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
 805        return;
 806    }
 807
 808    switch (evt->type) {
 809    case INPUT_EVENT_KIND_REL:
 810        move = evt->u.rel.data;
 811        if (move->axis == INPUT_AXIS_X) {
 812            s->mouse_dx += move->value;
 813        } else if (move->axis == INPUT_AXIS_Y) {
 814            s->mouse_dy -= move->value;
 815        }
 816        break;
 817
 818    case INPUT_EVENT_KIND_BTN:
 819        btn = evt->u.btn.data;
 820        if (btn->down) {
 821            s->mouse_buttons |= bmap[btn->button];
 822            if (btn->button == INPUT_BUTTON_WHEEL_UP) {
 823                s->mouse_dz--;
 824            } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 825                s->mouse_dz++;
 826            }
 827
 828            if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
 829                s->mouse_dw--;
 830            } else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) {
 831                s->mouse_dw++;
 832            }
 833        } else {
 834            s->mouse_buttons &= ~bmap[btn->button];
 835        }
 836        break;
 837
 838    default:
 839        /* keep gcc happy */
 840        break;
 841    }
 842}
 843
 844static void ps2_mouse_sync(DeviceState *dev)
 845{
 846    PS2MouseState *s = (PS2MouseState *)dev;
 847
 848    /* do not sync while disabled to prevent stream corruption */
 849    if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
 850        return;
 851    }
 852
 853    if (s->mouse_buttons) {
 854        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
 855    }
 856    if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
 857        /*
 858         * if not remote, send event. Multiple events are sent if
 859         * too big deltas
 860         */
 861        while (ps2_mouse_send_packet(s)) {
 862            if (s->mouse_dx == 0 && s->mouse_dy == 0
 863                    && s->mouse_dz == 0 && s->mouse_dw == 0) {
 864                break;
 865            }
 866        }
 867    }
 868}
 869
 870void ps2_mouse_fake_event(PS2MouseState *s)
 871{
 872    trace_ps2_mouse_fake_event(s);
 873    s->mouse_dx++;
 874    ps2_mouse_sync(DEVICE(s));
 875}
 876
 877void ps2_write_mouse(PS2MouseState *s, int val)
 878{
 879    PS2State *ps2 = PS2_DEVICE(s);
 880
 881    trace_ps2_write_mouse(s, val);
 882    switch (ps2->write_cmd) {
 883    default:
 884    case -1:
 885        /* mouse command */
 886        if (s->mouse_wrap) {
 887            if (val == AUX_RESET_WRAP) {
 888                s->mouse_wrap = 0;
 889                ps2_queue(ps2, AUX_ACK);
 890                return;
 891            } else if (val != AUX_RESET) {
 892                ps2_queue(ps2, val);
 893                return;
 894            }
 895        }
 896        switch (val) {
 897        case AUX_SET_SCALE11:
 898            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
 899            ps2_queue(ps2, AUX_ACK);
 900            break;
 901        case AUX_SET_SCALE21:
 902            s->mouse_status |= MOUSE_STATUS_SCALE21;
 903            ps2_queue(ps2, AUX_ACK);
 904            break;
 905        case AUX_SET_STREAM:
 906            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
 907            ps2_queue(ps2, AUX_ACK);
 908            break;
 909        case AUX_SET_WRAP:
 910            s->mouse_wrap = 1;
 911            ps2_queue(ps2, AUX_ACK);
 912            break;
 913        case AUX_SET_REMOTE:
 914            s->mouse_status |= MOUSE_STATUS_REMOTE;
 915            ps2_queue(ps2, AUX_ACK);
 916            break;
 917        case AUX_GET_TYPE:
 918            ps2_queue_2(ps2,
 919                AUX_ACK,
 920                s->mouse_type);
 921            break;
 922        case AUX_SET_RES:
 923        case AUX_SET_SAMPLE:
 924            ps2->write_cmd = val;
 925            ps2_queue(ps2, AUX_ACK);
 926            break;
 927        case AUX_GET_SCALE:
 928            ps2_queue_4(ps2,
 929                AUX_ACK,
 930                s->mouse_status,
 931                s->mouse_resolution,
 932                s->mouse_sample_rate);
 933            break;
 934        case AUX_POLL:
 935            ps2_queue(ps2, AUX_ACK);
 936            ps2_mouse_send_packet(s);
 937            break;
 938        case AUX_ENABLE_DEV:
 939            s->mouse_status |= MOUSE_STATUS_ENABLED;
 940            ps2_queue(ps2, AUX_ACK);
 941            break;
 942        case AUX_DISABLE_DEV:
 943            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
 944            ps2_queue(ps2, AUX_ACK);
 945            break;
 946        case AUX_SET_DEFAULT:
 947            s->mouse_sample_rate = 100;
 948            s->mouse_resolution = 2;
 949            s->mouse_status = 0;
 950            ps2_queue(ps2, AUX_ACK);
 951            break;
 952        case AUX_RESET:
 953            s->mouse_sample_rate = 100;
 954            s->mouse_resolution = 2;
 955            s->mouse_status = 0;
 956            s->mouse_type = 0;
 957            ps2_reset_queue(ps2);
 958            ps2_queue_3(ps2,
 959                AUX_ACK,
 960                0xaa,
 961                s->mouse_type);
 962            break;
 963        default:
 964            break;
 965        }
 966        break;
 967    case AUX_SET_SAMPLE:
 968        s->mouse_sample_rate = val;
 969        /* detect IMPS/2 or IMEX */
 970        switch (s->mouse_detect_state) {
 971        default:
 972        case 0:
 973            if (val == 200) {
 974                s->mouse_detect_state = 1;
 975            }
 976            break;
 977        case 1:
 978            if (val == 100) {
 979                s->mouse_detect_state = 2;
 980            } else if (val == 200) {
 981                s->mouse_detect_state = 3;
 982            } else {
 983                s->mouse_detect_state = 0;
 984            }
 985            break;
 986        case 2:
 987            if (val == 80) {
 988                s->mouse_type = 3; /* IMPS/2 */
 989            }
 990            s->mouse_detect_state = 0;
 991            break;
 992        case 3:
 993            if (val == 80) {
 994                s->mouse_type = 4; /* IMEX */
 995            }
 996            s->mouse_detect_state = 0;
 997            break;
 998        }
 999        ps2_queue(ps2, AUX_ACK);
1000        ps2->write_cmd = -1;
1001        break;
1002    case AUX_SET_RES:
1003        s->mouse_resolution = val;
1004        ps2_queue(ps2, AUX_ACK);
1005        ps2->write_cmd = -1;
1006        break;
1007    }
1008}
1009
1010static void ps2_reset_hold(Object *obj)
1011{
1012    PS2State *s = PS2_DEVICE(obj);
1013
1014    s->write_cmd = -1;
1015    ps2_reset_queue(s);
1016}
1017
1018static void ps2_reset_exit(Object *obj)
1019{
1020    PS2State *s = PS2_DEVICE(obj);
1021
1022    ps2_lower_irq(s);
1023}
1024
1025static void ps2_common_post_load(PS2State *s)
1026{
1027    PS2Queue *q = &s->queue;
1028    int ccount = 0;
1029
1030    /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */
1031    if (q->cwptr != -1) {
1032        ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
1033        if (ccount > PS2_QUEUE_HEADROOM) {
1034            ccount = PS2_QUEUE_HEADROOM;
1035        }
1036    }
1037
1038    /* limit the scancode queue size to PS2_QUEUE_SIZE */
1039    if (q->count < ccount) {
1040        q->count = ccount;
1041    } else if (q->count > ccount + PS2_QUEUE_SIZE) {
1042        q->count = ccount + PS2_QUEUE_SIZE;
1043    }
1044
1045    /* sanitize rptr and recalculate wptr and cwptr */
1046    q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
1047    q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
1048    q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1;
1049}
1050
1051static void ps2_kbd_reset_hold(Object *obj)
1052{
1053    PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(obj);
1054    PS2KbdState *s = PS2_KBD_DEVICE(obj);
1055
1056    trace_ps2_kbd_reset(s);
1057
1058    if (ps2dc->parent_phases.hold) {
1059        ps2dc->parent_phases.hold(obj);
1060    }
1061
1062    s->scan_enabled = 1;
1063    s->translate = 0;
1064    s->scancode_set = 2;
1065    s->modifiers = 0;
1066}
1067
1068static void ps2_mouse_reset_hold(Object *obj)
1069{
1070    PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(obj);
1071    PS2MouseState *s = PS2_MOUSE_DEVICE(obj);
1072
1073    trace_ps2_mouse_reset(s);
1074
1075    if (ps2dc->parent_phases.hold) {
1076        ps2dc->parent_phases.hold(obj);
1077    }
1078
1079    s->mouse_status = 0;
1080    s->mouse_resolution = 0;
1081    s->mouse_sample_rate = 0;
1082    s->mouse_wrap = 0;
1083    s->mouse_type = 0;
1084    s->mouse_detect_state = 0;
1085    s->mouse_dx = 0;
1086    s->mouse_dy = 0;
1087    s->mouse_dz = 0;
1088    s->mouse_dw = 0;
1089    s->mouse_buttons = 0;
1090}
1091
1092static const VMStateDescription vmstate_ps2_common = {
1093    .name = "PS2 Common State",
1094    .version_id = 3,
1095    .minimum_version_id = 2,
1096    .fields = (VMStateField[]) {
1097        VMSTATE_INT32(write_cmd, PS2State),
1098        VMSTATE_INT32(queue.rptr, PS2State),
1099        VMSTATE_INT32(queue.wptr, PS2State),
1100        VMSTATE_INT32(queue.count, PS2State),
1101        VMSTATE_BUFFER(queue.data, PS2State),
1102        VMSTATE_END_OF_LIST()
1103    }
1104};
1105
1106static bool ps2_keyboard_ledstate_needed(void *opaque)
1107{
1108    PS2KbdState *s = opaque;
1109
1110    return s->ledstate != 0; /* 0 is default state */
1111}
1112
1113static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1114{
1115    PS2KbdState *s = opaque;
1116
1117    kbd_put_ledstate(s->ledstate);
1118    return 0;
1119}
1120
1121static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1122    .name = "ps2kbd/ledstate",
1123    .version_id = 3,
1124    .minimum_version_id = 2,
1125    .post_load = ps2_kbd_ledstate_post_load,
1126    .needed = ps2_keyboard_ledstate_needed,
1127    .fields = (VMStateField[]) {
1128        VMSTATE_INT32(ledstate, PS2KbdState),
1129        VMSTATE_END_OF_LIST()
1130    }
1131};
1132
1133static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1134{
1135    PS2KbdState *s = opaque;
1136    return s->need_high_bit != 0; /* 0 is the usual state */
1137}
1138
1139static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1140    .name = "ps2kbd/need_high_bit",
1141    .version_id = 1,
1142    .minimum_version_id = 1,
1143    .needed = ps2_keyboard_need_high_bit_needed,
1144    .fields = (VMStateField[]) {
1145        VMSTATE_BOOL(need_high_bit, PS2KbdState),
1146        VMSTATE_END_OF_LIST()
1147    }
1148};
1149
1150static bool ps2_keyboard_cqueue_needed(void *opaque)
1151{
1152    PS2KbdState *s = opaque;
1153    PS2State *ps2 = PS2_DEVICE(s);
1154
1155    return ps2->queue.cwptr != -1; /* the queue is mostly empty */
1156}
1157
1158static const VMStateDescription vmstate_ps2_keyboard_cqueue = {
1159    .name = "ps2kbd/command_reply_queue",
1160    .needed = ps2_keyboard_cqueue_needed,
1161    .fields = (VMStateField[]) {
1162        VMSTATE_INT32(parent_obj.queue.cwptr, PS2KbdState),
1163        VMSTATE_END_OF_LIST()
1164    }
1165};
1166
1167static int ps2_kbd_post_load(void *opaque, int version_id)
1168{
1169    PS2KbdState *s = (PS2KbdState *)opaque;
1170    PS2State *ps2 = PS2_DEVICE(s);
1171
1172    if (version_id == 2) {
1173        s->scancode_set = 2;
1174    }
1175
1176    ps2_common_post_load(ps2);
1177
1178    return 0;
1179}
1180
1181static const VMStateDescription vmstate_ps2_keyboard = {
1182    .name = "ps2kbd",
1183    .version_id = 3,
1184    .minimum_version_id = 2,
1185    .post_load = ps2_kbd_post_load,
1186    .fields = (VMStateField[]) {
1187        VMSTATE_STRUCT(parent_obj, PS2KbdState, 0, vmstate_ps2_common,
1188                       PS2State),
1189        VMSTATE_INT32(scan_enabled, PS2KbdState),
1190        VMSTATE_INT32(translate, PS2KbdState),
1191        VMSTATE_INT32_V(scancode_set, PS2KbdState, 3),
1192        VMSTATE_END_OF_LIST()
1193    },
1194    .subsections = (const VMStateDescription * []) {
1195        &vmstate_ps2_keyboard_ledstate,
1196        &vmstate_ps2_keyboard_need_high_bit,
1197        &vmstate_ps2_keyboard_cqueue,
1198        NULL
1199    }
1200};
1201
1202static int ps2_mouse_post_load(void *opaque, int version_id)
1203{
1204    PS2MouseState *s = (PS2MouseState *)opaque;
1205    PS2State *ps2 = PS2_DEVICE(s);
1206
1207    ps2_common_post_load(ps2);
1208
1209    return 0;
1210}
1211
1212static const VMStateDescription vmstate_ps2_mouse = {
1213    .name = "ps2mouse",
1214    .version_id = 2,
1215    .minimum_version_id = 2,
1216    .post_load = ps2_mouse_post_load,
1217    .fields = (VMStateField[]) {
1218        VMSTATE_STRUCT(parent_obj, PS2MouseState, 0, vmstate_ps2_common,
1219                       PS2State),
1220        VMSTATE_UINT8(mouse_status, PS2MouseState),
1221        VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1222        VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1223        VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1224        VMSTATE_UINT8(mouse_type, PS2MouseState),
1225        VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1226        VMSTATE_INT32(mouse_dx, PS2MouseState),
1227        VMSTATE_INT32(mouse_dy, PS2MouseState),
1228        VMSTATE_INT32(mouse_dz, PS2MouseState),
1229        VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1230        VMSTATE_END_OF_LIST()
1231    }
1232};
1233
1234static QemuInputHandler ps2_keyboard_handler = {
1235    .name  = "QEMU PS/2 Keyboard",
1236    .mask  = INPUT_EVENT_MASK_KEY,
1237    .event = ps2_keyboard_event,
1238};
1239
1240static void ps2_kbd_realize(DeviceState *dev, Error **errp)
1241{
1242    qemu_input_handler_register(dev, &ps2_keyboard_handler);
1243}
1244
1245static QemuInputHandler ps2_mouse_handler = {
1246    .name  = "QEMU PS/2 Mouse",
1247    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1248    .event = ps2_mouse_event,
1249    .sync  = ps2_mouse_sync,
1250};
1251
1252static void ps2_mouse_realize(DeviceState *dev, Error **errp)
1253{
1254    qemu_input_handler_register(dev, &ps2_mouse_handler);
1255}
1256
1257static void ps2_kbd_class_init(ObjectClass *klass, void *data)
1258{
1259    DeviceClass *dc = DEVICE_CLASS(klass);
1260    ResettableClass *rc = RESETTABLE_CLASS(klass);
1261    PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass);
1262
1263    dc->realize = ps2_kbd_realize;
1264    resettable_class_set_parent_phases(rc, NULL, ps2_kbd_reset_hold, NULL,
1265                                       &ps2dc->parent_phases);
1266    dc->vmsd = &vmstate_ps2_keyboard;
1267}
1268
1269static const TypeInfo ps2_kbd_info = {
1270    .name          = TYPE_PS2_KBD_DEVICE,
1271    .parent        = TYPE_PS2_DEVICE,
1272    .instance_size = sizeof(PS2KbdState),
1273    .class_init    = ps2_kbd_class_init
1274};
1275
1276static void ps2_mouse_class_init(ObjectClass *klass, void *data)
1277{
1278    DeviceClass *dc = DEVICE_CLASS(klass);
1279    ResettableClass *rc = RESETTABLE_CLASS(klass);
1280    PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass);
1281
1282    dc->realize = ps2_mouse_realize;
1283    resettable_class_set_parent_phases(rc, NULL, ps2_mouse_reset_hold, NULL,
1284                                       &ps2dc->parent_phases);
1285    dc->vmsd = &vmstate_ps2_mouse;
1286}
1287
1288static const TypeInfo ps2_mouse_info = {
1289    .name          = TYPE_PS2_MOUSE_DEVICE,
1290    .parent        = TYPE_PS2_DEVICE,
1291    .instance_size = sizeof(PS2MouseState),
1292    .class_init    = ps2_mouse_class_init
1293};
1294
1295static void ps2_init(Object *obj)
1296{
1297    PS2State *s = PS2_DEVICE(obj);
1298
1299    qdev_init_gpio_out(DEVICE(obj), &s->irq, 1);
1300}
1301
1302static void ps2_class_init(ObjectClass *klass, void *data)
1303{
1304    DeviceClass *dc = DEVICE_CLASS(klass);
1305    ResettableClass *rc = RESETTABLE_CLASS(klass);
1306
1307    rc->phases.hold = ps2_reset_hold;
1308    rc->phases.exit = ps2_reset_exit;
1309    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1310}
1311
1312static const TypeInfo ps2_info = {
1313    .name          = TYPE_PS2_DEVICE,
1314    .parent        = TYPE_SYS_BUS_DEVICE,
1315    .instance_init = ps2_init,
1316    .instance_size = sizeof(PS2State),
1317    .class_init    = ps2_class_init,
1318    .class_size    = sizeof(PS2DeviceClass),
1319    .abstract      = true
1320};
1321
1322static void ps2_register_types(void)
1323{
1324    type_register_static(&ps2_info);
1325    type_register_static(&ps2_kbd_info);
1326    type_register_static(&ps2_mouse_info);
1327}
1328
1329type_init(ps2_register_types)
1330