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