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