ps2: allow keycode translation for all scancode sets
[sdk/emulator/qemu.git] / hw / input / ps2.c
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 "hw/hw.h"
26 #include "hw/input/ps2.h"
27 #include "ui/console.h"
28 #include "ui/input.h"
29 #include "sysemu/sysemu.h"
30
31 #include "trace.h"
32
33 /* debug PC keyboard */
34 //#define DEBUG_KBD
35
36 /* debug PC keyboard : only mouse */
37 //#define DEBUG_MOUSE
38
39 /* Keyboard Commands */
40 #define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
41 #define KBD_CMD_ECHO            0xEE
42 #define KBD_CMD_SCANCODE        0xF0    /* Get/set scancode set */
43 #define KBD_CMD_GET_ID          0xF2    /* get keyboard ID */
44 #define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
45 #define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
46 #define KBD_CMD_RESET_DISABLE   0xF5    /* reset and disable scanning */
47 #define KBD_CMD_RESET_ENABLE    0xF6    /* reset and enable scanning */
48 #define KBD_CMD_RESET           0xFF    /* Reset */
49
50 /* Keyboard Replies */
51 #define KBD_REPLY_POR           0xAA    /* Power on reset */
52 #define KBD_REPLY_ID            0xAB    /* Keyboard ID */
53 #define KBD_REPLY_ACK           0xFA    /* Command ACK */
54 #define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
55
56 /* Mouse Commands */
57 #define AUX_SET_SCALE11         0xE6    /* Set 1:1 scaling */
58 #define AUX_SET_SCALE21         0xE7    /* Set 2:1 scaling */
59 #define AUX_SET_RES             0xE8    /* Set resolution */
60 #define AUX_GET_SCALE           0xE9    /* Get scaling factor */
61 #define AUX_SET_STREAM          0xEA    /* Set stream mode */
62 #define AUX_POLL                0xEB    /* Poll */
63 #define AUX_RESET_WRAP          0xEC    /* Reset wrap mode */
64 #define AUX_SET_WRAP            0xEE    /* Set wrap mode */
65 #define AUX_SET_REMOTE          0xF0    /* Set remote mode */
66 #define AUX_GET_TYPE            0xF2    /* Get type */
67 #define AUX_SET_SAMPLE          0xF3    /* Set sample rate */
68 #define AUX_ENABLE_DEV          0xF4    /* Enable aux device */
69 #define AUX_DISABLE_DEV         0xF5    /* Disable aux device */
70 #define AUX_SET_DEFAULT         0xF6
71 #define AUX_RESET               0xFF    /* Reset aux device */
72 #define AUX_ACK                 0xFA    /* Command byte ACK. */
73
74 #define MOUSE_STATUS_REMOTE     0x40
75 #define MOUSE_STATUS_ENABLED    0x20
76 #define MOUSE_STATUS_SCALE21    0x10
77
78 #define PS2_QUEUE_SIZE 16  /* Buffer size required by PS/2 protocol */
79
80 typedef struct {
81     /* Keep the data array 256 bytes long, which compatibility
82      with older qemu versions. */
83     uint8_t data[256];
84     int rptr, wptr, count;
85 } PS2Queue;
86
87 typedef struct {
88     PS2Queue queue;
89     int32_t write_cmd;
90     void (*update_irq)(void *, int);
91     void *update_arg;
92 } PS2State;
93
94 typedef struct {
95     PS2State common;
96     int scan_enabled;
97     int translate;
98     int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
99     int ledstate;
100     bool need_high_bit;
101 } PS2KbdState;
102
103 typedef struct {
104     PS2State common;
105     uint8_t mouse_status;
106     uint8_t mouse_resolution;
107     uint8_t mouse_sample_rate;
108     uint8_t mouse_wrap;
109     uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
110     uint8_t mouse_detect_state;
111     int mouse_dx; /* current values, needed for 'poll' mode */
112     int mouse_dy;
113     int mouse_dz;
114     uint8_t mouse_buttons;
115 } PS2MouseState;
116
117 /* Table to convert from PC scancodes to raw scancodes.  */
118 static const unsigned char ps2_raw_keycode[128] = {
119   0, 118,  22,  30,  38,  37,  46,  54,  61,  62,  70,  69,  78,  85, 102,  13,
120  21,  29,  36,  45,  44,  53,  60,  67,  68,  77,  84,  91,  90,  20,  28,  27,
121  35,  43,  52,  51,  59,  66,  75,  76,  82,  14,  18,  93,  26,  34,  33,  42,
122  50,  49,  58,  65,  73,  74,  89, 124,  17,  41,  88,   5,   6,   4,  12,   3,
123  11,   2,  10,   1,   9, 119, 126, 108, 117, 125, 123, 107, 115, 116, 121, 105,
124 114, 122, 112, 113, 127,  96,  97, 120,   7,  15,  23,  31,  39,  47,  55,  63,
125  71,  79,  86,  94,   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  87, 111,
126  19,  25,  57,  81,  83,  92,  95,  98,  99, 100, 101, 103, 104, 106, 109, 110
127 };
128 static const unsigned char ps2_raw_keycode_set3[128] = {
129   0,   8,  22,  30,  38,  37,  46,  54,  61,  62,  70,  69,  78,  85, 102,  13,
130  21,  29,  36,  45,  44,  53,  60,  67,  68,  77,  84,  91,  90,  17,  28,  27,
131  35,  43,  52,  51,  59,  66,  75,  76,  82,  14,  18,  92,  26,  34,  33,  42,
132  50,  49,  58,  65,  73,  74,  89, 126,  25,  41,  20,   7,  15,  23,  31,  39,
133  47,   2,  63,  71,  79, 118,  95, 108, 117, 125, 132, 107, 115, 116, 124, 105,
134 114, 122, 112, 113, 127,  96,  97,  86,  94,  15,  23,  31,  39,  47,  55,  63,
135  71,  79,  86,  94,   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  87, 111,
136  19,  25,  57,  81,  83,  92,  95,  98,  99, 100, 101, 103, 104, 106, 109, 110
137 };
138
139 static uint8_t translate_table[256] = {
140     0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
141     0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
142     0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
143     0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
144     0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
145     0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
146     0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
147     0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
148     0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
149     0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
150     0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
151     0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
152     0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
153     0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
154     0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
155     0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
156     0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
157     0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
158     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
159     0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
160     0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
161     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
162     0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
163     0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
164     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
165     0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
166     0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
167     0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
168     0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
169     0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
170     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
171     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
172 };
173
174 void ps2_queue(void *opaque, int b)
175 {
176     PS2State *s = (PS2State *)opaque;
177     PS2Queue *q = &s->queue;
178
179     if (q->count >= PS2_QUEUE_SIZE - 1)
180         return;
181     q->data[q->wptr] = b;
182     if (++q->wptr == PS2_QUEUE_SIZE)
183         q->wptr = 0;
184     q->count++;
185     s->update_irq(s->update_arg, 1);
186 }
187
188 /* keycode is the untranslated scancode in the current scancode set. */
189 static void ps2_put_keycode(void *opaque, int keycode)
190 {
191     PS2KbdState *s = opaque;
192
193     trace_ps2_put_keycode(opaque, keycode);
194     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
195
196     if (s->translate) {
197         if (keycode == 0xf0) {
198             s->need_high_bit = true;
199         } else if (s->need_high_bit) {
200             ps2_queue(&s->common, translate_table[keycode] | 0x80);
201             s->need_high_bit = false;
202         } else {
203             ps2_queue(&s->common, translate_table[keycode]);
204         }
205     } else {
206         ps2_queue(&s->common, keycode);
207     }
208 }
209
210 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
211                                InputEvent *evt)
212 {
213     PS2KbdState *s = (PS2KbdState *)dev;
214     int scancodes[3], i, count;
215     InputKeyEvent *key = evt->u.key.data;
216     int keycode;
217
218     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
219     count = qemu_input_key_value_to_scancode(key->key,
220                                              key->down,
221                                              scancodes);
222
223     /* handle invalid key */
224     if (count == 1 && scancodes[0] == 0x00) {
225         ps2_queue(&s->common, 0x00);
226         return;
227     } else if (count == 1 && scancodes[0] == 0x80) {
228         if (s->translate || s->scancode_set == 1) {
229             ps2_queue(&s->common, 0x80);
230         } else {
231             ps2_queue(&s->common, 0xf0);
232             ps2_queue(&s->common, 0x00);
233         }
234         return;
235     }
236
237     for (i = 0; i < count; i++) {
238         /* XXX: add support for scancode set 1 */
239         keycode = scancodes[i];
240         if (keycode < 0xe0 && (s->scancode_set > 1 || s->translate)) {
241             if (keycode & 0x80) {
242                 ps2_put_keycode(&s->common, 0xf0);
243             }
244             if (s->scancode_set == 1 || s->scancode_set == 2) {
245                 keycode = ps2_raw_keycode[keycode & 0x7f];
246             } else if (s->scancode_set == 3) {
247                 keycode = ps2_raw_keycode_set3[keycode & 0x7f];
248             }
249         }
250         ps2_put_keycode(s, keycode);
251     }
252 }
253
254 uint32_t ps2_read_data(void *opaque)
255 {
256     PS2State *s = (PS2State *)opaque;
257     PS2Queue *q;
258     int val, index;
259
260     trace_ps2_read_data(opaque);
261     q = &s->queue;
262     if (q->count == 0) {
263         /* NOTE: if no data left, we return the last keyboard one
264            (needed for EMM386) */
265         /* XXX: need a timer to do things correctly */
266         index = q->rptr - 1;
267         if (index < 0)
268             index = PS2_QUEUE_SIZE - 1;
269         val = q->data[index];
270     } else {
271         val = q->data[q->rptr];
272         if (++q->rptr == PS2_QUEUE_SIZE)
273             q->rptr = 0;
274         q->count--;
275         /* reading deasserts IRQ */
276         s->update_irq(s->update_arg, 0);
277         /* reassert IRQs if data left */
278         s->update_irq(s->update_arg, q->count != 0);
279     }
280     return val;
281 }
282
283 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
284 {
285     trace_ps2_set_ledstate(s, ledstate);
286     s->ledstate = ledstate;
287     kbd_put_ledstate(ledstate);
288 }
289
290 static void ps2_reset_keyboard(PS2KbdState *s)
291 {
292     trace_ps2_reset_keyboard(s);
293     s->scan_enabled = 1;
294     s->scancode_set = 2;
295     ps2_set_ledstate(s, 0);
296 }
297
298 void ps2_write_keyboard(void *opaque, int val)
299 {
300     PS2KbdState *s = (PS2KbdState *)opaque;
301
302     trace_ps2_write_keyboard(opaque, val);
303     switch(s->common.write_cmd) {
304     default:
305     case -1:
306         switch(val) {
307         case 0x00:
308             ps2_queue(&s->common, KBD_REPLY_ACK);
309             break;
310         case 0x05:
311             ps2_queue(&s->common, KBD_REPLY_RESEND);
312             break;
313         case KBD_CMD_GET_ID:
314             ps2_queue(&s->common, KBD_REPLY_ACK);
315             /* We emulate a MF2 AT keyboard here */
316             ps2_queue(&s->common, KBD_REPLY_ID);
317             if (s->translate)
318                 ps2_queue(&s->common, 0x41);
319             else
320                 ps2_queue(&s->common, 0x83);
321             break;
322         case KBD_CMD_ECHO:
323             ps2_queue(&s->common, KBD_CMD_ECHO);
324             break;
325         case KBD_CMD_ENABLE:
326             s->scan_enabled = 1;
327             ps2_queue(&s->common, KBD_REPLY_ACK);
328             break;
329         case KBD_CMD_SCANCODE:
330         case KBD_CMD_SET_LEDS:
331         case KBD_CMD_SET_RATE:
332             s->common.write_cmd = val;
333             ps2_queue(&s->common, KBD_REPLY_ACK);
334             break;
335         case KBD_CMD_RESET_DISABLE:
336             ps2_reset_keyboard(s);
337             s->scan_enabled = 0;
338             ps2_queue(&s->common, KBD_REPLY_ACK);
339             break;
340         case KBD_CMD_RESET_ENABLE:
341             ps2_reset_keyboard(s);
342             s->scan_enabled = 1;
343             ps2_queue(&s->common, KBD_REPLY_ACK);
344             break;
345         case KBD_CMD_RESET:
346             ps2_reset_keyboard(s);
347             ps2_queue(&s->common, KBD_REPLY_ACK);
348             ps2_queue(&s->common, KBD_REPLY_POR);
349             break;
350         default:
351             ps2_queue(&s->common, KBD_REPLY_RESEND);
352             break;
353         }
354         break;
355     case KBD_CMD_SCANCODE:
356         if (val == 0) {
357             ps2_queue(&s->common, KBD_REPLY_ACK);
358             ps2_put_keycode(s, s->scancode_set);
359         } else if (val >= 1 && val <= 3) {
360             s->scancode_set = val;
361             ps2_queue(&s->common, KBD_REPLY_ACK);
362         } else {
363             ps2_queue(&s->common, KBD_REPLY_RESEND);
364         }
365         s->common.write_cmd = -1;
366         break;
367     case KBD_CMD_SET_LEDS:
368         ps2_set_ledstate(s, val);
369         ps2_queue(&s->common, KBD_REPLY_ACK);
370         s->common.write_cmd = -1;
371         break;
372     case KBD_CMD_SET_RATE:
373         ps2_queue(&s->common, KBD_REPLY_ACK);
374         s->common.write_cmd = -1;
375         break;
376     }
377 }
378
379 /* Set the scancode translation mode.
380    0 = raw scancodes.
381    1 = translated scancodes (used by qemu internally).  */
382
383 void ps2_keyboard_set_translation(void *opaque, int mode)
384 {
385     PS2KbdState *s = (PS2KbdState *)opaque;
386     trace_ps2_keyboard_set_translation(opaque, mode);
387     s->translate = mode;
388 }
389
390 static void ps2_mouse_send_packet(PS2MouseState *s)
391 {
392     unsigned int b;
393     int dx1, dy1, dz1;
394
395     dx1 = s->mouse_dx;
396     dy1 = s->mouse_dy;
397     dz1 = s->mouse_dz;
398     /* XXX: increase range to 8 bits ? */
399     if (dx1 > 127)
400         dx1 = 127;
401     else if (dx1 < -127)
402         dx1 = -127;
403     if (dy1 > 127)
404         dy1 = 127;
405     else if (dy1 < -127)
406         dy1 = -127;
407     b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
408     ps2_queue(&s->common, b);
409     ps2_queue(&s->common, dx1 & 0xff);
410     ps2_queue(&s->common, dy1 & 0xff);
411     /* extra byte for IMPS/2 or IMEX */
412     switch(s->mouse_type) {
413     default:
414         break;
415     case 3:
416         if (dz1 > 127)
417             dz1 = 127;
418         else if (dz1 < -127)
419                 dz1 = -127;
420         ps2_queue(&s->common, dz1 & 0xff);
421         break;
422     case 4:
423         if (dz1 > 7)
424             dz1 = 7;
425         else if (dz1 < -7)
426             dz1 = -7;
427         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
428         ps2_queue(&s->common, b);
429         break;
430     }
431
432     trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
433     /* update deltas */
434     s->mouse_dx -= dx1;
435     s->mouse_dy -= dy1;
436     s->mouse_dz -= dz1;
437 }
438
439 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
440                             InputEvent *evt)
441 {
442     static const int bmap[INPUT_BUTTON__MAX] = {
443         [INPUT_BUTTON_LEFT]   = MOUSE_EVENT_LBUTTON,
444         [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
445         [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON,
446     };
447     PS2MouseState *s = (PS2MouseState *)dev;
448     InputMoveEvent *move;
449     InputBtnEvent *btn;
450
451     /* check if deltas are recorded when disabled */
452     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
453         return;
454
455     switch (evt->type) {
456     case INPUT_EVENT_KIND_REL:
457         move = evt->u.rel.data;
458         if (move->axis == INPUT_AXIS_X) {
459             s->mouse_dx += move->value;
460         } else if (move->axis == INPUT_AXIS_Y) {
461             s->mouse_dy -= move->value;
462         }
463         break;
464
465     case INPUT_EVENT_KIND_BTN:
466         btn = evt->u.btn.data;
467         if (btn->down) {
468             s->mouse_buttons |= bmap[btn->button];
469             if (btn->button == INPUT_BUTTON_WHEEL_UP) {
470                 s->mouse_dz--;
471             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
472                 s->mouse_dz++;
473             }
474         } else {
475             s->mouse_buttons &= ~bmap[btn->button];
476         }
477         break;
478
479     default:
480         /* keep gcc happy */
481         break;
482     }
483 }
484
485 static void ps2_mouse_sync(DeviceState *dev)
486 {
487     PS2MouseState *s = (PS2MouseState *)dev;
488
489     if (s->mouse_buttons) {
490         qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
491     }
492     if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
493         while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
494             /* if not remote, send event. Multiple events are sent if
495                too big deltas */
496             ps2_mouse_send_packet(s);
497             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
498                 break;
499         }
500     }
501 }
502
503 void ps2_mouse_fake_event(void *opaque)
504 {
505     PS2MouseState *s = opaque;
506     trace_ps2_mouse_fake_event(opaque);
507     s->mouse_dx++;
508     ps2_mouse_sync(opaque);
509 }
510
511 void ps2_write_mouse(void *opaque, int val)
512 {
513     PS2MouseState *s = (PS2MouseState *)opaque;
514
515     trace_ps2_write_mouse(opaque, val);
516 #ifdef DEBUG_MOUSE
517     printf("kbd: write mouse 0x%02x\n", val);
518 #endif
519     switch(s->common.write_cmd) {
520     default:
521     case -1:
522         /* mouse command */
523         if (s->mouse_wrap) {
524             if (val == AUX_RESET_WRAP) {
525                 s->mouse_wrap = 0;
526                 ps2_queue(&s->common, AUX_ACK);
527                 return;
528             } else if (val != AUX_RESET) {
529                 ps2_queue(&s->common, val);
530                 return;
531             }
532         }
533         switch(val) {
534         case AUX_SET_SCALE11:
535             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
536             ps2_queue(&s->common, AUX_ACK);
537             break;
538         case AUX_SET_SCALE21:
539             s->mouse_status |= MOUSE_STATUS_SCALE21;
540             ps2_queue(&s->common, AUX_ACK);
541             break;
542         case AUX_SET_STREAM:
543             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
544             ps2_queue(&s->common, AUX_ACK);
545             break;
546         case AUX_SET_WRAP:
547             s->mouse_wrap = 1;
548             ps2_queue(&s->common, AUX_ACK);
549             break;
550         case AUX_SET_REMOTE:
551             s->mouse_status |= MOUSE_STATUS_REMOTE;
552             ps2_queue(&s->common, AUX_ACK);
553             break;
554         case AUX_GET_TYPE:
555             ps2_queue(&s->common, AUX_ACK);
556             ps2_queue(&s->common, s->mouse_type);
557             break;
558         case AUX_SET_RES:
559         case AUX_SET_SAMPLE:
560             s->common.write_cmd = val;
561             ps2_queue(&s->common, AUX_ACK);
562             break;
563         case AUX_GET_SCALE:
564             ps2_queue(&s->common, AUX_ACK);
565             ps2_queue(&s->common, s->mouse_status);
566             ps2_queue(&s->common, s->mouse_resolution);
567             ps2_queue(&s->common, s->mouse_sample_rate);
568             break;
569         case AUX_POLL:
570             ps2_queue(&s->common, AUX_ACK);
571             ps2_mouse_send_packet(s);
572             break;
573         case AUX_ENABLE_DEV:
574             s->mouse_status |= MOUSE_STATUS_ENABLED;
575             ps2_queue(&s->common, AUX_ACK);
576             break;
577         case AUX_DISABLE_DEV:
578             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
579             ps2_queue(&s->common, AUX_ACK);
580             break;
581         case AUX_SET_DEFAULT:
582             s->mouse_sample_rate = 100;
583             s->mouse_resolution = 2;
584             s->mouse_status = 0;
585             ps2_queue(&s->common, AUX_ACK);
586             break;
587         case AUX_RESET:
588             s->mouse_sample_rate = 100;
589             s->mouse_resolution = 2;
590             s->mouse_status = 0;
591             s->mouse_type = 0;
592             ps2_queue(&s->common, AUX_ACK);
593             ps2_queue(&s->common, 0xaa);
594             ps2_queue(&s->common, s->mouse_type);
595             break;
596         default:
597             break;
598         }
599         break;
600     case AUX_SET_SAMPLE:
601         s->mouse_sample_rate = val;
602         /* detect IMPS/2 or IMEX */
603         switch(s->mouse_detect_state) {
604         default:
605         case 0:
606             if (val == 200)
607                 s->mouse_detect_state = 1;
608             break;
609         case 1:
610             if (val == 100)
611                 s->mouse_detect_state = 2;
612             else if (val == 200)
613                 s->mouse_detect_state = 3;
614             else
615                 s->mouse_detect_state = 0;
616             break;
617         case 2:
618             if (val == 80)
619                 s->mouse_type = 3; /* IMPS/2 */
620             s->mouse_detect_state = 0;
621             break;
622         case 3:
623             if (val == 80)
624                 s->mouse_type = 4; /* IMEX */
625             s->mouse_detect_state = 0;
626             break;
627         }
628         ps2_queue(&s->common, AUX_ACK);
629         s->common.write_cmd = -1;
630         break;
631     case AUX_SET_RES:
632         s->mouse_resolution = val;
633         ps2_queue(&s->common, AUX_ACK);
634         s->common.write_cmd = -1;
635         break;
636     }
637 }
638
639 static void ps2_common_reset(PS2State *s)
640 {
641     PS2Queue *q;
642     s->write_cmd = -1;
643     q = &s->queue;
644     q->rptr = 0;
645     q->wptr = 0;
646     q->count = 0;
647     s->update_irq(s->update_arg, 0);
648 }
649
650 static void ps2_common_post_load(PS2State *s)
651 {
652     PS2Queue *q = &s->queue;
653     int size;
654     int i;
655     int tmp_data[PS2_QUEUE_SIZE];
656
657     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
658     size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
659
660     /* move the queue elements to the start of data array */
661     if (size > 0) {
662         for (i = 0; i < size; i++) {
663             /* move the queue elements to the temporary buffer */
664             tmp_data[i] = q->data[q->rptr];
665             if (++q->rptr == 256) {
666                 q->rptr = 0;
667             }
668         }
669         memcpy(q->data, tmp_data, size);
670     }
671     /* reset rptr/wptr/count */
672     q->rptr = 0;
673     q->wptr = size;
674     q->count = size;
675     s->update_irq(s->update_arg, q->count != 0);
676 }
677
678 static void ps2_kbd_reset(void *opaque)
679 {
680     PS2KbdState *s = (PS2KbdState *) opaque;
681
682     trace_ps2_kbd_reset(opaque);
683     ps2_common_reset(&s->common);
684     s->scan_enabled = 0;
685     s->translate = 0;
686     s->scancode_set = 2;
687 }
688
689 static void ps2_mouse_reset(void *opaque)
690 {
691     PS2MouseState *s = (PS2MouseState *) opaque;
692
693     trace_ps2_mouse_reset(opaque);
694     ps2_common_reset(&s->common);
695     s->mouse_status = 0;
696     s->mouse_resolution = 0;
697     s->mouse_sample_rate = 0;
698     s->mouse_wrap = 0;
699     s->mouse_type = 0;
700     s->mouse_detect_state = 0;
701     s->mouse_dx = 0;
702     s->mouse_dy = 0;
703     s->mouse_dz = 0;
704     s->mouse_buttons = 0;
705 }
706
707 static const VMStateDescription vmstate_ps2_common = {
708     .name = "PS2 Common State",
709     .version_id = 3,
710     .minimum_version_id = 2,
711     .fields = (VMStateField[]) {
712         VMSTATE_INT32(write_cmd, PS2State),
713         VMSTATE_INT32(queue.rptr, PS2State),
714         VMSTATE_INT32(queue.wptr, PS2State),
715         VMSTATE_INT32(queue.count, PS2State),
716         VMSTATE_BUFFER(queue.data, PS2State),
717         VMSTATE_END_OF_LIST()
718     }
719 };
720
721 static bool ps2_keyboard_ledstate_needed(void *opaque)
722 {
723     PS2KbdState *s = opaque;
724
725     return s->ledstate != 0; /* 0 is default state */
726 }
727
728 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
729 {
730     PS2KbdState *s = opaque;
731
732     kbd_put_ledstate(s->ledstate);
733     return 0;
734 }
735
736 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
737     .name = "ps2kbd/ledstate",
738     .version_id = 3,
739     .minimum_version_id = 2,
740     .post_load = ps2_kbd_ledstate_post_load,
741     .needed = ps2_keyboard_ledstate_needed,
742     .fields = (VMStateField[]) {
743         VMSTATE_INT32(ledstate, PS2KbdState),
744         VMSTATE_END_OF_LIST()
745     }
746 };
747
748 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
749 {
750     PS2KbdState *s = opaque;
751     return s->need_high_bit != 0; /* 0 is the usual state */
752 }
753
754 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
755     .name = "ps2kbd/need_high_bit",
756     .version_id = 1,
757     .minimum_version_id = 1,
758     .needed = ps2_keyboard_need_high_bit_needed,
759     .fields = (VMStateField[]) {
760         VMSTATE_BOOL(need_high_bit, PS2KbdState),
761         VMSTATE_END_OF_LIST()
762     }
763 };
764
765 static int ps2_kbd_post_load(void* opaque, int version_id)
766 {
767     PS2KbdState *s = (PS2KbdState*)opaque;
768     PS2State *ps2 = &s->common;
769
770     if (version_id == 2)
771         s->scancode_set=2;
772
773     ps2_common_post_load(ps2);
774
775     return 0;
776 }
777
778 static void ps2_kbd_pre_save(void *opaque)
779 {
780     PS2KbdState *s = (PS2KbdState *)opaque;
781     PS2State *ps2 = &s->common;
782
783     ps2_common_post_load(ps2);
784 }
785
786 static const VMStateDescription vmstate_ps2_keyboard = {
787     .name = "ps2kbd",
788     .version_id = 3,
789     .minimum_version_id = 2,
790     .post_load = ps2_kbd_post_load,
791     .pre_save = ps2_kbd_pre_save,
792     .fields = (VMStateField[]) {
793         VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
794         VMSTATE_INT32(scan_enabled, PS2KbdState),
795         VMSTATE_INT32(translate, PS2KbdState),
796         VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
797         VMSTATE_END_OF_LIST()
798     },
799     .subsections = (const VMStateDescription*[]) {
800         &vmstate_ps2_keyboard_ledstate,
801         &vmstate_ps2_keyboard_need_high_bit,
802         NULL
803     }
804 };
805
806 static int ps2_mouse_post_load(void *opaque, int version_id)
807 {
808     PS2MouseState *s = (PS2MouseState *)opaque;
809     PS2State *ps2 = &s->common;
810
811     ps2_common_post_load(ps2);
812
813     return 0;
814 }
815
816 static void ps2_mouse_pre_save(void *opaque)
817 {
818     PS2MouseState *s = (PS2MouseState *)opaque;
819     PS2State *ps2 = &s->common;
820
821     ps2_common_post_load(ps2);
822 }
823
824 static const VMStateDescription vmstate_ps2_mouse = {
825     .name = "ps2mouse",
826     .version_id = 2,
827     .minimum_version_id = 2,
828     .post_load = ps2_mouse_post_load,
829     .pre_save = ps2_mouse_pre_save,
830     .fields = (VMStateField[]) {
831         VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
832         VMSTATE_UINT8(mouse_status, PS2MouseState),
833         VMSTATE_UINT8(mouse_resolution, PS2MouseState),
834         VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
835         VMSTATE_UINT8(mouse_wrap, PS2MouseState),
836         VMSTATE_UINT8(mouse_type, PS2MouseState),
837         VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
838         VMSTATE_INT32(mouse_dx, PS2MouseState),
839         VMSTATE_INT32(mouse_dy, PS2MouseState),
840         VMSTATE_INT32(mouse_dz, PS2MouseState),
841         VMSTATE_UINT8(mouse_buttons, PS2MouseState),
842         VMSTATE_END_OF_LIST()
843     }
844 };
845
846 static QemuInputHandler ps2_keyboard_handler = {
847     .name  = "QEMU PS/2 Keyboard",
848     .mask  = INPUT_EVENT_MASK_KEY,
849     .event = ps2_keyboard_event,
850 };
851
852 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
853 {
854     PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
855
856     trace_ps2_kbd_init(s);
857     s->common.update_irq = update_irq;
858     s->common.update_arg = update_arg;
859     s->scancode_set = 2;
860     vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
861     qemu_input_handler_register((DeviceState *)s,
862                                 &ps2_keyboard_handler);
863     qemu_register_reset(ps2_kbd_reset, s);
864     return s;
865 }
866
867 static QemuInputHandler ps2_mouse_handler = {
868     .name  = "QEMU PS/2 Mouse",
869     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
870     .event = ps2_mouse_event,
871     .sync  = ps2_mouse_sync,
872 };
873
874 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
875 {
876     PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
877
878     trace_ps2_mouse_init(s);
879     s->common.update_irq = update_irq;
880     s->common.update_arg = update_arg;
881     vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
882     qemu_input_handler_register((DeviceState *)s,
883                                 &ps2_mouse_handler);
884     qemu_register_reset(ps2_mouse_reset, s);
885     return s;
886 }