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