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
  88struct PS2State {
  89    PS2Queue queue;
  90    int32_t write_cmd;
  91    void (*update_irq)(void *, int);
  92    void *update_arg;
  93};
  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    [Q_KEY_CODE_POWER] = 0x0e5e,
 228    [Q_KEY_CODE_SLEEP] = 0x0e5f,
 229    [Q_KEY_CODE_WAKE] = 0x0e63,
 230
 231    [Q_KEY_CODE_AUDIONEXT] = 0xe019,
 232    [Q_KEY_CODE_AUDIOPREV] = 0xe010,
 233    [Q_KEY_CODE_AUDIOSTOP] = 0xe024,
 234    [Q_KEY_CODE_AUDIOPLAY] = 0xe022,
 235    [Q_KEY_CODE_AUDIOMUTE] = 0xe020,
 236    [Q_KEY_CODE_VOLUMEUP] = 0xe030,
 237    [Q_KEY_CODE_VOLUMEDOWN] = 0xe02e,
 238    [Q_KEY_CODE_MEDIASELECT] = 0xe06d,
 239    [Q_KEY_CODE_MAIL] = 0xe06c,
 240    [Q_KEY_CODE_CALCULATOR] = 0xe021,
 241    [Q_KEY_CODE_COMPUTER] = 0xe06b,
 242    [Q_KEY_CODE_FIND] = 0xe065,
 243    [Q_KEY_CODE_AC_HOME] = 0xe032,
 244    [Q_KEY_CODE_AC_BACK] = 0xe06a,
 245    [Q_KEY_CODE_AC_FORWARD] = 0xe069,
 246    [Q_KEY_CODE_STOP] = 0xe068,
 247    [Q_KEY_CODE_AC_REFRESH] = 0xe067,
 248    [Q_KEY_CODE_AC_BOOKMARKS] = 0xe066,
 249
 250    [Q_KEY_CODE_ASTERISK] = 0x37,
 251    [Q_KEY_CODE_LESS] = 0x56,
 252    [Q_KEY_CODE_RO] = 0x73,
 253    [Q_KEY_CODE_HIRAGANA] = 0x70,
 254    [Q_KEY_CODE_HENKAN] = 0x79,
 255    [Q_KEY_CODE_YEN] = 0x7d,
 256    [Q_KEY_CODE_KP_COMMA] = 0x7e,
 257};
 258
 259static const uint16_t qcode_to_keycode_set2[Q_KEY_CODE__MAX] = {
 260    [0 ... Q_KEY_CODE__MAX - 1] = 0,
 261
 262    [Q_KEY_CODE_A] = 0x1c,
 263    [Q_KEY_CODE_B] = 0x32,
 264    [Q_KEY_CODE_C] = 0x21,
 265    [Q_KEY_CODE_D] = 0x23,
 266    [Q_KEY_CODE_E] = 0x24,
 267    [Q_KEY_CODE_F] = 0x2b,
 268    [Q_KEY_CODE_G] = 0x34,
 269    [Q_KEY_CODE_H] = 0x33,
 270    [Q_KEY_CODE_I] = 0x43,
 271    [Q_KEY_CODE_J] = 0x3b,
 272    [Q_KEY_CODE_K] = 0x42,
 273    [Q_KEY_CODE_L] = 0x4b,
 274    [Q_KEY_CODE_M] = 0x3a,
 275    [Q_KEY_CODE_N] = 0x31,
 276    [Q_KEY_CODE_O] = 0x44,
 277    [Q_KEY_CODE_P] = 0x4d,
 278    [Q_KEY_CODE_Q] = 0x15,
 279    [Q_KEY_CODE_R] = 0x2d,
 280    [Q_KEY_CODE_S] = 0x1b,
 281    [Q_KEY_CODE_T] = 0x2c,
 282    [Q_KEY_CODE_U] = 0x3c,
 283    [Q_KEY_CODE_V] = 0x2a,
 284    [Q_KEY_CODE_W] = 0x1d,
 285    [Q_KEY_CODE_X] = 0x22,
 286    [Q_KEY_CODE_Y] = 0x35,
 287    [Q_KEY_CODE_Z] = 0x1a,
 288    [Q_KEY_CODE_0] = 0x45,
 289    [Q_KEY_CODE_1] = 0x16,
 290    [Q_KEY_CODE_2] = 0x1e,
 291    [Q_KEY_CODE_3] = 0x26,
 292    [Q_KEY_CODE_4] = 0x25,
 293    [Q_KEY_CODE_5] = 0x2e,
 294    [Q_KEY_CODE_6] = 0x36,
 295    [Q_KEY_CODE_7] = 0x3d,
 296    [Q_KEY_CODE_8] = 0x3e,
 297    [Q_KEY_CODE_9] = 0x46,
 298    [Q_KEY_CODE_GRAVE_ACCENT] = 0x0e,
 299    [Q_KEY_CODE_MINUS] = 0x4e,
 300    [Q_KEY_CODE_EQUAL] = 0x55,
 301    [Q_KEY_CODE_BACKSLASH] = 0x5d,
 302    [Q_KEY_CODE_BACKSPACE] = 0x66,
 303    [Q_KEY_CODE_SPC] = 0x29,
 304    [Q_KEY_CODE_TAB] = 0x0d,
 305    [Q_KEY_CODE_CAPS_LOCK] = 0x58,
 306    [Q_KEY_CODE_SHIFT] = 0x12,
 307    [Q_KEY_CODE_CTRL] = 0x14,
 308    [Q_KEY_CODE_META_L] = 0xe01f,
 309    [Q_KEY_CODE_ALT] = 0x11,
 310    [Q_KEY_CODE_SHIFT_R] = 0x59,
 311    [Q_KEY_CODE_CTRL_R] = 0xe014,
 312    [Q_KEY_CODE_META_R] = 0xe027,
 313    [Q_KEY_CODE_ALT_R] = 0xe011,
 314    [Q_KEY_CODE_MENU] = 0xe02f,
 315    [Q_KEY_CODE_RET] = 0x5a,
 316    [Q_KEY_CODE_ESC] = 0x76,
 317    [Q_KEY_CODE_F1] = 0x05,
 318    [Q_KEY_CODE_F2] = 0x06,
 319    [Q_KEY_CODE_F3] = 0x04,
 320    [Q_KEY_CODE_F4] = 0x0c,
 321    [Q_KEY_CODE_F5] = 0x03,
 322    [Q_KEY_CODE_F6] = 0x0b,
 323    [Q_KEY_CODE_F7] = 0x83,
 324    [Q_KEY_CODE_F8] = 0x0a,
 325    [Q_KEY_CODE_F9] = 0x01,
 326    [Q_KEY_CODE_F10] = 0x09,
 327    [Q_KEY_CODE_F11] = 0x78,
 328    [Q_KEY_CODE_F12] = 0x07,
 329    /* special handling for Q_KEY_CODE_PRINT */
 330    [Q_KEY_CODE_SCROLL_LOCK] = 0x7e,
 331    /* special handling for Q_KEY_CODE_PAUSE */
 332    [Q_KEY_CODE_BRACKET_LEFT] = 0x54,
 333    [Q_KEY_CODE_INSERT] = 0xe070,
 334    [Q_KEY_CODE_HOME] = 0xe06c,
 335    [Q_KEY_CODE_PGUP] = 0xe07d,
 336    [Q_KEY_CODE_DELETE] = 0xe071,
 337    [Q_KEY_CODE_END] = 0xe069,
 338    [Q_KEY_CODE_PGDN] = 0xe07a,
 339    [Q_KEY_CODE_UP] = 0xe075,
 340    [Q_KEY_CODE_LEFT] = 0xe06b,
 341    [Q_KEY_CODE_DOWN] = 0xe072,
 342    [Q_KEY_CODE_RIGHT] = 0xe074,
 343    [Q_KEY_CODE_NUM_LOCK] = 0x77,
 344    [Q_KEY_CODE_KP_DIVIDE] = 0xe04a,
 345    [Q_KEY_CODE_KP_MULTIPLY] = 0x7c,
 346    [Q_KEY_CODE_KP_SUBTRACT] = 0x7b,
 347    [Q_KEY_CODE_KP_ADD] = 0x79,
 348    [Q_KEY_CODE_KP_ENTER] = 0xe05a,
 349    [Q_KEY_CODE_KP_DECIMAL] = 0x71,
 350    [Q_KEY_CODE_KP_0] = 0x70,
 351    [Q_KEY_CODE_KP_1] = 0x69,
 352    [Q_KEY_CODE_KP_2] = 0x72,
 353    [Q_KEY_CODE_KP_3] = 0x7a,
 354    [Q_KEY_CODE_KP_4] = 0x6b,
 355    [Q_KEY_CODE_KP_5] = 0x73,
 356    [Q_KEY_CODE_KP_6] = 0x74,
 357    [Q_KEY_CODE_KP_7] = 0x6c,
 358    [Q_KEY_CODE_KP_8] = 0x75,
 359    [Q_KEY_CODE_KP_9] = 0x7d,
 360    [Q_KEY_CODE_BRACKET_RIGHT] = 0x5b,
 361    [Q_KEY_CODE_SEMICOLON] = 0x4c,
 362    [Q_KEY_CODE_APOSTROPHE] = 0x52,
 363    [Q_KEY_CODE_COMMA] = 0x41,
 364    [Q_KEY_CODE_DOT] = 0x49,
 365    [Q_KEY_CODE_SLASH] = 0x4a,
 366
 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_FIND] = 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_STOP] = 0xe028,
 387    [Q_KEY_CODE_AC_REFRESH] = 0xe020,
 388    [Q_KEY_CODE_AC_BOOKMARKS] = 0xe018,
 389
 390    [Q_KEY_CODE_ASTERISK] = 0x7c,
 391    [Q_KEY_CODE_LESS] = 0x61,
 392    [Q_KEY_CODE_SYSRQ] = 0x7f,
 393    [Q_KEY_CODE_RO] = 0x51,
 394    [Q_KEY_CODE_HIRAGANA] = 0x13,
 395    [Q_KEY_CODE_HENKAN] = 0x64,
 396    [Q_KEY_CODE_YEN] = 0x6a,
 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    [Q_KEY_CODE_HIRAGANA] = 0x87,
 509    [Q_KEY_CODE_HENKAN] = 0x86,
 510    [Q_KEY_CODE_YEN] = 0x5d,
 511};
 512
 513static uint8_t translate_table[256] = {
 514    0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
 515    0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
 516    0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
 517    0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
 518    0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
 519    0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
 520    0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
 521    0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
 522    0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
 523    0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
 524    0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
 525    0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
 526    0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
 527    0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
 528    0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
 529    0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
 530    0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
 531    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 532    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
 533    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 534    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 535    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 536    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
 537    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 538    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 539    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 540    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 541    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 542    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 543    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 544    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 545    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 546};
 547
 548static void ps2_reset_queue(PS2State *s)
 549{
 550    PS2Queue *q = &s->queue;
 551
 552    q->rptr = 0;
 553    q->wptr = 0;
 554    q->count = 0;
 555}
 556
 557void ps2_queue(PS2State *s, int b)
 558{
 559    PS2Queue *q = &s->queue;
 560
 561    if (q->count >= PS2_QUEUE_SIZE - 1)
 562        return;
 563    q->data[q->wptr] = b;
 564    if (++q->wptr == PS2_QUEUE_SIZE)
 565        q->wptr = 0;
 566    q->count++;
 567    s->update_irq(s->update_arg, 1);
 568}
 569
 570/* keycode is the untranslated scancode in the current scancode set. */
 571static void ps2_put_keycode(void *opaque, int keycode)
 572{
 573    PS2KbdState *s = opaque;
 574
 575    trace_ps2_put_keycode(opaque, keycode);
 576    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 577
 578    if (s->translate) {
 579        if (keycode == 0xf0) {
 580            s->need_high_bit = true;
 581        } else if (s->need_high_bit) {
 582            ps2_queue(&s->common, translate_table[keycode] | 0x80);
 583            s->need_high_bit = false;
 584        } else {
 585            ps2_queue(&s->common, translate_table[keycode]);
 586        }
 587    } else {
 588        ps2_queue(&s->common, keycode);
 589    }
 590}
 591
 592static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
 593                               InputEvent *evt)
 594{
 595    PS2KbdState *s = (PS2KbdState *)dev;
 596    InputKeyEvent *key = evt->u.key.data;
 597    int qcode;
 598    uint16_t keycode;
 599
 600    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 601    assert(evt->type == INPUT_EVENT_KIND_KEY);
 602    qcode = qemu_input_key_value_to_qcode(key->key);
 603
 604    if (s->scancode_set == 1) {
 605        if (qcode == Q_KEY_CODE_PAUSE) {
 606            if (key->down) {
 607                ps2_put_keycode(s, 0xe1);
 608                ps2_put_keycode(s, 0x1d);
 609                ps2_put_keycode(s, 0x45);
 610                ps2_put_keycode(s, 0x91);
 611                ps2_put_keycode(s, 0x9d);
 612                ps2_put_keycode(s, 0xc5);
 613            }
 614        } else if (qcode == Q_KEY_CODE_PRINT) {
 615            if (key->down) {
 616                ps2_put_keycode(s, 0xe0);
 617                ps2_put_keycode(s, 0x2a);
 618                ps2_put_keycode(s, 0xe0);
 619                ps2_put_keycode(s, 0x37);
 620            } else {
 621                ps2_put_keycode(s, 0xe0);
 622                ps2_put_keycode(s, 0xb7);
 623                ps2_put_keycode(s, 0xe0);
 624                ps2_put_keycode(s, 0xaa);
 625            }
 626        } else {
 627            keycode = qcode_to_keycode_set1[qcode];
 628            if (keycode) {
 629                if (keycode & 0xff00) {
 630                    ps2_put_keycode(s, keycode >> 8);
 631                }
 632                if (!key->down) {
 633                    keycode |= 0x80;
 634                }
 635                ps2_put_keycode(s, keycode & 0xff);
 636            } else {
 637                qemu_log_mask(LOG_UNIMP,
 638                              "ps2: ignoring key with qcode %d\n", qcode);
 639            }
 640        }
 641    } else if (s->scancode_set == 2) {
 642        if (qcode == Q_KEY_CODE_PAUSE) {
 643            if (key->down) {
 644                ps2_put_keycode(s, 0xe1);
 645                ps2_put_keycode(s, 0x14);
 646                ps2_put_keycode(s, 0x77);
 647                ps2_put_keycode(s, 0xe1);
 648                ps2_put_keycode(s, 0xf0);
 649                ps2_put_keycode(s, 0x14);
 650                ps2_put_keycode(s, 0xf0);
 651                ps2_put_keycode(s, 0x77);
 652            }
 653        } else if (qcode == Q_KEY_CODE_PRINT) {
 654            if (key->down) {
 655                ps2_put_keycode(s, 0xe0);
 656                ps2_put_keycode(s, 0x12);
 657                ps2_put_keycode(s, 0xe0);
 658                ps2_put_keycode(s, 0x7c);
 659            } else {
 660                ps2_put_keycode(s, 0xe0);
 661                ps2_put_keycode(s, 0xf0);
 662                ps2_put_keycode(s, 0x7c);
 663                ps2_put_keycode(s, 0xe0);
 664                ps2_put_keycode(s, 0xf0);
 665                ps2_put_keycode(s, 0x12);
 666            }
 667        } else {
 668            keycode = qcode_to_keycode_set2[qcode];
 669            if (keycode) {
 670                if (keycode & 0xff00) {
 671                    ps2_put_keycode(s, keycode >> 8);
 672                }
 673                if (!key->down) {
 674                    ps2_put_keycode(s, 0xf0);
 675                }
 676                ps2_put_keycode(s, keycode & 0xff);
 677            } else {
 678                qemu_log_mask(LOG_UNIMP,
 679                              "ps2: ignoring key with qcode %d\n", qcode);
 680            }
 681        }
 682    } else if (s->scancode_set == 3) {
 683        keycode = qcode_to_keycode_set3[qcode];
 684        if (keycode) {
 685            /* FIXME: break code should be configured on a key by key basis */
 686            if (!key->down) {
 687                ps2_put_keycode(s, 0xf0);
 688            }
 689            ps2_put_keycode(s, keycode);
 690        } else {
 691            qemu_log_mask(LOG_UNIMP,
 692                          "ps2: ignoring key with qcode %d\n", qcode);
 693        }
 694    }
 695}
 696
 697uint32_t ps2_read_data(PS2State *s)
 698{
 699    PS2Queue *q;
 700    int val, index;
 701
 702    trace_ps2_read_data(s);
 703    q = &s->queue;
 704    if (q->count == 0) {
 705        /* NOTE: if no data left, we return the last keyboard one
 706           (needed for EMM386) */
 707        /* XXX: need a timer to do things correctly */
 708        index = q->rptr - 1;
 709        if (index < 0)
 710            index = PS2_QUEUE_SIZE - 1;
 711        val = q->data[index];
 712    } else {
 713        val = q->data[q->rptr];
 714        if (++q->rptr == PS2_QUEUE_SIZE)
 715            q->rptr = 0;
 716        q->count--;
 717        /* reading deasserts IRQ */
 718        s->update_irq(s->update_arg, 0);
 719        /* reassert IRQs if data left */
 720        s->update_irq(s->update_arg, q->count != 0);
 721    }
 722    return val;
 723}
 724
 725static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
 726{
 727    trace_ps2_set_ledstate(s, ledstate);
 728    s->ledstate = ledstate;
 729    kbd_put_ledstate(ledstate);
 730}
 731
 732static void ps2_reset_keyboard(PS2KbdState *s)
 733{
 734    trace_ps2_reset_keyboard(s);
 735    s->scan_enabled = 1;
 736    s->scancode_set = 2;
 737    ps2_reset_queue(&s->common);
 738    ps2_set_ledstate(s, 0);
 739}
 740
 741void ps2_write_keyboard(void *opaque, int val)
 742{
 743    PS2KbdState *s = (PS2KbdState *)opaque;
 744
 745    trace_ps2_write_keyboard(opaque, val);
 746    switch(s->common.write_cmd) {
 747    default:
 748    case -1:
 749        switch(val) {
 750        case 0x00:
 751            ps2_queue(&s->common, KBD_REPLY_ACK);
 752            break;
 753        case 0x05:
 754            ps2_queue(&s->common, KBD_REPLY_RESEND);
 755            break;
 756        case KBD_CMD_GET_ID:
 757            ps2_queue(&s->common, KBD_REPLY_ACK);
 758            /* We emulate a MF2 AT keyboard here */
 759            ps2_queue(&s->common, KBD_REPLY_ID);
 760            if (s->translate)
 761                ps2_queue(&s->common, 0x41);
 762            else
 763                ps2_queue(&s->common, 0x83);
 764            break;
 765        case KBD_CMD_ECHO:
 766            ps2_queue(&s->common, KBD_CMD_ECHO);
 767            break;
 768        case KBD_CMD_ENABLE:
 769            s->scan_enabled = 1;
 770            ps2_queue(&s->common, KBD_REPLY_ACK);
 771            break;
 772        case KBD_CMD_SCANCODE:
 773        case KBD_CMD_SET_LEDS:
 774        case KBD_CMD_SET_RATE:
 775            s->common.write_cmd = val;
 776            ps2_queue(&s->common, KBD_REPLY_ACK);
 777            break;
 778        case KBD_CMD_RESET_DISABLE:
 779            ps2_reset_keyboard(s);
 780            s->scan_enabled = 0;
 781            ps2_queue(&s->common, KBD_REPLY_ACK);
 782            break;
 783        case KBD_CMD_RESET_ENABLE:
 784            ps2_reset_keyboard(s);
 785            s->scan_enabled = 1;
 786            ps2_queue(&s->common, KBD_REPLY_ACK);
 787            break;
 788        case KBD_CMD_RESET:
 789            ps2_reset_keyboard(s);
 790            ps2_queue(&s->common, KBD_REPLY_ACK);
 791            ps2_queue(&s->common, KBD_REPLY_POR);
 792            break;
 793        default:
 794            ps2_queue(&s->common, KBD_REPLY_RESEND);
 795            break;
 796        }
 797        break;
 798    case KBD_CMD_SCANCODE:
 799        if (val == 0) {
 800            ps2_queue(&s->common, KBD_REPLY_ACK);
 801            ps2_put_keycode(s, s->scancode_set);
 802        } else if (val >= 1 && val <= 3) {
 803            s->scancode_set = val;
 804            ps2_queue(&s->common, KBD_REPLY_ACK);
 805        } else {
 806            ps2_queue(&s->common, KBD_REPLY_RESEND);
 807        }
 808        s->common.write_cmd = -1;
 809        break;
 810    case KBD_CMD_SET_LEDS:
 811        ps2_set_ledstate(s, val);
 812        ps2_queue(&s->common, KBD_REPLY_ACK);
 813        s->common.write_cmd = -1;
 814        break;
 815    case KBD_CMD_SET_RATE:
 816        ps2_queue(&s->common, KBD_REPLY_ACK);
 817        s->common.write_cmd = -1;
 818        break;
 819    }
 820}
 821
 822/* Set the scancode translation mode.
 823   0 = raw scancodes.
 824   1 = translated scancodes (used by qemu internally).  */
 825
 826void ps2_keyboard_set_translation(void *opaque, int mode)
 827{
 828    PS2KbdState *s = (PS2KbdState *)opaque;
 829    trace_ps2_keyboard_set_translation(opaque, mode);
 830    s->translate = mode;
 831}
 832
 833static void ps2_mouse_send_packet(PS2MouseState *s)
 834{
 835    unsigned int b;
 836    int dx1, dy1, dz1;
 837
 838    dx1 = s->mouse_dx;
 839    dy1 = s->mouse_dy;
 840    dz1 = s->mouse_dz;
 841    /* XXX: increase range to 8 bits ? */
 842    if (dx1 > 127)
 843        dx1 = 127;
 844    else if (dx1 < -127)
 845        dx1 = -127;
 846    if (dy1 > 127)
 847        dy1 = 127;
 848    else if (dy1 < -127)
 849        dy1 = -127;
 850    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
 851    ps2_queue(&s->common, b);
 852    ps2_queue(&s->common, dx1 & 0xff);
 853    ps2_queue(&s->common, dy1 & 0xff);
 854    /* extra byte for IMPS/2 or IMEX */
 855    switch(s->mouse_type) {
 856    default:
 857        break;
 858    case 3:
 859        if (dz1 > 127)
 860            dz1 = 127;
 861        else if (dz1 < -127)
 862                dz1 = -127;
 863        ps2_queue(&s->common, dz1 & 0xff);
 864        break;
 865    case 4:
 866        if (dz1 > 7)
 867            dz1 = 7;
 868        else if (dz1 < -7)
 869            dz1 = -7;
 870        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
 871        ps2_queue(&s->common, b);
 872        break;
 873    }
 874
 875    trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
 876    /* update deltas */
 877    s->mouse_dx -= dx1;
 878    s->mouse_dy -= dy1;
 879    s->mouse_dz -= dz1;
 880}
 881
 882static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
 883                            InputEvent *evt)
 884{
 885    static const int bmap[INPUT_BUTTON__MAX] = {
 886        [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
 887        [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
 888        [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
 889        [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
 890        [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
 891    };
 892    PS2MouseState *s = (PS2MouseState *)dev;
 893    InputMoveEvent *move;
 894    InputBtnEvent *btn;
 895
 896    /* check if deltas are recorded when disabled */
 897    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
 898        return;
 899
 900    switch (evt->type) {
 901    case INPUT_EVENT_KIND_REL:
 902        move = evt->u.rel.data;
 903        if (move->axis == INPUT_AXIS_X) {
 904            s->mouse_dx += move->value;
 905        } else if (move->axis == INPUT_AXIS_Y) {
 906            s->mouse_dy -= move->value;
 907        }
 908        break;
 909
 910    case INPUT_EVENT_KIND_BTN:
 911        btn = evt->u.btn.data;
 912        if (btn->down) {
 913            s->mouse_buttons |= bmap[btn->button];
 914            if (btn->button == INPUT_BUTTON_WHEEL_UP) {
 915                s->mouse_dz--;
 916            } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 917                s->mouse_dz++;
 918            }
 919        } else {
 920            s->mouse_buttons &= ~bmap[btn->button];
 921        }
 922        break;
 923
 924    default:
 925        /* keep gcc happy */
 926        break;
 927    }
 928}
 929
 930static void ps2_mouse_sync(DeviceState *dev)
 931{
 932    PS2MouseState *s = (PS2MouseState *)dev;
 933
 934    if (s->mouse_buttons) {
 935        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 936    }
 937    if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
 938        while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
 939            /* if not remote, send event. Multiple events are sent if
 940               too big deltas */
 941            ps2_mouse_send_packet(s);
 942            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
 943                break;
 944        }
 945    }
 946}
 947
 948void ps2_mouse_fake_event(void *opaque)
 949{
 950    PS2MouseState *s = opaque;
 951    trace_ps2_mouse_fake_event(opaque);
 952    s->mouse_dx++;
 953    ps2_mouse_sync(opaque);
 954}
 955
 956void ps2_write_mouse(void *opaque, int val)
 957{
 958    PS2MouseState *s = (PS2MouseState *)opaque;
 959
 960    trace_ps2_write_mouse(opaque, val);
 961#ifdef DEBUG_MOUSE
 962    printf("kbd: write mouse 0x%02x\n", val);
 963#endif
 964    switch(s->common.write_cmd) {
 965    default:
 966    case -1:
 967        /* mouse command */
 968        if (s->mouse_wrap) {
 969            if (val == AUX_RESET_WRAP) {
 970                s->mouse_wrap = 0;
 971                ps2_queue(&s->common, AUX_ACK);
 972                return;
 973            } else if (val != AUX_RESET) {
 974                ps2_queue(&s->common, val);
 975                return;
 976            }
 977        }
 978        switch(val) {
 979        case AUX_SET_SCALE11:
 980            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
 981            ps2_queue(&s->common, AUX_ACK);
 982            break;
 983        case AUX_SET_SCALE21:
 984            s->mouse_status |= MOUSE_STATUS_SCALE21;
 985            ps2_queue(&s->common, AUX_ACK);
 986            break;
 987        case AUX_SET_STREAM:
 988            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
 989            ps2_queue(&s->common, AUX_ACK);
 990            break;
 991        case AUX_SET_WRAP:
 992            s->mouse_wrap = 1;
 993            ps2_queue(&s->common, AUX_ACK);
 994            break;
 995        case AUX_SET_REMOTE:
 996            s->mouse_status |= MOUSE_STATUS_REMOTE;
 997            ps2_queue(&s->common, AUX_ACK);
 998            break;
 999        case AUX_GET_TYPE:
1000            ps2_queue(&s->common, AUX_ACK);
1001            ps2_queue(&s->common, s->mouse_type);
1002            break;
1003        case AUX_SET_RES:
1004        case AUX_SET_SAMPLE:
1005            s->common.write_cmd = val;
1006            ps2_queue(&s->common, AUX_ACK);
1007            break;
1008        case AUX_GET_SCALE:
1009            ps2_queue(&s->common, AUX_ACK);
1010            ps2_queue(&s->common, s->mouse_status);
1011            ps2_queue(&s->common, s->mouse_resolution);
1012            ps2_queue(&s->common, s->mouse_sample_rate);
1013            break;
1014        case AUX_POLL:
1015            ps2_queue(&s->common, AUX_ACK);
1016            ps2_mouse_send_packet(s);
1017            break;
1018        case AUX_ENABLE_DEV:
1019            s->mouse_status |= MOUSE_STATUS_ENABLED;
1020            ps2_queue(&s->common, AUX_ACK);
1021            break;
1022        case AUX_DISABLE_DEV:
1023            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
1024            ps2_queue(&s->common, AUX_ACK);
1025            break;
1026        case AUX_SET_DEFAULT:
1027            s->mouse_sample_rate = 100;
1028            s->mouse_resolution = 2;
1029            s->mouse_status = 0;
1030            ps2_queue(&s->common, AUX_ACK);
1031            break;
1032        case AUX_RESET:
1033            s->mouse_sample_rate = 100;
1034            s->mouse_resolution = 2;
1035            s->mouse_status = 0;
1036            s->mouse_type = 0;
1037            ps2_queue(&s->common, AUX_ACK);
1038            ps2_queue(&s->common, 0xaa);
1039            ps2_queue(&s->common, s->mouse_type);
1040            break;
1041        default:
1042            break;
1043        }
1044        break;
1045    case AUX_SET_SAMPLE:
1046        s->mouse_sample_rate = val;
1047        /* detect IMPS/2 or IMEX */
1048        switch(s->mouse_detect_state) {
1049        default:
1050        case 0:
1051            if (val == 200)
1052                s->mouse_detect_state = 1;
1053            break;
1054        case 1:
1055            if (val == 100)
1056                s->mouse_detect_state = 2;
1057            else if (val == 200)
1058                s->mouse_detect_state = 3;
1059            else
1060                s->mouse_detect_state = 0;
1061            break;
1062        case 2:
1063            if (val == 80)
1064                s->mouse_type = 3; /* IMPS/2 */
1065            s->mouse_detect_state = 0;
1066            break;
1067        case 3:
1068            if (val == 80)
1069                s->mouse_type = 4; /* IMEX */
1070            s->mouse_detect_state = 0;
1071            break;
1072        }
1073        ps2_queue(&s->common, AUX_ACK);
1074        s->common.write_cmd = -1;
1075        break;
1076    case AUX_SET_RES:
1077        s->mouse_resolution = val;
1078        ps2_queue(&s->common, AUX_ACK);
1079        s->common.write_cmd = -1;
1080        break;
1081    }
1082}
1083
1084static void ps2_common_reset(PS2State *s)
1085{
1086    s->write_cmd = -1;
1087    ps2_reset_queue(s);
1088    s->update_irq(s->update_arg, 0);
1089}
1090
1091static void ps2_common_post_load(PS2State *s)
1092{
1093    PS2Queue *q = &s->queue;
1094    int size;
1095    int i;
1096    int tmp_data[PS2_QUEUE_SIZE];
1097
1098    /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
1099    size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
1100
1101    /* move the queue elements to the start of data array */
1102    if (size > 0) {
1103        for (i = 0; i < size; i++) {
1104            /* move the queue elements to the temporary buffer */
1105            tmp_data[i] = q->data[q->rptr];
1106            if (++q->rptr == 256) {
1107                q->rptr = 0;
1108            }
1109        }
1110        memcpy(q->data, tmp_data, size);
1111    }
1112    /* reset rptr/wptr/count */
1113    q->rptr = 0;
1114    q->wptr = size;
1115    q->count = size;
1116    s->update_irq(s->update_arg, q->count != 0);
1117}
1118
1119static void ps2_kbd_reset(void *opaque)
1120{
1121    PS2KbdState *s = (PS2KbdState *) opaque;
1122
1123    trace_ps2_kbd_reset(opaque);
1124    ps2_common_reset(&s->common);
1125    s->scan_enabled = 0;
1126    s->translate = 0;
1127    s->scancode_set = 2;
1128}
1129
1130static void ps2_mouse_reset(void *opaque)
1131{
1132    PS2MouseState *s = (PS2MouseState *) opaque;
1133
1134    trace_ps2_mouse_reset(opaque);
1135    ps2_common_reset(&s->common);
1136    s->mouse_status = 0;
1137    s->mouse_resolution = 0;
1138    s->mouse_sample_rate = 0;
1139    s->mouse_wrap = 0;
1140    s->mouse_type = 0;
1141    s->mouse_detect_state = 0;
1142    s->mouse_dx = 0;
1143    s->mouse_dy = 0;
1144    s->mouse_dz = 0;
1145    s->mouse_buttons = 0;
1146}
1147
1148static const VMStateDescription vmstate_ps2_common = {
1149    .name = "PS2 Common State",
1150    .version_id = 3,
1151    .minimum_version_id = 2,
1152    .fields = (VMStateField[]) {
1153        VMSTATE_INT32(write_cmd, PS2State),
1154        VMSTATE_INT32(queue.rptr, PS2State),
1155        VMSTATE_INT32(queue.wptr, PS2State),
1156        VMSTATE_INT32(queue.count, PS2State),
1157        VMSTATE_BUFFER(queue.data, PS2State),
1158        VMSTATE_END_OF_LIST()
1159    }
1160};
1161
1162static bool ps2_keyboard_ledstate_needed(void *opaque)
1163{
1164    PS2KbdState *s = opaque;
1165
1166    return s->ledstate != 0; /* 0 is default state */
1167}
1168
1169static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1170{
1171    PS2KbdState *s = opaque;
1172
1173    kbd_put_ledstate(s->ledstate);
1174    return 0;
1175}
1176
1177static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1178    .name = "ps2kbd/ledstate",
1179    .version_id = 3,
1180    .minimum_version_id = 2,
1181    .post_load = ps2_kbd_ledstate_post_load,
1182    .needed = ps2_keyboard_ledstate_needed,
1183    .fields = (VMStateField[]) {
1184        VMSTATE_INT32(ledstate, PS2KbdState),
1185        VMSTATE_END_OF_LIST()
1186    }
1187};
1188
1189static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1190{
1191    PS2KbdState *s = opaque;
1192    return s->need_high_bit != 0; /* 0 is the usual state */
1193}
1194
1195static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1196    .name = "ps2kbd/need_high_bit",
1197    .version_id = 1,
1198    .minimum_version_id = 1,
1199    .needed = ps2_keyboard_need_high_bit_needed,
1200    .fields = (VMStateField[]) {
1201        VMSTATE_BOOL(need_high_bit, PS2KbdState),
1202        VMSTATE_END_OF_LIST()
1203    }
1204};
1205
1206static int ps2_kbd_post_load(void* opaque, int version_id)
1207{
1208    PS2KbdState *s = (PS2KbdState*)opaque;
1209    PS2State *ps2 = &s->common;
1210
1211    if (version_id == 2)
1212        s->scancode_set=2;
1213
1214    ps2_common_post_load(ps2);
1215
1216    return 0;
1217}
1218
1219static void ps2_kbd_pre_save(void *opaque)
1220{
1221    PS2KbdState *s = (PS2KbdState *)opaque;
1222    PS2State *ps2 = &s->common;
1223
1224    ps2_common_post_load(ps2);
1225}
1226
1227static const VMStateDescription vmstate_ps2_keyboard = {
1228    .name = "ps2kbd",
1229    .version_id = 3,
1230    .minimum_version_id = 2,
1231    .post_load = ps2_kbd_post_load,
1232    .pre_save = ps2_kbd_pre_save,
1233    .fields = (VMStateField[]) {
1234        VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1235        VMSTATE_INT32(scan_enabled, PS2KbdState),
1236        VMSTATE_INT32(translate, PS2KbdState),
1237        VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1238        VMSTATE_END_OF_LIST()
1239    },
1240    .subsections = (const VMStateDescription*[]) {
1241        &vmstate_ps2_keyboard_ledstate,
1242        &vmstate_ps2_keyboard_need_high_bit,
1243        NULL
1244    }
1245};
1246
1247static int ps2_mouse_post_load(void *opaque, int version_id)
1248{
1249    PS2MouseState *s = (PS2MouseState *)opaque;
1250    PS2State *ps2 = &s->common;
1251
1252    ps2_common_post_load(ps2);
1253
1254    return 0;
1255}
1256
1257static void ps2_mouse_pre_save(void *opaque)
1258{
1259    PS2MouseState *s = (PS2MouseState *)opaque;
1260    PS2State *ps2 = &s->common;
1261
1262    ps2_common_post_load(ps2);
1263}
1264
1265static const VMStateDescription vmstate_ps2_mouse = {
1266    .name = "ps2mouse",
1267    .version_id = 2,
1268    .minimum_version_id = 2,
1269    .post_load = ps2_mouse_post_load,
1270    .pre_save = ps2_mouse_pre_save,
1271    .fields = (VMStateField[]) {
1272        VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1273        VMSTATE_UINT8(mouse_status, PS2MouseState),
1274        VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1275        VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1276        VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1277        VMSTATE_UINT8(mouse_type, PS2MouseState),
1278        VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1279        VMSTATE_INT32(mouse_dx, PS2MouseState),
1280        VMSTATE_INT32(mouse_dy, PS2MouseState),
1281        VMSTATE_INT32(mouse_dz, PS2MouseState),
1282        VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1283        VMSTATE_END_OF_LIST()
1284    }
1285};
1286
1287static QemuInputHandler ps2_keyboard_handler = {
1288    .name  = "QEMU PS/2 Keyboard",
1289    .mask  = INPUT_EVENT_MASK_KEY,
1290    .event = ps2_keyboard_event,
1291};
1292
1293void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1294{
1295    PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1296
1297    trace_ps2_kbd_init(s);
1298    s->common.update_irq = update_irq;
1299    s->common.update_arg = update_arg;
1300    s->scancode_set = 2;
1301    vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1302    qemu_input_handler_register((DeviceState *)s,
1303                                &ps2_keyboard_handler);
1304    qemu_register_reset(ps2_kbd_reset, s);
1305    return s;
1306}
1307
1308static QemuInputHandler ps2_mouse_handler = {
1309    .name  = "QEMU PS/2 Mouse",
1310    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1311    .event = ps2_mouse_event,
1312    .sync  = ps2_mouse_sync,
1313};
1314
1315void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1316{
1317    PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1318
1319    trace_ps2_mouse_init(s);
1320    s->common.update_irq = update_irq;
1321    s->common.update_arg = update_arg;
1322    vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1323    qemu_input_handler_register((DeviceState *)s,
1324                                &ps2_mouse_handler);
1325    qemu_register_reset(ps2_mouse_reset, s);
1326    return s;
1327}
1328