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