xref: /qemu/hw/input/ps2.c (revision bfa3ab61)
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 "hw/hw.h"
25 #include "hw/input/ps2.h"
26 #include "ui/console.h"
27 #include "ui/input.h"
28 #include "sysemu/sysemu.h"
29 
30 #include "trace.h"
31 
32 /* debug PC keyboard */
33 //#define DEBUG_KBD
34 
35 /* debug PC keyboard : only mouse */
36 //#define DEBUG_MOUSE
37 
38 /* Keyboard Commands */
39 #define KBD_CMD_SET_LEDS	0xED	/* Set keyboard leds */
40 #define KBD_CMD_ECHO     	0xEE
41 #define KBD_CMD_SCANCODE	0xF0	/* Get/set scancode set */
42 #define KBD_CMD_GET_ID 	        0xF2	/* get keyboard ID */
43 #define KBD_CMD_SET_RATE	0xF3	/* Set typematic rate */
44 #define KBD_CMD_ENABLE		0xF4	/* Enable scanning */
45 #define KBD_CMD_RESET_DISABLE	0xF5	/* reset and disable scanning */
46 #define KBD_CMD_RESET_ENABLE   	0xF6    /* reset and enable scanning */
47 #define KBD_CMD_RESET		0xFF	/* Reset */
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 #define PS2_QUEUE_SIZE 16  /* Buffer size required by PS/2 protocol */
78 
79 typedef struct {
80     /* Keep the data array 256 bytes long, which compatibility
81      with older qemu versions. */
82     uint8_t data[256];
83     int rptr, wptr, count;
84 } PS2Queue;
85 
86 typedef struct {
87     PS2Queue queue;
88     int32_t write_cmd;
89     void (*update_irq)(void *, int);
90     void *update_arg;
91 } PS2State;
92 
93 typedef struct {
94     PS2State common;
95     int scan_enabled;
96     /* QEMU uses translated PC scancodes internally.  To avoid multiple
97        conversions we do the translation (if any) in the PS/2 emulation
98        not the keyboard controller.  */
99     int translate;
100     int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
101     int ledstate;
102 } PS2KbdState;
103 
104 typedef struct {
105     PS2State common;
106     uint8_t mouse_status;
107     uint8_t mouse_resolution;
108     uint8_t mouse_sample_rate;
109     uint8_t mouse_wrap;
110     uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
111     uint8_t mouse_detect_state;
112     int mouse_dx; /* current values, needed for 'poll' mode */
113     int mouse_dy;
114     int mouse_dz;
115     uint8_t mouse_buttons;
116 } PS2MouseState;
117 
118 /* Table to convert from PC scancodes to raw scancodes.  */
119 static const unsigned char ps2_raw_keycode[128] = {
120   0, 118,  22,  30,  38,  37,  46,  54,  61,  62,  70,  69,  78,  85, 102,  13,
121  21,  29,  36,  45,  44,  53,  60,  67,  68,  77,  84,  91,  90,  20,  28,  27,
122  35,  43,  52,  51,  59,  66,  75,  76,  82,  14,  18,  93,  26,  34,  33,  42,
123  50,  49,  58,  65,  73,  74,  89, 124,  17,  41,  88,   5,   6,   4,  12,   3,
124  11,   2,  10,   1,   9, 119, 126, 108, 117, 125, 123, 107, 115, 116, 121, 105,
125 114, 122, 112, 113, 127,  96,  97, 120,   7,  15,  23,  31,  39,  47,  55,  63,
126  71,  79,  86,  94,   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  87, 111,
127  19,  25,  57,  81,  83,  92,  95,  98,  99, 100, 101, 103, 104, 106, 109, 110
128 };
129 static const unsigned char ps2_raw_keycode_set3[128] = {
130   0,   8,  22,  30,  38,  37,  46,  54,  61,  62,  70,  69,  78,  85, 102,  13,
131  21,  29,  36,  45,  44,  53,  60,  67,  68,  77,  84,  91,  90,  17,  28,  27,
132  35,  43,  52,  51,  59,  66,  75,  76,  82,  14,  18,  92,  26,  34,  33,  42,
133  50,  49,  58,  65,  73,  74,  89, 126,  25,  41,  20,   7,  15,  23,  31,  39,
134  47,   2,  63,  71,  79, 118,  95, 108, 117, 125, 132, 107, 115, 116, 124, 105,
135 114, 122, 112, 113, 127,  96,  97,  86,  94,  15,  23,  31,  39,  47,  55,  63,
136  71,  79,  86,  94,   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  87, 111,
137  19,  25,  57,  81,  83,  92,  95,  98,  99, 100, 101, 103, 104, 106, 109, 110
138 };
139 
140 void ps2_queue(void *opaque, int b)
141 {
142     PS2State *s = (PS2State *)opaque;
143     PS2Queue *q = &s->queue;
144 
145     if (q->count >= PS2_QUEUE_SIZE - 1)
146         return;
147     q->data[q->wptr] = b;
148     if (++q->wptr == PS2_QUEUE_SIZE)
149         q->wptr = 0;
150     q->count++;
151     s->update_irq(s->update_arg, 1);
152 }
153 
154 /*
155    keycode is expressed as follow:
156    bit 7    - 0 key pressed, 1 = key released
157    bits 6-0 - translated scancode set 2
158  */
159 static void ps2_put_keycode(void *opaque, int keycode)
160 {
161     PS2KbdState *s = opaque;
162 
163     trace_ps2_put_keycode(opaque, keycode);
164     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
165     /* XXX: add support for scancode set 1 */
166     if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) {
167         if (keycode & 0x80) {
168             ps2_queue(&s->common, 0xf0);
169         }
170         if (s->scancode_set == 2) {
171             keycode = ps2_raw_keycode[keycode & 0x7f];
172         } else if (s->scancode_set == 3) {
173             keycode = ps2_raw_keycode_set3[keycode & 0x7f];
174         }
175       }
176     ps2_queue(&s->common, keycode);
177 }
178 
179 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
180                                InputEvent *evt)
181 {
182     PS2KbdState *s = (PS2KbdState *)dev;
183     int scancodes[3], i, count;
184 
185     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
186     count = qemu_input_key_value_to_scancode(evt->key->key,
187                                              evt->key->down,
188                                              scancodes);
189     for (i = 0; i < count; i++) {
190         ps2_put_keycode(s, scancodes[i]);
191     }
192 }
193 
194 uint32_t ps2_read_data(void *opaque)
195 {
196     PS2State *s = (PS2State *)opaque;
197     PS2Queue *q;
198     int val, index;
199 
200     trace_ps2_read_data(opaque);
201     q = &s->queue;
202     if (q->count == 0) {
203         /* NOTE: if no data left, we return the last keyboard one
204            (needed for EMM386) */
205         /* XXX: need a timer to do things correctly */
206         index = q->rptr - 1;
207         if (index < 0)
208             index = PS2_QUEUE_SIZE - 1;
209         val = q->data[index];
210     } else {
211         val = q->data[q->rptr];
212         if (++q->rptr == PS2_QUEUE_SIZE)
213             q->rptr = 0;
214         q->count--;
215         /* reading deasserts IRQ */
216         s->update_irq(s->update_arg, 0);
217         /* reassert IRQs if data left */
218         s->update_irq(s->update_arg, q->count != 0);
219     }
220     return val;
221 }
222 
223 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
224 {
225     trace_ps2_set_ledstate(s, ledstate);
226     s->ledstate = ledstate;
227     kbd_put_ledstate(ledstate);
228 }
229 
230 static void ps2_reset_keyboard(PS2KbdState *s)
231 {
232     trace_ps2_reset_keyboard(s);
233     s->scan_enabled = 1;
234     s->scancode_set = 2;
235     ps2_set_ledstate(s, 0);
236 }
237 
238 void ps2_write_keyboard(void *opaque, int val)
239 {
240     PS2KbdState *s = (PS2KbdState *)opaque;
241 
242     trace_ps2_write_keyboard(opaque, val);
243     switch(s->common.write_cmd) {
244     default:
245     case -1:
246         switch(val) {
247         case 0x00:
248             ps2_queue(&s->common, KBD_REPLY_ACK);
249             break;
250         case 0x05:
251             ps2_queue(&s->common, KBD_REPLY_RESEND);
252             break;
253         case KBD_CMD_GET_ID:
254             ps2_queue(&s->common, KBD_REPLY_ACK);
255             /* We emulate a MF2 AT keyboard here */
256             ps2_queue(&s->common, KBD_REPLY_ID);
257             if (s->translate)
258                 ps2_queue(&s->common, 0x41);
259             else
260                 ps2_queue(&s->common, 0x83);
261             break;
262         case KBD_CMD_ECHO:
263             ps2_queue(&s->common, KBD_CMD_ECHO);
264             break;
265         case KBD_CMD_ENABLE:
266             s->scan_enabled = 1;
267             ps2_queue(&s->common, KBD_REPLY_ACK);
268             break;
269         case KBD_CMD_SCANCODE:
270         case KBD_CMD_SET_LEDS:
271         case KBD_CMD_SET_RATE:
272             s->common.write_cmd = val;
273             ps2_queue(&s->common, KBD_REPLY_ACK);
274             break;
275         case KBD_CMD_RESET_DISABLE:
276             ps2_reset_keyboard(s);
277             s->scan_enabled = 0;
278             ps2_queue(&s->common, KBD_REPLY_ACK);
279             break;
280         case KBD_CMD_RESET_ENABLE:
281             ps2_reset_keyboard(s);
282             s->scan_enabled = 1;
283             ps2_queue(&s->common, KBD_REPLY_ACK);
284             break;
285         case KBD_CMD_RESET:
286             ps2_reset_keyboard(s);
287             ps2_queue(&s->common, KBD_REPLY_ACK);
288             ps2_queue(&s->common, KBD_REPLY_POR);
289             break;
290         default:
291             ps2_queue(&s->common, KBD_REPLY_ACK);
292             break;
293         }
294         break;
295     case KBD_CMD_SCANCODE:
296         if (val == 0) {
297             if (s->scancode_set == 1)
298                 ps2_put_keycode(s, 0x43);
299             else if (s->scancode_set == 2)
300                 ps2_put_keycode(s, 0x41);
301             else if (s->scancode_set == 3)
302                 ps2_put_keycode(s, 0x3f);
303         } else {
304             if (val >= 1 && val <= 3)
305                 s->scancode_set = val;
306             ps2_queue(&s->common, KBD_REPLY_ACK);
307         }
308         s->common.write_cmd = -1;
309         break;
310     case KBD_CMD_SET_LEDS:
311         ps2_set_ledstate(s, val);
312         ps2_queue(&s->common, KBD_REPLY_ACK);
313         s->common.write_cmd = -1;
314         break;
315     case KBD_CMD_SET_RATE:
316         ps2_queue(&s->common, KBD_REPLY_ACK);
317         s->common.write_cmd = -1;
318         break;
319     }
320 }
321 
322 /* Set the scancode translation mode.
323    0 = raw scancodes.
324    1 = translated scancodes (used by qemu internally).  */
325 
326 void ps2_keyboard_set_translation(void *opaque, int mode)
327 {
328     PS2KbdState *s = (PS2KbdState *)opaque;
329     trace_ps2_keyboard_set_translation(opaque, mode);
330     s->translate = mode;
331 }
332 
333 static void ps2_mouse_send_packet(PS2MouseState *s)
334 {
335     unsigned int b;
336     int dx1, dy1, dz1;
337 
338     dx1 = s->mouse_dx;
339     dy1 = s->mouse_dy;
340     dz1 = s->mouse_dz;
341     /* XXX: increase range to 8 bits ? */
342     if (dx1 > 127)
343         dx1 = 127;
344     else if (dx1 < -127)
345         dx1 = -127;
346     if (dy1 > 127)
347         dy1 = 127;
348     else if (dy1 < -127)
349         dy1 = -127;
350     b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
351     ps2_queue(&s->common, b);
352     ps2_queue(&s->common, dx1 & 0xff);
353     ps2_queue(&s->common, dy1 & 0xff);
354     /* extra byte for IMPS/2 or IMEX */
355     switch(s->mouse_type) {
356     default:
357         break;
358     case 3:
359         if (dz1 > 127)
360             dz1 = 127;
361         else if (dz1 < -127)
362                 dz1 = -127;
363         ps2_queue(&s->common, dz1 & 0xff);
364         break;
365     case 4:
366         if (dz1 > 7)
367             dz1 = 7;
368         else if (dz1 < -7)
369             dz1 = -7;
370         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
371         ps2_queue(&s->common, b);
372         break;
373     }
374 
375     trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
376     /* update deltas */
377     s->mouse_dx -= dx1;
378     s->mouse_dy -= dy1;
379     s->mouse_dz -= dz1;
380 }
381 
382 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
383                             InputEvent *evt)
384 {
385     static const int bmap[INPUT_BUTTON_MAX] = {
386         [INPUT_BUTTON_LEFT]   = MOUSE_EVENT_LBUTTON,
387         [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
388         [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON,
389     };
390     PS2MouseState *s = (PS2MouseState *)dev;
391 
392     /* check if deltas are recorded when disabled */
393     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
394         return;
395 
396     switch (evt->kind) {
397     case INPUT_EVENT_KIND_REL:
398         if (evt->rel->axis == INPUT_AXIS_X) {
399             s->mouse_dx += evt->rel->value;
400         } else if (evt->rel->axis == INPUT_AXIS_Y) {
401             s->mouse_dy -= evt->rel->value;
402         }
403         break;
404 
405     case INPUT_EVENT_KIND_BTN:
406         if (evt->btn->down) {
407             s->mouse_buttons |= bmap[evt->btn->button];
408             if (evt->btn->button == INPUT_BUTTON_WHEEL_UP) {
409                 s->mouse_dz--;
410             } else if (evt->btn->button == INPUT_BUTTON_WHEEL_DOWN) {
411                 s->mouse_dz++;
412             }
413         } else {
414             s->mouse_buttons &= ~bmap[evt->btn->button];
415         }
416         break;
417 
418     default:
419         /* keep gcc happy */
420         break;
421     }
422 }
423 
424 static void ps2_mouse_sync(DeviceState *dev)
425 {
426     PS2MouseState *s = (PS2MouseState *)dev;
427 
428     if (s->mouse_buttons) {
429         qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
430     }
431     if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
432         while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
433             /* if not remote, send event. Multiple events are sent if
434                too big deltas */
435             ps2_mouse_send_packet(s);
436             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
437                 break;
438         }
439     }
440 }
441 
442 void ps2_mouse_fake_event(void *opaque)
443 {
444     PS2MouseState *s = opaque;
445     trace_ps2_mouse_fake_event(opaque);
446     s->mouse_dx++;
447     ps2_mouse_sync(opaque);
448 }
449 
450 void ps2_write_mouse(void *opaque, int val)
451 {
452     PS2MouseState *s = (PS2MouseState *)opaque;
453 
454     trace_ps2_write_mouse(opaque, val);
455 #ifdef DEBUG_MOUSE
456     printf("kbd: write mouse 0x%02x\n", val);
457 #endif
458     switch(s->common.write_cmd) {
459     default:
460     case -1:
461         /* mouse command */
462         if (s->mouse_wrap) {
463             if (val == AUX_RESET_WRAP) {
464                 s->mouse_wrap = 0;
465                 ps2_queue(&s->common, AUX_ACK);
466                 return;
467             } else if (val != AUX_RESET) {
468                 ps2_queue(&s->common, val);
469                 return;
470             }
471         }
472         switch(val) {
473         case AUX_SET_SCALE11:
474             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
475             ps2_queue(&s->common, AUX_ACK);
476             break;
477         case AUX_SET_SCALE21:
478             s->mouse_status |= MOUSE_STATUS_SCALE21;
479             ps2_queue(&s->common, AUX_ACK);
480             break;
481         case AUX_SET_STREAM:
482             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
483             ps2_queue(&s->common, AUX_ACK);
484             break;
485         case AUX_SET_WRAP:
486             s->mouse_wrap = 1;
487             ps2_queue(&s->common, AUX_ACK);
488             break;
489         case AUX_SET_REMOTE:
490             s->mouse_status |= MOUSE_STATUS_REMOTE;
491             ps2_queue(&s->common, AUX_ACK);
492             break;
493         case AUX_GET_TYPE:
494             ps2_queue(&s->common, AUX_ACK);
495             ps2_queue(&s->common, s->mouse_type);
496             break;
497         case AUX_SET_RES:
498         case AUX_SET_SAMPLE:
499             s->common.write_cmd = val;
500             ps2_queue(&s->common, AUX_ACK);
501             break;
502         case AUX_GET_SCALE:
503             ps2_queue(&s->common, AUX_ACK);
504             ps2_queue(&s->common, s->mouse_status);
505             ps2_queue(&s->common, s->mouse_resolution);
506             ps2_queue(&s->common, s->mouse_sample_rate);
507             break;
508         case AUX_POLL:
509             ps2_queue(&s->common, AUX_ACK);
510             ps2_mouse_send_packet(s);
511             break;
512         case AUX_ENABLE_DEV:
513             s->mouse_status |= MOUSE_STATUS_ENABLED;
514             ps2_queue(&s->common, AUX_ACK);
515             break;
516         case AUX_DISABLE_DEV:
517             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
518             ps2_queue(&s->common, AUX_ACK);
519             break;
520         case AUX_SET_DEFAULT:
521             s->mouse_sample_rate = 100;
522             s->mouse_resolution = 2;
523             s->mouse_status = 0;
524             ps2_queue(&s->common, AUX_ACK);
525             break;
526         case AUX_RESET:
527             s->mouse_sample_rate = 100;
528             s->mouse_resolution = 2;
529             s->mouse_status = 0;
530             s->mouse_type = 0;
531             ps2_queue(&s->common, AUX_ACK);
532             ps2_queue(&s->common, 0xaa);
533             ps2_queue(&s->common, s->mouse_type);
534             break;
535         default:
536             break;
537         }
538         break;
539     case AUX_SET_SAMPLE:
540         s->mouse_sample_rate = val;
541         /* detect IMPS/2 or IMEX */
542         switch(s->mouse_detect_state) {
543         default:
544         case 0:
545             if (val == 200)
546                 s->mouse_detect_state = 1;
547             break;
548         case 1:
549             if (val == 100)
550                 s->mouse_detect_state = 2;
551             else if (val == 200)
552                 s->mouse_detect_state = 3;
553             else
554                 s->mouse_detect_state = 0;
555             break;
556         case 2:
557             if (val == 80)
558                 s->mouse_type = 3; /* IMPS/2 */
559             s->mouse_detect_state = 0;
560             break;
561         case 3:
562             if (val == 80)
563                 s->mouse_type = 4; /* IMEX */
564             s->mouse_detect_state = 0;
565             break;
566         }
567         ps2_queue(&s->common, AUX_ACK);
568         s->common.write_cmd = -1;
569         break;
570     case AUX_SET_RES:
571         s->mouse_resolution = val;
572         ps2_queue(&s->common, AUX_ACK);
573         s->common.write_cmd = -1;
574         break;
575     }
576 }
577 
578 static void ps2_common_reset(PS2State *s)
579 {
580     PS2Queue *q;
581     s->write_cmd = -1;
582     q = &s->queue;
583     q->rptr = 0;
584     q->wptr = 0;
585     q->count = 0;
586     s->update_irq(s->update_arg, 0);
587 }
588 
589 static void ps2_common_post_load(PS2State *s)
590 {
591     PS2Queue *q = &s->queue;
592     int size;
593     int i;
594     int tmp_data[PS2_QUEUE_SIZE];
595 
596     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
597     size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
598 
599     /* move the queue elements to the start of data array */
600     if (size > 0) {
601         for (i = 0; i < size; i++) {
602             /* move the queue elements to the temporary buffer */
603             tmp_data[i] = q->data[q->rptr];
604             if (++q->rptr == 256) {
605                 q->rptr = 0;
606             }
607         }
608         memcpy(q->data, tmp_data, size);
609     }
610     /* reset rptr/wptr/count */
611     q->rptr = 0;
612     q->wptr = size;
613     q->count = size;
614     s->update_irq(s->update_arg, q->count != 0);
615 }
616 
617 static void ps2_kbd_reset(void *opaque)
618 {
619     PS2KbdState *s = (PS2KbdState *) opaque;
620 
621     trace_ps2_kbd_reset(opaque);
622     ps2_common_reset(&s->common);
623     s->scan_enabled = 0;
624     s->translate = 0;
625     s->scancode_set = 0;
626 }
627 
628 static void ps2_mouse_reset(void *opaque)
629 {
630     PS2MouseState *s = (PS2MouseState *) opaque;
631 
632     trace_ps2_mouse_reset(opaque);
633     ps2_common_reset(&s->common);
634     s->mouse_status = 0;
635     s->mouse_resolution = 0;
636     s->mouse_sample_rate = 0;
637     s->mouse_wrap = 0;
638     s->mouse_type = 0;
639     s->mouse_detect_state = 0;
640     s->mouse_dx = 0;
641     s->mouse_dy = 0;
642     s->mouse_dz = 0;
643     s->mouse_buttons = 0;
644 }
645 
646 static const VMStateDescription vmstate_ps2_common = {
647     .name = "PS2 Common State",
648     .version_id = 3,
649     .minimum_version_id = 2,
650     .fields = (VMStateField[]) {
651         VMSTATE_INT32(write_cmd, PS2State),
652         VMSTATE_INT32(queue.rptr, PS2State),
653         VMSTATE_INT32(queue.wptr, PS2State),
654         VMSTATE_INT32(queue.count, PS2State),
655         VMSTATE_BUFFER(queue.data, PS2State),
656         VMSTATE_END_OF_LIST()
657     }
658 };
659 
660 static bool ps2_keyboard_ledstate_needed(void *opaque)
661 {
662     PS2KbdState *s = opaque;
663 
664     return s->ledstate != 0; /* 0 is default state */
665 }
666 
667 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
668 {
669     PS2KbdState *s = opaque;
670 
671     kbd_put_ledstate(s->ledstate);
672     return 0;
673 }
674 
675 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
676     .name = "ps2kbd/ledstate",
677     .version_id = 3,
678     .minimum_version_id = 2,
679     .post_load = ps2_kbd_ledstate_post_load,
680     .needed = ps2_keyboard_ledstate_needed,
681     .fields = (VMStateField[]) {
682         VMSTATE_INT32(ledstate, PS2KbdState),
683         VMSTATE_END_OF_LIST()
684     }
685 };
686 
687 static int ps2_kbd_post_load(void* opaque, int version_id)
688 {
689     PS2KbdState *s = (PS2KbdState*)opaque;
690     PS2State *ps2 = &s->common;
691 
692     if (version_id == 2)
693         s->scancode_set=2;
694 
695     ps2_common_post_load(ps2);
696 
697     return 0;
698 }
699 
700 static void ps2_kbd_pre_save(void *opaque)
701 {
702     PS2KbdState *s = (PS2KbdState *)opaque;
703     PS2State *ps2 = &s->common;
704 
705     ps2_common_post_load(ps2);
706 }
707 
708 static const VMStateDescription vmstate_ps2_keyboard = {
709     .name = "ps2kbd",
710     .version_id = 3,
711     .minimum_version_id = 2,
712     .post_load = ps2_kbd_post_load,
713     .pre_save = ps2_kbd_pre_save,
714     .fields = (VMStateField[]) {
715         VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
716         VMSTATE_INT32(scan_enabled, PS2KbdState),
717         VMSTATE_INT32(translate, PS2KbdState),
718         VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
719         VMSTATE_END_OF_LIST()
720     },
721     .subsections = (const VMStateDescription*[]) {
722         &vmstate_ps2_keyboard_ledstate,
723         NULL
724     }
725 };
726 
727 static int ps2_mouse_post_load(void *opaque, int version_id)
728 {
729     PS2MouseState *s = (PS2MouseState *)opaque;
730     PS2State *ps2 = &s->common;
731 
732     ps2_common_post_load(ps2);
733 
734     return 0;
735 }
736 
737 static void ps2_mouse_pre_save(void *opaque)
738 {
739     PS2MouseState *s = (PS2MouseState *)opaque;
740     PS2State *ps2 = &s->common;
741 
742     ps2_common_post_load(ps2);
743 }
744 
745 static const VMStateDescription vmstate_ps2_mouse = {
746     .name = "ps2mouse",
747     .version_id = 2,
748     .minimum_version_id = 2,
749     .post_load = ps2_mouse_post_load,
750     .pre_save = ps2_mouse_pre_save,
751     .fields = (VMStateField[]) {
752         VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
753         VMSTATE_UINT8(mouse_status, PS2MouseState),
754         VMSTATE_UINT8(mouse_resolution, PS2MouseState),
755         VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
756         VMSTATE_UINT8(mouse_wrap, PS2MouseState),
757         VMSTATE_UINT8(mouse_type, PS2MouseState),
758         VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
759         VMSTATE_INT32(mouse_dx, PS2MouseState),
760         VMSTATE_INT32(mouse_dy, PS2MouseState),
761         VMSTATE_INT32(mouse_dz, PS2MouseState),
762         VMSTATE_UINT8(mouse_buttons, PS2MouseState),
763         VMSTATE_END_OF_LIST()
764     }
765 };
766 
767 static QemuInputHandler ps2_keyboard_handler = {
768     .name  = "QEMU PS/2 Keyboard",
769     .mask  = INPUT_EVENT_MASK_KEY,
770     .event = ps2_keyboard_event,
771 };
772 
773 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
774 {
775     PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
776 
777     trace_ps2_kbd_init(s);
778     s->common.update_irq = update_irq;
779     s->common.update_arg = update_arg;
780     s->scancode_set = 2;
781     vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
782     qemu_input_handler_register((DeviceState *)s,
783                                 &ps2_keyboard_handler);
784     qemu_register_reset(ps2_kbd_reset, s);
785     return s;
786 }
787 
788 static QemuInputHandler ps2_mouse_handler = {
789     .name  = "QEMU PS/2 Mouse",
790     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
791     .event = ps2_mouse_event,
792     .sync  = ps2_mouse_sync,
793 };
794 
795 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
796 {
797     PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
798 
799     trace_ps2_mouse_init(s);
800     s->common.update_irq = update_irq;
801     s->common.update_arg = update_arg;
802     vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
803     qemu_input_handler_register((DeviceState *)s,
804                                 &ps2_mouse_handler);
805     qemu_register_reset(ps2_mouse_reset, s);
806     return s;
807 }
808