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
 127static uint8_t translate_table[256] = {
 128    0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
 129    0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
 130    0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
 131    0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
 132    0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
 133    0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
 134    0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
 135    0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
 136    0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
 137    0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
 138    0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
 139    0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
 140    0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
 141    0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
 142    0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
 143    0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
 144    0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
 145    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 146    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
 147    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 148    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
 149    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 150    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
 151    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 152    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 153    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 154    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 155    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 156    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 157    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 158    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 159    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 160};
 161
 162static unsigned int ps2_modifier_bit(QKeyCode key)
 163{
 164    switch (key) {
 165    case Q_KEY_CODE_CTRL:
 166        return MOD_CTRL_L;
 167    case Q_KEY_CODE_CTRL_R:
 168        return MOD_CTRL_R;
 169    case Q_KEY_CODE_SHIFT:
 170        return MOD_SHIFT_L;
 171    case Q_KEY_CODE_SHIFT_R:
 172        return MOD_SHIFT_R;
 173    case Q_KEY_CODE_ALT:
 174        return MOD_ALT_L;
 175    case Q_KEY_CODE_ALT_R:
 176        return MOD_ALT_R;
 177    default:
 178        return 0;
 179    }
 180}
 181
 182static void ps2_reset_queue(PS2State *s)
 183{
 184    PS2Queue *q = &s->queue;
 185
 186    q->rptr = 0;
 187    q->wptr = 0;
 188    q->count = 0;
 189}
 190
 191void ps2_queue(PS2State *s, int b)
 192{
 193    PS2Queue *q = &s->queue;
 194
 195    if (q->count >= PS2_QUEUE_SIZE - 1)
 196        return;
 197    q->data[q->wptr] = b;
 198    if (++q->wptr == PS2_QUEUE_SIZE)
 199        q->wptr = 0;
 200    q->count++;
 201    s->update_irq(s->update_arg, 1);
 202}
 203
 204/* keycode is the untranslated scancode in the current scancode set. */
 205static void ps2_put_keycode(void *opaque, int keycode)
 206{
 207    PS2KbdState *s = opaque;
 208
 209    trace_ps2_put_keycode(opaque, keycode);
 210    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 211
 212    if (s->translate) {
 213        if (keycode == 0xf0) {
 214            s->need_high_bit = true;
 215        } else if (s->need_high_bit) {
 216            ps2_queue(&s->common, translate_table[keycode] | 0x80);
 217            s->need_high_bit = false;
 218        } else {
 219            ps2_queue(&s->common, translate_table[keycode]);
 220        }
 221    } else {
 222        ps2_queue(&s->common, keycode);
 223    }
 224}
 225
 226static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
 227                               InputEvent *evt)
 228{
 229    PS2KbdState *s = (PS2KbdState *)dev;
 230    InputKeyEvent *key = evt->u.key.data;
 231    int qcode;
 232    uint16_t keycode = 0;
 233    int mod;
 234
 235    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 236    assert(evt->type == INPUT_EVENT_KIND_KEY);
 237    qcode = qemu_input_key_value_to_qcode(key->key);
 238
 239    mod = ps2_modifier_bit(qcode);
 240    trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
 241    if (key->down) {
 242        s->modifiers |= mod;
 243    } else {
 244        s->modifiers &= ~mod;
 245    }
 246
 247    if (s->scancode_set == 1) {
 248        if (qcode == Q_KEY_CODE_PAUSE) {
 249            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 250                if (key->down) {
 251                    ps2_put_keycode(s, 0xe0);
 252                    ps2_put_keycode(s, 0x46);
 253                    ps2_put_keycode(s, 0xe0);
 254                    ps2_put_keycode(s, 0xc6);
 255                }
 256            } else {
 257                if (key->down) {
 258                    ps2_put_keycode(s, 0xe1);
 259                    ps2_put_keycode(s, 0x1d);
 260                    ps2_put_keycode(s, 0x45);
 261                    ps2_put_keycode(s, 0xe1);
 262                    ps2_put_keycode(s, 0x9d);
 263                    ps2_put_keycode(s, 0xc5);
 264                }
 265            }
 266        } else if (qcode == Q_KEY_CODE_PRINT) {
 267            if (s->modifiers & MOD_ALT_L) {
 268                if (key->down) {
 269                    ps2_put_keycode(s, 0xb8);
 270                    ps2_put_keycode(s, 0x38);
 271                    ps2_put_keycode(s, 0x54);
 272                } else {
 273                    ps2_put_keycode(s, 0xd4);
 274                    ps2_put_keycode(s, 0xb8);
 275                    ps2_put_keycode(s, 0x38);
 276                }
 277            } else if (s->modifiers & MOD_ALT_R) {
 278                if (key->down) {
 279                    ps2_put_keycode(s, 0xe0);
 280                    ps2_put_keycode(s, 0xb8);
 281                    ps2_put_keycode(s, 0xe0);
 282                    ps2_put_keycode(s, 0x38);
 283                    ps2_put_keycode(s, 0x54);
 284                } else {
 285                    ps2_put_keycode(s, 0xd4);
 286                    ps2_put_keycode(s, 0xe0);
 287                    ps2_put_keycode(s, 0xb8);
 288                    ps2_put_keycode(s, 0xe0);
 289                    ps2_put_keycode(s, 0x38);
 290                }
 291            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 292                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 293                if (key->down) {
 294                    ps2_put_keycode(s, 0xe0);
 295                    ps2_put_keycode(s, 0x37);
 296                } else {
 297                    ps2_put_keycode(s, 0xe0);
 298                    ps2_put_keycode(s, 0xb7);
 299                }
 300            } else {
 301                if (key->down) {
 302                    ps2_put_keycode(s, 0xe0);
 303                    ps2_put_keycode(s, 0x2a);
 304                    ps2_put_keycode(s, 0xe0);
 305                    ps2_put_keycode(s, 0x37);
 306                } else {
 307                    ps2_put_keycode(s, 0xe0);
 308                    ps2_put_keycode(s, 0xb7);
 309                    ps2_put_keycode(s, 0xe0);
 310                    ps2_put_keycode(s, 0xaa);
 311                }
 312            }
 313        } else {
 314            if (qcode < qemu_input_map_qcode_to_atset1_len)
 315                keycode = qemu_input_map_qcode_to_atset1[qcode];
 316            if (keycode) {
 317                if (keycode & 0xff00) {
 318                    ps2_put_keycode(s, keycode >> 8);
 319                }
 320                if (!key->down) {
 321                    keycode |= 0x80;
 322                }
 323                ps2_put_keycode(s, keycode & 0xff);
 324            } else {
 325                qemu_log_mask(LOG_UNIMP,
 326                              "ps2: ignoring key with qcode %d\n", qcode);
 327            }
 328        }
 329    } else if (s->scancode_set == 2) {
 330        if (qcode == Q_KEY_CODE_PAUSE) {
 331            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 332                if (key->down) {
 333                    ps2_put_keycode(s, 0xe0);
 334                    ps2_put_keycode(s, 0x7e);
 335                    ps2_put_keycode(s, 0xe0);
 336                    ps2_put_keycode(s, 0xf0);
 337                    ps2_put_keycode(s, 0x7e);
 338                }
 339            } else {
 340                if (key->down) {
 341                    ps2_put_keycode(s, 0xe1);
 342                    ps2_put_keycode(s, 0x14);
 343                    ps2_put_keycode(s, 0x77);
 344                    ps2_put_keycode(s, 0xe1);
 345                    ps2_put_keycode(s, 0xf0);
 346                    ps2_put_keycode(s, 0x14);
 347                    ps2_put_keycode(s, 0xf0);
 348                    ps2_put_keycode(s, 0x77);
 349                }
 350            }
 351        } else if (qcode == Q_KEY_CODE_PRINT) {
 352            if (s->modifiers & MOD_ALT_L) {
 353                if (key->down) {
 354                    ps2_put_keycode(s, 0xf0);
 355                    ps2_put_keycode(s, 0x11);
 356                    ps2_put_keycode(s, 0x11);
 357                    ps2_put_keycode(s, 0x84);
 358                } else {
 359                    ps2_put_keycode(s, 0xf0);
 360                    ps2_put_keycode(s, 0x84);
 361                    ps2_put_keycode(s, 0xf0);
 362                    ps2_put_keycode(s, 0x11);
 363                    ps2_put_keycode(s, 0x11);
 364                }
 365            } else if (s->modifiers & MOD_ALT_R) {
 366                if (key->down) {
 367                    ps2_put_keycode(s, 0xe0);
 368                    ps2_put_keycode(s, 0xf0);
 369                    ps2_put_keycode(s, 0x11);
 370                    ps2_put_keycode(s, 0xe0);
 371                    ps2_put_keycode(s, 0x11);
 372                    ps2_put_keycode(s, 0x84);
 373                } else {
 374                    ps2_put_keycode(s, 0xf0);
 375                    ps2_put_keycode(s, 0x84);
 376                    ps2_put_keycode(s, 0xe0);
 377                    ps2_put_keycode(s, 0xf0);
 378                    ps2_put_keycode(s, 0x11);
 379                    ps2_put_keycode(s, 0xe0);
 380                    ps2_put_keycode(s, 0x11);
 381                }
 382            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 383                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 384                if (key->down) {
 385                    ps2_put_keycode(s, 0xe0);
 386                    ps2_put_keycode(s, 0x7c);
 387                } else {
 388                    ps2_put_keycode(s, 0xe0);
 389                    ps2_put_keycode(s, 0xf0);
 390                    ps2_put_keycode(s, 0x7c);
 391                }
 392            } else {
 393                if (key->down) {
 394                    ps2_put_keycode(s, 0xe0);
 395                    ps2_put_keycode(s, 0x12);
 396                    ps2_put_keycode(s, 0xe0);
 397                    ps2_put_keycode(s, 0x7c);
 398                } else {
 399                    ps2_put_keycode(s, 0xe0);
 400                    ps2_put_keycode(s, 0xf0);
 401                    ps2_put_keycode(s, 0x7c);
 402                    ps2_put_keycode(s, 0xe0);
 403                    ps2_put_keycode(s, 0xf0);
 404                    ps2_put_keycode(s, 0x12);
 405                }
 406            }
 407        } else {
 408            if (qcode < qemu_input_map_qcode_to_atset2_len)
 409                keycode = qemu_input_map_qcode_to_atset2[qcode];
 410            if (keycode) {
 411                if (keycode & 0xff00) {
 412                    ps2_put_keycode(s, keycode >> 8);
 413                }
 414                if (!key->down) {
 415                    ps2_put_keycode(s, 0xf0);
 416                }
 417                ps2_put_keycode(s, keycode & 0xff);
 418            } else {
 419                qemu_log_mask(LOG_UNIMP,
 420                              "ps2: ignoring key with qcode %d\n", qcode);
 421            }
 422        }
 423    } else if (s->scancode_set == 3) {
 424        if (qcode < qemu_input_map_qcode_to_atset3_len)
 425            keycode = qemu_input_map_qcode_to_atset3[qcode];
 426        if (keycode) {
 427            /* FIXME: break code should be configured on a key by key basis */
 428            if (!key->down) {
 429                ps2_put_keycode(s, 0xf0);
 430            }
 431            ps2_put_keycode(s, keycode);
 432        } else {
 433            qemu_log_mask(LOG_UNIMP,
 434                          "ps2: ignoring key with qcode %d\n", qcode);
 435        }
 436    }
 437}
 438
 439uint32_t ps2_read_data(PS2State *s)
 440{
 441    PS2Queue *q;
 442    int val, index;
 443
 444    trace_ps2_read_data(s);
 445    q = &s->queue;
 446    if (q->count == 0) {
 447        /* NOTE: if no data left, we return the last keyboard one
 448           (needed for EMM386) */
 449        /* XXX: need a timer to do things correctly */
 450        index = q->rptr - 1;
 451        if (index < 0)
 452            index = PS2_QUEUE_SIZE - 1;
 453        val = q->data[index];
 454    } else {
 455        val = q->data[q->rptr];
 456        if (++q->rptr == PS2_QUEUE_SIZE)
 457            q->rptr = 0;
 458        q->count--;
 459        /* reading deasserts IRQ */
 460        s->update_irq(s->update_arg, 0);
 461        /* reassert IRQs if data left */
 462        s->update_irq(s->update_arg, q->count != 0);
 463    }
 464    return val;
 465}
 466
 467static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
 468{
 469    trace_ps2_set_ledstate(s, ledstate);
 470    s->ledstate = ledstate;
 471    kbd_put_ledstate(ledstate);
 472}
 473
 474static void ps2_reset_keyboard(PS2KbdState *s)
 475{
 476    trace_ps2_reset_keyboard(s);
 477    s->scan_enabled = 1;
 478    s->scancode_set = 2;
 479    ps2_reset_queue(&s->common);
 480    ps2_set_ledstate(s, 0);
 481}
 482
 483void ps2_write_keyboard(void *opaque, int val)
 484{
 485    PS2KbdState *s = (PS2KbdState *)opaque;
 486
 487    trace_ps2_write_keyboard(opaque, val);
 488    switch(s->common.write_cmd) {
 489    default:
 490    case -1:
 491        switch(val) {
 492        case 0x00:
 493            ps2_queue(&s->common, KBD_REPLY_ACK);
 494            break;
 495        case 0x05:
 496            ps2_queue(&s->common, KBD_REPLY_RESEND);
 497            break;
 498        case KBD_CMD_GET_ID:
 499            ps2_queue(&s->common, KBD_REPLY_ACK);
 500            /* We emulate a MF2 AT keyboard here */
 501            ps2_queue(&s->common, KBD_REPLY_ID);
 502            if (s->translate)
 503                ps2_queue(&s->common, 0x41);
 504            else
 505                ps2_queue(&s->common, 0x83);
 506            break;
 507        case KBD_CMD_ECHO:
 508            ps2_queue(&s->common, KBD_CMD_ECHO);
 509            break;
 510        case KBD_CMD_ENABLE:
 511            s->scan_enabled = 1;
 512            ps2_queue(&s->common, KBD_REPLY_ACK);
 513            break;
 514        case KBD_CMD_SCANCODE:
 515        case KBD_CMD_SET_LEDS:
 516        case KBD_CMD_SET_RATE:
 517            s->common.write_cmd = val;
 518            ps2_queue(&s->common, KBD_REPLY_ACK);
 519            break;
 520        case KBD_CMD_RESET_DISABLE:
 521            ps2_reset_keyboard(s);
 522            s->scan_enabled = 0;
 523            ps2_queue(&s->common, KBD_REPLY_ACK);
 524            break;
 525        case KBD_CMD_RESET_ENABLE:
 526            ps2_reset_keyboard(s);
 527            s->scan_enabled = 1;
 528            ps2_queue(&s->common, KBD_REPLY_ACK);
 529            break;
 530        case KBD_CMD_RESET:
 531            ps2_reset_keyboard(s);
 532            ps2_queue(&s->common, KBD_REPLY_ACK);
 533            ps2_queue(&s->common, KBD_REPLY_POR);
 534            break;
 535        default:
 536            ps2_queue(&s->common, KBD_REPLY_RESEND);
 537            break;
 538        }
 539        break;
 540    case KBD_CMD_SCANCODE:
 541        if (val == 0) {
 542            ps2_queue(&s->common, KBD_REPLY_ACK);
 543            ps2_put_keycode(s, s->scancode_set);
 544        } else if (val >= 1 && val <= 3) {
 545            s->scancode_set = val;
 546            ps2_queue(&s->common, KBD_REPLY_ACK);
 547        } else {
 548            ps2_queue(&s->common, KBD_REPLY_RESEND);
 549        }
 550        s->common.write_cmd = -1;
 551        break;
 552    case KBD_CMD_SET_LEDS:
 553        ps2_set_ledstate(s, val);
 554        ps2_queue(&s->common, KBD_REPLY_ACK);
 555        s->common.write_cmd = -1;
 556        break;
 557    case KBD_CMD_SET_RATE:
 558        ps2_queue(&s->common, KBD_REPLY_ACK);
 559        s->common.write_cmd = -1;
 560        break;
 561    }
 562}
 563
 564/* Set the scancode translation mode.
 565   0 = raw scancodes.
 566   1 = translated scancodes (used by qemu internally).  */
 567
 568void ps2_keyboard_set_translation(void *opaque, int mode)
 569{
 570    PS2KbdState *s = (PS2KbdState *)opaque;
 571    trace_ps2_keyboard_set_translation(opaque, mode);
 572    s->translate = mode;
 573}
 574
 575static void ps2_mouse_send_packet(PS2MouseState *s)
 576{
 577    unsigned int b;
 578    int dx1, dy1, dz1;
 579
 580    dx1 = s->mouse_dx;
 581    dy1 = s->mouse_dy;
 582    dz1 = s->mouse_dz;
 583    /* XXX: increase range to 8 bits ? */
 584    if (dx1 > 127)
 585        dx1 = 127;
 586    else if (dx1 < -127)
 587        dx1 = -127;
 588    if (dy1 > 127)
 589        dy1 = 127;
 590    else if (dy1 < -127)
 591        dy1 = -127;
 592    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
 593    ps2_queue(&s->common, b);
 594    ps2_queue(&s->common, dx1 & 0xff);
 595    ps2_queue(&s->common, dy1 & 0xff);
 596    /* extra byte for IMPS/2 or IMEX */
 597    switch(s->mouse_type) {
 598    default:
 599        break;
 600    case 3:
 601        if (dz1 > 127)
 602            dz1 = 127;
 603        else if (dz1 < -127)
 604                dz1 = -127;
 605        ps2_queue(&s->common, dz1 & 0xff);
 606        break;
 607    case 4:
 608        if (dz1 > 7)
 609            dz1 = 7;
 610        else if (dz1 < -7)
 611            dz1 = -7;
 612        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
 613        ps2_queue(&s->common, b);
 614        break;
 615    }
 616
 617    trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
 618    /* update deltas */
 619    s->mouse_dx -= dx1;
 620    s->mouse_dy -= dy1;
 621    s->mouse_dz -= dz1;
 622}
 623
 624static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
 625                            InputEvent *evt)
 626{
 627    static const int bmap[INPUT_BUTTON__MAX] = {
 628        [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
 629        [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
 630        [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
 631        [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
 632        [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
 633    };
 634    PS2MouseState *s = (PS2MouseState *)dev;
 635    InputMoveEvent *move;
 636    InputBtnEvent *btn;
 637
 638    /* check if deltas are recorded when disabled */
 639    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
 640        return;
 641
 642    switch (evt->type) {
 643    case INPUT_EVENT_KIND_REL:
 644        move = evt->u.rel.data;
 645        if (move->axis == INPUT_AXIS_X) {
 646            s->mouse_dx += move->value;
 647        } else if (move->axis == INPUT_AXIS_Y) {
 648            s->mouse_dy -= move->value;
 649        }
 650        break;
 651
 652    case INPUT_EVENT_KIND_BTN:
 653        btn = evt->u.btn.data;
 654        if (btn->down) {
 655            s->mouse_buttons |= bmap[btn->button];
 656            if (btn->button == INPUT_BUTTON_WHEEL_UP) {
 657                s->mouse_dz--;
 658            } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 659                s->mouse_dz++;
 660            }
 661        } else {
 662            s->mouse_buttons &= ~bmap[btn->button];
 663        }
 664        break;
 665
 666    default:
 667        /* keep gcc happy */
 668        break;
 669    }
 670}
 671
 672static void ps2_mouse_sync(DeviceState *dev)
 673{
 674    PS2MouseState *s = (PS2MouseState *)dev;
 675
 676    if (s->mouse_buttons) {
 677        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 678    }
 679    if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
 680        while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
 681            /* if not remote, send event. Multiple events are sent if
 682               too big deltas */
 683            ps2_mouse_send_packet(s);
 684            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
 685                break;
 686        }
 687    }
 688}
 689
 690void ps2_mouse_fake_event(void *opaque)
 691{
 692    PS2MouseState *s = opaque;
 693    trace_ps2_mouse_fake_event(opaque);
 694    s->mouse_dx++;
 695    ps2_mouse_sync(opaque);
 696}
 697
 698void ps2_write_mouse(void *opaque, int val)
 699{
 700    PS2MouseState *s = (PS2MouseState *)opaque;
 701
 702    trace_ps2_write_mouse(opaque, val);
 703#ifdef DEBUG_MOUSE
 704    printf("kbd: write mouse 0x%02x\n", val);
 705#endif
 706    switch(s->common.write_cmd) {
 707    default:
 708    case -1:
 709        /* mouse command */
 710        if (s->mouse_wrap) {
 711            if (val == AUX_RESET_WRAP) {
 712                s->mouse_wrap = 0;
 713                ps2_queue(&s->common, AUX_ACK);
 714                return;
 715            } else if (val != AUX_RESET) {
 716                ps2_queue(&s->common, val);
 717                return;
 718            }
 719        }
 720        switch(val) {
 721        case AUX_SET_SCALE11:
 722            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
 723            ps2_queue(&s->common, AUX_ACK);
 724            break;
 725        case AUX_SET_SCALE21:
 726            s->mouse_status |= MOUSE_STATUS_SCALE21;
 727            ps2_queue(&s->common, AUX_ACK);
 728            break;
 729        case AUX_SET_STREAM:
 730            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
 731            ps2_queue(&s->common, AUX_ACK);
 732            break;
 733        case AUX_SET_WRAP:
 734            s->mouse_wrap = 1;
 735            ps2_queue(&s->common, AUX_ACK);
 736            break;
 737        case AUX_SET_REMOTE:
 738            s->mouse_status |= MOUSE_STATUS_REMOTE;
 739            ps2_queue(&s->common, AUX_ACK);
 740            break;
 741        case AUX_GET_TYPE:
 742            ps2_queue(&s->common, AUX_ACK);
 743            ps2_queue(&s->common, s->mouse_type);
 744            break;
 745        case AUX_SET_RES:
 746        case AUX_SET_SAMPLE:
 747            s->common.write_cmd = val;
 748            ps2_queue(&s->common, AUX_ACK);
 749            break;
 750        case AUX_GET_SCALE:
 751            ps2_queue(&s->common, AUX_ACK);
 752            ps2_queue(&s->common, s->mouse_status);
 753            ps2_queue(&s->common, s->mouse_resolution);
 754            ps2_queue(&s->common, s->mouse_sample_rate);
 755            break;
 756        case AUX_POLL:
 757            ps2_queue(&s->common, AUX_ACK);
 758            ps2_mouse_send_packet(s);
 759            break;
 760        case AUX_ENABLE_DEV:
 761            s->mouse_status |= MOUSE_STATUS_ENABLED;
 762            ps2_queue(&s->common, AUX_ACK);
 763            break;
 764        case AUX_DISABLE_DEV:
 765            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
 766            ps2_queue(&s->common, AUX_ACK);
 767            break;
 768        case AUX_SET_DEFAULT:
 769            s->mouse_sample_rate = 100;
 770            s->mouse_resolution = 2;
 771            s->mouse_status = 0;
 772            ps2_queue(&s->common, AUX_ACK);
 773            break;
 774        case AUX_RESET:
 775            s->mouse_sample_rate = 100;
 776            s->mouse_resolution = 2;
 777            s->mouse_status = 0;
 778            s->mouse_type = 0;
 779            ps2_queue(&s->common, AUX_ACK);
 780            ps2_queue(&s->common, 0xaa);
 781            ps2_queue(&s->common, s->mouse_type);
 782            break;
 783        default:
 784            break;
 785        }
 786        break;
 787    case AUX_SET_SAMPLE:
 788        s->mouse_sample_rate = val;
 789        /* detect IMPS/2 or IMEX */
 790        switch(s->mouse_detect_state) {
 791        default:
 792        case 0:
 793            if (val == 200)
 794                s->mouse_detect_state = 1;
 795            break;
 796        case 1:
 797            if (val == 100)
 798                s->mouse_detect_state = 2;
 799            else if (val == 200)
 800                s->mouse_detect_state = 3;
 801            else
 802                s->mouse_detect_state = 0;
 803            break;
 804        case 2:
 805            if (val == 80)
 806                s->mouse_type = 3; /* IMPS/2 */
 807            s->mouse_detect_state = 0;
 808            break;
 809        case 3:
 810            if (val == 80)
 811                s->mouse_type = 4; /* IMEX */
 812            s->mouse_detect_state = 0;
 813            break;
 814        }
 815        ps2_queue(&s->common, AUX_ACK);
 816        s->common.write_cmd = -1;
 817        break;
 818    case AUX_SET_RES:
 819        s->mouse_resolution = val;
 820        ps2_queue(&s->common, AUX_ACK);
 821        s->common.write_cmd = -1;
 822        break;
 823    }
 824}
 825
 826static void ps2_common_reset(PS2State *s)
 827{
 828    s->write_cmd = -1;
 829    ps2_reset_queue(s);
 830    s->update_irq(s->update_arg, 0);
 831}
 832
 833static void ps2_common_post_load(PS2State *s)
 834{
 835    PS2Queue *q = &s->queue;
 836    uint8_t i, size;
 837    uint8_t tmp_data[PS2_QUEUE_SIZE];
 838
 839    /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
 840    size = (q->count < 0 || q->count > PS2_QUEUE_SIZE) ? 0 : q->count;
 841
 842    /* move the queue elements to the start of data array */
 843    for (i = 0; i < size; i++) {
 844        if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
 845            q->rptr = 0;
 846        }
 847        tmp_data[i] = q->data[q->rptr++];
 848    }
 849    memcpy(q->data, tmp_data, size);
 850
 851    /* reset rptr/wptr/count */
 852    q->rptr = 0;
 853    q->wptr = size;
 854    q->count = size;
 855    s->update_irq(s->update_arg, q->count != 0);
 856}
 857
 858static void ps2_kbd_reset(void *opaque)
 859{
 860    PS2KbdState *s = (PS2KbdState *) opaque;
 861
 862    trace_ps2_kbd_reset(opaque);
 863    ps2_common_reset(&s->common);
 864    s->scan_enabled = 0;
 865    s->translate = 0;
 866    s->scancode_set = 2;
 867    s->modifiers = 0;
 868}
 869
 870static void ps2_mouse_reset(void *opaque)
 871{
 872    PS2MouseState *s = (PS2MouseState *) opaque;
 873
 874    trace_ps2_mouse_reset(opaque);
 875    ps2_common_reset(&s->common);
 876    s->mouse_status = 0;
 877    s->mouse_resolution = 0;
 878    s->mouse_sample_rate = 0;
 879    s->mouse_wrap = 0;
 880    s->mouse_type = 0;
 881    s->mouse_detect_state = 0;
 882    s->mouse_dx = 0;
 883    s->mouse_dy = 0;
 884    s->mouse_dz = 0;
 885    s->mouse_buttons = 0;
 886}
 887
 888static const VMStateDescription vmstate_ps2_common = {
 889    .name = "PS2 Common State",
 890    .version_id = 3,
 891    .minimum_version_id = 2,
 892    .fields = (VMStateField[]) {
 893        VMSTATE_INT32(write_cmd, PS2State),
 894        VMSTATE_INT32(queue.rptr, PS2State),
 895        VMSTATE_INT32(queue.wptr, PS2State),
 896        VMSTATE_INT32(queue.count, PS2State),
 897        VMSTATE_BUFFER(queue.data, PS2State),
 898        VMSTATE_END_OF_LIST()
 899    }
 900};
 901
 902static bool ps2_keyboard_ledstate_needed(void *opaque)
 903{
 904    PS2KbdState *s = opaque;
 905
 906    return s->ledstate != 0; /* 0 is default state */
 907}
 908
 909static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
 910{
 911    PS2KbdState *s = opaque;
 912
 913    kbd_put_ledstate(s->ledstate);
 914    return 0;
 915}
 916
 917static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
 918    .name = "ps2kbd/ledstate",
 919    .version_id = 3,
 920    .minimum_version_id = 2,
 921    .post_load = ps2_kbd_ledstate_post_load,
 922    .needed = ps2_keyboard_ledstate_needed,
 923    .fields = (VMStateField[]) {
 924        VMSTATE_INT32(ledstate, PS2KbdState),
 925        VMSTATE_END_OF_LIST()
 926    }
 927};
 928
 929static bool ps2_keyboard_need_high_bit_needed(void *opaque)
 930{
 931    PS2KbdState *s = opaque;
 932    return s->need_high_bit != 0; /* 0 is the usual state */
 933}
 934
 935static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
 936    .name = "ps2kbd/need_high_bit",
 937    .version_id = 1,
 938    .minimum_version_id = 1,
 939    .needed = ps2_keyboard_need_high_bit_needed,
 940    .fields = (VMStateField[]) {
 941        VMSTATE_BOOL(need_high_bit, PS2KbdState),
 942        VMSTATE_END_OF_LIST()
 943    }
 944};
 945
 946static int ps2_kbd_post_load(void* opaque, int version_id)
 947{
 948    PS2KbdState *s = (PS2KbdState*)opaque;
 949    PS2State *ps2 = &s->common;
 950
 951    if (version_id == 2)
 952        s->scancode_set=2;
 953
 954    ps2_common_post_load(ps2);
 955
 956    return 0;
 957}
 958
 959static int ps2_kbd_pre_save(void *opaque)
 960{
 961    PS2KbdState *s = (PS2KbdState *)opaque;
 962    PS2State *ps2 = &s->common;
 963
 964    ps2_common_post_load(ps2);
 965
 966    return 0;
 967}
 968
 969static const VMStateDescription vmstate_ps2_keyboard = {
 970    .name = "ps2kbd",
 971    .version_id = 3,
 972    .minimum_version_id = 2,
 973    .post_load = ps2_kbd_post_load,
 974    .pre_save = ps2_kbd_pre_save,
 975    .fields = (VMStateField[]) {
 976        VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
 977        VMSTATE_INT32(scan_enabled, PS2KbdState),
 978        VMSTATE_INT32(translate, PS2KbdState),
 979        VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
 980        VMSTATE_END_OF_LIST()
 981    },
 982    .subsections = (const VMStateDescription*[]) {
 983        &vmstate_ps2_keyboard_ledstate,
 984        &vmstate_ps2_keyboard_need_high_bit,
 985        NULL
 986    }
 987};
 988
 989static int ps2_mouse_post_load(void *opaque, int version_id)
 990{
 991    PS2MouseState *s = (PS2MouseState *)opaque;
 992    PS2State *ps2 = &s->common;
 993
 994    ps2_common_post_load(ps2);
 995
 996    return 0;
 997}
 998
 999static int ps2_mouse_pre_save(void *opaque)
