2 * QEMU PS/2 keyboard/mouse emulation
4 * Copyright (c) 2003 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 #include "qemu/osdep.h"
27 #include "hw/input/ps2.h"
28 #include "ui/console.h"
30 #include "sysemu/sysemu.h"
34 /* debug PC keyboard */
37 /* debug PC keyboard : only mouse */
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 */
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 */
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. */
75 #define MOUSE_STATUS_REMOTE 0x40
76 #define MOUSE_STATUS_ENABLED 0x20
77 #define MOUSE_STATUS_SCALE21 0x10
79 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
82 /* Keep the data array 256 bytes long, which compatibility
83 with older qemu versions. */
85 int rptr, wptr, count;
91 void (*update_irq)(void *, int);
99 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
106 uint8_t mouse_status;
107 uint8_t mouse_resolution;
108 uint8_t mouse_sample_rate;
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 */
115 uint8_t mouse_buttons;
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,
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,
228 [Q_KEY_CODE_POWER] = 0x0e5e,
229 [Q_KEY_CODE_SLEEP] = 0x0e5f,
230 [Q_KEY_CODE_WAKE] = 0x0e63,
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,
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,
261 static const uint16_t qcode_to_keycode_set2[Q_KEY_CODE__MAX] = {
262 [0 ... Q_KEY_CODE__MAX - 1] = 0,
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,
370 [Q_KEY_CODE_POWER] = 0x0e37,
371 [Q_KEY_CODE_SLEEP] = 0x0e3f,
372 [Q_KEY_CODE_WAKE] = 0x0e5e,
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,
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,
406 static const uint16_t qcode_to_keycode_set3[Q_KEY_CODE__MAX] = {
407 [0 ... Q_KEY_CODE__MAX - 1] = 0,
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,
514 [Q_KEY_CODE_HIRAGANA] = 0x87,
515 [Q_KEY_CODE_HENKAN] = 0x86,
516 [Q_KEY_CODE_YEN] = 0x5d,
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,
554 static void ps2_reset_queue(PS2State *s)
556 PS2Queue *q = &s->queue;
563 void ps2_queue(PS2State *s, int b)
565 PS2Queue *q = &s->queue;
567 if (q->count >= PS2_QUEUE_SIZE - 1)
569 q->data[q->wptr] = b;
570 if (++q->wptr == PS2_QUEUE_SIZE)
573 s->update_irq(s->update_arg, 1);
576 /* keycode is the untranslated scancode in the current scancode set. */
577 static void ps2_put_keycode(void *opaque, int keycode)
579 PS2KbdState *s = opaque;
581 trace_ps2_put_keycode(opaque, keycode);
582 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
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;
591 ps2_queue(&s->common, translate_table[keycode]);
594 ps2_queue(&s->common, keycode);
598 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
601 PS2KbdState *s = (PS2KbdState *)dev;
602 InputKeyEvent *key = evt->u.key.data;
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);
610 if (s->scancode_set == 1) {
611 if (qcode == Q_KEY_CODE_PAUSE) {
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);
620 } else if (qcode == Q_KEY_CODE_PRINT) {
622 ps2_put_keycode(s, 0xe0);
623 ps2_put_keycode(s, 0x2a);
624 ps2_put_keycode(s, 0xe0);
625 ps2_put_keycode(s, 0x37);
627 ps2_put_keycode(s, 0xe0);
628 ps2_put_keycode(s, 0xb7);
629 ps2_put_keycode(s, 0xe0);
630 ps2_put_keycode(s, 0xaa);
633 keycode = qcode_to_keycode_set1[qcode];
635 if (keycode & 0xff00) {
636 ps2_put_keycode(s, keycode >> 8);
641 ps2_put_keycode(s, keycode & 0xff);
643 qemu_log_mask(LOG_UNIMP,
644 "ps2: ignoring key with qcode %d\n", qcode);
647 } else if (s->scancode_set == 2) {
648 if (qcode == Q_KEY_CODE_PAUSE) {
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);
659 } else if (qcode == Q_KEY_CODE_PRINT) {
661 ps2_put_keycode(s, 0xe0);
662 ps2_put_keycode(s, 0x12);
663 ps2_put_keycode(s, 0xe0);
664 ps2_put_keycode(s, 0x7c);
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);
674 keycode = qcode_to_keycode_set2[qcode];
676 if (keycode & 0xff00) {
677 ps2_put_keycode(s, keycode >> 8);
680 ps2_put_keycode(s, 0xf0);
682 ps2_put_keycode(s, keycode & 0xff);
684 qemu_log_mask(LOG_UNIMP,
685 "ps2: ignoring key with qcode %d\n", qcode);
688 } else if (s->scancode_set == 3) {
689 keycode = qcode_to_keycode_set3[qcode];
691 /* FIXME: break code should be configured on a key by key basis */
693 ps2_put_keycode(s, 0xf0);
695 ps2_put_keycode(s, keycode);
697 qemu_log_mask(LOG_UNIMP,
698 "ps2: ignoring key with qcode %d\n", qcode);
703 uint32_t ps2_read_data(PS2State *s)
708 trace_ps2_read_data(s);
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 */
716 index = PS2_QUEUE_SIZE - 1;
717 val = q->data[index];
719 val = q->data[q->rptr];
720 if (++q->rptr == PS2_QUEUE_SIZE)
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);
731 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
733 trace_ps2_set_ledstate(s, ledstate);
734 s->ledstate = ledstate;
735 kbd_put_ledstate(ledstate);
738 static void ps2_reset_keyboard(PS2KbdState *s)
740 trace_ps2_reset_keyboard(s);
743 ps2_reset_queue(&s->common);
744 ps2_set_ledstate(s, 0);
747 void ps2_write_keyboard(void *opaque, int val)
749 PS2KbdState *s = (PS2KbdState *)opaque;
751 trace_ps2_write_keyboard(opaque, val);
752 switch(s->common.write_cmd) {
757 ps2_queue(&s->common, KBD_REPLY_ACK);
760 ps2_queue(&s->common, KBD_REPLY_RESEND);
763 ps2_queue(&s->common, KBD_REPLY_ACK);
764 /* We emulate a MF2 AT keyboard here */
765 ps2_queue(&s->common, KBD_REPLY_ID);
767 ps2_queue(&s->common, 0x41);
769 ps2_queue(&s->common, 0x83);
772 ps2_queue(&s->common, KBD_CMD_ECHO);
776 ps2_queue(&s->common, KBD_REPLY_ACK);
778 case KBD_CMD_SCANCODE:
779 case KBD_CMD_SET_LEDS:
780 case KBD_CMD_SET_RATE:
781 s->common.write_cmd = val;
782 ps2_queue(&s->common, KBD_REPLY_ACK);
784 case KBD_CMD_RESET_DISABLE:
785 ps2_reset_keyboard(s);
787 ps2_queue(&s->common, KBD_REPLY_ACK);
789 case KBD_CMD_RESET_ENABLE:
790 ps2_reset_keyboard(s);
792 ps2_queue(&s->common, KBD_REPLY_ACK);
795 ps2_reset_keyboard(s);
796 ps2_queue(&s->common, KBD_REPLY_ACK);
797 ps2_queue(&s->common, KBD_REPLY_POR);
800 ps2_queue(&s->common, KBD_REPLY_RESEND);
804 case KBD_CMD_SCANCODE:
806 ps2_queue(&s->common, KBD_REPLY_ACK);
807 ps2_put_keycode(s, s->scancode_set);
808 } else if (val >= 1 && val <= 3) {
809 s->scancode_set = val;
810 ps2_queue(&s->common, KBD_REPLY_ACK);
812 ps2_queue(&s->common, KBD_REPLY_RESEND);
814 s->common.write_cmd = -1;
816 case KBD_CMD_SET_LEDS:
817 ps2_set_ledstate(s, val);
818 ps2_queue(&s->common, KBD_REPLY_ACK);
819 s->common.write_cmd = -1;
821 case KBD_CMD_SET_RATE:
822 ps2_queue(&s->common, KBD_REPLY_ACK);
823 s->common.write_cmd = -1;
828 /* Set the scancode translation mode.
830 1 = translated scancodes (used by qemu internally). */
832 void ps2_keyboard_set_translation(void *opaque, int mode)
834 PS2KbdState *s = (PS2KbdState *)opaque;
835 trace_ps2_keyboard_set_translation(opaque, mode);
839 static void ps2_mouse_send_packet(PS2MouseState *s)
847 /* XXX: increase range to 8 bits ? */
856 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
857 ps2_queue(&s->common, b);
858 ps2_queue(&s->common, dx1 & 0xff);
859 ps2_queue(&s->common, dy1 & 0xff);
860 /* extra byte for IMPS/2 or IMEX */
861 switch(s->mouse_type) {
869 ps2_queue(&s->common, dz1 & 0xff);
876 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
877 ps2_queue(&s->common, b);
881 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
888 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
891 static const int bmap[INPUT_BUTTON__MAX] = {
892 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT,
893 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
894 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT,
895 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE,
896 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA,
898 PS2MouseState *s = (PS2MouseState *)dev;
899 InputMoveEvent *move;
902 /* check if deltas are recorded when disabled */
903 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
907 case INPUT_EVENT_KIND_REL:
908 move = evt->u.rel.data;
909 if (move->axis == INPUT_AXIS_X) {
910 s->mouse_dx += move->value;
911 } else if (move->axis == INPUT_AXIS_Y) {
912 s->mouse_dy -= move->value;
916 case INPUT_EVENT_KIND_BTN:
917 btn = evt->u.btn.data;
919 s->mouse_buttons |= bmap[btn->button];
920 if (btn->button == INPUT_BUTTON_WHEEL_UP) {
922 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
926 s->mouse_buttons &= ~bmap[btn->button];
936 static void ps2_mouse_sync(DeviceState *dev)
938 PS2MouseState *s = (PS2MouseState *)dev;
940 if (s->mouse_buttons) {
941 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
943 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
944 while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
945 /* if not remote, send event. Multiple events are sent if
947 ps2_mouse_send_packet(s);
948 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
954 void ps2_mouse_fake_event(void *opaque)
956 PS2MouseState *s = opaque;
957 trace_ps2_mouse_fake_event(opaque);
959 ps2_mouse_sync(opaque);
962 void ps2_write_mouse(void *opaque, int val)
964 PS2MouseState *s = (PS2MouseState *)opaque;
966 trace_ps2_write_mouse(opaque, val);
968 printf("kbd: write mouse 0x%02x\n", val);
970 switch(s->common.write_cmd) {
975 if (val == AUX_RESET_WRAP) {
977 ps2_queue(&s->common, AUX_ACK);
979 } else if (val != AUX_RESET) {
980 ps2_queue(&s->common, val);
985 case AUX_SET_SCALE11:
986 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
987 ps2_queue(&s->common, AUX_ACK);
989 case AUX_SET_SCALE21:
990 s->mouse_status |= MOUSE_STATUS_SCALE21;
991 ps2_queue(&s->common, AUX_ACK);
994 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
995 ps2_queue(&s->common, AUX_ACK);
999 ps2_queue(&s->common, AUX_ACK);
1001 case AUX_SET_REMOTE:
1002 s->mouse_status |= MOUSE_STATUS_REMOTE;
1003 ps2_queue(&s->common, AUX_ACK);
1006 ps2_queue(&s->common, AUX_ACK);
1007 ps2_queue(&s->common, s->mouse_type);
1010 case AUX_SET_SAMPLE:
1011 s->common.write_cmd = val;
1012 ps2_queue(&s->common, AUX_ACK);
1015 ps2_queue(&s->common, AUX_ACK);
1016 ps2_queue(&s->common, s->mouse_status);
1017 ps2_queue(&s->common, s->mouse_resolution);
1018 ps2_queue(&s->common, s->mouse_sample_rate);
1021 ps2_queue(&s->common, AUX_ACK);
1022 ps2_mouse_send_packet(s);
1024 case AUX_ENABLE_DEV:
1025 s->mouse_status |= MOUSE_STATUS_ENABLED;
1026 ps2_queue(&s->common, AUX_ACK);
1028 case AUX_DISABLE_DEV:
1029 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
1030 ps2_queue(&s->common, AUX_ACK);
1032 case AUX_SET_DEFAULT:
1033 s->mouse_sample_rate = 100;
1034 s->mouse_resolution = 2;
1035 s->mouse_status = 0;
1036 ps2_queue(&s->common, AUX_ACK);
1039 s->mouse_sample_rate = 100;
1040 s->mouse_resolution = 2;
1041 s->mouse_status = 0;
1043 ps2_queue(&s->common, AUX_ACK);
1044 ps2_queue(&s->common, 0xaa);
1045 ps2_queue(&s->common, s->mouse_type);
1051 case AUX_SET_SAMPLE:
1052 s->mouse_sample_rate = val;
1053 /* detect IMPS/2 or IMEX */
1054 switch(s->mouse_detect_state) {
1058 s->mouse_detect_state = 1;
1062 s->mouse_detect_state = 2;
1063 else if (val == 200)
1064 s->mouse_detect_state = 3;
1066 s->mouse_detect_state = 0;
1070 s->mouse_type = 3; /* IMPS/2 */
1071 s->mouse_detect_state = 0;
1075 s->mouse_type = 4; /* IMEX */
1076 s->mouse_detect_state = 0;
1079 ps2_queue(&s->common, AUX_ACK);
1080 s->common.write_cmd = -1;
1083 s->mouse_resolution = val;
1084 ps2_queue(&s->common, AUX_ACK);
1085 s->common.write_cmd = -1;
1090 static void ps2_common_reset(PS2State *s)
1094 s->update_irq(s->update_arg, 0);
1097 static void ps2_common_post_load(PS2State *s)
1099 PS2Queue *q = &s->queue;
1102 int tmp_data[PS2_QUEUE_SIZE];
1104 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
1105 size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
1107 /* move the queue elements to the start of data array */
1109 for (i = 0; i < size; i++) {
1110 /* move the queue elements to the temporary buffer */
1111 tmp_data[i] = q->data[q->rptr];
1112 if (++q->rptr == 256) {
1116 memcpy(q->data, tmp_data, size);
1118 /* reset rptr/wptr/count */
1122 s->update_irq(s->update_arg, q->count != 0);
1125 static void ps2_kbd_reset(void *opaque)
1127 PS2KbdState *s = (PS2KbdState *) opaque;
1129 trace_ps2_kbd_reset(opaque);
1130 ps2_common_reset(&s->common);
1131 s->scan_enabled = 0;
1133 s->scancode_set = 2;
1136 static void ps2_mouse_reset(void *opaque)
1138 PS2MouseState *s = (PS2MouseState *) opaque;
1140 trace_ps2_mouse_reset(opaque);
1141 ps2_common_reset(&s->common);
1142 s->mouse_status = 0;
1143 s->mouse_resolution = 0;
1144 s->mouse_sample_rate = 0;
1147 s->mouse_detect_state = 0;
1151 s->mouse_buttons = 0;
1154 static const VMStateDescription vmstate_ps2_common = {
1155 .name = "PS2 Common State",
1157 .minimum_version_id = 2,
1158 .fields = (VMStateField[]) {
1159 VMSTATE_INT32(write_cmd, PS2State),
1160 VMSTATE_INT32(queue.rptr, PS2State),
1161 VMSTATE_INT32(queue.wptr, PS2State),
1162 VMSTATE_INT32(queue.count, PS2State),
1163 VMSTATE_BUFFER(queue.data, PS2State),
1164 VMSTATE_END_OF_LIST()
1168 static bool ps2_keyboard_ledstate_needed(void *opaque)
1170 PS2KbdState *s = opaque;
1172 return s->ledstate != 0; /* 0 is default state */
1175 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1177 PS2KbdState *s = opaque;
1179 kbd_put_ledstate(s->ledstate);
1183 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1184 .name = "ps2kbd/ledstate",
1186 .minimum_version_id = 2,
1187 .post_load = ps2_kbd_ledstate_post_load,
1188 .needed = ps2_keyboard_ledstate_needed,
1189 .fields = (VMStateField[]) {
1190 VMSTATE_INT32(ledstate, PS2KbdState),
1191 VMSTATE_END_OF_LIST()
1195 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1197 PS2KbdState *s = opaque;
1198 return s->need_high_bit != 0; /* 0 is the usual state */
1201 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1202 .name = "ps2kbd/need_high_bit",
1204 .minimum_version_id = 1,
1205 .needed = ps2_keyboard_need_high_bit_needed,
1206 .fields = (VMStateField[]) {
1207 VMSTATE_BOOL(need_high_bit, PS2KbdState),
1208 VMSTATE_END_OF_LIST()
1212 static int ps2_kbd_post_load(void* opaque, int version_id)
1214 PS2KbdState *s = (PS2KbdState*)opaque;
1215 PS2State *ps2 = &s->common;
1217 if (version_id == 2)
1220 ps2_common_post_load(ps2);
1225 static void ps2_kbd_pre_save(void *opaque)
1227 PS2KbdState *s = (PS2KbdState *)opaque;
1228 PS2State *ps2 = &s->common;
1230 ps2_common_post_load(ps2);
1233 static const VMStateDescription vmstate_ps2_keyboard = {
1236 .minimum_version_id = 2,
1237 .post_load = ps2_kbd_post_load,
1238 .pre_save = ps2_kbd_pre_save,
1239 .fields = (VMStateField[]) {
1240 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1241 VMSTATE_INT32(scan_enabled, PS2KbdState),
1242 VMSTATE_INT32(translate, PS2KbdState),
1243 VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1244 VMSTATE_END_OF_LIST()
1246 .subsections = (const VMStateDescription*[]) {
1247 &vmstate_ps2_keyboard_ledstate,
1248 &vmstate_ps2_keyboard_need_high_bit,
1253 static int ps2_mouse_post_load(void *opaque, int version_id)
1255 PS2MouseState *s = (PS2MouseState *)opaque;
1256 PS2State *ps2 = &s->common;
1258 ps2_common_post_load(ps2);
1263 static void ps2_mouse_pre_save(void *opaque)
1265 PS2MouseState *s = (PS2MouseState *)opaque;
1266 PS2State *ps2 = &s->common;
1268 ps2_common_post_load(ps2);
1271 static const VMStateDescription vmstate_ps2_mouse = {
1274 .minimum_version_id = 2,
1275 .post_load = ps2_mouse_post_load,
1276 .pre_save = ps2_mouse_pre_save,
1277 .fields = (VMStateField[]) {
1278 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1279 VMSTATE_UINT8(mouse_status, PS2MouseState),
1280 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1281 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1282 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1283 VMSTATE_UINT8(mouse_type, PS2MouseState),
1284 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1285 VMSTATE_INT32(mouse_dx, PS2MouseState),
1286 VMSTATE_INT32(mouse_dy, PS2MouseState),
1287 VMSTATE_INT32(mouse_dz, PS2MouseState),
1288 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1289 VMSTATE_END_OF_LIST()
1293 static QemuInputHandler ps2_keyboard_handler = {
1294 .name = "QEMU PS/2 Keyboard",
1295 .mask = INPUT_EVENT_MASK_KEY,
1296 .event = ps2_keyboard_event,
1299 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1301 PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1303 trace_ps2_kbd_init(s);
1304 s->common.update_irq = update_irq;
1305 s->common.update_arg = update_arg;
1306 s->scancode_set = 2;
1307 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1308 qemu_input_handler_register((DeviceState *)s,
1309 &ps2_keyboard_handler);
1310 qemu_register_reset(ps2_kbd_reset, s);
1314 static QemuInputHandler ps2_mouse_handler = {
1315 .name = "QEMU PS/2 Mouse",
1316 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1317 .event = ps2_mouse_event,
1318 .sync = ps2_mouse_sync,
1321 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1323 PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1325 trace_ps2_mouse_init(s);
1326 s->common.update_irq = update_irq;
1327 s->common.update_arg = update_arg;
1328 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1329 qemu_input_handler_register((DeviceState *)s,
1330 &ps2_mouse_handler);
1331 qemu_register_reset(ps2_mouse_reset, s);