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