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