cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

ps2.c (37034B)


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