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"
26 #include "hw/input/ps2.h"
27 #include "ui/console.h"
29 #include "sysemu/sysemu.h"
33 /* debug PC keyboard */
36 /* debug PC keyboard : only mouse */
39 /* Keyboard Commands */
40 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
41 #define KBD_CMD_ECHO 0xEE
42 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
43 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
44 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
45 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
46 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
47 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
48 #define KBD_CMD_RESET 0xFF /* Reset */
50 /* Keyboard Replies */
51 #define KBD_REPLY_POR 0xAA /* Power on reset */
52 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
53 #define KBD_REPLY_ACK 0xFA /* Command ACK */
54 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
57 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
58 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
59 #define AUX_SET_RES 0xE8 /* Set resolution */
60 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
61 #define AUX_SET_STREAM 0xEA /* Set stream mode */
62 #define AUX_POLL 0xEB /* Poll */
63 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
64 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
65 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
66 #define AUX_GET_TYPE 0xF2 /* Get type */
67 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
68 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
69 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
70 #define AUX_SET_DEFAULT 0xF6
71 #define AUX_RESET 0xFF /* Reset aux device */
72 #define AUX_ACK 0xFA /* Command byte ACK. */
74 #define MOUSE_STATUS_REMOTE 0x40
75 #define MOUSE_STATUS_ENABLED 0x20
76 #define MOUSE_STATUS_SCALE21 0x10
78 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
81 /* Keep the data array 256 bytes long, which compatibility
82 with older qemu versions. */
84 int rptr
, wptr
, count
;
90 void (*update_irq
)(void *, int);
98 int scancode_set
; /* 1=XT, 2=AT, 3=PS/2 */
105 uint8_t mouse_status
;
106 uint8_t mouse_resolution
;
107 uint8_t mouse_sample_rate
;
109 uint8_t mouse_type
; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
110 uint8_t mouse_detect_state
;
111 int mouse_dx
; /* current values, needed for 'poll' mode */
114 uint8_t mouse_buttons
;
117 /* Table to convert from QEMU codes to scancodes. */
118 static const uint16_t qcode_to_keycode_set1
[Q_KEY_CODE__MAX
] = {
119 [0 ... Q_KEY_CODE__MAX
- 1] = 0,
121 [Q_KEY_CODE_A
] = 0x1e,
122 [Q_KEY_CODE_B
] = 0x30,
123 [Q_KEY_CODE_C
] = 0x2e,
124 [Q_KEY_CODE_D
] = 0x20,
125 [Q_KEY_CODE_E
] = 0x12,
126 [Q_KEY_CODE_F
] = 0x21,
127 [Q_KEY_CODE_G
] = 0x22,
128 [Q_KEY_CODE_H
] = 0x23,
129 [Q_KEY_CODE_I
] = 0x17,
130 [Q_KEY_CODE_J
] = 0x24,
131 [Q_KEY_CODE_K
] = 0x25,
132 [Q_KEY_CODE_L
] = 0x26,
133 [Q_KEY_CODE_M
] = 0x32,
134 [Q_KEY_CODE_N
] = 0x31,
135 [Q_KEY_CODE_O
] = 0x18,
136 [Q_KEY_CODE_P
] = 0x19,
137 [Q_KEY_CODE_Q
] = 0x10,
138 [Q_KEY_CODE_R
] = 0x13,
139 [Q_KEY_CODE_S
] = 0x1f,
140 [Q_KEY_CODE_T
] = 0x14,
141 [Q_KEY_CODE_U
] = 0x16,
142 [Q_KEY_CODE_V
] = 0x2f,
143 [Q_KEY_CODE_W
] = 0x11,
144 [Q_KEY_CODE_X
] = 0x2d,
145 [Q_KEY_CODE_Y
] = 0x15,
146 [Q_KEY_CODE_Z
] = 0x2c,
147 [Q_KEY_CODE_0
] = 0x0b,
148 [Q_KEY_CODE_1
] = 0x02,
149 [Q_KEY_CODE_2
] = 0x03,
150 [Q_KEY_CODE_3
] = 0x04,
151 [Q_KEY_CODE_4
] = 0x05,
152 [Q_KEY_CODE_5
] = 0x06,
153 [Q_KEY_CODE_6
] = 0x07,
154 [Q_KEY_CODE_7
] = 0x08,
155 [Q_KEY_CODE_8
] = 0x09,
156 [Q_KEY_CODE_9
] = 0x0a,
157 [Q_KEY_CODE_GRAVE_ACCENT
] = 0x29,
158 [Q_KEY_CODE_MINUS
] = 0x0c,
159 [Q_KEY_CODE_EQUAL
] = 0x0d,
160 [Q_KEY_CODE_BACKSLASH
] = 0x2b,
161 [Q_KEY_CODE_BACKSPACE
] = 0x0e,
162 [Q_KEY_CODE_SPC
] = 0x39,
163 [Q_KEY_CODE_TAB
] = 0x0f,
164 [Q_KEY_CODE_CAPS_LOCK
] = 0x3a,
165 [Q_KEY_CODE_SHIFT
] = 0x2a,
166 [Q_KEY_CODE_CTRL
] = 0x1d,
167 [Q_KEY_CODE_META_L
] = 0xe05b,
168 [Q_KEY_CODE_ALT
] = 0x38,
169 [Q_KEY_CODE_SHIFT_R
] = 0x36,
170 [Q_KEY_CODE_CTRL_R
] = 0xe01d,
171 [Q_KEY_CODE_META_R
] = 0xe05c,
172 [Q_KEY_CODE_ALT_R
] = 0xe038,
173 [Q_KEY_CODE_MENU
] = 0xe05d,
174 [Q_KEY_CODE_RET
] = 0x1c,
175 [Q_KEY_CODE_ESC
] = 0x01,
176 [Q_KEY_CODE_F1
] = 0x3b,
177 [Q_KEY_CODE_F2
] = 0x3c,
178 [Q_KEY_CODE_F3
] = 0x3d,
179 [Q_KEY_CODE_F4
] = 0x3e,
180 [Q_KEY_CODE_F5
] = 0x3f,
181 [Q_KEY_CODE_F6
] = 0x40,
182 [Q_KEY_CODE_F7
] = 0x41,
183 [Q_KEY_CODE_F8
] = 0x42,
184 [Q_KEY_CODE_F9
] = 0x43,
185 [Q_KEY_CODE_F10
] = 0x44,
186 [Q_KEY_CODE_F11
] = 0x57,
187 [Q_KEY_CODE_F12
] = 0x58,
188 /* special handling for Q_KEY_CODE_PRINT */
189 [Q_KEY_CODE_SCROLL_LOCK
] = 0x46,
190 /* special handling for Q_KEY_CODE_PAUSE */
191 [Q_KEY_CODE_BRACKET_LEFT
] = 0x1a,
192 [Q_KEY_CODE_INSERT
] = 0xe052,
193 [Q_KEY_CODE_HOME
] = 0xe047,
194 [Q_KEY_CODE_PGUP
] = 0xe049,
195 [Q_KEY_CODE_DELETE
] = 0xe053,
196 [Q_KEY_CODE_END
] = 0xe04f,
197 [Q_KEY_CODE_PGDN
] = 0xe051,
198 [Q_KEY_CODE_UP
] = 0xe048,
199 [Q_KEY_CODE_LEFT
] = 0xe04b,
200 [Q_KEY_CODE_DOWN
] = 0xe050,
201 [Q_KEY_CODE_RIGHT
] = 0xe04d,
202 [Q_KEY_CODE_NUM_LOCK
] = 0x45,
203 [Q_KEY_CODE_KP_DIVIDE
] = 0xe035,
204 [Q_KEY_CODE_KP_MULTIPLY
] = 0x37,
205 [Q_KEY_CODE_KP_SUBTRACT
] = 0x4a,
206 [Q_KEY_CODE_KP_ADD
] = 0x4e,
207 [Q_KEY_CODE_KP_ENTER
] = 0xe01c,
208 [Q_KEY_CODE_KP_DECIMAL
] = 0x53,
209 [Q_KEY_CODE_KP_0
] = 0x52,
210 [Q_KEY_CODE_KP_1
] = 0x4f,
211 [Q_KEY_CODE_KP_2
] = 0x50,
212 [Q_KEY_CODE_KP_3
] = 0x51,
213 [Q_KEY_CODE_KP_4
] = 0x4b,
214 [Q_KEY_CODE_KP_5
] = 0x4c,
215 [Q_KEY_CODE_KP_6
] = 0x4d,
216 [Q_KEY_CODE_KP_7
] = 0x47,
217 [Q_KEY_CODE_KP_8
] = 0x48,
218 [Q_KEY_CODE_KP_9
] = 0x49,
219 [Q_KEY_CODE_BRACKET_RIGHT
] = 0x1b,
220 [Q_KEY_CODE_SEMICOLON
] = 0x27,
221 [Q_KEY_CODE_APOSTROPHE
] = 0x28,
222 [Q_KEY_CODE_COMMA
] = 0x33,
223 [Q_KEY_CODE_DOT
] = 0x34,
224 [Q_KEY_CODE_SLASH
] = 0x35,
227 [Q_KEY_CODE_POWER
] = 0x0e5e,
228 [Q_KEY_CODE_SLEEP
] = 0x0e5f,
229 [Q_KEY_CODE_WAKE
] = 0x0e63,
231 [Q_KEY_CODE_AUDIONEXT
] = 0xe019,
232 [Q_KEY_CODE_AUDIOPREV
] = 0xe010,
233 [Q_KEY_CODE_AUDIOSTOP
] = 0xe024,
234 [Q_KEY_CODE_AUDIOPLAY
] = 0xe022,
235 [Q_KEY_CODE_AUDIOMUTE
] = 0xe020,
236 [Q_KEY_CODE_VOLUMEUP
] = 0xe030,
237 [Q_KEY_CODE_VOLUMEDOWN
] = 0xe02e,
238 [Q_KEY_CODE_MEDIASELECT
] = 0xe06d,
239 [Q_KEY_CODE_MAIL
] = 0xe06c,
240 [Q_KEY_CODE_CALCULATOR
] = 0xe021,
241 [Q_KEY_CODE_COMPUTER
] = 0xe06b,
242 [Q_KEY_CODE_AC_SEARCH
] = 0xe065,
243 [Q_KEY_CODE_AC_HOME
] = 0xe032,
244 [Q_KEY_CODE_AC_BACK
] = 0xe06a,
245 [Q_KEY_CODE_AC_FORWARD
] = 0xe069,
246 [Q_KEY_CODE_AC_STOP
] = 0xe068,
247 [Q_KEY_CODE_AC_REFRESH
] = 0xe067,
248 [Q_KEY_CODE_AC_BOOKMARKS
] = 0xe066,
251 [Q_KEY_CODE_ASTERISK
] = 0x37,
252 [Q_KEY_CODE_LESS
] = 0x56,
253 [Q_KEY_CODE_RO
] = 0x73,
254 [Q_KEY_CODE_KP_COMMA
] = 0x7e,
257 static const uint16_t qcode_to_keycode_set2
[Q_KEY_CODE__MAX
] = {
258 [0 ... Q_KEY_CODE__MAX
- 1] = 0,
260 [Q_KEY_CODE_A
] = 0x1c,
261 [Q_KEY_CODE_B
] = 0x32,
262 [Q_KEY_CODE_C
] = 0x21,
263 [Q_KEY_CODE_D
] = 0x23,
264 [Q_KEY_CODE_E
] = 0x24,
265 [Q_KEY_CODE_F
] = 0x2b,
266 [Q_KEY_CODE_G
] = 0x34,
267 [Q_KEY_CODE_H
] = 0x33,
268 [Q_KEY_CODE_I
] = 0x43,
269 [Q_KEY_CODE_J
] = 0x3b,
270 [Q_KEY_CODE_K
] = 0x42,
271 [Q_KEY_CODE_L
] = 0x4b,
272 [Q_KEY_CODE_M
] = 0x3a,
273 [Q_KEY_CODE_N
] = 0x31,
274 [Q_KEY_CODE_O
] = 0x44,
275 [Q_KEY_CODE_P
] = 0x4d,
276 [Q_KEY_CODE_Q
] = 0x15,
277 [Q_KEY_CODE_R
] = 0x2d,
278 [Q_KEY_CODE_S
] = 0x1b,
279 [Q_KEY_CODE_T
] = 0x2c,
280 [Q_KEY_CODE_U
] = 0x3c,
281 [Q_KEY_CODE_V
] = 0x2a,
282 [Q_KEY_CODE_W
] = 0x1d,
283 [Q_KEY_CODE_X
] = 0x22,
284 [Q_KEY_CODE_Y
] = 0x35,
285 [Q_KEY_CODE_Z
] = 0x1a,
286 [Q_KEY_CODE_0
] = 0x45,
287 [Q_KEY_CODE_1
] = 0x16,
288 [Q_KEY_CODE_2
] = 0x1e,
289 [Q_KEY_CODE_3
] = 0x26,
290 [Q_KEY_CODE_4
] = 0x25,
291 [Q_KEY_CODE_5
] = 0x2e,
292 [Q_KEY_CODE_6
] = 0x36,
293 [Q_KEY_CODE_7
] = 0x3d,
294 [Q_KEY_CODE_8
] = 0x3e,
295 [Q_KEY_CODE_9
] = 0x46,
296 [Q_KEY_CODE_GRAVE_ACCENT
] = 0x0e,
297 [Q_KEY_CODE_MINUS
] = 0x4e,
298 [Q_KEY_CODE_EQUAL
] = 0x55,
299 [Q_KEY_CODE_BACKSLASH
] = 0x5d,
300 [Q_KEY_CODE_BACKSPACE
] = 0x66,
301 [Q_KEY_CODE_SPC
] = 0x29,
302 [Q_KEY_CODE_TAB
] = 0x0d,
303 [Q_KEY_CODE_CAPS_LOCK
] = 0x58,
304 [Q_KEY_CODE_SHIFT
] = 0x12,
305 [Q_KEY_CODE_CTRL
] = 0x14,
306 [Q_KEY_CODE_META_L
] = 0xe01f,
307 [Q_KEY_CODE_ALT
] = 0x11,
308 [Q_KEY_CODE_SHIFT_R
] = 0x59,
309 [Q_KEY_CODE_CTRL_R
] = 0xe014,
310 [Q_KEY_CODE_META_R
] = 0xe027,
311 [Q_KEY_CODE_ALT_R
] = 0xe011,
312 [Q_KEY_CODE_MENU
] = 0xe02f,
313 [Q_KEY_CODE_RET
] = 0x5a,
314 [Q_KEY_CODE_ESC
] = 0x76,
315 [Q_KEY_CODE_F1
] = 0x05,
316 [Q_KEY_CODE_F2
] = 0x06,
317 [Q_KEY_CODE_F3
] = 0x04,
318 [Q_KEY_CODE_F4
] = 0x0c,
319 [Q_KEY_CODE_F5
] = 0x03,
320 [Q_KEY_CODE_F6
] = 0x0b,
321 [Q_KEY_CODE_F7
] = 0x83,
322 [Q_KEY_CODE_F8
] = 0x0a,
323 [Q_KEY_CODE_F9
] = 0x01,
324 [Q_KEY_CODE_F10
] = 0x09,
325 [Q_KEY_CODE_F11
] = 0x78,
326 [Q_KEY_CODE_F12
] = 0x07,
327 /* special handling for Q_KEY_CODE_PRINT */
328 [Q_KEY_CODE_SCROLL_LOCK
] = 0x7e,
329 /* special handling for Q_KEY_CODE_PAUSE */
330 [Q_KEY_CODE_BRACKET_LEFT
] = 0x54,
331 [Q_KEY_CODE_INSERT
] = 0xe070,
332 [Q_KEY_CODE_HOME
] = 0xe06c,
333 [Q_KEY_CODE_PGUP
] = 0xe07d,
334 [Q_KEY_CODE_DELETE
] = 0xe071,
335 [Q_KEY_CODE_END
] = 0xe069,
336 [Q_KEY_CODE_PGDN
] = 0xe07a,
337 [Q_KEY_CODE_UP
] = 0xe075,
338 [Q_KEY_CODE_LEFT
] = 0xe06b,
339 [Q_KEY_CODE_DOWN
] = 0xe072,
340 [Q_KEY_CODE_RIGHT
] = 0xe074,
341 [Q_KEY_CODE_NUM_LOCK
] = 0x77,
342 [Q_KEY_CODE_KP_DIVIDE
] = 0xe04a,
343 [Q_KEY_CODE_KP_MULTIPLY
] = 0x7c,
344 [Q_KEY_CODE_KP_SUBTRACT
] = 0x7b,
345 [Q_KEY_CODE_KP_ADD
] = 0x79,
346 [Q_KEY_CODE_KP_ENTER
] = 0xe05a,
347 [Q_KEY_CODE_KP_DECIMAL
] = 0x71,
348 [Q_KEY_CODE_KP_0
] = 0x70,
349 [Q_KEY_CODE_KP_1
] = 0x69,
350 [Q_KEY_CODE_KP_2
] = 0x72,
351 [Q_KEY_CODE_KP_3
] = 0x7a,
352 [Q_KEY_CODE_KP_4
] = 0x6b,
353 [Q_KEY_CODE_KP_5
] = 0x73,
354 [Q_KEY_CODE_KP_6
] = 0x74,
355 [Q_KEY_CODE_KP_7
] = 0x6c,
356 [Q_KEY_CODE_KP_8
] = 0x75,
357 [Q_KEY_CODE_KP_9
] = 0x7d,
358 [Q_KEY_CODE_BRACKET_RIGHT
] = 0x5b,
359 [Q_KEY_CODE_SEMICOLON
] = 0x4c,
360 [Q_KEY_CODE_APOSTROPHE
] = 0x52,
361 [Q_KEY_CODE_COMMA
] = 0x41,
362 [Q_KEY_CODE_DOT
] = 0x49,
363 [Q_KEY_CODE_SLASH
] = 0x4a,
366 [Q_KEY_CODE_POWER
] = 0x0e37,
367 [Q_KEY_CODE_SLEEP
] = 0x0e3f,
368 [Q_KEY_CODE_WAKE
] = 0x0e5e,
370 [Q_KEY_CODE_AUDIONEXT
] = 0xe04d,
371 [Q_KEY_CODE_AUDIOPREV
] = 0xe015,
372 [Q_KEY_CODE_AUDIOSTOP
] = 0xe03b,
373 [Q_KEY_CODE_AUDIOPLAY
] = 0xe034,
374 [Q_KEY_CODE_AUDIOMUTE
] = 0xe023,
375 [Q_KEY_CODE_VOLUMEUP
] = 0xe032,
376 [Q_KEY_CODE_VOLUMEDOWN
] = 0xe021,
377 [Q_KEY_CODE_MEDIASELECT
] = 0xe050,
378 [Q_KEY_CODE_MAIL
] = 0xe048,
379 [Q_KEY_CODE_CALCULATOR
] = 0xe02b,
380 [Q_KEY_CODE_COMPUTER
] = 0xe040,
381 [Q_KEY_CODE_AC_SEARCH
] = 0xe010,
382 [Q_KEY_CODE_AC_HOME
] = 0xe03a,
383 [Q_KEY_CODE_AC_BACK
] = 0xe038,
384 [Q_KEY_CODE_AC_FORWARD
] = 0xe030,
385 [Q_KEY_CODE_AC_STOP
] = 0xe028,
386 [Q_KEY_CODE_AC_REFRESH
] = 0xe020,
387 [Q_KEY_CODE_AC_BOOKMARKS
] = 0xe018,
390 [Q_KEY_CODE_ALTGR
] = 0x08,
391 [Q_KEY_CODE_ALTGR_R
] = 0xe008,
392 [Q_KEY_CODE_ASTERISK
] = 0x7c,
393 [Q_KEY_CODE_LESS
] = 0x61,
394 [Q_KEY_CODE_SYSRQ
] = 0x7f,
395 [Q_KEY_CODE_RO
] = 0x51,
396 [Q_KEY_CODE_KP_COMMA
] = 0x6d,
399 static const uint16_t qcode_to_keycode_set3
[Q_KEY_CODE__MAX
] = {
400 [0 ... Q_KEY_CODE__MAX
- 1] = 0,
402 [Q_KEY_CODE_A
] = 0x1c,
403 [Q_KEY_CODE_B
] = 0x32,
404 [Q_KEY_CODE_C
] = 0x21,
405 [Q_KEY_CODE_D
] = 0x23,
406 [Q_KEY_CODE_E
] = 0x24,
407 [Q_KEY_CODE_F
] = 0x2b,
408 [Q_KEY_CODE_G
] = 0x34,
409 [Q_KEY_CODE_H
] = 0x33,
410 [Q_KEY_CODE_I
] = 0x43,
411 [Q_KEY_CODE_J
] = 0x3b,
412 [Q_KEY_CODE_K
] = 0x42,
413 [Q_KEY_CODE_L
] = 0x4b,
414 [Q_KEY_CODE_M
] = 0x3a,
415 [Q_KEY_CODE_N
] = 0x31,
416 [Q_KEY_CODE_O
] = 0x44,
417 [Q_KEY_CODE_P
] = 0x4d,
418 [Q_KEY_CODE_Q
] = 0x15,
419 [Q_KEY_CODE_R
] = 0x2d,
420 [Q_KEY_CODE_S
] = 0x1b,
421 [Q_KEY_CODE_T
] = 0x2c,
422 [Q_KEY_CODE_U
] = 0x3c,
423 [Q_KEY_CODE_V
] = 0x2a,
424 [Q_KEY_CODE_W
] = 0x1d,
425 [Q_KEY_CODE_X
] = 0x22,
426 [Q_KEY_CODE_Y
] = 0x35,
427 [Q_KEY_CODE_Z
] = 0x1a,
428 [Q_KEY_CODE_0
] = 0x45,
429 [Q_KEY_CODE_1
] = 0x16,
430 [Q_KEY_CODE_2
] = 0x1e,
431 [Q_KEY_CODE_3
] = 0x26,
432 [Q_KEY_CODE_4
] = 0x25,
433 [Q_KEY_CODE_5
] = 0x2e,
434 [Q_KEY_CODE_6
] = 0x36,
435 [Q_KEY_CODE_7
] = 0x3d,
436 [Q_KEY_CODE_8
] = 0x3e,
437 [Q_KEY_CODE_9
] = 0x46,
438 [Q_KEY_CODE_GRAVE_ACCENT
] = 0x0e,
439 [Q_KEY_CODE_MINUS
] = 0x4e,
440 [Q_KEY_CODE_EQUAL
] = 0x55,
441 [Q_KEY_CODE_BACKSLASH
] = 0x5c,
442 [Q_KEY_CODE_BACKSPACE
] = 0x66,
443 [Q_KEY_CODE_SPC
] = 0x29,
444 [Q_KEY_CODE_TAB
] = 0x0d,
445 [Q_KEY_CODE_CAPS_LOCK
] = 0x14,
446 [Q_KEY_CODE_SHIFT
] = 0x12,
447 [Q_KEY_CODE_CTRL
] = 0x11,
448 [Q_KEY_CODE_META_L
] = 0x8b,
449 [Q_KEY_CODE_ALT
] = 0x19,
450 [Q_KEY_CODE_SHIFT_R
] = 0x59,
451 [Q_KEY_CODE_CTRL_R
] = 0x58,
452 [Q_KEY_CODE_META_R
] = 0x8c,
453 [Q_KEY_CODE_ALT_R
] = 0x39,
454 [Q_KEY_CODE_MENU
] = 0x8d,
455 [Q_KEY_CODE_RET
] = 0x5a,
456 [Q_KEY_CODE_ESC
] = 0x08,
457 [Q_KEY_CODE_F1
] = 0x07,
458 [Q_KEY_CODE_F2
] = 0x0f,
459 [Q_KEY_CODE_F3
] = 0x17,
460 [Q_KEY_CODE_F4
] = 0x1f,
461 [Q_KEY_CODE_F5
] = 0x27,
462 [Q_KEY_CODE_F6
] = 0x2f,
463 [Q_KEY_CODE_F7
] = 0x37,
464 [Q_KEY_CODE_F8
] = 0x3f,
465 [Q_KEY_CODE_F9
] = 0x47,
466 [Q_KEY_CODE_F10
] = 0x4f,
467 [Q_KEY_CODE_F11
] = 0x56,
468 [Q_KEY_CODE_F12
] = 0x5e,
469 [Q_KEY_CODE_PRINT
] = 0x57,
470 [Q_KEY_CODE_SCROLL_LOCK
] = 0x5f,
471 [Q_KEY_CODE_PAUSE
] = 0x62,
472 [Q_KEY_CODE_BRACKET_LEFT
] = 0x54,
473 [Q_KEY_CODE_INSERT
] = 0x67,
474 [Q_KEY_CODE_HOME
] = 0x6e,
475 [Q_KEY_CODE_PGUP
] = 0x6f,
476 [Q_KEY_CODE_DELETE
] = 0x64,
477 [Q_KEY_CODE_END
] = 0x65,
478 [Q_KEY_CODE_PGDN
] = 0x6d,
479 [Q_KEY_CODE_UP
] = 0x63,
480 [Q_KEY_CODE_LEFT
] = 0x61,
481 [Q_KEY_CODE_DOWN
] = 0x60,
482 [Q_KEY_CODE_RIGHT
] = 0x6a,
483 [Q_KEY_CODE_NUM_LOCK
] = 0x76,
484 [Q_KEY_CODE_KP_DIVIDE
] = 0x4a,
485 [Q_KEY_CODE_KP_MULTIPLY
] = 0x7e,
486 [Q_KEY_CODE_KP_SUBTRACT
] = 0x4e,
487 [Q_KEY_CODE_KP_ADD
] = 0x7c,
488 [Q_KEY_CODE_KP_ENTER
] = 0x79,
489 [Q_KEY_CODE_KP_DECIMAL
] = 0x71,
490 [Q_KEY_CODE_KP_0
] = 0x70,
491 [Q_KEY_CODE_KP_1
] = 0x69,
492 [Q_KEY_CODE_KP_2
] = 0x72,
493 [Q_KEY_CODE_KP_3
] = 0x7a,
494 [Q_KEY_CODE_KP_4
] = 0x6b,
495 [Q_KEY_CODE_KP_5
] = 0x73,
496 [Q_KEY_CODE_KP_6
] = 0x74,
497 [Q_KEY_CODE_KP_7
] = 0x6c,
498 [Q_KEY_CODE_KP_8
] = 0x75,
499 [Q_KEY_CODE_KP_9
] = 0x7d,
500 [Q_KEY_CODE_BRACKET_RIGHT
] = 0x5b,
501 [Q_KEY_CODE_SEMICOLON
] = 0x4c,
502 [Q_KEY_CODE_APOSTROPHE
] = 0x52,
503 [Q_KEY_CODE_COMMA
] = 0x41,
504 [Q_KEY_CODE_DOT
] = 0x49,
505 [Q_KEY_CODE_SLASH
] = 0x4a,
508 static uint8_t translate_table
[256] = {
509 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
510 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
511 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
512 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
513 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
514 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
515 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
516 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
517 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
518 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
519 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
520 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
521 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
522 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
523 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
524 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
525 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
526 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
527 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
528 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
529 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
530 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
531 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
532 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
533 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
534 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
535 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
536 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
537 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
538 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
539 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
540 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
543 void ps2_queue(void *opaque
, int b
)
545 PS2State
*s
= (PS2State
*)opaque
;
546 PS2Queue
*q
= &s
->queue
;
548 if (q
->count
>= PS2_QUEUE_SIZE
- 1)
550 q
->data
[q
->wptr
] = b
;
551 if (++q
->wptr
== PS2_QUEUE_SIZE
)
554 s
->update_irq(s
->update_arg
, 1);
557 /* keycode is the untranslated scancode in the current scancode set. */
558 static void ps2_put_keycode(void *opaque
, int keycode
)
560 PS2KbdState
*s
= opaque
;
562 trace_ps2_put_keycode(opaque
, keycode
);
563 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
566 if (keycode
== 0xf0) {
567 s
->need_high_bit
= true;
568 } else if (s
->need_high_bit
) {
569 ps2_queue(&s
->common
, translate_table
[keycode
] | 0x80);
570 s
->need_high_bit
= false;
572 ps2_queue(&s
->common
, translate_table
[keycode
]);
575 ps2_queue(&s
->common
, keycode
);
579 static void ps2_keyboard_event(DeviceState
*dev
, QemuConsole
*src
,
582 PS2KbdState
*s
= (PS2KbdState
*)dev
;
583 InputKeyEvent
*key
= evt
->u
.key
.data
;
587 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
588 assert(evt
->type
== INPUT_EVENT_KIND_KEY
);
589 qcode
= qemu_input_key_value_to_qcode(key
->key
);
591 if (s
->scancode_set
== 1) {
592 if (qcode
== Q_KEY_CODE_PAUSE
) {
594 ps2_put_keycode(s
, 0xe1);
595 ps2_put_keycode(s
, 0x1d);
596 ps2_put_keycode(s
, 0x45);
597 ps2_put_keycode(s
, 0x91);
598 ps2_put_keycode(s
, 0x9d);
599 ps2_put_keycode(s
, 0xc5);
601 } else if (qcode
== Q_KEY_CODE_PRINT
) {
603 ps2_put_keycode(s
, 0xe0);
604 ps2_put_keycode(s
, 0x2a);
605 ps2_put_keycode(s
, 0xe0);
606 ps2_put_keycode(s
, 0x37);
608 ps2_put_keycode(s
, 0xe0);
609 ps2_put_keycode(s
, 0xb7);
610 ps2_put_keycode(s
, 0xe0);
611 ps2_put_keycode(s
, 0xaa);
614 keycode
= qcode_to_keycode_set1
[qcode
];
616 if (keycode
& 0xff00) {
617 ps2_put_keycode(s
, keycode
>> 8);
622 ps2_put_keycode(s
, keycode
& 0xff);
624 ps2_queue(&s
->common
, key
->down
? 0x00 : 0x80);
627 } else if (s
->scancode_set
== 2) {
628 if (qcode
== Q_KEY_CODE_PAUSE
) {
630 ps2_put_keycode(s
, 0xe1);
631 ps2_put_keycode(s
, 0x14);
632 ps2_put_keycode(s
, 0x77);
633 ps2_put_keycode(s
, 0xe1);
634 ps2_put_keycode(s
, 0xf0);
635 ps2_put_keycode(s
, 0x14);
636 ps2_put_keycode(s
, 0xf0);
637 ps2_put_keycode(s
, 0x77);
639 } else if (qcode
== Q_KEY_CODE_PRINT
) {
641 ps2_put_keycode(s
, 0xe0);
642 ps2_put_keycode(s
, 0x12);
643 ps2_put_keycode(s
, 0xe0);
644 ps2_put_keycode(s
, 0x7c);
646 ps2_put_keycode(s
, 0xe0);
647 ps2_put_keycode(s
, 0xf0);
648 ps2_put_keycode(s
, 0x7c);
649 ps2_put_keycode(s
, 0xe0);
650 ps2_put_keycode(s
, 0xf0);
651 ps2_put_keycode(s
, 0x12);
654 keycode
= qcode_to_keycode_set2
[qcode
];
656 if (keycode
& 0xff00) {
657 ps2_put_keycode(s
, keycode
>> 8);
660 ps2_put_keycode(s
, 0xf0);
662 ps2_put_keycode(s
, keycode
& 0xff);
663 } else if (key
->down
) {
664 ps2_queue(&s
->common
, 0x00);
665 } else if (s
->translate
) {
666 ps2_queue(&s
->common
, 0x80);
668 ps2_queue(&s
->common
, 0xf0);
669 ps2_queue(&s
->common
, 0x00);
672 } else if (s
->scancode_set
== 3) {
673 keycode
= qcode_to_keycode_set3
[qcode
];
675 /* FIXME: break code should be configured on a key by key basis */
677 ps2_put_keycode(s
, 0xf0);
679 ps2_put_keycode(s
, keycode
);
680 } else if (key
->down
) {
681 ps2_queue(&s
->common
, 0x00);
682 } else if (s
->translate
) {
683 ps2_queue(&s
->common
, 0x80);
685 ps2_queue(&s
->common
, 0xf0);
686 ps2_queue(&s
->common
, 0x00);
691 uint32_t ps2_read_data(void *opaque
)
693 PS2State
*s
= (PS2State
*)opaque
;
697 trace_ps2_read_data(opaque
);
700 /* NOTE: if no data left, we return the last keyboard one
701 (needed for EMM386) */
702 /* XXX: need a timer to do things correctly */
705 index
= PS2_QUEUE_SIZE
- 1;
706 val
= q
->data
[index
];
708 val
= q
->data
[q
->rptr
];
709 if (++q
->rptr
== PS2_QUEUE_SIZE
)
712 /* reading deasserts IRQ */
713 s
->update_irq(s
->update_arg
, 0);
714 /* reassert IRQs if data left */
715 s
->update_irq(s
->update_arg
, q
->count
!= 0);
720 static void ps2_set_ledstate(PS2KbdState
*s
, int ledstate
)
722 trace_ps2_set_ledstate(s
, ledstate
);
723 s
->ledstate
= ledstate
;
724 kbd_put_ledstate(ledstate
);
727 static void ps2_reset_keyboard(PS2KbdState
*s
)
729 trace_ps2_reset_keyboard(s
);
732 ps2_set_ledstate(s
, 0);
735 void ps2_write_keyboard(void *opaque
, int val
)
737 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
739 trace_ps2_write_keyboard(opaque
, val
);
740 switch(s
->common
.write_cmd
) {
745 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
748 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
751 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
752 /* We emulate a MF2 AT keyboard here */
753 ps2_queue(&s
->common
, KBD_REPLY_ID
);
755 ps2_queue(&s
->common
, 0x41);
757 ps2_queue(&s
->common
, 0x83);
760 ps2_queue(&s
->common
, KBD_CMD_ECHO
);
764 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
766 case KBD_CMD_SCANCODE
:
767 case KBD_CMD_SET_LEDS
:
768 case KBD_CMD_SET_RATE
:
769 s
->common
.write_cmd
= val
;
770 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
772 case KBD_CMD_RESET_DISABLE
:
773 ps2_reset_keyboard(s
);
775 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
777 case KBD_CMD_RESET_ENABLE
:
778 ps2_reset_keyboard(s
);
780 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
783 ps2_reset_keyboard(s
);
784 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
785 ps2_queue(&s
->common
, KBD_REPLY_POR
);
788 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
792 case KBD_CMD_SCANCODE
:
794 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
795 ps2_put_keycode(s
, s
->scancode_set
);
796 } else if (val
>= 1 && val
<= 3) {
797 s
->scancode_set
= val
;
798 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
800 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
802 s
->common
.write_cmd
= -1;
804 case KBD_CMD_SET_LEDS
:
805 ps2_set_ledstate(s
, val
);
806 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
807 s
->common
.write_cmd
= -1;
809 case KBD_CMD_SET_RATE
:
810 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
811 s
->common
.write_cmd
= -1;
816 /* Set the scancode translation mode.
818 1 = translated scancodes (used by qemu internally). */
820 void ps2_keyboard_set_translation(void *opaque
, int mode
)
822 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
823 trace_ps2_keyboard_set_translation(opaque
, mode
);
827 static void ps2_mouse_send_packet(PS2MouseState
*s
)
835 /* XXX: increase range to 8 bits ? */
844 b
= 0x08 | ((dx1
< 0) << 4) | ((dy1
< 0) << 5) | (s
->mouse_buttons
& 0x07);
845 ps2_queue(&s
->common
, b
);
846 ps2_queue(&s
->common
, dx1
& 0xff);
847 ps2_queue(&s
->common
, dy1
& 0xff);
848 /* extra byte for IMPS/2 or IMEX */
849 switch(s
->mouse_type
) {
857 ps2_queue(&s
->common
, dz1
& 0xff);
864 b
= (dz1
& 0x0f) | ((s
->mouse_buttons
& 0x18) << 1);
865 ps2_queue(&s
->common
, b
);
869 trace_ps2_mouse_send_packet(s
, dx1
, dy1
, dz1
, b
);
876 static void ps2_mouse_event(DeviceState
*dev
, QemuConsole
*src
,
879 static const int bmap
[INPUT_BUTTON__MAX
] = {
880 [INPUT_BUTTON_LEFT
] = MOUSE_EVENT_LBUTTON
,
881 [INPUT_BUTTON_MIDDLE
] = MOUSE_EVENT_MBUTTON
,
882 [INPUT_BUTTON_RIGHT
] = MOUSE_EVENT_RBUTTON
,
884 PS2MouseState
*s
= (PS2MouseState
*)dev
;
885 InputMoveEvent
*move
;
888 /* check if deltas are recorded when disabled */
889 if (!(s
->mouse_status
& MOUSE_STATUS_ENABLED
))
893 case INPUT_EVENT_KIND_REL
:
894 move
= evt
->u
.rel
.data
;
895 if (move
->axis
== INPUT_AXIS_X
) {
896 s
->mouse_dx
+= move
->value
;
897 } else if (move
->axis
== INPUT_AXIS_Y
) {
898 s
->mouse_dy
-= move
->value
;
902 case INPUT_EVENT_KIND_BTN
:
903 btn
= evt
->u
.btn
.data
;
905 s
->mouse_buttons
|= bmap
[btn
->button
];
906 if (btn
->button
== INPUT_BUTTON_WHEEL_UP
) {
908 } else if (btn
->button
== INPUT_BUTTON_WHEEL_DOWN
) {
912 s
->mouse_buttons
&= ~bmap
[btn
->button
];
922 static void ps2_mouse_sync(DeviceState
*dev
)
924 PS2MouseState
*s
= (PS2MouseState
*)dev
;
926 if (s
->mouse_buttons
) {
927 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
929 if (!(s
->mouse_status
& MOUSE_STATUS_REMOTE
)) {
930 while (s
->common
.queue
.count
< PS2_QUEUE_SIZE
- 4) {
931 /* if not remote, send event. Multiple events are sent if
933 ps2_mouse_send_packet(s
);
934 if (s
->mouse_dx
== 0 && s
->mouse_dy
== 0 && s
->mouse_dz
== 0)
940 void ps2_mouse_fake_event(void *opaque
)
942 PS2MouseState
*s
= opaque
;
943 trace_ps2_mouse_fake_event(opaque
);
945 ps2_mouse_sync(opaque
);
948 void ps2_write_mouse(void *opaque
, int val
)
950 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
952 trace_ps2_write_mouse(opaque
, val
);
954 printf("kbd: write mouse 0x%02x\n", val
);
956 switch(s
->common
.write_cmd
) {
961 if (val
== AUX_RESET_WRAP
) {
963 ps2_queue(&s
->common
, AUX_ACK
);
965 } else if (val
!= AUX_RESET
) {
966 ps2_queue(&s
->common
, val
);
971 case AUX_SET_SCALE11
:
972 s
->mouse_status
&= ~MOUSE_STATUS_SCALE21
;
973 ps2_queue(&s
->common
, AUX_ACK
);
975 case AUX_SET_SCALE21
:
976 s
->mouse_status
|= MOUSE_STATUS_SCALE21
;
977 ps2_queue(&s
->common
, AUX_ACK
);
980 s
->mouse_status
&= ~MOUSE_STATUS_REMOTE
;
981 ps2_queue(&s
->common
, AUX_ACK
);
985 ps2_queue(&s
->common
, AUX_ACK
);
988 s
->mouse_status
|= MOUSE_STATUS_REMOTE
;
989 ps2_queue(&s
->common
, AUX_ACK
);
992 ps2_queue(&s
->common
, AUX_ACK
);
993 ps2_queue(&s
->common
, s
->mouse_type
);
997 s
->common
.write_cmd
= val
;
998 ps2_queue(&s
->common
, AUX_ACK
);
1001 ps2_queue(&s
->common
, AUX_ACK
);
1002 ps2_queue(&s
->common
, s
->mouse_status
);
1003 ps2_queue(&s
->common
, s
->mouse_resolution
);
1004 ps2_queue(&s
->common
, s
->mouse_sample_rate
);
1007 ps2_queue(&s
->common
, AUX_ACK
);
1008 ps2_mouse_send_packet(s
);
1010 case AUX_ENABLE_DEV
:
1011 s
->mouse_status
|= MOUSE_STATUS_ENABLED
;
1012 ps2_queue(&s
->common
, AUX_ACK
);
1014 case AUX_DISABLE_DEV
:
1015 s
->mouse_status
&= ~MOUSE_STATUS_ENABLED
;
1016 ps2_queue(&s
->common
, AUX_ACK
);
1018 case AUX_SET_DEFAULT
:
1019 s
->mouse_sample_rate
= 100;
1020 s
->mouse_resolution
= 2;
1021 s
->mouse_status
= 0;
1022 ps2_queue(&s
->common
, AUX_ACK
);
1025 s
->mouse_sample_rate
= 100;
1026 s
->mouse_resolution
= 2;
1027 s
->mouse_status
= 0;
1029 ps2_queue(&s
->common
, AUX_ACK
);
1030 ps2_queue(&s
->common
, 0xaa);
1031 ps2_queue(&s
->common
, s
->mouse_type
);
1037 case AUX_SET_SAMPLE
:
1038 s
->mouse_sample_rate
= val
;
1039 /* detect IMPS/2 or IMEX */
1040 switch(s
->mouse_detect_state
) {
1044 s
->mouse_detect_state
= 1;
1048 s
->mouse_detect_state
= 2;
1049 else if (val
== 200)
1050 s
->mouse_detect_state
= 3;
1052 s
->mouse_detect_state
= 0;
1056 s
->mouse_type
= 3; /* IMPS/2 */
1057 s
->mouse_detect_state
= 0;
1061 s
->mouse_type
= 4; /* IMEX */
1062 s
->mouse_detect_state
= 0;
1065 ps2_queue(&s
->common
, AUX_ACK
);
1066 s
->common
.write_cmd
= -1;
1069 s
->mouse_resolution
= val
;
1070 ps2_queue(&s
->common
, AUX_ACK
);
1071 s
->common
.write_cmd
= -1;
1076 static void ps2_common_reset(PS2State
*s
)
1084 s
->update_irq(s
->update_arg
, 0);
1087 static void ps2_common_post_load(PS2State
*s
)
1089 PS2Queue
*q
= &s
->queue
;
1092 int tmp_data
[PS2_QUEUE_SIZE
];
1094 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
1095 size
= q
->count
> PS2_QUEUE_SIZE
? 0 : q
->count
;
1097 /* move the queue elements to the start of data array */
1099 for (i
= 0; i
< size
; i
++) {
1100 /* move the queue elements to the temporary buffer */
1101 tmp_data
[i
] = q
->data
[q
->rptr
];
1102 if (++q
->rptr
== 256) {
1106 memcpy(q
->data
, tmp_data
, size
);
1108 /* reset rptr/wptr/count */
1112 s
->update_irq(s
->update_arg
, q
->count
!= 0);
1115 static void ps2_kbd_reset(void *opaque
)
1117 PS2KbdState
*s
= (PS2KbdState
*) opaque
;
1119 trace_ps2_kbd_reset(opaque
);
1120 ps2_common_reset(&s
->common
);
1121 s
->scan_enabled
= 0;
1123 s
->scancode_set
= 2;
1126 static void ps2_mouse_reset(void *opaque
)
1128 PS2MouseState
*s
= (PS2MouseState
*) opaque
;
1130 trace_ps2_mouse_reset(opaque
);
1131 ps2_common_reset(&s
->common
);
1132 s
->mouse_status
= 0;
1133 s
->mouse_resolution
= 0;
1134 s
->mouse_sample_rate
= 0;
1137 s
->mouse_detect_state
= 0;
1141 s
->mouse_buttons
= 0;
1144 static const VMStateDescription vmstate_ps2_common
= {
1145 .name
= "PS2 Common State",
1147 .minimum_version_id
= 2,
1148 .fields
= (VMStateField
[]) {
1149 VMSTATE_INT32(write_cmd
, PS2State
),
1150 VMSTATE_INT32(queue
.rptr
, PS2State
),
1151 VMSTATE_INT32(queue
.wptr
, PS2State
),
1152 VMSTATE_INT32(queue
.count
, PS2State
),
1153 VMSTATE_BUFFER(queue
.data
, PS2State
),
1154 VMSTATE_END_OF_LIST()
1158 static bool ps2_keyboard_ledstate_needed(void *opaque
)
1160 PS2KbdState
*s
= opaque
;
1162 return s
->ledstate
!= 0; /* 0 is default state */
1165 static int ps2_kbd_ledstate_post_load(void *opaque
, int version_id
)
1167 PS2KbdState
*s
= opaque
;
1169 kbd_put_ledstate(s
->ledstate
);
1173 static const VMStateDescription vmstate_ps2_keyboard_ledstate
= {
1174 .name
= "ps2kbd/ledstate",
1176 .minimum_version_id
= 2,
1177 .post_load
= ps2_kbd_ledstate_post_load
,
1178 .needed
= ps2_keyboard_ledstate_needed
,
1179 .fields
= (VMStateField
[]) {
1180 VMSTATE_INT32(ledstate
, PS2KbdState
),
1181 VMSTATE_END_OF_LIST()
1185 static bool ps2_keyboard_need_high_bit_needed(void *opaque
)
1187 PS2KbdState
*s
= opaque
;
1188 return s
->need_high_bit
!= 0; /* 0 is the usual state */
1191 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit
= {
1192 .name
= "ps2kbd/need_high_bit",
1194 .minimum_version_id
= 1,
1195 .needed
= ps2_keyboard_need_high_bit_needed
,
1196 .fields
= (VMStateField
[]) {
1197 VMSTATE_BOOL(need_high_bit
, PS2KbdState
),
1198 VMSTATE_END_OF_LIST()
1202 static int ps2_kbd_post_load(void* opaque
, int version_id
)
1204 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1205 PS2State
*ps2
= &s
->common
;
1207 if (version_id
== 2)
1210 ps2_common_post_load(ps2
);
1215 static void ps2_kbd_pre_save(void *opaque
)
1217 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1218 PS2State
*ps2
= &s
->common
;
1220 ps2_common_post_load(ps2
);
1223 static const VMStateDescription vmstate_ps2_keyboard
= {
1226 .minimum_version_id
= 2,
1227 .post_load
= ps2_kbd_post_load
,
1228 .pre_save
= ps2_kbd_pre_save
,
1229 .fields
= (VMStateField
[]) {
1230 VMSTATE_STRUCT(common
, PS2KbdState
, 0, vmstate_ps2_common
, PS2State
),
1231 VMSTATE_INT32(scan_enabled
, PS2KbdState
),
1232 VMSTATE_INT32(translate
, PS2KbdState
),
1233 VMSTATE_INT32_V(scancode_set
, PS2KbdState
,3),
1234 VMSTATE_END_OF_LIST()
1236 .subsections
= (const VMStateDescription
*[]) {
1237 &vmstate_ps2_keyboard_ledstate
,
1238 &vmstate_ps2_keyboard_need_high_bit
,
1243 static int ps2_mouse_post_load(void *opaque
, int version_id
)
1245 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1246 PS2State
*ps2
= &s
->common
;
1248 ps2_common_post_load(ps2
);
1253 static void ps2_mouse_pre_save(void *opaque
)
1255 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1256 PS2State
*ps2
= &s
->common
;
1258 ps2_common_post_load(ps2
);
1261 static const VMStateDescription vmstate_ps2_mouse
= {
1264 .minimum_version_id
= 2,
1265 .post_load
= ps2_mouse_post_load
,
1266 .pre_save
= ps2_mouse_pre_save
,
1267 .fields
= (VMStateField
[]) {
1268 VMSTATE_STRUCT(common
, PS2MouseState
, 0, vmstate_ps2_common
, PS2State
),
1269 VMSTATE_UINT8(mouse_status
, PS2MouseState
),
1270 VMSTATE_UINT8(mouse_resolution
, PS2MouseState
),
1271 VMSTATE_UINT8(mouse_sample_rate
, PS2MouseState
),
1272 VMSTATE_UINT8(mouse_wrap
, PS2MouseState
),
1273 VMSTATE_UINT8(mouse_type
, PS2MouseState
),
1274 VMSTATE_UINT8(mouse_detect_state
, PS2MouseState
),
1275 VMSTATE_INT32(mouse_dx
, PS2MouseState
),
1276 VMSTATE_INT32(mouse_dy
, PS2MouseState
),
1277 VMSTATE_INT32(mouse_dz
, PS2MouseState
),
1278 VMSTATE_UINT8(mouse_buttons
, PS2MouseState
),
1279 VMSTATE_END_OF_LIST()
1283 static QemuInputHandler ps2_keyboard_handler
= {
1284 .name
= "QEMU PS/2 Keyboard",
1285 .mask
= INPUT_EVENT_MASK_KEY
,
1286 .event
= ps2_keyboard_event
,
1289 void *ps2_kbd_init(void (*update_irq
)(void *, int), void *update_arg
)
1291 PS2KbdState
*s
= (PS2KbdState
*)g_malloc0(sizeof(PS2KbdState
));
1293 trace_ps2_kbd_init(s
);
1294 s
->common
.update_irq
= update_irq
;
1295 s
->common
.update_arg
= update_arg
;
1296 s
->scancode_set
= 2;
1297 vmstate_register(NULL
, 0, &vmstate_ps2_keyboard
, s
);
1298 qemu_input_handler_register((DeviceState
*)s
,
1299 &ps2_keyboard_handler
);
1300 qemu_register_reset(ps2_kbd_reset
, s
);
1304 static QemuInputHandler ps2_mouse_handler
= {
1305 .name
= "QEMU PS/2 Mouse",
1306 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_REL
,
1307 .event
= ps2_mouse_event
,
1308 .sync
= ps2_mouse_sync
,
1311 void *ps2_mouse_init(void (*update_irq
)(void *, int), void *update_arg
)
1313 PS2MouseState
*s
= (PS2MouseState
*)g_malloc0(sizeof(PS2MouseState
));
1315 trace_ps2_mouse_init(s
);
1316 s
->common
.update_irq
= update_irq
;
1317 s
->common
.update_arg
= update_arg
;
1318 vmstate_register(NULL
, 0, &vmstate_ps2_mouse
, s
);
1319 qemu_input_handler_register((DeviceState
*)s
,
1320 &ps2_mouse_handler
);
1321 qemu_register_reset(ps2_mouse_reset
, s
);