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_noirq(PS2State *s, int b)
 192{
 193    PS2Queue *q = &s->queue;
 194
 195    if (q->count == PS2_QUEUE_SIZE) {
 196        return;
 197    }
 198
 199    q->data[q->wptr] = b;
 200    if (++q->wptr == PS2_QUEUE_SIZE)
 201        q->wptr = 0;
 202    q->count++;
 203}
 204
 205void ps2_raise_irq(PS2State *s)
 206{
 207    s->update_irq(s->update_arg, 1);
 208}
 209
 210void ps2_queue(PS2State *s, int b)
 211{
 212    ps2_queue_noirq(s, b);
 213    s->update_irq(s->update_arg, 1);
 214}
 215
 216void ps2_queue_2(PS2State *s, int b1, int b2)
 217{
 218    if (PS2_QUEUE_SIZE - s->queue.count < 2) {
 219        return;
 220    }
 221
 222    ps2_queue_noirq(s, b1);
 223    ps2_queue_noirq(s, b2);
 224    s->update_irq(s->update_arg, 1);
 225}
 226
 227void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
 228{
 229    if (PS2_QUEUE_SIZE - s->queue.count < 3) {
 230        return;
 231    }
 232
 233    ps2_queue_noirq(s, b1);
 234    ps2_queue_noirq(s, b2);
 235    ps2_queue_noirq(s, b3);
 236    s->update_irq(s->update_arg, 1);
 237}
 238
 239void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
 240{
 241    if (PS2_QUEUE_SIZE - s->queue.count < 4) {
 242        return;
 243    }
 244
 245    ps2_queue_noirq(s, b1);
 246    ps2_queue_noirq(s, b2);
 247    ps2_queue_noirq(s, b3);
 248    ps2_queue_noirq(s, b4);
 249    s->update_irq(s->update_arg, 1);
 250}
 251
 252/* keycode is the untranslated scancode in the current scancode set. */
 253static void ps2_put_keycode(void *opaque, int keycode)
 254{
 255    PS2KbdState *s = opaque;
 256
 257    trace_ps2_put_keycode(opaque, keycode);
 258    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 259
 260    if (s->translate) {
 261        if (keycode == 0xf0) {
 262            s->need_high_bit = true;
 263        } else if (s->need_high_bit) {
 264            ps2_queue(&s->common, translate_table[keycode] | 0x80);
 265            s->need_high_bit = false;
 266        } else {
 267            ps2_queue(&s->common, translate_table[keycode]);
 268        }
 269    } else {
 270        ps2_queue(&s->common, keycode);
 271    }
 272}
 273
 274static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
 275                               InputEvent *evt)
 276{
 277    PS2KbdState *s = (PS2KbdState *)dev;
 278    InputKeyEvent *key = evt->u.key.data;
 279    int qcode;
 280    uint16_t keycode = 0;
 281    int mod;
 282
 283    /* do not process events while disabled to prevent stream corruption */
 284    if (!s->scan_enabled) {
 285        return;
 286    }
 287
 288    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 289    assert(evt->type == INPUT_EVENT_KIND_KEY);
 290    qcode = qemu_input_key_value_to_qcode(key->key);
 291
 292    mod = ps2_modifier_bit(qcode);
 293    trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
 294    if (key->down) {
 295        s->modifiers |= mod;
 296    } else {
 297        s->modifiers &= ~mod;
 298    }
 299
 300    if (s->scancode_set == 1) {
 301        if (qcode == Q_KEY_CODE_PAUSE) {
 302            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 303                if (key->down) {
 304                    ps2_put_keycode(s, 0xe0);
 305                    ps2_put_keycode(s, 0x46);
 306                    ps2_put_keycode(s, 0xe0);
 307                    ps2_put_keycode(s, 0xc6);
 308                }
 309            } else {
 310                if (key->down) {
 311                    ps2_put_keycode(s, 0xe1);
 312                    ps2_put_keycode(s, 0x1d);
 313                    ps2_put_keycode(s, 0x45);
 314                    ps2_put_keycode(s, 0xe1);
 315                    ps2_put_keycode(s, 0x9d);
 316                    ps2_put_keycode(s, 0xc5);
 317                }
 318            }
 319        } else if (qcode == Q_KEY_CODE_PRINT) {
 320            if (s->modifiers & MOD_ALT_L) {
 321                if (key->down) {
 322                    ps2_put_keycode(s, 0xb8);
 323                    ps2_put_keycode(s, 0x38);
 324                    ps2_put_keycode(s, 0x54);
 325                } else {
 326                    ps2_put_keycode(s, 0xd4);
 327                    ps2_put_keycode(s, 0xb8);
 328                    ps2_put_keycode(s, 0x38);
 329                }
 330            } else if (s->modifiers & MOD_ALT_R) {
 331                if (key->down) {
 332                    ps2_put_keycode(s, 0xe0);
 333                    ps2_put_keycode(s, 0xb8);
 334                    ps2_put_keycode(s, 0xe0);
 335                    ps2_put_keycode(s, 0x38);
 336                    ps2_put_keycode(s, 0x54);
 337                } else {
 338                    ps2_put_keycode(s, 0xd4);
 339                    ps2_put_keycode(s, 0xe0);
 340                    ps2_put_keycode(s, 0xb8);
 341                    ps2_put_keycode(s, 0xe0);
 342                    ps2_put_keycode(s, 0x38);
 343                }
 344            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 345                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 346                if (key->down) {
 347                    ps2_put_keycode(s, 0xe0);
 348                    ps2_put_keycode(s, 0x37);
 349                } else {
 350                    ps2_put_keycode(s, 0xe0);
 351                    ps2_put_keycode(s, 0xb7);
 352                }
 353            } else {
 354                if (key->down) {
 355                    ps2_put_keycode(s, 0xe0);
 356                    ps2_put_keycode(s, 0x2a);
 357                    ps2_put_keycode(s, 0xe0);
 358                    ps2_put_keycode(s, 0x37);
 359                } else {
 360                    ps2_put_keycode(s, 0xe0);
 361                    ps2_put_keycode(s, 0xb7);
 362                    ps2_put_keycode(s, 0xe0);
 363                    ps2_put_keycode(s, 0xaa);
 364                }
 365            }
 366        } else {
 367            if (qcode < qemu_input_map_qcode_to_atset1_len)
 368                keycode = qemu_input_map_qcode_to_atset1[qcode];
 369            if (keycode) {
 370                if (keycode & 0xff00) {
 371                    ps2_put_keycode(s, keycode >> 8);
 372                }
 373                if (!key->down) {
 374                    keycode |= 0x80;
 375                }
 376                ps2_put_keycode(s, keycode & 0xff);
 377            } else {
 378                qemu_log_mask(LOG_UNIMP,
 379                              "ps2: ignoring key with qcode %d\n", qcode);
 380            }
 381        }
 382    } else if (s->scancode_set == 2) {
 383        if (qcode == Q_KEY_CODE_PAUSE) {
 384            if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
 385                if (key->down) {
 386                    ps2_put_keycode(s, 0xe0);
 387                    ps2_put_keycode(s, 0x7e);
 388                    ps2_put_keycode(s, 0xe0);
 389                    ps2_put_keycode(s, 0xf0);
 390                    ps2_put_keycode(s, 0x7e);
 391                }
 392            } else {
 393                if (key->down) {
 394                    ps2_put_keycode(s, 0xe1);
 395                    ps2_put_keycode(s, 0x14);
 396                    ps2_put_keycode(s, 0x77);
 397                    ps2_put_keycode(s, 0xe1);
 398                    ps2_put_keycode(s, 0xf0);
 399                    ps2_put_keycode(s, 0x14);
 400                    ps2_put_keycode(s, 0xf0);
 401                    ps2_put_keycode(s, 0x77);
 402                }
 403            }
 404        } else if (qcode == Q_KEY_CODE_PRINT) {
 405            if (s->modifiers & MOD_ALT_L) {
 406                if (key->down) {
 407                    ps2_put_keycode(s, 0xf0);
 408                    ps2_put_keycode(s, 0x11);
 409                    ps2_put_keycode(s, 0x11);
 410                    ps2_put_keycode(s, 0x84);
 411                } else {
 412                    ps2_put_keycode(s, 0xf0);
 413                    ps2_put_keycode(s, 0x84);
 414                    ps2_put_keycode(s, 0xf0);
 415                    ps2_put_keycode(s, 0x11);
 416                    ps2_put_keycode(s, 0x11);
 417                }
 418            } else if (s->modifiers & MOD_ALT_R) {
 419                if (key->down) {
 420                    ps2_put_keycode(s, 0xe0);
 421                    ps2_put_keycode(s, 0xf0);
 422                    ps2_put_keycode(s, 0x11);
 423                    ps2_put_keycode(s, 0xe0);
 424                    ps2_put_keycode(s, 0x11);
 425                    ps2_put_keycode(s, 0x84);
 426                } else {
 427                    ps2_put_keycode(s, 0xf0);
 428                    ps2_put_keycode(s, 0x84);
 429                    ps2_put_keycode(s, 0xe0);
 430                    ps2_put_keycode(s, 0xf0);
 431                    ps2_put_keycode(s, 0x11);
 432                    ps2_put_keycode(s, 0xe0);
 433                    ps2_put_keycode(s, 0x11);
 434                }
 435            } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
 436                                       MOD_SHIFT_R | MOD_CTRL_R)) {
 437                if (key->down) {
 438                    ps2_put_keycode(s, 0xe0);
 439                    ps2_put_keycode(s, 0x7c);
 440                } else {
 441                    ps2_put_keycode(s, 0xe0);
 442                    ps2_put_keycode(s, 0xf0);
 443                    ps2_put_keycode(s, 0x7c);
 444                }
 445            } else {
 446                if (key->down) {
 447                    ps2_put_keycode(s, 0xe0);
 448                    ps2_put_keycode(s, 0x12);
 449                    ps2_put_keycode(s, 0xe0);
 450                    ps2_put_keycode(s, 0x7c);
 451                } else {
 452                    ps2_put_keycode(s, 0xe0);
 453                    ps2_put_keycode(s, 0xf0);
 454                    ps2_put_keycode(s, 0x7c);
 455                    ps2_put_keycode(s, 0xe0);
 456                    ps2_put_keycode(s, 0xf0);
 457                    ps2_put_keycode(s, 0x12);
 458                }
 459            }
 460        } else {
 461            if (qcode < qemu_input_map_qcode_to_atset2_len)
 462                keycode = qemu_input_map_qcode_to_atset2[qcode];
 463            if (keycode) {
 464                if (keycode & 0xff00) {
 465                    ps2_put_keycode(s, keycode >> 8);
 466                }
 467                if (!key->down) {
 468                    ps2_put_keycode(s, 0xf0);
 469                }
 470                ps2_put_keycode(s, keycode & 0xff);
 471            } else {
 472                qemu_log_mask(LOG_UNIMP,
 473                              "ps2: ignoring key with qcode %d\n", qcode);
 474            }
 475        }
 476    } else if (s->scancode_set == 3) {
 477        if (qcode < qemu_input_map_qcode_to_atset3_len)
 478            keycode = qemu_input_map_qcode_to_atset3[qcode];
 479        if (keycode) {
 480            /* FIXME: break code should be configured on a key by key basis */
 481            if (!key->down) {
 482                ps2_put_keycode(s, 0xf0);
 483            }
 484            ps2_put_keycode(s, keycode);
 485        } else {
 486            qemu_log_mask(LOG_UNIMP,
 487                          "ps2: ignoring key with qcode %d\n", qcode);
 488        }
 489    }
 490}
 491
 492uint32_t ps2_read_data(PS2State *s)
 493{
 494    PS2Queue *q;
 495    int val, index;
 496
 497    trace_ps2_read_data(s);
 498    q = &s->queue;
 499    if (q->count == 0) {
 500        /* NOTE: if no data left, we return the last keyboard one
 501           (needed for EMM386) */
 502        /* XXX: need a timer to do things correctly */
 503        index = q->rptr - 1;
 504        if (index < 0)
 505            index = PS2_QUEUE_SIZE - 1;
 506        val = q->data[index];
 507    } else {
 508        val = q->data[q->rptr];
 509        if (++q->rptr == PS2_QUEUE_SIZE)
 510            q->rptr = 0;
 511        q->count--;
 512        /* reading deasserts IRQ */
 513        s->update_irq(s->update_arg, 0);
 514        /* reassert IRQs if data left */
 515        s->update_irq(s->update_arg, q->count != 0);
 516    }
 517    return val;
 518}
 519
 520static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
 521{
 522    trace_ps2_set_ledstate(s, ledstate);
 523    s->ledstate = ledstate;
 524    kbd_put_ledstate(ledstate);
 525}
 526
 527static void ps2_reset_keyboard(PS2KbdState *s)
 528{
 529    trace_ps2_reset_keyboard(s);
 530    s->scan_enabled = 1;
 531    s->scancode_set = 2;
 532    ps2_reset_queue(&s->common);
 533    ps2_set_ledstate(s, 0);
 534}
 535
 536void ps2_write_keyboard(void *opaque, int val)
 537{
 538    PS2KbdState *s = (PS2KbdState *)opaque;
 539
 540    trace_ps2_write_keyboard(opaque, val);
 541    switch(s->common.write_cmd) {
 542    default:
 543    case -1:
 544        switch(val) {
 545        case 0x00:
 546            ps2_queue(&s->common, KBD_REPLY_ACK);
 547            break;
 548        case 0x05:
 549            ps2_queue(&s->common, KBD_REPLY_RESEND);
 550            break;
 551        case KBD_CMD_GET_ID:
 552            /* We emulate a MF2 AT keyboard here */
 553            if (s->translate)
 554                ps2_queue_3(&s->common,
 555                    KBD_REPLY_ACK,
 556                    KBD_REPLY_ID,
 557                    0x41);
 558            else
 559                ps2_queue_3(&s->common,
 560                    KBD_REPLY_ACK,
 561                    KBD_REPLY_ID,
 562                    0x83);
 563            break;
 564        case KBD_CMD_ECHO:
 565            ps2_queue(&s->common, KBD_CMD_ECHO);
 566            break;
 567        case KBD_CMD_ENABLE:
 568            s->scan_enabled = 1;
 569            ps2_queue(&s->common, KBD_REPLY_ACK);
 570            break;
 571        case KBD_CMD_SCANCODE:
 572        case KBD_CMD_SET_LEDS:
 573        case KBD_CMD_SET_RATE:
 574            s->common.write_cmd = val;
 575            ps2_queue(&s->common, KBD_REPLY_ACK);
 576            break;
 577        case KBD_CMD_RESET_DISABLE:
 578            ps2_reset_keyboard(s);
 579            s->scan_enabled = 0;
 580            ps2_queue(&s->common, KBD_REPLY_ACK);
 581            break;
 582        case KBD_CMD_RESET_ENABLE:
 583            ps2_reset_keyboard(s);
 584            s->scan_enabled = 1;
 585            ps2_queue(&s->common, KBD_REPLY_ACK);
 586            break;
 587        case KBD_CMD_RESET:
 588            ps2_reset_keyboard(s);
 589            ps2_queue_2(&s->common,
 590                KBD_REPLY_ACK,
 591                KBD_REPLY_POR);
 592            break;
 593        default:
 594            ps2_queue(&s->common, KBD_REPLY_RESEND);
 595            break;
 596        }
 597        break;
 598    case KBD_CMD_SCANCODE:
 599        if (val == 0) {
 600            if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
 601                ps2_queue(&s->common, KBD_REPLY_ACK);
 602                ps2_put_keycode(s, s->scancode_set);
 603            }
 604        } else if (val >= 1 && val <= 3) {
 605            s->scancode_set = val;
 606            ps2_queue(&s->common, KBD_REPLY_ACK);
 607        } else {
 608            ps2_queue(&s->common, KBD_REPLY_RESEND);
 609        }
 610        s->common.write_cmd = -1;
 611        break;
 612    case KBD_CMD_SET_LEDS:
 613        ps2_set_ledstate(s, val);
 614        ps2_queue(&s->common, KBD_REPLY_ACK);
 615        s->common.write_cmd = -1;
 616        break;
 617    case KBD_CMD_SET_RATE:
 618        ps2_queue(&s->common, KBD_REPLY_ACK);
 619        s->common.write_cmd = -1;
 620        break;
 621    }
 622}
 623
 624/* Set the scancode translation mode.
 625   0 = raw scancodes.
 626   1 = translated scancodes (used by qemu internally).  */
 627
 628void ps2_keyboard_set_translation(void *opaque, int mode)
 629{
 630    PS2KbdState *s = (PS2KbdState *)opaque;
 631    trace_ps2_keyboard_set_translation(opaque, mode);
 632    s->translate = mode;
 633}
 634
 635static int ps2_mouse_send_packet(PS2MouseState *s)
 636{
 637    const int needed = 3 + (s->mouse_type - 2);
 638    unsigned int b;
 639    int dx1, dy1, dz1;
 640
 641    if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
 642        return 0;
 643    }
 644
 645    dx1 = s->mouse_dx;
 646    dy1 = s->mouse_dy;
 647    dz1 = s->mouse_dz;
 648    /* XXX: increase range to 8 bits ? */
 649    if (dx1 > 127)
 650        dx1 = 127;
 651    else if (dx1 < -127)
 652        dx1 = -127;
 653    if (dy1 > 127)
 654        dy1 = 127;
 655    else if (dy1 < -127)
 656        dy1 = -127;
 657    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
 658    ps2_queue_noirq(&s->common, b);
 659    ps2_queue_noirq(&s->common, dx1 & 0xff);
 660    ps2_queue_noirq(&s->common, dy1 & 0xff);
 661    /* extra byte for IMPS/2 or IMEX */
 662    switch(s->mouse_type) {
 663    default:
 664        break;
 665    case 3:
 666        if (dz1 > 127)
 667            dz1 = 127;
 668        else if (dz1 < -127)
 669                dz1 = -127;
 670        ps2_queue_noirq(&s->common, dz1 & 0xff);
 671        break;
 672    case 4:
 673        if (dz1 > 7)
 674            dz1 = 7;
 675        else if (dz1 < -7)
 676            dz1 = -7;
 677        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
 678        ps2_queue_noirq(&s->common, b);
 679        break;
 680    }
 681
 682    ps2_raise_irq(&s->common);
 683
 684    trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
 685    /* update deltas */
 686    s->mouse_dx -= dx1;
 687    s->mouse_dy -= dy1;
 688    s->mouse_dz -= dz1;
 689
 690    return 1;
 691}
 692
 693static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
 694                            InputEvent *evt)
 695{
 696    static const int bmap[INPUT_BUTTON__MAX] = {
 697        [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
 698        [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
 699        [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
 700        [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
 701        [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
 702    };
 703    PS2MouseState *s = (PS2MouseState *)dev;
 704    InputMoveEvent *move;
 705    InputBtnEvent *btn;
 706
 707    /* check if deltas are recorded when disabled */
 708    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
 709        return;
 710
 711    switch (evt->type) {
 712    case INPUT_EVENT_KIND_REL:
 713        move = evt->u.rel.data;
 714        if (move->axis == INPUT_AXIS_X) {
 715            s->mouse_dx += move->value;
 716        } else if (move->axis == INPUT_AXIS_Y) {
 717            s->mouse_dy -= move->value;
 718        }
 719        break;
 720
 721    case INPUT_EVENT_KIND_BTN:
 722        btn = evt->u.btn.data;
 723        if (btn->down) {
 724            s->mouse_buttons |= bmap[btn->button];
 725            if (btn->button == INPUT_BUTTON_WHEEL_UP) {
 726                s->mouse_dz--;
 727            } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
 728                s->mouse_dz++;
 729            }
 730        } else {
 731            s->mouse_buttons &= ~bmap[btn->button];
 732        }
 733        break;
 734
 735    default:
 736        /* keep gcc happy */
 737        break;
 738    }
 739}
 740
 741static void ps2_mouse_sync(DeviceState *dev)
 742{
 743    PS2MouseState *s = (PS2MouseState *)dev;
 744
 745    /* do not sync while disabled to prevent stream corruption */
 746    if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
 747        return;
 748    }
 749
 750    if (s->mouse_buttons) {
 751        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
 752    }
 753    if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
 754        /* if not remote, send event. Multiple events are sent if
 755           too big deltas */
 756        while (ps2_mouse_send_packet(s)) {
 757            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
 758                break;
 759        }
 760    }
 761}
 762
 763void ps2_mouse_fake_event(void *opaque)
 764{
 765    PS2MouseState *s = opaque;
 766    trace_ps2_mouse_fake_event(opaque);
 767    s->mouse_dx++;
 768    ps2_mouse_sync(opaque);
 769}
 770
 771void ps2_write_mouse(void *opaque, int val)
 772{
 773    PS2MouseState *s = (PS2MouseState *)opaque;
 774
 775    trace_ps2_write_mouse(opaque, val);
 776#ifdef DEBUG_MOUSE
 777    printf("kbd: write mouse 0x%02x\n", val);
 778#endif
 779    switch(s->common.write_cmd) {
 780    default:
 781    case -1:
 782        /* mouse command */
 783        if (s->mouse_wrap) {
 784            if (val == AUX_RESET_WRAP) {
 785                s->mouse_wrap = 0;
 786                ps2_queue(&s->common, AUX_ACK);
 787                return;
 788            } else if (val != AUX_RESET) {
 789                ps2_queue(&s->common, val);
 790                return;
 791            }
 792        }
 793        switch(val) {
 794        case AUX_SET_SCALE11:
 795            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
 796            ps2_queue(&s->common, AUX_ACK);
 797            break;
 798        case AUX_SET_SCALE21:
 799            s->mouse_status |= MOUSE_STATUS_SCALE21;
 800            ps2_queue(&s->common, AUX_ACK);
 801            break;
 802        case AUX_SET_STREAM:
 803            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
 804            ps2_queue(&s->common, AUX_ACK);
 805            break;
 806        case AUX_SET_WRAP:
 807            s->mouse_wrap = 1;
 808            ps2_queue(&s->common, AUX_ACK);
 809            break;
 810        case AUX_SET_REMOTE:
 811            s->mouse_status |= MOUSE_STATUS_REMOTE;
 812            ps2_queue(&s->common, AUX_ACK);
 813            break;
 814        case AUX_GET_TYPE:
 815            ps2_queue_2(&s->common,
 816                AUX_ACK,
 817                s->mouse_type);
 818            break;
 819        case AUX_SET_RES:
 820        case AUX_SET_SAMPLE:
 821            s->common.write_cmd = val;
 822            ps2_queue(&s->common, AUX_ACK);
 823            break;
 824        case AUX_GET_SCALE:
 825            ps2_queue_4(&s->common,
 826                AUX_ACK,
 827                s->mouse_status,
 828                s->mouse_resolution,
 829                s->mouse_sample_rate);
 830            break;
 831        case AUX_POLL:
 832            ps2_queue(&s->common, AUX_ACK);
 833            ps2_mouse_send_packet(s);
 834            break;
 835        case AUX_ENABLE_DEV:
 836            s->mouse_status |= MOUSE_STATUS_ENABLED;
 837            ps2_queue(&s->common, AUX_ACK);
 838            break;
 839        case AUX_DISABLE_DEV:
 840            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
 841            ps2_queue(&s->common, AUX_ACK);
 842            break;
 843        case AUX_SET_DEFAULT:
 844            s->mouse_sample_rate = 100;
 845            s->mouse_resolution = 2;
 846            s->mouse_status = 0;
 847            ps2_queue(&s->common, AUX_ACK);
 848            break;
 849        case AUX_RESET:
 850            s->mouse_sample_rate = 100;
 851            s->mouse_resolution = 2;
 852            s->mouse_status = 0;
 853            s->mouse_type = 0;
 854            ps2_reset_queue(&s->common);
 855            ps2_queue_3(&s->common,
 856                AUX_ACK,
 857                0xaa,
 858                s->mouse_type);
 859            break;
 860        default:
 861            break;
 862        }
 863        break;
 864    case AUX_SET_SAMPLE:
 865        s->mouse_sample_rate = val;
 866        /* detect IMPS/2 or IMEX */
 867        switch(s->mouse_detect_state) {
 868        default:
 869        case 0:
 870            if (val == 200)
 871                s->mouse_detect_state = 1;
 872            break;
 873        case 1:
 874            if (val == 100)
 875                s->mouse_detect_state = 2;
 876            else if (val == 200)
 877                s->mouse_detect_state = 3;
 878            else
 879                s->mouse_detect_state = 0;
 880            break;
 881        case 2:
 882            if (val == 80)
 883                s->mouse_type = 3; /* IMPS/2 */
 884            s->mouse_detect_state = 0;
 885            break;
 886        case 3:
 887            if (val == 80)
 888                s->mouse_type = 4; /* IMEX */
 889            s->mouse_detect_state = 0;
 890            break;
 891        }
 892        ps2_queue(&s->common, AUX_ACK);
 893        s->common.write_cmd = -1;
 894        break;
 895    case AUX_SET_RES:
 896        s->mouse_resolution = val;
 897        ps2_queue(&s->common, AUX_ACK);
 898        s->common.write_cmd = -1;
 899        break;
 900    }
 901}
 902
 903static void ps2_common_reset(PS2State *s)
 904{
 905    s->write_cmd = -1;
 906    ps2_reset_queue(s);
 907    s->update_irq(s->update_arg, 0);
 908}
 909
 910static void ps2_common_post_load(PS2State *s)
 911{
 912    PS2Queue *q = &s->queue;
 913    uint8_t i, size;
 914    uint8_t tmp_data[PS2_QUEUE_SIZE];
 915
 916    /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
 917    size = (q->count < 0 || q->count > PS2_QUEUE_SIZE) ? 0 : q->count;
 918
 919    /* move the queue elements to the start of data array */
 920    for (i = 0; i < size; i++) {
 921        if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
 922            q->rptr = 0;
 923        }
 924        tmp_data[i] = q->data[q->rptr++];
 925    }
 926    memcpy(q->data, tmp_data, size);
 927
 928    /* reset rptr/wptr/count */
 929    q->rptr = 0;
 930    q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
 931    q->count = size;
 932    s->update_irq(s->update_arg, q->count != 0);
 933}
 934
 935static void ps2_kbd_reset(void *opaque)
 936{
 937    PS2KbdState *s = (PS2KbdState *) opaque;
 938
 939    trace_ps2_kbd_reset(opaque);
 940    ps2_common_reset(&s->common);
 941    s->scan_enabled = 0;
 942    s->translate = 0;
 943    s->scancode_set = 2;
 944    s->modifiers = 0;
 945}
 946
 947static void ps2_mouse_reset(void *opaque)
 948{
 949    PS2MouseState *s = (PS2MouseState *) opaque;
 950
 951    trace_ps2_mouse_reset(opaque);
 952    ps2_common_reset(&s->common);
 953    s->mouse_status = 0;
 954    s->mouse_resolution = 0;
 955    s->mouse_sample_rate = 0;
 956    s->mouse_wrap = 0;
 957    s->mouse_type = 0;
 958    s->mouse_detect_state = 0;
 959    s->mouse_dx = 0;
 960    s->mouse_dy = 0;
 961    s->mouse_dz = 0;
 962    s->mouse_buttons = 0;
 963}
 964
 965static const VMStateDescription vmstate_ps2_common = {
 966    .name = "PS2 Common State",
 967    .version_id = 3,
 968    .minimum_version_id = 2,
 969    .fields = (VMStateField[]) {
 970        VMSTATE_INT32(write_cmd, PS2State),
 971        VMSTATE_INT32(queue.rptr, PS2State),
 972        VMSTATE_INT32(queue.wptr, PS2State),
 973        VMSTATE_INT32(queue.count, PS2State),
 974        VMSTATE_BUFFER(queue.data, PS2State),
 975        VMSTATE_END_OF_LIST()
 976    }
 977};
 978
 979static bool ps2_keyboard_ledstate_needed(void *opaque)
 980{
 981    PS2KbdState *s = opaque;
 982
 983    return s->ledstate != 0; /* 0 is default state */
 984}
 985
 986static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
 987{
 988    PS2KbdState *s = opaque;
 989
 990    kbd_put_ledstate(s->ledstate);
 991    return 0;
 992}
 993
 994static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
 995    .name = "ps2kbd/ledstate",
 996    .version_id = 3,
 997    .minimum_version_id = 2,
 998    .post_load = ps2_kbd_ledstate_post_load,
 999    .needed = ps2_keyboard_ledstate_needed,
1000    .fields = (VMStateField[]) {
1001        VMSTATE_INT32(ledstate, PS2KbdState),
1002        VMSTATE_END_OF_LIST()
1003    }
1004};
1005
1006static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1007{
1008    PS2KbdState *s = opaque;
1009    return s->need_high_bit != 0; /* 0 is the usual state */
1010}
1011
1012static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1013    .name = "ps2kbd/need_high_bit",
1014    .version_id = 1,
1015    .minimum_version_id = 1,
1016    .needed = ps2_keyboard_need_high_bit_needed,
1017    .fields = (VMStateField[]) {
1018        VMSTATE_BOOL(need_high_bit, PS2KbdState),
1019        VMSTATE_END_OF_LIST()
1020    }
1021};
1022
1023static int ps2_kbd_post_load(void* opaque, int version_id)
1024{
1025    PS2KbdState *s = (PS2KbdState*)opaque;
1026    PS2State *ps2 = &s->common;
1027
1028    if (version_id == 2)
1029        s->scancode_set=2;
1030
1031    ps2_common_post_load(ps2);
1032
1033    return 0;
1034}
1035
1036static int ps2_kbd_pre_save(void *opaque)
1037{
1038    PS2KbdState *s = (PS2KbdState *)opaque;
1039    PS2State *ps2 = &s->common;
1040
1041    ps2_common_post_load(ps2);
1042
1043    return 0;
1044}
1045
1046static const VMStateDescription vmstate_ps2_keyboard = {
1047    .name = "ps2kbd",
1048    .version_id = 3,
1049    .minimum_version_id = 2,
1050    .post_load = ps2_kbd_post_load,
1051    .pre_save = ps2_kbd_pre_save,
1052    .fields = (VMStateField[]) {
1053        VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1054        VMSTATE_INT32(scan_enabled, PS2KbdState),
1055        VMSTATE_INT32(translate, PS2KbdState),
1056        VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1057        VMSTATE_END_OF_LIST()
1058    },
1059    .subsections = (const VMStateDescription*[]) {
1060        &vmstate_ps2_keyboard_ledstate,
1061        &vmstate_ps2_keyboard_need_high_bit,
1062        NULL
1063    }
1064};
1065
1066static int ps2_mouse_post_load(void *opaque, int version_id)
1067{
1068    PS2MouseState *s = (PS2MouseState *)opaque;
1069    PS2State *ps2 = &s->common;
1070
1071    ps2_common_post_load(ps2);
1072
1073    return 0;
1074}
1075
1076static int ps2_mouse_pre_save(void *opaque)
1077{
1078    PS2MouseState *s = (PS2MouseState *)opaque;
1079    PS2State *ps2 = &s->common;
1080
1081    ps2_common_post_load(ps2);
1082
1083    return 0;
1084}
1085
1086static const VMStateDescription vmstate_ps2_mouse = {
1087    .name = "ps2mouse",
1088    .version_id = 2,
1089    .minimum_version_id = 2,
1090    .post_load = ps2_mouse_post_load,
1091    .pre_save = ps2_mouse_pre_save,
1092    .fields = (VMStateField[]) {
1093        VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1094        VMSTATE_UINT8(mouse_status, PS2MouseState),
1095        VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1096        VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1097        VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1098        VMSTATE_UINT8(mouse_type, PS2MouseState),
1099        VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1100        VMSTATE_INT32(mouse_dx, PS2MouseState),
1101        VMSTATE_INT32(mouse_dy, PS2MouseState),
1102        VMSTATE_INT32(mouse_dz, PS2MouseState),
1103        VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1104        VMSTATE_END_OF_LIST()
1105    }
1106};
1107
1108static QemuInputHandler ps2_keyboard_handler = {
1109    .name  = "QEMU PS/2 Keyboard",
1110    .mask  = INPUT_EVENT_MASK_KEY,
1111    .event = ps2_keyboard_event,
1112};
1113
1114void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1115{
1116    PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1117
1118    trace_ps2_kbd_init(s);
1119    s->common.update_irq = update_irq;
1120    s->common.update_arg = update_arg;
1121    s->scancode_set = 2;
1122    vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1123    qemu_input_handler_register((DeviceState *)s,
1124                                &ps2_keyboard_handler);
1125    qemu_register_reset(ps2_kbd_reset, s);
1126    return s;
1127}
1128
1129static QemuInputHandler ps2_mouse_handler = {
1130    .name  = "QEMU PS/2 Mouse",
1131    .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1132    .event = ps2_mouse_event,
1133    .sync  = ps2_mouse_sync,
1134};
1135
1136void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1137{
1138    PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1139
1140    trace_ps2_mouse_init(s);
1141    s->common.update_irq = update_irq;
1142    s->common.update_arg = update_arg;
1143    vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1144    qemu_input_handler_register((DeviceState *)s,
1145                                &ps2_mouse_handler);
1146    qemu_register_reset(ps2_mouse_reset, s);
1147    return s;
1148}
1149