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