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