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