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