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