xref: /qemu/hw/input/ps2.c (revision 57d5c005d35dc6d6d7e15a6b8c4d9ea16a7c738d)
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 }
887