xref: /qemu/hw/input/ps2.c (revision 8c10e0baf0260b59a4e984744462a18016662e3e)
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 
31 #include "trace.h"
32 
33 /* debug PC keyboard */
34 //#define DEBUG_KBD
35 
36 /* debug PC keyboard : only mouse */
37 //#define DEBUG_MOUSE
38 
39 /* Keyboard Commands */
40 #define KBD_CMD_SET_LEDS	0xED	/* Set keyboard leds */
41 #define KBD_CMD_ECHO     	0xEE
42 #define KBD_CMD_SCANCODE	0xF0	/* Get/set scancode set */
43 #define KBD_CMD_GET_ID 	        0xF2	/* get keyboard ID */
44 #define KBD_CMD_SET_RATE	0xF3	/* Set typematic rate */
45 #define KBD_CMD_ENABLE		0xF4	/* Enable scanning */
46 #define KBD_CMD_RESET_DISABLE	0xF5	/* reset and disable scanning */
47 #define KBD_CMD_RESET_ENABLE   	0xF6    /* reset and enable scanning */
48 #define KBD_CMD_RESET		0xFF	/* Reset */
49 
50 /* Keyboard Replies */
51 #define KBD_REPLY_POR		0xAA	/* Power on reset */
52 #define KBD_REPLY_ID		0xAB	/* Keyboard ID */
53 #define KBD_REPLY_ACK		0xFA	/* Command ACK */
54 #define KBD_REPLY_RESEND	0xFE	/* Command NACK, send the cmd again */
55 
56 /* Mouse Commands */
57 #define AUX_SET_SCALE11		0xE6	/* Set 1:1 scaling */
58 #define AUX_SET_SCALE21		0xE7	/* Set 2:1 scaling */
59 #define AUX_SET_RES		0xE8	/* Set resolution */
60 #define AUX_GET_SCALE		0xE9	/* Get scaling factor */
61 #define AUX_SET_STREAM		0xEA	/* Set stream mode */
62 #define AUX_POLL		0xEB	/* Poll */
63 #define AUX_RESET_WRAP		0xEC	/* Reset wrap mode */
64 #define AUX_SET_WRAP		0xEE	/* Set wrap mode */
65 #define AUX_SET_REMOTE		0xF0	/* Set remote mode */
66 #define AUX_GET_TYPE		0xF2	/* Get type */
67 #define AUX_SET_SAMPLE		0xF3	/* Set sample rate */
68 #define AUX_ENABLE_DEV		0xF4	/* Enable aux device */
69 #define AUX_DISABLE_DEV		0xF5	/* Disable aux device */
70 #define AUX_SET_DEFAULT		0xF6
71 #define AUX_RESET		0xFF	/* Reset aux device */
72 #define AUX_ACK			0xFA	/* Command byte ACK. */
73 
74 #define MOUSE_STATUS_REMOTE     0x40
75 #define MOUSE_STATUS_ENABLED    0x20
76 #define MOUSE_STATUS_SCALE21    0x10
77 
78 #define PS2_QUEUE_SIZE 16  /* Buffer size required by PS/2 protocol */
79 
80 typedef struct {
81     /* Keep the data array 256 bytes long, which compatibility
82      with older qemu versions. */
83     uint8_t data[256];
84     int rptr, wptr, count;
85 } PS2Queue;
86 
87 typedef struct {
88     PS2Queue queue;
89     int32_t write_cmd;
90     void (*update_irq)(void *, int);
91     void *update_arg;
92 } PS2State;
93 
94 typedef struct {
95     PS2State common;
96     int scan_enabled;
97     int translate;
98     int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
99     int ledstate;
100     bool need_high_bit;
101 } PS2KbdState;
102 
103 typedef struct {
104     PS2State common;
105     uint8_t mouse_status;
106     uint8_t mouse_resolution;
107     uint8_t mouse_sample_rate;
108     uint8_t mouse_wrap;
109     uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
110     uint8_t mouse_detect_state;
111     int mouse_dx; /* current values, needed for 'poll' mode */
112     int mouse_dy;
113     int mouse_dz;
114     uint8_t mouse_buttons;
115 } PS2MouseState;
116 
117 /* Table to convert from QEMU codes to scancodes.  */
118 static const uint16_t qcode_to_keycode_set1[Q_KEY_CODE__MAX] = {
119     [0 ... Q_KEY_CODE__MAX - 1] = 0,
120 
121     [Q_KEY_CODE_A] = 0x1e,
122     [Q_KEY_CODE_B] = 0x30,
123     [Q_KEY_CODE_C] = 0x2e,
124     [Q_KEY_CODE_D] = 0x20,
125     [Q_KEY_CODE_E] = 0x12,
126     [Q_KEY_CODE_F] = 0x21,
127     [Q_KEY_CODE_G] = 0x22,
128     [Q_KEY_CODE_H] = 0x23,
129     [Q_KEY_CODE_I] = 0x17,
130     [Q_KEY_CODE_J] = 0x24,
131     [Q_KEY_CODE_K] = 0x25,
132     [Q_KEY_CODE_L] = 0x26,
133     [Q_KEY_CODE_M] = 0x32,
134     [Q_KEY_CODE_N] = 0x31,
135     [Q_KEY_CODE_O] = 0x18,
136     [Q_KEY_CODE_P] = 0x19,
137     [Q_KEY_CODE_Q] = 0x10,
138     [Q_KEY_CODE_R] = 0x13,
139     [Q_KEY_CODE_S] = 0x1f,
140     [Q_KEY_CODE_T] = 0x14,
141     [Q_KEY_CODE_U] = 0x16,
142     [Q_KEY_CODE_V] = 0x2f,
143     [Q_KEY_CODE_W] = 0x11,
144     [Q_KEY_CODE_X] = 0x2d,
145     [Q_KEY_CODE_Y] = 0x15,
146     [Q_KEY_CODE_Z] = 0x2c,
147     [Q_KEY_CODE_0] = 0x0b,
148     [Q_KEY_CODE_1] = 0x02,
149     [Q_KEY_CODE_2] = 0x03,
150     [Q_KEY_CODE_3] = 0x04,
151     [Q_KEY_CODE_4] = 0x05,
152     [Q_KEY_CODE_5] = 0x06,
153     [Q_KEY_CODE_6] = 0x07,
154     [Q_KEY_CODE_7] = 0x08,
155     [Q_KEY_CODE_8] = 0x09,
156     [Q_KEY_CODE_9] = 0x0a,
157     [Q_KEY_CODE_GRAVE_ACCENT] = 0x29,
158     [Q_KEY_CODE_MINUS] = 0x0c,
159     [Q_KEY_CODE_EQUAL] = 0x0d,
160     [Q_KEY_CODE_BACKSLASH] = 0x2b,
161     [Q_KEY_CODE_BACKSPACE] = 0x0e,
162     [Q_KEY_CODE_SPC] = 0x39,
163     [Q_KEY_CODE_TAB] = 0x0f,
164     [Q_KEY_CODE_CAPS_LOCK] = 0x3a,
165     [Q_KEY_CODE_SHIFT] = 0x2a,
166     [Q_KEY_CODE_CTRL] = 0x1d,
167     [Q_KEY_CODE_META_L] = 0xe05b,
168     [Q_KEY_CODE_ALT] = 0x38,
169     [Q_KEY_CODE_SHIFT_R] = 0x36,
170     [Q_KEY_CODE_CTRL_R] = 0xe01d,
171     [Q_KEY_CODE_META_R] = 0xe05c,
172     [Q_KEY_CODE_ALT_R] = 0xe038,
173     [Q_KEY_CODE_MENU] = 0xe05d,
174     [Q_KEY_CODE_RET] = 0x1c,
175     [Q_KEY_CODE_ESC] = 0x01,
176     [Q_KEY_CODE_F1] = 0x3b,
177     [Q_KEY_CODE_F2] = 0x3c,
178     [Q_KEY_CODE_F3] = 0x3d,
179     [Q_KEY_CODE_F4] = 0x3e,
180     [Q_KEY_CODE_F5] = 0x3f,
181     [Q_KEY_CODE_F6] = 0x40,
182     [Q_KEY_CODE_F7] = 0x41,
183     [Q_KEY_CODE_F8] = 0x42,
184     [Q_KEY_CODE_F9] = 0x43,
185     [Q_KEY_CODE_F10] = 0x44,
186     [Q_KEY_CODE_F11] = 0x57,
187     [Q_KEY_CODE_F12] = 0x58,
188     /* special handling for Q_KEY_CODE_PRINT */
189     [Q_KEY_CODE_SCROLL_LOCK] = 0x46,
190     /* special handling for Q_KEY_CODE_PAUSE */
191     [Q_KEY_CODE_BRACKET_LEFT] = 0x1a,
192     [Q_KEY_CODE_INSERT] = 0xe052,
193     [Q_KEY_CODE_HOME] = 0xe047,
194     [Q_KEY_CODE_PGUP] = 0xe049,
195     [Q_KEY_CODE_DELETE] = 0xe053,
196     [Q_KEY_CODE_END] = 0xe04f,
197     [Q_KEY_CODE_PGDN] = 0xe051,
198     [Q_KEY_CODE_UP] = 0xe048,
199     [Q_KEY_CODE_LEFT] = 0xe04b,
200     [Q_KEY_CODE_DOWN] = 0xe050,
201     [Q_KEY_CODE_RIGHT] = 0xe04d,
202     [Q_KEY_CODE_NUM_LOCK] = 0x45,
203     [Q_KEY_CODE_KP_DIVIDE] = 0xe035,
204     [Q_KEY_CODE_KP_MULTIPLY] = 0x37,
205     [Q_KEY_CODE_KP_SUBTRACT] = 0x4a,
206     [Q_KEY_CODE_KP_ADD] = 0x4e,
207     [Q_KEY_CODE_KP_ENTER] = 0xe01c,
208     [Q_KEY_CODE_KP_DECIMAL] = 0x53,
209     [Q_KEY_CODE_KP_0] = 0x52,
210     [Q_KEY_CODE_KP_1] = 0x4f,
211     [Q_KEY_CODE_KP_2] = 0x50,
212     [Q_KEY_CODE_KP_3] = 0x51,
213     [Q_KEY_CODE_KP_4] = 0x4b,
214     [Q_KEY_CODE_KP_5] = 0x4c,
215     [Q_KEY_CODE_KP_6] = 0x4d,
216     [Q_KEY_CODE_KP_7] = 0x47,
217     [Q_KEY_CODE_KP_8] = 0x48,
218     [Q_KEY_CODE_KP_9] = 0x49,
219     [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b,
220     [Q_KEY_CODE_SEMICOLON] = 0x27,
221     [Q_KEY_CODE_APOSTROPHE] = 0x28,
222     [Q_KEY_CODE_COMMA] = 0x33,
223     [Q_KEY_CODE_DOT] = 0x34,
224     [Q_KEY_CODE_SLASH] = 0x35,
225 
226 #if 0
227     [Q_KEY_CODE_POWER] = 0x0e5e,
228     [Q_KEY_CODE_SLEEP] = 0x0e5f,
229     [Q_KEY_CODE_WAKE] = 0x0e63,
230 
231     [Q_KEY_CODE_AUDIONEXT] = 0xe019,
232     [Q_KEY_CODE_AUDIOPREV] = 0xe010,
233     [Q_KEY_CODE_AUDIOSTOP] = 0xe024,
234     [Q_KEY_CODE_AUDIOPLAY] = 0xe022,
235     [Q_KEY_CODE_AUDIOMUTE] = 0xe020,
236     [Q_KEY_CODE_VOLUMEUP] = 0xe030,
237     [Q_KEY_CODE_VOLUMEDOWN] = 0xe02e,
238     [Q_KEY_CODE_MEDIASELECT] = 0xe06d,
239     [Q_KEY_CODE_MAIL] = 0xe06c,
240     [Q_KEY_CODE_CALCULATOR] = 0xe021,
241     [Q_KEY_CODE_COMPUTER] = 0xe06b,
242     [Q_KEY_CODE_AC_SEARCH] = 0xe065,
243     [Q_KEY_CODE_AC_HOME] = 0xe032,
244     [Q_KEY_CODE_AC_BACK] = 0xe06a,
245     [Q_KEY_CODE_AC_FORWARD] = 0xe069,
246     [Q_KEY_CODE_AC_STOP] = 0xe068,
247     [Q_KEY_CODE_AC_REFRESH] = 0xe067,
248     [Q_KEY_CODE_AC_BOOKMARKS] = 0xe066,
249 #endif
250 
251     [Q_KEY_CODE_ASTERISK] = 0x37,
252     [Q_KEY_CODE_LESS] = 0x56,
253     [Q_KEY_CODE_RO] = 0x73,
254     [Q_KEY_CODE_KP_COMMA] = 0x7e,
255 };
256 
257 static const uint16_t qcode_to_keycode_set2[Q_KEY_CODE__MAX] = {
258     [0 ... Q_KEY_CODE__MAX - 1] = 0,
259 
260     [Q_KEY_CODE_A] = 0x1c,
261     [Q_KEY_CODE_B] = 0x32,
262     [Q_KEY_CODE_C] = 0x21,
263     [Q_KEY_CODE_D] = 0x23,
264     [Q_KEY_CODE_E] = 0x24,
265     [Q_KEY_CODE_F] = 0x2b,
266     [Q_KEY_CODE_G] = 0x34,
267     [Q_KEY_CODE_H] = 0x33,
268     [Q_KEY_CODE_I] = 0x43,
269     [Q_KEY_CODE_J] = 0x3b,
270     [Q_KEY_CODE_K] = 0x42,
271     [Q_KEY_CODE_L] = 0x4b,
272     [Q_KEY_CODE_M] = 0x3a,
273     [Q_KEY_CODE_N] = 0x31,
274     [Q_KEY_CODE_O] = 0x44,
275     [Q_KEY_CODE_P] = 0x4d,
276     [Q_KEY_CODE_Q] = 0x15,
277     [Q_KEY_CODE_R] = 0x2d,
278     [Q_KEY_CODE_S] = 0x1b,
279     [Q_KEY_CODE_T] = 0x2c,
280     [Q_KEY_CODE_U] = 0x3c,
281     [Q_KEY_CODE_V] = 0x2a,
282     [Q_KEY_CODE_W] = 0x1d,
283     [Q_KEY_CODE_X] = 0x22,
284     [Q_KEY_CODE_Y] = 0x35,
285     [Q_KEY_CODE_Z] = 0x1a,
286     [Q_KEY_CODE_0] = 0x45,
287     [Q_KEY_CODE_1] = 0x16,
288     [Q_KEY_CODE_2] = 0x1e,
289     [Q_KEY_CODE_3] = 0x26,
290     [Q_KEY_CODE_4] = 0x25,
291     [Q_KEY_CODE_5] = 0x2e,
292     [Q_KEY_CODE_6] = 0x36,
293     [Q_KEY_CODE_7] = 0x3d,
294     [Q_KEY_CODE_8] = 0x3e,
295     [Q_KEY_CODE_9] = 0x46,
296     [Q_KEY_CODE_GRAVE_ACCENT] = 0x0e,
297     [Q_KEY_CODE_MINUS] = 0x4e,
298     [Q_KEY_CODE_EQUAL] = 0x55,
299     [Q_KEY_CODE_BACKSLASH] = 0x5d,
300     [Q_KEY_CODE_BACKSPACE] = 0x66,
301     [Q_KEY_CODE_SPC] = 0x29,
302     [Q_KEY_CODE_TAB] = 0x0d,
303     [Q_KEY_CODE_CAPS_LOCK] = 0x58,
304     [Q_KEY_CODE_SHIFT] = 0x12,
305     [Q_KEY_CODE_CTRL] = 0x14,
306     [Q_KEY_CODE_META_L] = 0xe01f,
307     [Q_KEY_CODE_ALT] = 0x11,
308     [Q_KEY_CODE_SHIFT_R] = 0x59,
309     [Q_KEY_CODE_CTRL_R] = 0xe014,
310     [Q_KEY_CODE_META_R] = 0xe027,
311     [Q_KEY_CODE_ALT_R] = 0xe011,
312     [Q_KEY_CODE_MENU] = 0xe02f,
313     [Q_KEY_CODE_RET] = 0x5a,
314     [Q_KEY_CODE_ESC] = 0x76,
315     [Q_KEY_CODE_F1] = 0x05,
316     [Q_KEY_CODE_F2] = 0x06,
317     [Q_KEY_CODE_F3] = 0x04,
318     [Q_KEY_CODE_F4] = 0x0c,
319     [Q_KEY_CODE_F5] = 0x03,
320     [Q_KEY_CODE_F6] = 0x0b,
321     [Q_KEY_CODE_F7] = 0x83,
322     [Q_KEY_CODE_F8] = 0x0a,
323     [Q_KEY_CODE_F9] = 0x01,
324     [Q_KEY_CODE_F10] = 0x09,
325     [Q_KEY_CODE_F11] = 0x78,
326     [Q_KEY_CODE_F12] = 0x07,
327     /* special handling for Q_KEY_CODE_PRINT */
328     [Q_KEY_CODE_SCROLL_LOCK] = 0x7e,
329     /* special handling for Q_KEY_CODE_PAUSE */
330     [Q_KEY_CODE_BRACKET_LEFT] = 0x54,
331     [Q_KEY_CODE_INSERT] = 0xe070,
332     [Q_KEY_CODE_HOME] = 0xe06c,
333     [Q_KEY_CODE_PGUP] = 0xe07d,
334     [Q_KEY_CODE_DELETE] = 0xe071,
335     [Q_KEY_CODE_END] = 0xe069,
336     [Q_KEY_CODE_PGDN] = 0xe07a,
337     [Q_KEY_CODE_UP] = 0xe075,
338     [Q_KEY_CODE_LEFT] = 0xe06b,
339     [Q_KEY_CODE_DOWN] = 0xe072,
340     [Q_KEY_CODE_RIGHT] = 0xe074,
341     [Q_KEY_CODE_NUM_LOCK] = 0x77,
342     [Q_KEY_CODE_KP_DIVIDE] = 0xe04a,
343     [Q_KEY_CODE_KP_MULTIPLY] = 0x7c,
344     [Q_KEY_CODE_KP_SUBTRACT] = 0x7b,
345     [Q_KEY_CODE_KP_ADD] = 0x79,
346     [Q_KEY_CODE_KP_ENTER] = 0xe05a,
347     [Q_KEY_CODE_KP_DECIMAL] = 0x71,
348     [Q_KEY_CODE_KP_0] = 0x70,
349     [Q_KEY_CODE_KP_1] = 0x69,
350     [Q_KEY_CODE_KP_2] = 0x72,
351     [Q_KEY_CODE_KP_3] = 0x7a,
352     [Q_KEY_CODE_KP_4] = 0x6b,
353     [Q_KEY_CODE_KP_5] = 0x73,
354     [Q_KEY_CODE_KP_6] = 0x74,
355     [Q_KEY_CODE_KP_7] = 0x6c,
356     [Q_KEY_CODE_KP_8] = 0x75,
357     [Q_KEY_CODE_KP_9] = 0x7d,
358     [Q_KEY_CODE_BRACKET_RIGHT] = 0x5b,
359     [Q_KEY_CODE_SEMICOLON] = 0x4c,
360     [Q_KEY_CODE_APOSTROPHE] = 0x52,
361     [Q_KEY_CODE_COMMA] = 0x41,
362     [Q_KEY_CODE_DOT] = 0x49,
363     [Q_KEY_CODE_SLASH] = 0x4a,
364 
365 #if 0
366     [Q_KEY_CODE_POWER] = 0x0e37,
367     [Q_KEY_CODE_SLEEP] = 0x0e3f,
368     [Q_KEY_CODE_WAKE] = 0x0e5e,
369 
370     [Q_KEY_CODE_AUDIONEXT] = 0xe04d,
371     [Q_KEY_CODE_AUDIOPREV] = 0xe015,
372     [Q_KEY_CODE_AUDIOSTOP] = 0xe03b,
373     [Q_KEY_CODE_AUDIOPLAY] = 0xe034,
374     [Q_KEY_CODE_AUDIOMUTE] = 0xe023,
375     [Q_KEY_CODE_VOLUMEUP] = 0xe032,
376     [Q_KEY_CODE_VOLUMEDOWN] = 0xe021,
377     [Q_KEY_CODE_MEDIASELECT] = 0xe050,
378     [Q_KEY_CODE_MAIL] = 0xe048,
379     [Q_KEY_CODE_CALCULATOR] = 0xe02b,
380     [Q_KEY_CODE_COMPUTER] = 0xe040,
381     [Q_KEY_CODE_AC_SEARCH] = 0xe010,
382     [Q_KEY_CODE_AC_HOME] = 0xe03a,
383     [Q_KEY_CODE_AC_BACK] = 0xe038,
384     [Q_KEY_CODE_AC_FORWARD] = 0xe030,
385     [Q_KEY_CODE_AC_STOP] = 0xe028,
386     [Q_KEY_CODE_AC_REFRESH] = 0xe020,
387     [Q_KEY_CODE_AC_BOOKMARKS] = 0xe018,
388 #endif
389 
390     [Q_KEY_CODE_ALTGR] = 0x08,
391     [Q_KEY_CODE_ALTGR_R] = 0xe008,
392     [Q_KEY_CODE_ASTERISK] = 0x7c,
393     [Q_KEY_CODE_LESS] = 0x61,
394     [Q_KEY_CODE_SYSRQ] = 0x7f,
395     [Q_KEY_CODE_RO] = 0x51,
396     [Q_KEY_CODE_KP_COMMA] = 0x6d,
397 };
398 
399 static const uint16_t qcode_to_keycode_set3[Q_KEY_CODE__MAX] = {
400     [0 ... Q_KEY_CODE__MAX - 1] = 0,
401 
402     [Q_KEY_CODE_A] = 0x1c,
403     [Q_KEY_CODE_B] = 0x32,
404     [Q_KEY_CODE_C] = 0x21,
405     [Q_KEY_CODE_D] = 0x23,
406     [Q_KEY_CODE_E] = 0x24,
407     [Q_KEY_CODE_F] = 0x2b,
408     [Q_KEY_CODE_G] = 0x34,
409     [Q_KEY_CODE_H] = 0x33,
410     [Q_KEY_CODE_I] = 0x43,
411     [Q_KEY_CODE_J] = 0x3b,
412     [Q_KEY_CODE_K] = 0x42,
413     [Q_KEY_CODE_L] = 0x4b,
414     [Q_KEY_CODE_M] = 0x3a,
415     [Q_KEY_CODE_N] = 0x31,
416     [Q_KEY_CODE_O] = 0x44,
417     [Q_KEY_CODE_P] = 0x4d,
418     [Q_KEY_CODE_Q] = 0x15,
419     [Q_KEY_CODE_R] = 0x2d,
420     [Q_KEY_CODE_S] = 0x1b,
421     [Q_KEY_CODE_T] = 0x2c,
422     [Q_KEY_CODE_U] = 0x3c,
423     [Q_KEY_CODE_V] = 0x2a,
424     [Q_KEY_CODE_W] = 0x1d,
425     [Q_KEY_CODE_X] = 0x22,
426     [Q_KEY_CODE_Y] = 0x35,
427     [Q_KEY_CODE_Z] = 0x1a,
428     [Q_KEY_CODE_0] = 0x45,
429     [Q_KEY_CODE_1] = 0x16,
430     [Q_KEY_CODE_2] = 0x1e,
431     [Q_KEY_CODE_3] = 0x26,
432     [Q_KEY_CODE_4] = 0x25,
433     [Q_KEY_CODE_5] = 0x2e,
434     [Q_KEY_CODE_6] = 0x36,
435     [Q_KEY_CODE_7] = 0x3d,
436     [Q_KEY_CODE_8] = 0x3e,
437     [Q_KEY_CODE_9] = 0x46,
438     [Q_KEY_CODE_GRAVE_ACCENT] = 0x0e,
439     [Q_KEY_CODE_MINUS] = 0x4e,
440     [Q_KEY_CODE_EQUAL] = 0x55,
441     [Q_KEY_CODE_BACKSLASH] = 0x5c,
442     [Q_KEY_CODE_BACKSPACE] = 0x66,
443     [Q_KEY_CODE_SPC] = 0x29,
444     [Q_KEY_CODE_TAB] = 0x0d,
445     [Q_KEY_CODE_CAPS_LOCK] = 0x14,
446     [Q_KEY_CODE_SHIFT] = 0x12,
447     [Q_KEY_CODE_CTRL] = 0x11,
448     [Q_KEY_CODE_META_L] = 0x8b,
449     [Q_KEY_CODE_ALT] = 0x19,
450     [Q_KEY_CODE_SHIFT_R] = 0x59,
451     [Q_KEY_CODE_CTRL_R] = 0x58,
452     [Q_KEY_CODE_META_R] = 0x8c,
453     [Q_KEY_CODE_ALT_R] = 0x39,
454     [Q_KEY_CODE_MENU] = 0x8d,
455     [Q_KEY_CODE_RET] = 0x5a,
456     [Q_KEY_CODE_ESC] = 0x08,
457     [Q_KEY_CODE_F1] = 0x07,
458     [Q_KEY_CODE_F2] = 0x0f,
459     [Q_KEY_CODE_F3] = 0x17,
460     [Q_KEY_CODE_F4] = 0x1f,
461     [Q_KEY_CODE_F5] = 0x27,
462     [Q_KEY_CODE_F6] = 0x2f,
463     [Q_KEY_CODE_F7] = 0x37,
464     [Q_KEY_CODE_F8] = 0x3f,
465     [Q_KEY_CODE_F9] = 0x47,
466     [Q_KEY_CODE_F10] = 0x4f,
467     [Q_KEY_CODE_F11] = 0x56,
468     [Q_KEY_CODE_F12] = 0x5e,
469     [Q_KEY_CODE_PRINT] = 0x57,
470     [Q_KEY_CODE_SCROLL_LOCK] = 0x5f,
471     [Q_KEY_CODE_PAUSE] = 0x62,
472     [Q_KEY_CODE_BRACKET_LEFT] = 0x54,
473     [Q_KEY_CODE_INSERT] = 0x67,
474     [Q_KEY_CODE_HOME] = 0x6e,
475     [Q_KEY_CODE_PGUP] = 0x6f,
476     [Q_KEY_CODE_DELETE] = 0x64,
477     [Q_KEY_CODE_END] = 0x65,
478     [Q_KEY_CODE_PGDN] = 0x6d,
479     [Q_KEY_CODE_UP] = 0x63,
480     [Q_KEY_CODE_LEFT] = 0x61,
481     [Q_KEY_CODE_DOWN] = 0x60,
482     [Q_KEY_CODE_RIGHT] = 0x6a,
483     [Q_KEY_CODE_NUM_LOCK] = 0x76,
484     [Q_KEY_CODE_KP_DIVIDE] = 0x4a,
485     [Q_KEY_CODE_KP_MULTIPLY] = 0x7e,
486     [Q_KEY_CODE_KP_SUBTRACT] = 0x4e,
487     [Q_KEY_CODE_KP_ADD] = 0x7c,
488     [Q_KEY_CODE_KP_ENTER] = 0x79,
489     [Q_KEY_CODE_KP_DECIMAL] = 0x71,
490     [Q_KEY_CODE_KP_0] = 0x70,
491     [Q_KEY_CODE_KP_1] = 0x69,
492     [Q_KEY_CODE_KP_2] = 0x72,
493     [Q_KEY_CODE_KP_3] = 0x7a,
494     [Q_KEY_CODE_KP_4] = 0x6b,
495     [Q_KEY_CODE_KP_5] = 0x73,
496     [Q_KEY_CODE_KP_6] = 0x74,
497     [Q_KEY_CODE_KP_7] = 0x6c,
498     [Q_KEY_CODE_KP_8] = 0x75,
499     [Q_KEY_CODE_KP_9] = 0x7d,
500     [Q_KEY_CODE_BRACKET_RIGHT] = 0x5b,
501     [Q_KEY_CODE_SEMICOLON] = 0x4c,
502     [Q_KEY_CODE_APOSTROPHE] = 0x52,
503     [Q_KEY_CODE_COMMA] = 0x41,
504     [Q_KEY_CODE_DOT] = 0x49,
505     [Q_KEY_CODE_SLASH] = 0x4a,
506 };
507 
508 static uint8_t translate_table[256] = {
509     0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
510     0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
511     0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
512     0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
513     0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
514     0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
515     0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
516     0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
517     0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
518     0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
519     0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
520     0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
521     0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
522     0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
523     0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
524     0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
525     0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
526     0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
527     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
528     0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
529     0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
530     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
531     0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
532     0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
533     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
534     0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
535     0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
536     0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
537     0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
538     0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
539     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
540     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
541 };
542 
543 void ps2_queue(void *opaque, int b)
544 {
545     PS2State *s = (PS2State *)opaque;
546     PS2Queue *q = &s->queue;
547 
548     if (q->count >= PS2_QUEUE_SIZE - 1)
549         return;
550     q->data[q->wptr] = b;
551     if (++q->wptr == PS2_QUEUE_SIZE)
552         q->wptr = 0;
553     q->count++;
554     s->update_irq(s->update_arg, 1);
555 }
556 
557 /* keycode is the untranslated scancode in the current scancode set. */
558 static void ps2_put_keycode(void *opaque, int keycode)
559 {
560     PS2KbdState *s = opaque;
561 
562     trace_ps2_put_keycode(opaque, keycode);
563     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
564 
565     if (s->translate) {
566         if (keycode == 0xf0) {
567             s->need_high_bit = true;
568         } else if (s->need_high_bit) {
569             ps2_queue(&s->common, translate_table[keycode] | 0x80);
570             s->need_high_bit = false;
571         } else {
572             ps2_queue(&s->common, translate_table[keycode]);
573         }
574     } else {
575         ps2_queue(&s->common, keycode);
576     }
577 }
578 
579 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
580                                InputEvent *evt)
581 {
582     PS2KbdState *s = (PS2KbdState *)dev;
583     InputKeyEvent *key = evt->u.key.data;
584     int qcode;
585     uint16_t keycode;
586 
587     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
588     assert(evt->type == INPUT_EVENT_KIND_KEY);
589     qcode = qemu_input_key_value_to_qcode(key->key);
590 
591     if (s->scancode_set == 1) {
592         if (qcode == Q_KEY_CODE_PAUSE) {
593             if (key->down) {
594                 ps2_put_keycode(s, 0xe1);
595                 ps2_put_keycode(s, 0x1d);
596                 ps2_put_keycode(s, 0x45);
597                 ps2_put_keycode(s, 0x91);
598                 ps2_put_keycode(s, 0x9d);
599                 ps2_put_keycode(s, 0xc5);
600             }
601         } else if (qcode == Q_KEY_CODE_PRINT) {
602             if (key->down) {
603                 ps2_put_keycode(s, 0xe0);
604                 ps2_put_keycode(s, 0x2a);
605                 ps2_put_keycode(s, 0xe0);
606                 ps2_put_keycode(s, 0x37);
607             } else {
608                 ps2_put_keycode(s, 0xe0);
609                 ps2_put_keycode(s, 0xb7);
610                 ps2_put_keycode(s, 0xe0);
611                 ps2_put_keycode(s, 0xaa);
612             }
613         } else {
614             keycode = qcode_to_keycode_set1[qcode];
615             if (keycode) {
616                 if (keycode & 0xff00) {
617                     ps2_put_keycode(s, keycode >> 8);
618                 }
619                 if (!key->down) {
620                     keycode |= 0x80;
621                 }
622                 ps2_put_keycode(s, keycode & 0xff);
623             } else {
624                 ps2_queue(&s->common, key->down ? 0x00 : 0x80);
625             }
626         }
627     } else if (s->scancode_set == 2) {
628         if (qcode == Q_KEY_CODE_PAUSE) {
629             if (key->down) {
630                 ps2_put_keycode(s, 0xe1);
631                 ps2_put_keycode(s, 0x14);
632                 ps2_put_keycode(s, 0x77);
633                 ps2_put_keycode(s, 0xe1);
634                 ps2_put_keycode(s, 0xf0);
635                 ps2_put_keycode(s, 0x14);
636                 ps2_put_keycode(s, 0xf0);
637                 ps2_put_keycode(s, 0x77);
638             }
639         } else if (qcode == Q_KEY_CODE_PRINT) {
640             if (key->down) {
641                 ps2_put_keycode(s, 0xe0);
642                 ps2_put_keycode(s, 0x12);
643                 ps2_put_keycode(s, 0xe0);
644                 ps2_put_keycode(s, 0x7c);
645             } else {
646                 ps2_put_keycode(s, 0xe0);
647                 ps2_put_keycode(s, 0xf0);
648                 ps2_put_keycode(s, 0x7c);
649                 ps2_put_keycode(s, 0xe0);
650                 ps2_put_keycode(s, 0xf0);
651                 ps2_put_keycode(s, 0x12);
652             }
653         } else {
654             keycode = qcode_to_keycode_set2[qcode];
655             if (keycode) {
656                 if (keycode & 0xff00) {
657                     ps2_put_keycode(s, keycode >> 8);
658                 }
659                 if (!key->down) {
660                     ps2_put_keycode(s, 0xf0);
661                 }
662                 ps2_put_keycode(s, keycode & 0xff);
663             } else if (key->down) {
664                 ps2_queue(&s->common, 0x00);
665             } else if (s->translate) {
666                 ps2_queue(&s->common, 0x80);
667             } else {
668                 ps2_queue(&s->common, 0xf0);
669                 ps2_queue(&s->common, 0x00);
670             }
671         }
672     } else if (s->scancode_set == 3) {
673         keycode = qcode_to_keycode_set3[qcode];
674         if (keycode) {
675             /* FIXME: break code should be configured on a key by key basis */
676             if (!key->down) {
677                 ps2_put_keycode(s, 0xf0);
678             }
679             ps2_put_keycode(s, keycode);
680         } else if (key->down) {
681             ps2_queue(&s->common, 0x00);
682         } else if (s->translate) {
683             ps2_queue(&s->common, 0x80);
684         } else {
685             ps2_queue(&s->common, 0xf0);
686             ps2_queue(&s->common, 0x00);
687         }
688     }
689 }
690 
691 uint32_t ps2_read_data(void *opaque)
692 {
693     PS2State *s = (PS2State *)opaque;
694     PS2Queue *q;
695     int val, index;
696 
697     trace_ps2_read_data(opaque);
698     q = &s->queue;
699     if (q->count == 0) {
700         /* NOTE: if no data left, we return the last keyboard one
701            (needed for EMM386) */
702         /* XXX: need a timer to do things correctly */
703         index = q->rptr - 1;
704         if (index < 0)
705             index = PS2_QUEUE_SIZE - 1;
706         val = q->data[index];
707     } else {
708         val = q->data[q->rptr];
709         if (++q->rptr == PS2_QUEUE_SIZE)
710             q->rptr = 0;
711         q->count--;
712         /* reading deasserts IRQ */
713         s->update_irq(s->update_arg, 0);
714         /* reassert IRQs if data left */
715         s->update_irq(s->update_arg, q->count != 0);
716     }
717     return val;
718 }
719 
720 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
721 {
722     trace_ps2_set_ledstate(s, ledstate);
723     s->ledstate = ledstate;
724     kbd_put_ledstate(ledstate);
725 }
726 
727 static void ps2_reset_keyboard(PS2KbdState *s)
728 {
729     trace_ps2_reset_keyboard(s);
730     s->scan_enabled = 1;
731     s->scancode_set = 2;
732     ps2_set_ledstate(s, 0);
733 }
734 
735 void ps2_write_keyboard(void *opaque, int val)
736 {
737     PS2KbdState *s = (PS2KbdState *)opaque;
738 
739     trace_ps2_write_keyboard(opaque, val);
740     switch(s->common.write_cmd) {
741     default:
742     case -1:
743         switch(val) {
744         case 0x00:
745             ps2_queue(&s->common, KBD_REPLY_ACK);
746             break;
747         case 0x05:
748             ps2_queue(&s->common, KBD_REPLY_RESEND);
749             break;
750         case KBD_CMD_GET_ID:
751             ps2_queue(&s->common, KBD_REPLY_ACK);
752             /* We emulate a MF2 AT keyboard here */
753             ps2_queue(&s->common, KBD_REPLY_ID);
754             if (s->translate)
755                 ps2_queue(&s->common, 0x41);
756             else
757                 ps2_queue(&s->common, 0x83);
758             break;
759         case KBD_CMD_ECHO:
760             ps2_queue(&s->common, KBD_CMD_ECHO);
761             break;
762         case KBD_CMD_ENABLE:
763             s->scan_enabled = 1;
764             ps2_queue(&s->common, KBD_REPLY_ACK);
765             break;
766         case KBD_CMD_SCANCODE:
767         case KBD_CMD_SET_LEDS:
768         case KBD_CMD_SET_RATE:
769             s->common.write_cmd = val;
770             ps2_queue(&s->common, KBD_REPLY_ACK);
771             break;
772         case KBD_CMD_RESET_DISABLE:
773             ps2_reset_keyboard(s);
774             s->scan_enabled = 0;
775             ps2_queue(&s->common, KBD_REPLY_ACK);
776             break;
777         case KBD_CMD_RESET_ENABLE:
778             ps2_reset_keyboard(s);
779             s->scan_enabled = 1;
780             ps2_queue(&s->common, KBD_REPLY_ACK);
781             break;
782         case KBD_CMD_RESET:
783             ps2_reset_keyboard(s);
784             ps2_queue(&s->common, KBD_REPLY_ACK);
785             ps2_queue(&s->common, KBD_REPLY_POR);
786             break;
787         default:
788             ps2_queue(&s->common, KBD_REPLY_RESEND);
789             break;
790         }
791         break;
792     case KBD_CMD_SCANCODE:
793         if (val == 0) {
794             ps2_queue(&s->common, KBD_REPLY_ACK);
795             ps2_put_keycode(s, s->scancode_set);
796         } else if (val >= 1 && val <= 3) {
797             s->scancode_set = val;
798             ps2_queue(&s->common, KBD_REPLY_ACK);
799         } else {
800             ps2_queue(&s->common, KBD_REPLY_RESEND);
801         }
802         s->common.write_cmd = -1;
803         break;
804     case KBD_CMD_SET_LEDS:
805         ps2_set_ledstate(s, val);
806         ps2_queue(&s->common, KBD_REPLY_ACK);
807         s->common.write_cmd = -1;
808         break;
809     case KBD_CMD_SET_RATE:
810         ps2_queue(&s->common, KBD_REPLY_ACK);
811         s->common.write_cmd = -1;
812         break;
813     }
814 }
815 
816 /* Set the scancode translation mode.
817    0 = raw scancodes.
818    1 = translated scancodes (used by qemu internally).  */
819 
820 void ps2_keyboard_set_translation(void *opaque, int mode)
821 {
822     PS2KbdState *s = (PS2KbdState *)opaque;
823     trace_ps2_keyboard_set_translation(opaque, mode);
824     s->translate = mode;
825 }
826 
827 static void ps2_mouse_send_packet(PS2MouseState *s)
828 {
829     unsigned int b;
830     int dx1, dy1, dz1;
831 
832     dx1 = s->mouse_dx;
833     dy1 = s->mouse_dy;
834     dz1 = s->mouse_dz;
835     /* XXX: increase range to 8 bits ? */
836     if (dx1 > 127)
837         dx1 = 127;
838     else if (dx1 < -127)
839         dx1 = -127;
840     if (dy1 > 127)
841         dy1 = 127;
842     else if (dy1 < -127)
843         dy1 = -127;
844     b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
845     ps2_queue(&s->common, b);
846     ps2_queue(&s->common, dx1 & 0xff);
847     ps2_queue(&s->common, dy1 & 0xff);
848     /* extra byte for IMPS/2 or IMEX */
849     switch(s->mouse_type) {
850     default:
851         break;
852     case 3:
853         if (dz1 > 127)
854             dz1 = 127;
855         else if (dz1 < -127)
856                 dz1 = -127;
857         ps2_queue(&s->common, dz1 & 0xff);
858         break;
859     case 4:
860         if (dz1 > 7)
861             dz1 = 7;
862         else if (dz1 < -7)
863             dz1 = -7;
864         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
865         ps2_queue(&s->common, b);
866         break;
867     }
868 
869     trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
870     /* update deltas */
871     s->mouse_dx -= dx1;
872     s->mouse_dy -= dy1;
873     s->mouse_dz -= dz1;
874 }
875 
876 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
877                             InputEvent *evt)
878 {
879     static const int bmap[INPUT_BUTTON__MAX] = {
880         [INPUT_BUTTON_LEFT]   = MOUSE_EVENT_LBUTTON,
881         [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
882         [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON,
883     };
884     PS2MouseState *s = (PS2MouseState *)dev;
885     InputMoveEvent *move;
886     InputBtnEvent *btn;
887 
888     /* check if deltas are recorded when disabled */
889     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
890         return;
891 
892     switch (evt->type) {
893     case INPUT_EVENT_KIND_REL:
894         move = evt->u.rel.data;
895         if (move->axis == INPUT_AXIS_X) {
896             s->mouse_dx += move->value;
897         } else if (move->axis == INPUT_AXIS_Y) {
898             s->mouse_dy -= move->value;
899         }
900         break;
901 
902     case INPUT_EVENT_KIND_BTN:
903         btn = evt->u.btn.data;
904         if (btn->down) {
905             s->mouse_buttons |= bmap[btn->button];
906             if (btn->button == INPUT_BUTTON_WHEEL_UP) {
907                 s->mouse_dz--;
908             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
909                 s->mouse_dz++;
910             }
911         } else {
912             s->mouse_buttons &= ~bmap[btn->button];
913         }
914         break;
915 
916     default:
917         /* keep gcc happy */
918         break;
919     }
920 }
921 
922 static void ps2_mouse_sync(DeviceState *dev)
923 {
924     PS2MouseState *s = (PS2MouseState *)dev;
925 
926     if (s->mouse_buttons) {
927         qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
928     }
929     if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
930         while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
931             /* if not remote, send event. Multiple events are sent if
932                too big deltas */
933             ps2_mouse_send_packet(s);
934             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
935                 break;
936         }
937     }
938 }
939 
940 void ps2_mouse_fake_event(void *opaque)
941 {
942     PS2MouseState *s = opaque;
943     trace_ps2_mouse_fake_event(opaque);
944     s->mouse_dx++;
945     ps2_mouse_sync(opaque);
946 }
947 
948 void ps2_write_mouse(void *opaque, int val)
949 {
950     PS2MouseState *s = (PS2MouseState *)opaque;
951 
952     trace_ps2_write_mouse(opaque, val);
953 #ifdef DEBUG_MOUSE
954     printf("kbd: write mouse 0x%02x\n", val);
955 #endif
956     switch(s->common.write_cmd) {
957     default:
958     case -1:
959         /* mouse command */
960         if (s->mouse_wrap) {
961             if (val == AUX_RESET_WRAP) {
962                 s->mouse_wrap = 0;
963                 ps2_queue(&s->common, AUX_ACK);
964                 return;
965             } else if (val != AUX_RESET) {
966                 ps2_queue(&s->common, val);
967                 return;
968             }
969         }
970         switch(val) {
971         case AUX_SET_SCALE11:
972             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
973             ps2_queue(&s->common, AUX_ACK);
974             break;
975         case AUX_SET_SCALE21:
976             s->mouse_status |= MOUSE_STATUS_SCALE21;
977             ps2_queue(&s->common, AUX_ACK);
978             break;
979         case AUX_SET_STREAM:
980             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
981             ps2_queue(&s->common, AUX_ACK);
982             break;
983         case AUX_SET_WRAP:
984             s->mouse_wrap = 1;
985             ps2_queue(&s->common, AUX_ACK);
986             break;
987         case AUX_SET_REMOTE:
988             s->mouse_status |= MOUSE_STATUS_REMOTE;
989             ps2_queue(&s->common, AUX_ACK);
990             break;
991         case AUX_GET_TYPE:
992             ps2_queue(&s->common, AUX_ACK);
993             ps2_queue(&s->common, s->mouse_type);
994             break;
995         case AUX_SET_RES:
996         case AUX_SET_SAMPLE:
997             s->common.write_cmd = val;
998             ps2_queue(&s->common, AUX_ACK);
999             break;
1000         case AUX_GET_SCALE:
1001             ps2_queue(&s->common, AUX_ACK);
1002             ps2_queue(&s->common, s->mouse_status);
1003             ps2_queue(&s->common, s->mouse_resolution);
1004             ps2_queue(&s->common, s->mouse_sample_rate);
1005             break;
1006         case AUX_POLL:
1007             ps2_queue(&s->common, AUX_ACK);
1008             ps2_mouse_send_packet(s);
1009             break;
1010         case AUX_ENABLE_DEV:
1011             s->mouse_status |= MOUSE_STATUS_ENABLED;
1012             ps2_queue(&s->common, AUX_ACK);
1013             break;
1014         case AUX_DISABLE_DEV:
1015             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
1016             ps2_queue(&s->common, AUX_ACK);
1017             break;
1018         case AUX_SET_DEFAULT:
1019             s->mouse_sample_rate = 100;
1020             s->mouse_resolution = 2;
1021             s->mouse_status = 0;
1022             ps2_queue(&s->common, AUX_ACK);
1023             break;
1024         case AUX_RESET:
1025             s->mouse_sample_rate = 100;
1026             s->mouse_resolution = 2;
1027             s->mouse_status = 0;
1028             s->mouse_type = 0;
1029             ps2_queue(&s->common, AUX_ACK);
1030             ps2_queue(&s->common, 0xaa);
1031             ps2_queue(&s->common, s->mouse_type);
1032             break;
1033         default:
1034             break;
1035         }
1036         break;
1037     case AUX_SET_SAMPLE:
1038         s->mouse_sample_rate = val;
1039         /* detect IMPS/2 or IMEX */
1040         switch(s->mouse_detect_state) {
1041         default:
1042         case 0:
1043             if (val == 200)
1044                 s->mouse_detect_state = 1;
1045             break;
1046         case 1:
1047             if (val == 100)
1048                 s->mouse_detect_state = 2;
1049             else if (val == 200)
1050                 s->mouse_detect_state = 3;
1051             else
1052                 s->mouse_detect_state = 0;
1053             break;
1054         case 2:
1055             if (val == 80)
1056                 s->mouse_type = 3; /* IMPS/2 */
1057             s->mouse_detect_state = 0;
1058             break;
1059         case 3:
1060             if (val == 80)
1061                 s->mouse_type = 4; /* IMEX */
1062             s->mouse_detect_state = 0;
1063             break;
1064         }
1065         ps2_queue(&s->common, AUX_ACK);
1066         s->common.write_cmd = -1;
1067         break;
1068     case AUX_SET_RES:
1069         s->mouse_resolution = val;
1070         ps2_queue(&s->common, AUX_ACK);
1071         s->common.write_cmd = -1;
1072         break;
1073     }
1074 }
1075 
1076 static void ps2_common_reset(PS2State *s)
1077 {
1078     PS2Queue *q;
1079     s->write_cmd = -1;
1080     q = &s->queue;
1081     q->rptr = 0;
1082     q->wptr = 0;
1083     q->count = 0;
1084     s->update_irq(s->update_arg, 0);
1085 }
1086 
1087 static void ps2_common_post_load(PS2State *s)
1088 {
1089     PS2Queue *q = &s->queue;
1090     int size;
1091     int i;
1092     int tmp_data[PS2_QUEUE_SIZE];
1093 
1094     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
1095     size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
1096 
1097     /* move the queue elements to the start of data array */
1098     if (size > 0) {
1099         for (i = 0; i < size; i++) {
1100             /* move the queue elements to the temporary buffer */
1101             tmp_data[i] = q->data[q->rptr];
1102             if (++q->rptr == 256) {
1103                 q->rptr = 0;
1104             }
1105         }
1106         memcpy(q->data, tmp_data, size);
1107     }
1108     /* reset rptr/wptr/count */
1109     q->rptr = 0;
1110     q->wptr = size;
1111     q->count = size;
1112     s->update_irq(s->update_arg, q->count != 0);
1113 }
1114 
1115 static void ps2_kbd_reset(void *opaque)
1116 {
1117     PS2KbdState *s = (PS2KbdState *) opaque;
1118 
1119     trace_ps2_kbd_reset(opaque);
1120     ps2_common_reset(&s->common);
1121     s->scan_enabled = 0;
1122     s->translate = 0;
1123     s->scancode_set = 2;
1124 }
1125 
1126 static void ps2_mouse_reset(void *opaque)
1127 {
1128     PS2MouseState *s = (PS2MouseState *) opaque;
1129 
1130     trace_ps2_mouse_reset(opaque);
1131     ps2_common_reset(&s->common);
1132     s->mouse_status = 0;
1133     s->mouse_resolution = 0;
1134     s->mouse_sample_rate = 0;
1135     s->mouse_wrap = 0;
1136     s->mouse_type = 0;
1137     s->mouse_detect_state = 0;
1138     s->mouse_dx = 0;
1139     s->mouse_dy = 0;
1140     s->mouse_dz = 0;
1141     s->mouse_buttons = 0;
1142 }
1143 
1144 static const VMStateDescription vmstate_ps2_common = {
1145     .name = "PS2 Common State",
1146     .version_id = 3,
1147     .minimum_version_id = 2,
1148     .fields = (VMStateField[]) {
1149         VMSTATE_INT32(write_cmd, PS2State),
1150         VMSTATE_INT32(queue.rptr, PS2State),
1151         VMSTATE_INT32(queue.wptr, PS2State),
1152         VMSTATE_INT32(queue.count, PS2State),
1153         VMSTATE_BUFFER(queue.data, PS2State),
1154         VMSTATE_END_OF_LIST()
1155     }
1156 };
1157 
1158 static bool ps2_keyboard_ledstate_needed(void *opaque)
1159 {
1160     PS2KbdState *s = opaque;
1161 
1162     return s->ledstate != 0; /* 0 is default state */
1163 }
1164 
1165 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1166 {
1167     PS2KbdState *s = opaque;
1168 
1169     kbd_put_ledstate(s->ledstate);
1170     return 0;
1171 }
1172 
1173 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1174     .name = "ps2kbd/ledstate",
1175     .version_id = 3,
1176     .minimum_version_id = 2,
1177     .post_load = ps2_kbd_ledstate_post_load,
1178     .needed = ps2_keyboard_ledstate_needed,
1179     .fields = (VMStateField[]) {
1180         VMSTATE_INT32(ledstate, PS2KbdState),
1181         VMSTATE_END_OF_LIST()
1182     }
1183 };
1184 
1185 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1186 {
1187     PS2KbdState *s = opaque;
1188     return s->need_high_bit != 0; /* 0 is the usual state */
1189 }
1190 
1191 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1192     .name = "ps2kbd/need_high_bit",
1193     .version_id = 1,
1194     .minimum_version_id = 1,
1195     .needed = ps2_keyboard_need_high_bit_needed,
1196     .fields = (VMStateField[]) {
1197         VMSTATE_BOOL(need_high_bit, PS2KbdState),
1198         VMSTATE_END_OF_LIST()
1199     }
1200 };
1201 
1202 static int ps2_kbd_post_load(void* opaque, int version_id)
1203 {
1204     PS2KbdState *s = (PS2KbdState*)opaque;
1205     PS2State *ps2 = &s->common;
1206 
1207     if (version_id == 2)
1208         s->scancode_set=2;
1209 
1210     ps2_common_post_load(ps2);
1211 
1212     return 0;
1213 }
1214 
1215 static void ps2_kbd_pre_save(void *opaque)
1216 {
1217     PS2KbdState *s = (PS2KbdState *)opaque;
1218     PS2State *ps2 = &s->common;
1219 
1220     ps2_common_post_load(ps2);
1221 }
1222 
1223 static const VMStateDescription vmstate_ps2_keyboard = {
1224     .name = "ps2kbd",
1225     .version_id = 3,
1226     .minimum_version_id = 2,
1227     .post_load = ps2_kbd_post_load,
1228     .pre_save = ps2_kbd_pre_save,
1229     .fields = (VMStateField[]) {
1230         VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1231         VMSTATE_INT32(scan_enabled, PS2KbdState),
1232         VMSTATE_INT32(translate, PS2KbdState),
1233         VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1234         VMSTATE_END_OF_LIST()
1235     },
1236     .subsections = (const VMStateDescription*[]) {
1237         &vmstate_ps2_keyboard_ledstate,
1238         &vmstate_ps2_keyboard_need_high_bit,
1239         NULL
1240     }
1241 };
1242 
1243 static int ps2_mouse_post_load(void *opaque, int version_id)
1244 {
1245     PS2MouseState *s = (PS2MouseState *)opaque;
1246     PS2State *ps2 = &s->common;
1247 
1248     ps2_common_post_load(ps2);
1249 
1250     return 0;
1251 }
1252 
1253 static void ps2_mouse_pre_save(void *opaque)
1254 {
1255     PS2MouseState *s = (PS2MouseState *)opaque;
1256     PS2State *ps2 = &s->common;
1257 
1258     ps2_common_post_load(ps2);
1259 }
1260 
1261 static const VMStateDescription vmstate_ps2_mouse = {
1262     .name = "ps2mouse",
1263     .version_id = 2,
1264     .minimum_version_id = 2,
1265     .post_load = ps2_mouse_post_load,
1266     .pre_save = ps2_mouse_pre_save,
1267     .fields = (VMStateField[]) {
1268         VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1269         VMSTATE_UINT8(mouse_status, PS2MouseState),
1270         VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1271         VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1272         VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1273         VMSTATE_UINT8(mouse_type, PS2MouseState),
1274         VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1275         VMSTATE_INT32(mouse_dx, PS2MouseState),
1276         VMSTATE_INT32(mouse_dy, PS2MouseState),
1277         VMSTATE_INT32(mouse_dz, PS2MouseState),
1278         VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1279         VMSTATE_END_OF_LIST()
1280     }
1281 };
1282 
1283 static QemuInputHandler ps2_keyboard_handler = {
1284     .name  = "QEMU PS/2 Keyboard",
1285     .mask  = INPUT_EVENT_MASK_KEY,
1286     .event = ps2_keyboard_event,
1287 };
1288 
1289 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1290 {
1291     PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1292 
1293     trace_ps2_kbd_init(s);
1294     s->common.update_irq = update_irq;
1295     s->common.update_arg = update_arg;
1296     s->scancode_set = 2;
1297     vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1298     qemu_input_handler_register((DeviceState *)s,
1299                                 &ps2_keyboard_handler);
1300     qemu_register_reset(ps2_kbd_reset, s);
1301     return s;
1302 }
1303 
1304 static QemuInputHandler ps2_mouse_handler = {
1305     .name  = "QEMU PS/2 Mouse",
1306     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1307     .event = ps2_mouse_event,
1308     .sync  = ps2_mouse_sync,
1309 };
1310 
1311 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1312 {
1313     PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1314 
1315     trace_ps2_mouse_init(s);
1316     s->common.update_irq = update_irq;
1317     s->common.update_arg = update_arg;
1318     vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1319     qemu_input_handler_register((DeviceState *)s,
1320                                 &ps2_mouse_handler);
1321     qemu_register_reset(ps2_mouse_reset, s);
1322     return s;
1323 }
1324