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