xref: /openbmc/qemu/hw/input/ps2.c (revision 0b1183e3)
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 #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 static void ps2_reset_queue(PS2State *s)
555 {
556     PS2Queue *q = &s->queue;
557 
558     q->rptr = 0;
559     q->wptr = 0;
560     q->count = 0;
561 }
562 
563 void ps2_queue(PS2State *s, int b)
564 {
565     PS2Queue *q = &s->queue;
566 
567     if (q->count >= PS2_QUEUE_SIZE - 1)
568         return;
569     q->data[q->wptr] = b;
570     if (++q->wptr == PS2_QUEUE_SIZE)
571         q->wptr = 0;
572     q->count++;
573     s->update_irq(s->update_arg, 1);
574 }
575 
576 /* keycode is the untranslated scancode in the current scancode set. */
577 static void ps2_put_keycode(void *opaque, int keycode)
578 {
579     PS2KbdState *s = opaque;
580 
581     trace_ps2_put_keycode(opaque, keycode);
582     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
583 
584     if (s->translate) {
585         if (keycode == 0xf0) {
586             s->need_high_bit = true;
587         } else if (s->need_high_bit) {
588             ps2_queue(&s->common, translate_table[keycode] | 0x80);
589             s->need_high_bit = false;
590         } else {
591             ps2_queue(&s->common, translate_table[keycode]);
592         }
593     } else {
594         ps2_queue(&s->common, keycode);
595     }
596 }
597 
598 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
599                                InputEvent *evt)
600 {
601     PS2KbdState *s = (PS2KbdState *)dev;
602     InputKeyEvent *key = evt->u.key.data;
603     int qcode;
604     uint16_t keycode;
605 
606     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
607     assert(evt->type == INPUT_EVENT_KIND_KEY);
608     qcode = qemu_input_key_value_to_qcode(key->key);
609 
610     if (s->scancode_set == 1) {
611         if (qcode == Q_KEY_CODE_PAUSE) {
612             if (key->down) {
613                 ps2_put_keycode(s, 0xe1);
614                 ps2_put_keycode(s, 0x1d);
615                 ps2_put_keycode(s, 0x45);
616                 ps2_put_keycode(s, 0x91);
617                 ps2_put_keycode(s, 0x9d);
618                 ps2_put_keycode(s, 0xc5);
619             }
620         } else if (qcode == Q_KEY_CODE_PRINT) {
621             if (key->down) {
622                 ps2_put_keycode(s, 0xe0);
623                 ps2_put_keycode(s, 0x2a);
624                 ps2_put_keycode(s, 0xe0);
625                 ps2_put_keycode(s, 0x37);
626             } else {
627                 ps2_put_keycode(s, 0xe0);
628                 ps2_put_keycode(s, 0xb7);
629                 ps2_put_keycode(s, 0xe0);
630                 ps2_put_keycode(s, 0xaa);
631             }
632         } else {
633             keycode = qcode_to_keycode_set1[qcode];
634             if (keycode) {
635                 if (keycode & 0xff00) {
636                     ps2_put_keycode(s, keycode >> 8);
637                 }
638                 if (!key->down) {
639                     keycode |= 0x80;
640                 }
641                 ps2_put_keycode(s, keycode & 0xff);
642             } else {
643                 qemu_log_mask(LOG_UNIMP,
644                               "ps2: ignoring key with qcode %d\n", qcode);
645             }
646         }
647     } else if (s->scancode_set == 2) {
648         if (qcode == Q_KEY_CODE_PAUSE) {
649             if (key->down) {
650                 ps2_put_keycode(s, 0xe1);
651                 ps2_put_keycode(s, 0x14);
652                 ps2_put_keycode(s, 0x77);
653                 ps2_put_keycode(s, 0xe1);
654                 ps2_put_keycode(s, 0xf0);
655                 ps2_put_keycode(s, 0x14);
656                 ps2_put_keycode(s, 0xf0);
657                 ps2_put_keycode(s, 0x77);
658             }
659         } else if (qcode == Q_KEY_CODE_PRINT) {
660             if (key->down) {
661                 ps2_put_keycode(s, 0xe0);
662                 ps2_put_keycode(s, 0x12);
663                 ps2_put_keycode(s, 0xe0);
664                 ps2_put_keycode(s, 0x7c);
665             } else {
666                 ps2_put_keycode(s, 0xe0);
667                 ps2_put_keycode(s, 0xf0);
668                 ps2_put_keycode(s, 0x7c);
669                 ps2_put_keycode(s, 0xe0);
670                 ps2_put_keycode(s, 0xf0);
671                 ps2_put_keycode(s, 0x12);
672             }
673         } else {
674             keycode = qcode_to_keycode_set2[qcode];
675             if (keycode) {
676                 if (keycode & 0xff00) {
677                     ps2_put_keycode(s, keycode >> 8);
678                 }
679                 if (!key->down) {
680                     ps2_put_keycode(s, 0xf0);
681                 }
682                 ps2_put_keycode(s, keycode & 0xff);
683             } else {
684                 qemu_log_mask(LOG_UNIMP,
685                               "ps2: ignoring key with qcode %d\n", qcode);
686             }
687         }
688     } else if (s->scancode_set == 3) {
689         keycode = qcode_to_keycode_set3[qcode];
690         if (keycode) {
691             /* FIXME: break code should be configured on a key by key basis */
692             if (!key->down) {
693                 ps2_put_keycode(s, 0xf0);
694             }
695             ps2_put_keycode(s, keycode);
696         } else {
697             qemu_log_mask(LOG_UNIMP,
698                           "ps2: ignoring key with qcode %d\n", qcode);
699         }
700     }
701 }
702 
703 uint32_t ps2_read_data(PS2State *s)
704 {
705     PS2Queue *q;
706     int val, index;
707 
708     trace_ps2_read_data(s);
709     q = &s->queue;
710     if (q->count == 0) {
711         /* NOTE: if no data left, we return the last keyboard one
712            (needed for EMM386) */
713         /* XXX: need a timer to do things correctly */
714         index = q->rptr - 1;
715         if (index < 0)
716             index = PS2_QUEUE_SIZE - 1;
717         val = q->data[index];
718     } else {
719         val = q->data[q->rptr];
720         if (++q->rptr == PS2_QUEUE_SIZE)
721             q->rptr = 0;
722         q->count--;
723         /* reading deasserts IRQ */
724         s->update_irq(s->update_arg, 0);
725         /* reassert IRQs if data left */
726         s->update_irq(s->update_arg, q->count != 0);
727     }
728     return val;
729 }
730 
731 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
732 {
733     trace_ps2_set_ledstate(s, ledstate);
734     s->ledstate = ledstate;
735     kbd_put_ledstate(ledstate);
736 }
737 
738 static void ps2_reset_keyboard(PS2KbdState *s)
739 {
740     trace_ps2_reset_keyboard(s);
741     s->scan_enabled = 1;
742     s->scancode_set = 2;
743     ps2_reset_queue(&s->common);
744     ps2_set_ledstate(s, 0);
745 }
746 
747 void ps2_write_keyboard(void *opaque, int val)
748 {
749     PS2KbdState *s = (PS2KbdState *)opaque;
750 
751     trace_ps2_write_keyboard(opaque, val);
752     switch(s->common.write_cmd) {
753     default:
754     case -1:
755         switch(val) {
756         case 0x00:
757             ps2_queue(&s->common, KBD_REPLY_ACK);
758             break;
759         case 0x05:
760             ps2_queue(&s->common, KBD_REPLY_RESEND);
761             break;
762         case KBD_CMD_GET_ID:
763             ps2_queue(&s->common, KBD_REPLY_ACK);
764             /* We emulate a MF2 AT keyboard here */
765             ps2_queue(&s->common, KBD_REPLY_ID);
766             if (s->translate)
767                 ps2_queue(&s->common, 0x41);
768             else
769                 ps2_queue(&s->common, 0x83);
770             break;
771         case KBD_CMD_ECHO:
772             ps2_queue(&s->common, KBD_CMD_ECHO);
773             break;
774         case KBD_CMD_ENABLE:
775             s->scan_enabled = 1;
776             ps2_queue(&s->common, KBD_REPLY_ACK);
777             break;
778         case KBD_CMD_SCANCODE:
779         case KBD_CMD_SET_LEDS:
780         case KBD_CMD_SET_RATE:
781             s->common.write_cmd = val;
782             ps2_queue(&s->common, KBD_REPLY_ACK);
783             break;
784         case KBD_CMD_RESET_DISABLE:
785             ps2_reset_keyboard(s);
786             s->scan_enabled = 0;
787             ps2_queue(&s->common, KBD_REPLY_ACK);
788             break;
789         case KBD_CMD_RESET_ENABLE:
790             ps2_reset_keyboard(s);
791             s->scan_enabled = 1;
792             ps2_queue(&s->common, KBD_REPLY_ACK);
793             break;
794         case KBD_CMD_RESET:
795             ps2_reset_keyboard(s);
796             ps2_queue(&s->common, KBD_REPLY_ACK);
797             ps2_queue(&s->common, KBD_REPLY_POR);
798             break;
799         default:
800             ps2_queue(&s->common, KBD_REPLY_RESEND);
801             break;
802         }
803         break;
804     case KBD_CMD_SCANCODE:
805         if (val == 0) {
806             ps2_queue(&s->common, KBD_REPLY_ACK);
807             ps2_put_keycode(s, s->scancode_set);
808         } else if (val >= 1 && val <= 3) {
809             s->scancode_set = val;
810             ps2_queue(&s->common, KBD_REPLY_ACK);
811         } else {
812             ps2_queue(&s->common, KBD_REPLY_RESEND);
813         }
814         s->common.write_cmd = -1;
815         break;
816     case KBD_CMD_SET_LEDS:
817         ps2_set_ledstate(s, val);
818         ps2_queue(&s->common, KBD_REPLY_ACK);
819         s->common.write_cmd = -1;
820         break;
821     case KBD_CMD_SET_RATE:
822         ps2_queue(&s->common, KBD_REPLY_ACK);
823         s->common.write_cmd = -1;
824         break;
825     }
826 }
827 
828 /* Set the scancode translation mode.
829    0 = raw scancodes.
830    1 = translated scancodes (used by qemu internally).  */
831 
832 void ps2_keyboard_set_translation(void *opaque, int mode)
833 {
834     PS2KbdState *s = (PS2KbdState *)opaque;
835     trace_ps2_keyboard_set_translation(opaque, mode);
836     s->translate = mode;
837 }
838 
839 static void ps2_mouse_send_packet(PS2MouseState *s)
840 {
841     unsigned int b;
842     int dx1, dy1, dz1;
843 
844     dx1 = s->mouse_dx;
845     dy1 = s->mouse_dy;
846     dz1 = s->mouse_dz;
847     /* XXX: increase range to 8 bits ? */
848     if (dx1 > 127)
849         dx1 = 127;
850     else if (dx1 < -127)
851         dx1 = -127;
852     if (dy1 > 127)
853         dy1 = 127;
854     else if (dy1 < -127)
855         dy1 = -127;
856     b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
857     ps2_queue(&s->common, b);
858     ps2_queue(&s->common, dx1 & 0xff);
859     ps2_queue(&s->common, dy1 & 0xff);
860     /* extra byte for IMPS/2 or IMEX */
861     switch(s->mouse_type) {
862     default:
863         break;
864     case 3:
865         if (dz1 > 127)
866             dz1 = 127;
867         else if (dz1 < -127)
868                 dz1 = -127;
869         ps2_queue(&s->common, dz1 & 0xff);
870         break;
871     case 4:
872         if (dz1 > 7)
873             dz1 = 7;
874         else if (dz1 < -7)
875             dz1 = -7;
876         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
877         ps2_queue(&s->common, b);
878         break;
879     }
880 
881     trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
882     /* update deltas */
883     s->mouse_dx -= dx1;
884     s->mouse_dy -= dy1;
885     s->mouse_dz -= dz1;
886 }
887 
888 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
889                             InputEvent *evt)
890 {
891     static const int bmap[INPUT_BUTTON__MAX] = {
892         [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
893         [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
894         [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
895         [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
896         [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
897     };
898     PS2MouseState *s = (PS2MouseState *)dev;
899     InputMoveEvent *move;
900     InputBtnEvent *btn;
901 
902     /* check if deltas are recorded when disabled */
903     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
904         return;
905 
906     switch (evt->type) {
907     case INPUT_EVENT_KIND_REL:
908         move = evt->u.rel.data;
909         if (move->axis == INPUT_AXIS_X) {
910             s->mouse_dx += move->value;
911         } else if (move->axis == INPUT_AXIS_Y) {
912             s->mouse_dy -= move->value;
913         }
914         break;
915 
916     case INPUT_EVENT_KIND_BTN:
917         btn = evt->u.btn.data;
918         if (btn->down) {
919             s->mouse_buttons |= bmap[btn->button];
920             if (btn->button == INPUT_BUTTON_WHEEL_UP) {
921                 s->mouse_dz--;
922             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
923                 s->mouse_dz++;
924             }
925         } else {
926             s->mouse_buttons &= ~bmap[btn->button];
927         }
928         break;
929 
930     default:
931         /* keep gcc happy */
932         break;
933     }
934 }
935 
936 static void ps2_mouse_sync(DeviceState *dev)
937 {
938     PS2MouseState *s = (PS2MouseState *)dev;
939 
940     if (s->mouse_buttons) {
941         qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
942     }
943     if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
944         while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
945             /* if not remote, send event. Multiple events are sent if
946                too big deltas */
947             ps2_mouse_send_packet(s);
948             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
949                 break;
950         }
951     }
952 }
953 
954 void ps2_mouse_fake_event(void *opaque)
955 {
956     PS2MouseState *s = opaque;
957     trace_ps2_mouse_fake_event(opaque);
958     s->mouse_dx++;
959     ps2_mouse_sync(opaque);
960 }
961 
962 void ps2_write_mouse(void *opaque, int val)
963 {
964     PS2MouseState *s = (PS2MouseState *)opaque;
965 
966     trace_ps2_write_mouse(opaque, val);
967 #ifdef DEBUG_MOUSE
968     printf("kbd: write mouse 0x%02x\n", val);
969 #endif
970     switch(s->common.write_cmd) {
971     default:
972     case -1:
973         /* mouse command */
974         if (s->mouse_wrap) {
975             if (val == AUX_RESET_WRAP) {
976                 s->mouse_wrap = 0;
977                 ps2_queue(&s->common, AUX_ACK);
978                 return;
979             } else if (val != AUX_RESET) {
980                 ps2_queue(&s->common, val);
981                 return;
982             }
983         }
984         switch(val) {
985         case AUX_SET_SCALE11:
986             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
987             ps2_queue(&s->common, AUX_ACK);
988             break;
989         case AUX_SET_SCALE21:
990             s->mouse_status |= MOUSE_STATUS_SCALE21;
991             ps2_queue(&s->common, AUX_ACK);
992             break;
993         case AUX_SET_STREAM:
994             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
995             ps2_queue(&s->common, AUX_ACK);
996             break;
997         case AUX_SET_WRAP:
998             s->mouse_wrap = 1;
999             ps2_queue(&s->common, AUX_ACK);
1000             break;
1001         case AUX_SET_REMOTE:
1002             s->mouse_status |= MOUSE_STATUS_REMOTE;
1003             ps2_queue(&s->common, AUX_ACK);
1004             break;
1005         case AUX_GET_TYPE:
1006             ps2_queue(&s->common, AUX_ACK);
1007             ps2_queue(&s->common, s->mouse_type);
1008             break;
1009         case AUX_SET_RES:
1010         case AUX_SET_SAMPLE:
1011             s->common.write_cmd = val;
1012             ps2_queue(&s->common, AUX_ACK);
1013             break;
1014         case AUX_GET_SCALE:
1015             ps2_queue(&s->common, AUX_ACK);
1016             ps2_queue(&s->common, s->mouse_status);
1017             ps2_queue(&s->common, s->mouse_resolution);
1018             ps2_queue(&s->common, s->mouse_sample_rate);
1019             break;
1020         case AUX_POLL:
1021             ps2_queue(&s->common, AUX_ACK);
1022             ps2_mouse_send_packet(s);
1023             break;
1024         case AUX_ENABLE_DEV:
1025             s->mouse_status |= MOUSE_STATUS_ENABLED;
1026             ps2_queue(&s->common, AUX_ACK);
1027             break;
1028         case AUX_DISABLE_DEV:
1029             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
1030             ps2_queue(&s->common, AUX_ACK);
1031             break;
1032         case AUX_SET_DEFAULT:
1033             s->mouse_sample_rate = 100;
1034             s->mouse_resolution = 2;
1035             s->mouse_status = 0;
1036             ps2_queue(&s->common, AUX_ACK);
1037             break;
1038         case AUX_RESET:
1039             s->mouse_sample_rate = 100;
1040             s->mouse_resolution = 2;
1041             s->mouse_status = 0;
1042             s->mouse_type = 0;
1043             ps2_queue(&s->common, AUX_ACK);
1044             ps2_queue(&s->common, 0xaa);
1045             ps2_queue(&s->common, s->mouse_type);
1046             break;
1047         default:
1048             break;
1049         }
1050         break;
1051     case AUX_SET_SAMPLE:
1052         s->mouse_sample_rate = val;
1053         /* detect IMPS/2 or IMEX */
1054         switch(s->mouse_detect_state) {
1055         default:
1056         case 0:
1057             if (val == 200)
1058                 s->mouse_detect_state = 1;
1059             break;
1060         case 1:
1061             if (val == 100)
1062                 s->mouse_detect_state = 2;
1063             else if (val == 200)
1064                 s->mouse_detect_state = 3;
1065             else
1066                 s->mouse_detect_state = 0;
1067             break;
1068         case 2:
1069             if (val == 80)
1070                 s->mouse_type = 3; /* IMPS/2 */
1071             s->mouse_detect_state = 0;
1072             break;
1073         case 3:
1074             if (val == 80)
1075                 s->mouse_type = 4; /* IMEX */
1076             s->mouse_detect_state = 0;
1077             break;
1078         }
1079         ps2_queue(&s->common, AUX_ACK);
1080         s->common.write_cmd = -1;
1081         break;
1082     case AUX_SET_RES:
1083         s->mouse_resolution = val;
1084         ps2_queue(&s->common, AUX_ACK);
1085         s->common.write_cmd = -1;
1086         break;
1087     }
1088 }
1089 
1090 static void ps2_common_reset(PS2State *s)
1091 {
1092     s->write_cmd = -1;
1093     ps2_reset_queue(s);
1094     s->update_irq(s->update_arg, 0);
1095 }
1096 
1097 static void ps2_common_post_load(PS2State *s)
1098 {
1099     PS2Queue *q = &s->queue;
1100     int size;
1101     int i;
1102     int tmp_data[PS2_QUEUE_SIZE];
1103 
1104     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
1105     size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
1106 
1107     /* move the queue elements to the start of data array */
1108     if (size > 0) {
1109         for (i = 0; i < size; i++) {
1110             /* move the queue elements to the temporary buffer */
1111             tmp_data[i] = q->data[q->rptr];
1112             if (++q->rptr == 256) {
1113                 q->rptr = 0;
1114             }
1115         }
1116         memcpy(q->data, tmp_data, size);
1117     }
1118     /* reset rptr/wptr/count */
1119     q->rptr = 0;
1120     q->wptr = size;
1121     q->count = size;
1122     s->update_irq(s->update_arg, q->count != 0);
1123 }
1124 
1125 static void ps2_kbd_reset(void *opaque)
1126 {
1127     PS2KbdState *s = (PS2KbdState *) opaque;
1128 
1129     trace_ps2_kbd_reset(opaque);
1130     ps2_common_reset(&s->common);
1131     s->scan_enabled = 0;
1132     s->translate = 0;
1133     s->scancode_set = 2;
1134 }
1135 
1136 static void ps2_mouse_reset(void *opaque)
1137 {
1138     PS2MouseState *s = (PS2MouseState *) opaque;
1139 
1140     trace_ps2_mouse_reset(opaque);
1141     ps2_common_reset(&s->common);
1142     s->mouse_status = 0;
1143     s->mouse_resolution = 0;
1144     s->mouse_sample_rate = 0;
1145     s->mouse_wrap = 0;
1146     s->mouse_type = 0;
1147     s->mouse_detect_state = 0;
1148     s->mouse_dx = 0;
1149     s->mouse_dy = 0;
1150     s->mouse_dz = 0;
1151     s->mouse_buttons = 0;
1152 }
1153 
1154 static const VMStateDescription vmstate_ps2_common = {
1155     .name = "PS2 Common State",
1156     .version_id = 3,
1157     .minimum_version_id = 2,
1158     .fields = (VMStateField[]) {
1159         VMSTATE_INT32(write_cmd, PS2State),
1160         VMSTATE_INT32(queue.rptr, PS2State),
1161         VMSTATE_INT32(queue.wptr, PS2State),
1162         VMSTATE_INT32(queue.count, PS2State),
1163         VMSTATE_BUFFER(queue.data, PS2State),
1164         VMSTATE_END_OF_LIST()
1165     }
1166 };
1167 
1168 static bool ps2_keyboard_ledstate_needed(void *opaque)
1169 {
1170     PS2KbdState *s = opaque;
1171 
1172     return s->ledstate != 0; /* 0 is default state */
1173 }
1174 
1175 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1176 {
1177     PS2KbdState *s = opaque;
1178 
1179     kbd_put_ledstate(s->ledstate);
1180     return 0;
1181 }
1182 
1183 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1184     .name = "ps2kbd/ledstate",
1185     .version_id = 3,
1186     .minimum_version_id = 2,
1187     .post_load = ps2_kbd_ledstate_post_load,
1188     .needed = ps2_keyboard_ledstate_needed,
1189     .fields = (VMStateField[]) {
1190         VMSTATE_INT32(ledstate, PS2KbdState),
1191         VMSTATE_END_OF_LIST()
1192     }
1193 };
1194 
1195 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1196 {
1197     PS2KbdState *s = opaque;
1198     return s->need_high_bit != 0; /* 0 is the usual state */
1199 }
1200 
1201 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1202     .name = "ps2kbd/need_high_bit",
1203     .version_id = 1,
1204     .minimum_version_id = 1,
1205     .needed = ps2_keyboard_need_high_bit_needed,
1206     .fields = (VMStateField[]) {
1207         VMSTATE_BOOL(need_high_bit, PS2KbdState),
1208         VMSTATE_END_OF_LIST()
1209     }
1210 };
1211 
1212 static int ps2_kbd_post_load(void* opaque, int version_id)
1213 {
1214     PS2KbdState *s = (PS2KbdState*)opaque;
1215     PS2State *ps2 = &s->common;
1216 
1217     if (version_id == 2)
1218         s->scancode_set=2;
1219 
1220     ps2_common_post_load(ps2);
1221 
1222     return 0;
1223 }
1224 
1225 static void ps2_kbd_pre_save(void *opaque)
1226 {
1227     PS2KbdState *s = (PS2KbdState *)opaque;
1228     PS2State *ps2 = &s->common;
1229 
1230     ps2_common_post_load(ps2);
1231 }
1232 
1233 static const VMStateDescription vmstate_ps2_keyboard = {
1234     .name = "ps2kbd",
1235     .version_id = 3,
1236     .minimum_version_id = 2,
1237     .post_load = ps2_kbd_post_load,
1238     .pre_save = ps2_kbd_pre_save,
1239     .fields = (VMStateField[]) {
1240         VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1241         VMSTATE_INT32(scan_enabled, PS2KbdState),
1242         VMSTATE_INT32(translate, PS2KbdState),
1243         VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1244         VMSTATE_END_OF_LIST()
1245     },
1246     .subsections = (const VMStateDescription*[]) {
1247         &vmstate_ps2_keyboard_ledstate,
1248         &vmstate_ps2_keyboard_need_high_bit,
1249         NULL
1250     }
1251 };
1252 
1253 static int ps2_mouse_post_load(void *opaque, int version_id)
1254 {
1255     PS2MouseState *s = (PS2MouseState *)opaque;
1256     PS2State *ps2 = &s->common;
1257 
1258     ps2_common_post_load(ps2);
1259 
1260     return 0;
1261 }
1262 
1263 static void ps2_mouse_pre_save(void *opaque)
1264 {
1265     PS2MouseState *s = (PS2MouseState *)opaque;
1266     PS2State *ps2 = &s->common;
1267 
1268     ps2_common_post_load(ps2);
1269 }
1270 
1271 static const VMStateDescription vmstate_ps2_mouse = {
1272     .name = "ps2mouse",
1273     .version_id = 2,
1274     .minimum_version_id = 2,
1275     .post_load = ps2_mouse_post_load,
1276     .pre_save = ps2_mouse_pre_save,
1277     .fields = (VMStateField[]) {
1278         VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1279         VMSTATE_UINT8(mouse_status, PS2MouseState),
1280         VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1281         VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1282         VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1283         VMSTATE_UINT8(mouse_type, PS2MouseState),
1284         VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1285         VMSTATE_INT32(mouse_dx, PS2MouseState),
1286         VMSTATE_INT32(mouse_dy, PS2MouseState),
1287         VMSTATE_INT32(mouse_dz, PS2MouseState),
1288         VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1289         VMSTATE_END_OF_LIST()
1290     }
1291 };
1292 
1293 static QemuInputHandler ps2_keyboard_handler = {
1294     .name  = "QEMU PS/2 Keyboard",
1295     .mask  = INPUT_EVENT_MASK_KEY,
1296     .event = ps2_keyboard_event,
1297 };
1298 
1299 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1300 {
1301     PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1302 
1303     trace_ps2_kbd_init(s);
1304     s->common.update_irq = update_irq;
1305     s->common.update_arg = update_arg;
1306     s->scancode_set = 2;
1307     vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1308     qemu_input_handler_register((DeviceState *)s,
1309                                 &ps2_keyboard_handler);
1310     qemu_register_reset(ps2_kbd_reset, s);
1311     return s;
1312 }
1313 
1314 static QemuInputHandler ps2_mouse_handler = {
1315     .name  = "QEMU PS/2 Mouse",
1316     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1317     .event = ps2_mouse_event,
1318     .sync  = ps2_mouse_sync,
1319 };
1320 
1321 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1322 {
1323     PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1324 
1325     trace_ps2_mouse_init(s);
1326     s->common.update_irq = update_irq;
1327     s->common.update_arg = update_arg;
1328     vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1329     qemu_input_handler_register((DeviceState *)s,
1330                                 &ps2_mouse_handler);
1331     qemu_register_reset(ps2_mouse_reset, s);
1332     return s;
1333 }
1334