1000{
1001    PS2MouseState *s = (PS2MouseState *)opaque;
1002    PS2State *ps2 = &s->common;
1003
1004    ps2_common_post_load(ps2);
1005
1006    return 0;
1007}
1008
1009static const VMStateDescription vmstate_ps2_mouse = {
1010    .name = "ps2mouse",
1011    .version_id = 2,
1012    .minimum_version_id = 2,
1013    .post_load = ps2_mouse_post_load,
1014    .pre_save = ps2_mouse_pre_save,
1015    .fields = (VMStateField[]) {
1016        VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1017        VMSTATE_UINT8(mouse_status, PS2MouseState),
1018        VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1019        VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1020        VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1021        VMSTATE_UINT8(mouse_type, PS2MouseState),
1022        VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1023        VMSTATE_INT32(mouse_dx, PS2MouseState),
1024        VMSTATE_INT32(mouse_dy, PS2MouseState),
1025        VMSTATE_INT32(mouse_dz, PS2MouseState),
1026        VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1027        VMSTATE_END_OF_LIST()
1028    }
1029};
1030
1031static QemuInputHandler ps2_keyboard_handler = {
1032    .name  = "QEMU PS/2 Keyboard",
1033    .mask  = INPUT_EVENT_MASK_KEY,
1034    .event = ps2_keyboard_event,
1035};
1036
1037void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1038{
1039    PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1040
1041    trace_ps2_kbd_init(s);
1042    s->common.update_irq = update_irq;
1043    s->common.update_arg = update_arg;
1044    s->scancode_set = 2;
1045    vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1046    qemu_input_handler_register((DeviceState *)s,
1047                                &ps2_keyboard_handler);
1048    qemu_register_reset(ps2_kbd_reset, s);
1049    return s;
1050}
1051
1052static QemuInputHandler ps2_mouse_handler = {
1053    .name  = "QEMU PS/2 Mouse",
1054    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1055    .event = ps2_mouse_event,
1056    .sync  = ps2_mouse_sync,
1057};
1058
1059void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1060{
1061    PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1062
1063    trace_ps2_mouse_init(s);
1064    s->common.update_irq = update_irq;
1065    s->common.update_arg = update_arg;
1066    vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1067    qemu_input_handler_register((DeviceState *)s,
1068                                &ps2_mouse_handler);
1069    qemu_register_reset(ps2_mouse_reset, s);
1070    return s;
1071}
1072