xref: /qemu/hw/input/ps2.c (revision 954ee55bd528a97347f19f815e00f1e375f82f0a)
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_set_ledstate(s, 0);
744 }
745 
746 void ps2_write_keyboard(void *opaque, int val)
747 {
748     PS2KbdState *s = (PS2KbdState *)opaque;
749 
750     trace_ps2_write_keyboard(opaque, val);
751     switch(s->common.write_cmd) {
752     default:
753     case -1:
754         switch(val) {
755         case 0x00:
756             ps2_queue(&s->common, KBD_REPLY_ACK);
757             break;
758         case 0x05:
759             ps2_queue(&s->common, KBD_REPLY_RESEND);
760             break;
761         case KBD_CMD_GET_ID:
762             ps2_queue(&s->common, KBD_REPLY_ACK);
763             /* We emulate a MF2 AT keyboard here */
764             ps2_queue(&s->common, KBD_REPLY_ID);
765             if (s->translate)
766                 ps2_queue(&s->common, 0x41);
767             else
768                 ps2_queue(&s->common, 0x83);
769             break;
770         case KBD_CMD_ECHO:
771             ps2_queue(&s->common, KBD_CMD_ECHO);
772             break;
773         case KBD_CMD_ENABLE:
774             s->scan_enabled = 1;
775             ps2_queue(&s->common, KBD_REPLY_ACK);
776             break;
777         case KBD_CMD_SCANCODE:
778         case KBD_CMD_SET_LEDS:
779         case KBD_CMD_SET_RATE:
780             s->common.write_cmd = val;
781             ps2_queue(&s->common, KBD_REPLY_ACK);
782             break;
783         case KBD_CMD_RESET_DISABLE:
784             ps2_reset_keyboard(s);
785             s->scan_enabled = 0;
786             ps2_queue(&s->common, KBD_REPLY_ACK);
787             break;
788         case KBD_CMD_RESET_ENABLE:
789             ps2_reset_keyboard(s);
790             s->scan_enabled = 1;
791             ps2_queue(&s->common, KBD_REPLY_ACK);
792             break;
793         case KBD_CMD_RESET:
794             ps2_reset_keyboard(s);
795             ps2_queue(&s->common, KBD_REPLY_ACK);
796             ps2_queue(&s->common, KBD_REPLY_POR);
797             break;
798         default:
799             ps2_queue(&s->common, KBD_REPLY_RESEND);
800             break;
801         }
802         break;
803     case KBD_CMD_SCANCODE:
804         if (val == 0) {
805             ps2_queue(&s->common, KBD_REPLY_ACK);
806             ps2_put_keycode(s, s->scancode_set);
807         } else if (val >= 1 && val <= 3) {
808             s->scancode_set = val;
809             ps2_queue(&s->common, KBD_REPLY_ACK);
810         } else {
811             ps2_queue(&s->common, KBD_REPLY_RESEND);
812         }
813         s->common.write_cmd = -1;
814         break;
815     case KBD_CMD_SET_LEDS:
816         ps2_set_ledstate(s, val);
817         ps2_queue(&s->common, KBD_REPLY_ACK);
818         s->common.write_cmd = -1;
819         break;
820     case KBD_CMD_SET_RATE:
821         ps2_queue(&s->common, KBD_REPLY_ACK);
822         s->common.write_cmd = -1;
823         break;
824     }
825 }
826 
827 /* Set the scancode translation mode.
828    0 = raw scancodes.
829    1 = translated scancodes (used by qemu internally).  */
830 
831 void ps2_keyboard_set_translation(void *opaque, int mode)
832 {
833     PS2KbdState *s = (PS2KbdState *)opaque;
834     trace_ps2_keyboard_set_translation(opaque, mode);
835     s->translate = mode;
836 }
837 
838 static void ps2_mouse_send_packet(PS2MouseState *s)
839 {
840     unsigned int b;
841     int dx1, dy1, dz1;
842 
843     dx1 = s->mouse_dx;
844     dy1 = s->mouse_dy;
845     dz1 = s->mouse_dz;
846     /* XXX: increase range to 8 bits ? */
847     if (dx1 > 127)
848         dx1 = 127;
849     else if (dx1 < -127)
850         dx1 = -127;
851     if (dy1 > 127)
852         dy1 = 127;
853     else if (dy1 < -127)
854         dy1 = -127;
855     b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
856     ps2_queue(&s->common, b);
857     ps2_queue(&s->common, dx1 & 0xff);
858     ps2_queue(&s->common, dy1 & 0xff);
859     /* extra byte for IMPS/2 or IMEX */
860     switch(s->mouse_type) {
861     default:
862         break;
863     case 3:
864         if (dz1 > 127)
865             dz1 = 127;
866         else if (dz1 < -127)
867                 dz1 = -127;
868         ps2_queue(&s->common, dz1 & 0xff);
869         break;
870     case 4:
871         if (dz1 > 7)
872             dz1 = 7;
873         else if (dz1 < -7)
874             dz1 = -7;
875         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
876         ps2_queue(&s->common, b);
877         break;
878     }
879 
880     trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
881     /* update deltas */
882     s->mouse_dx -= dx1;
883     s->mouse_dy -= dy1;
884     s->mouse_dz -= dz1;
885 }
886 
887 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
888                             InputEvent *evt)
889 {
890     static const int bmap[INPUT_BUTTON__MAX] = {
891         [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
892         [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
893         [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
894         [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
895         [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
896     };
897     PS2MouseState *s = (PS2MouseState *)dev;
898     InputMoveEvent *move;
899     InputBtnEvent *btn;
900 
901     /* check if deltas are recorded when disabled */
902     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
903         return;
904 
905     switch (evt->type) {
906     case INPUT_EVENT_KIND_REL:
907         move = evt->u.rel.data;
908         if (move->axis == INPUT_AXIS_X) {
909             s->mouse_dx += move->value;
910         } else if (move->axis == INPUT_AXIS_Y) {
911             s->mouse_dy -= move->value;
912         }
913         break;
914 
915     case INPUT_EVENT_KIND_BTN:
916         btn = evt->u.btn.data;
917         if (btn->down) {
918             s->mouse_buttons |= bmap[btn->button];
919             if (btn->button == INPUT_BUTTON_WHEEL_UP) {
920                 s->mouse_dz--;
921             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
922                 s->mouse_dz++;
923             }
924         } else {
925             s->mouse_buttons &= ~bmap[btn->button];
926         }
927         break;
928 
929     default:
930         /* keep gcc happy */
931         break;
932     }
933 }
934 
935 static void ps2_mouse_sync(DeviceState *dev)
936 {
937     PS2MouseState *s = (PS2MouseState *)dev;
938 
939     if (s->mouse_buttons) {
940         qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
941     }
942     if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
943         while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
944             /* if not remote, send event. Multiple events are sent if
945                too big deltas */
946             ps2_mouse_send_packet(s);
947             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
948                 break;
949         }
950     }
951 }
952 
953 void ps2_mouse_fake_event(void *opaque)
954 {
955     PS2MouseState *s = opaque;
956     trace_ps2_mouse_fake_event(opaque);
957     s->mouse_dx++;
958     ps2_mouse_sync(opaque);
959 }
960 
961 void ps2_write_mouse(void *opaque, int val)
962 {
963     PS2MouseState *s = (PS2MouseState *)opaque;
964 
965     trace_ps2_write_mouse(opaque, val);
966 #ifdef DEBUG_MOUSE
967     printf("kbd: write mouse 0x%02x\n", val);
968 #endif
969     switch(s->common.write_cmd) {
970     default:
971     case -1:
972         /* mouse command */
973         if (s->mouse_wrap) {
974             if (val == AUX_RESET_WRAP) {
975                 s->mouse_wrap = 0;
976                 ps2_queue(&s->common, AUX_ACK);
977                 return;
978             } else if (val != AUX_RESET) {
979                 ps2_queue(&s->common, val);
980                 return;
981             }
982         }
983         switch(val) {
984         case AUX_SET_SCALE11:
985             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
986             ps2_queue(&s->common, AUX_ACK);
987             break;
988         case AUX_SET_SCALE21:
989             s->mouse_status |= MOUSE_STATUS_SCALE21;
990             ps2_queue(&s->common, AUX_ACK);
991             break;
992         case AUX_SET_STREAM:
993             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
994             ps2_queue(&s->common, AUX_ACK);
995             break;
996         case AUX_SET_WRAP:
997             s->mouse_wrap = 1;
998             ps2_queue(&s->common, AUX_ACK);
999             break;
1000         case AUX_SET_REMOTE:
1001             s->mouse_status |= MOUSE_STATUS_REMOTE;
1002             ps2_queue(&s->common, AUX_ACK);
1003             break;
1004         case AUX_GET_TYPE:
1005             ps2_queue(&s->common, AUX_ACK);
1006             ps2_queue(&s->common, s->mouse_type);
1007             break;
1008         case AUX_SET_RES:
1009         case AUX_SET_SAMPLE:
1010             s->common.write_cmd = val;
1011             ps2_queue(&s->common, AUX_ACK);
1012             break;
1013         case AUX_GET_SCALE:
1014             ps2_queue(&s->common, AUX_ACK);
1015             ps2_queue(&s->common, s->mouse_status);
1016             ps2_queue(&s->common, s->mouse_resolution);
1017             ps2_queue(&s->common, s->mouse_sample_rate);
1018             break;
1019         case AUX_POLL:
1020             ps2_queue(&s->common, AUX_ACK);
1021             ps2_mouse_send_packet(s);
1022             break;
1023         case AUX_ENABLE_DEV:
1024             s->mouse_status |= MOUSE_STATUS_ENABLED;
1025             ps2_queue(&s->common, AUX_ACK);
1026             break;
1027         case AUX_DISABLE_DEV:
1028             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
1029             ps2_queue(&s->common, AUX_ACK);
1030             break;
1031         case AUX_SET_DEFAULT:
1032             s->mouse_sample_rate = 100;
1033             s->mouse_resolution = 2;
1034             s->mouse_status = 0;
1035             ps2_queue(&s->common, AUX_ACK);
1036             break;
1037         case AUX_RESET:
1038             s->mouse_sample_rate = 100;
1039             s->mouse_resolution = 2;
1040             s->mouse_status = 0;
1041             s->mouse_type = 0;
1042             ps2_queue(&s->common, AUX_ACK);
1043             ps2_queue(&s->common, 0xaa);
1044             ps2_queue(&s->common, s->mouse_type);
1045             break;
1046         default:
1047             break;
1048         }
1049         break;
1050     case AUX_SET_SAMPLE:
1051         s->mouse_sample_rate = val;
1052         /* detect IMPS/2 or IMEX */
1053         switch(s->mouse_detect_state) {
1054         default:
1055         case 0:
1056             if (val == 200)
1057                 s->mouse_detect_state = 1;
1058             break;
1059         case 1:
1060             if (val == 100)
1061                 s->mouse_detect_state = 2;
1062             else if (val == 200)
1063                 s->mouse_detect_state = 3;
1064             else
1065                 s->mouse_detect_state = 0;
1066             break;
1067         case 2:
1068             if (val == 80)
1069                 s->mouse_type = 3; /* IMPS/2 */
1070             s->mouse_detect_state = 0;
1071             break;
1072         case 3:
1073             if (val == 80)
1074                 s->mouse_type = 4; /* IMEX */
1075             s->mouse_detect_state = 0;
1076             break;
1077         }
1078         ps2_queue(&s->common, AUX_ACK);
1079         s->common.write_cmd = -1;
1080         break;
1081     case AUX_SET_RES:
1082         s->mouse_resolution = val;
1083         ps2_queue(&s->common, AUX_ACK);
1084         s->common.write_cmd = -1;
1085         break;
1086     }
1087 }
1088 
1089 static void ps2_common_reset(PS2State *s)
1090 {
1091     s->write_cmd = -1;
1092     ps2_reset_queue(s);
1093     s->update_irq(s->update_arg, 0);
1094 }
1095 
1096 static void ps2_common_post_load(PS2State *s)
1097 {
1098     PS2Queue *q = &s->queue;
1099     int size;
1100     int i;
1101     int tmp_data[PS2_QUEUE_SIZE];
1102 
1103     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
1104     size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
1105 
1106     /* move the queue elements to the start of data array */
1107     if (size > 0) {
1108         for (i = 0; i < size; i++) {
1109             /* move the queue elements to the temporary buffer */
1110             tmp_data[i] = q->data[q->rptr];
1111             if (++q->rptr == 256) {
1112                 q->rptr = 0;
1113             }
1114         }
1115         memcpy(q->data, tmp_data, size);
1116     }
1117     /* reset rptr/wptr/count */
1118     q->rptr = 0;
1119     q->wptr = size;
1120     q->count = size;
1121     s->update_irq(s->update_arg, q->count != 0);
1122 }
1123 
1124 static void ps2_kbd_reset(void *opaque)
1125 {
1126     PS2KbdState *s = (PS2KbdState *) opaque;
1127 
1128     trace_ps2_kbd_reset(opaque);
1129     ps2_common_reset(&s->common);
1130     s->scan_enabled = 0;
1131     s->translate = 0;
1132     s->scancode_set = 2;
1133 }
1134 
1135 static void ps2_mouse_reset(void *opaque)
1136 {
1137     PS2MouseState *s = (PS2MouseState *) opaque;
1138 
1139     trace_ps2_mouse_reset(opaque);
1140     ps2_common_reset(&s->common);
1141     s->mouse_status = 0;
1142     s->mouse_resolution = 0;
1143     s->mouse_sample_rate = 0;
1144     s->mouse_wrap = 0;
1145     s->mouse_type = 0;
1146     s->mouse_detect_state = 0;
1147     s->mouse_dx = 0;
1148     s->mouse_dy = 0;
1149     s->mouse_dz = 0;
1150     s->mouse_buttons = 0;
1151 }
1152 
1153 static const VMStateDescription vmstate_ps2_common = {
1154     .name = "PS2 Common State",
1155     .version_id = 3,
1156     .minimum_version_id = 2,
1157     .fields = (VMStateField[]) {
1158         VMSTATE_INT32(write_cmd, PS2State),
1159         VMSTATE_INT32(queue.rptr, PS2State),
1160         VMSTATE_INT32(queue.wptr, PS2State),
1161         VMSTATE_INT32(queue.count, PS2State),
1162         VMSTATE_BUFFER(queue.data, PS2State),
1163         VMSTATE_END_OF_LIST()
1164     }
1165 };
1166 
1167 static bool ps2_keyboard_ledstate_needed(void *opaque)
1168 {
1169     PS2KbdState *s = opaque;
1170 
1171     return s->ledstate != 0; /* 0 is default state */
1172 }
1173 
1174 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1175 {
1176     PS2KbdState *s = opaque;
1177 
1178     kbd_put_ledstate(s->ledstate);
1179     return 0;
1180 }
1181 
1182 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1183     .name = "ps2kbd/ledstate",
1184     .version_id = 3,
1185     .minimum_version_id = 2,
1186     .post_load = ps2_kbd_ledstate_post_load,
1187     .needed = ps2_keyboard_ledstate_needed,
1188     .fields = (VMStateField[]) {
1189         VMSTATE_INT32(ledstate, PS2KbdState),
1190         VMSTATE_END_OF_LIST()
1191     }
1192 };
1193 
1194 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1195 {
1196     PS2KbdState *s = opaque;
1197     return s->need_high_bit != 0; /* 0 is the usual state */
1198 }
1199 
1200 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1201     .name = "ps2kbd/need_high_bit",
1202     .version_id = 1,
1203     .minimum_version_id = 1,
1204     .needed = ps2_keyboard_need_high_bit_needed,
1205     .fields = (VMStateField[]) {
1206         VMSTATE_BOOL(need_high_bit, PS2KbdState),
1207         VMSTATE_END_OF_LIST()
1208     }
1209 };
1210 
1211 static int ps2_kbd_post_load(void* opaque, int version_id)
1212 {
1213     PS2KbdState *s = (PS2KbdState*)opaque;
1214     PS2State *ps2 = &s->common;
1215 
1216     if (version_id == 2)
1217         s->scancode_set=2;
1218 
1219     ps2_common_post_load(ps2);
1220 
1221     return 0;
1222 }
1223 
1224 static void ps2_kbd_pre_save(void *opaque)
1225 {
1226     PS2KbdState *s = (PS2KbdState *)opaque;
1227     PS2State *ps2 = &s->common;
1228 
1229     ps2_common_post_load(ps2);
1230 }
1231 
1232 static const VMStateDescription vmstate_ps2_keyboard = {
1233     .name = "ps2kbd",
1234     .version_id = 3,
1235     .minimum_version_id = 2,
1236     .post_load = ps2_kbd_post_load,
1237     .pre_save = ps2_kbd_pre_save,
1238     .fields = (VMStateField[]) {
1239         VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1240         VMSTATE_INT32(scan_enabled, PS2KbdState),
1241         VMSTATE_INT32(translate, PS2KbdState),
1242         VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1243         VMSTATE_END_OF_LIST()
1244     },
1245     .subsections = (const VMStateDescription*[]) {
1246         &vmstate_ps2_keyboard_ledstate,
1247         &vmstate_ps2_keyboard_need_high_bit,
1248         NULL
1249     }
1250 };
1251 
1252 static int ps2_mouse_post_load(void *opaque, int version_id)
1253 {
1254     PS2MouseState *s = (PS2MouseState *)opaque;
1255     PS2State *ps2 = &s->common;
1256 
1257     ps2_common_post_load(ps2);
1258 
1259     return 0;
1260 }
1261 
1262 static void ps2_mouse_pre_save(void *opaque)
1263 {
1264     PS2MouseState *s = (PS2MouseState *)opaque;
1265     PS2State *ps2 = &s->common;
1266 
1267     ps2_common_post_load(ps2);
1268 }
1269 
1270 static const VMStateDescription vmstate_ps2_mouse = {
1271     .name = "ps2mouse",
1272     .version_id = 2,
1273     .minimum_version_id = 2,
1274     .post_load = ps2_mouse_post_load,
1275     .pre_save = ps2_mouse_pre_save,
1276     .fields = (VMStateField[]) {
1277         VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1278         VMSTATE_UINT8(mouse_status, PS2MouseState),
1279         VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1280         VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1281         VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1282         VMSTATE_UINT8(mouse_type, PS2MouseState),
1283         VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1284         VMSTATE_INT32(mouse_dx, PS2MouseState),
1285         VMSTATE_INT32(mouse_dy, PS2MouseState),
1286         VMSTATE_INT32(mouse_dz, PS2MouseState),
1287         VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1288         VMSTATE_END_OF_LIST()
1289     }
1290 };
1291 
1292 static QemuInputHandler ps2_keyboard_handler = {
1293     .name  = "QEMU PS/2 Keyboard",
1294     .mask  = INPUT_EVENT_MASK_KEY,
1295     .event = ps2_keyboard_event,
1296 };
1297 
1298 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1299 {
1300     PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1301 
1302     trace_ps2_kbd_init(s);
1303     s->common.update_irq = update_irq;
1304     s->common.update_arg = update_arg;
1305     s->scancode_set = 2;
1306     vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1307     qemu_input_handler_register((DeviceState *)s,
1308                                 &ps2_keyboard_handler);
1309     qemu_register_reset(ps2_kbd_reset, s);
1310     return s;
1311 }
1312 
1313 static QemuInputHandler ps2_mouse_handler = {
1314     .name  = "QEMU PS/2 Mouse",
1315     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1316     .event = ps2_mouse_event,
1317     .sync  = ps2_mouse_sync,
1318 };
1319 
1320 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1321 {
1322     PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1323 
1324     trace_ps2_mouse_init(s);
1325     s->common.update_irq = update_irq;
1326     s->common.update_arg = update_arg;
1327     vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1328     qemu_input_handler_register((DeviceState *)s,
1329                                 &ps2_mouse_handler);
1330     qemu_register_reset(ps2_mouse_reset, s);
1331     return s;
1332 }
1333