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