target/i386: make cpu_get_fp80()/cpu_set_fp80() static
[qemu/ar7.git] / hw / input / ps2.c
blob3ba05efd0656b66f5c9db33be7d0239d97790086
1 /*
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
22 * THE SOFTWARE.
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"
32 #include "trace.h"
34 /* debug PC keyboard */
35 //#define DEBUG_KBD
37 /* debug PC keyboard : only mouse */
38 //#define DEBUG_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 */
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. */
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 */
81 typedef struct {
82 /* Keep the data array 256 bytes long, which compatibility
83 with older qemu versions. */
84 uint8_t data[256];
85 int rptr, wptr, count;
86 } PS2Queue;
88 struct PS2State {
89 PS2Queue queue;
90 int32_t write_cmd;
91 void (*update_irq)(void *, int);
92 void *update_arg;
95 typedef struct {
96 PS2State common;
97 int scan_enabled;
98 int translate;
99 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
100 int ledstate;
101 bool need_high_bit;
102 } PS2KbdState;
104 typedef struct {
105 PS2State common;
106 uint8_t mouse_status;
107 uint8_t mouse_resolution;
108 uint8_t mouse_sample_rate;
109 uint8_t mouse_wrap;
110 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
111 uint8_t mouse_detect_state;
112 int mouse_dx; /* current values, needed for 'poll' mode */
113 int mouse_dy;
114 int mouse_dz;
115 uint8_t mouse_buttons;
116 } PS2MouseState;
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,
227 #if 0
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,
250 #endif
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,
369 #if 0
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,
392 #endif
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;
558 q->rptr = 0;
559 q->wptr = 0;
560 q->count = 0;
563 void ps2_queue(PS2State *s, int b)
565 PS2Queue *q = &s->queue;
567 if (q->count >= PS2_QUEUE_SIZE - 1)
568 return;
569 q->data[q->wptr] = b;
570 if (++q->wptr == PS2_QUEUE_SIZE)
571 q->wptr = 0;
572 q->count++;
573 s->update_irq(s->update_arg, 1);
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);
584 if (s->translate) {
585 if (keycode == 0xf0) {
586 s->need_high_bit = true;
587 } else if (s->need_high_bit) {
588 ps2_queue(&s->common, translate_table[keycode] | 0x80);
589 s->need_high_bit = false;
590 } else {
591 ps2_queue(&s->common, translate_table[keycode]);
593 } else {
594 ps2_queue(&s->common, keycode);
598 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
599 InputEvent *evt)
601 PS2KbdState *s = (PS2KbdState *)dev;
602 InputKeyEvent *key = evt->u.key.data;
603 int qcode;
604 uint16_t keycode;
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) {
612 if (key->down) {
613 ps2_put_keycode(s, 0xe1);
614 ps2_put_keycode(s, 0x1d);
615 ps2_put_keycode(s, 0x45);
616 ps2_put_keycode(s, 0x91);
617 ps2_put_keycode(s, 0x9d);
618 ps2_put_keycode(s, 0xc5);
620 } else if (qcode == Q_KEY_CODE_PRINT) {
621 if (key->down) {
622 ps2_put_keycode(s, 0xe0);
623 ps2_put_keycode(s, 0x2a);
624 ps2_put_keycode(s, 0xe0);
625 ps2_put_keycode(s, 0x37);
626 } else {
627 ps2_put_keycode(s, 0xe0);
628 ps2_put_keycode(s, 0xb7);
629 ps2_put_keycode(s, 0xe0);
630 ps2_put_keycode(s, 0xaa);
632 } else {
633 keycode = qcode_to_keycode_set1[qcode];
634 if (keycode) {
635 if (keycode & 0xff00) {
636 ps2_put_keycode(s, keycode >> 8);
638 if (!key->down) {
639 keycode |= 0x80;
641 ps2_put_keycode(s, keycode & 0xff);
642 } else {
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) {
649 if (key->down) {
650 ps2_put_keycode(s, 0xe1);
651 ps2_put_keycode(s, 0x14);
652 ps2_put_keycode(s, 0x77);
653 ps2_put_keycode(s, 0xe1);
654 ps2_put_keycode(s, 0xf0);
655 ps2_put_keycode(s, 0x14);
656 ps2_put_keycode(s, 0xf0);
657 ps2_put_keycode(s, 0x77);
659 } else if (qcode == Q_KEY_CODE_PRINT) {
660 if (key->down) {
661 ps2_put_keycode(s, 0xe0);
662 ps2_put_keycode(s, 0x12);
663 ps2_put_keycode(s, 0xe0);
664 ps2_put_keycode(s, 0x7c);
665 } else {
666 ps2_put_keycode(s, 0xe0);
667 ps2_put_keycode(s, 0xf0);
668 ps2_put_keycode(s, 0x7c);
669 ps2_put_keycode(s, 0xe0);
670 ps2_put_keycode(s, 0xf0);
671 ps2_put_keycode(s, 0x12);
673 } else {
674 keycode = qcode_to_keycode_set2[qcode];
675 if (keycode) {
676 if (keycode & 0xff00) {
677 ps2_put_keycode(s, keycode >> 8);
679 if (!key->down) {
680 ps2_put_keycode(s, 0xf0);
682 ps2_put_keycode(s, keycode & 0xff);
683 } else {
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];
690 if (keycode) {
691 /* FIXME: break code should be configured on a key by key basis */
692 if (!key->down) {
693 ps2_put_keycode(s, 0xf0);
695 ps2_put_keycode(s, keycode);
696 } else {
697 qemu_log_mask(LOG_UNIMP,
698 "ps2: ignoring key with qcode %d\n", qcode);
703 uint32_t ps2_read_data(PS2State *s)
705 PS2Queue *q;
706 int val, index;
708 trace_ps2_read_data(s);
709 q = &s->queue;
710 if (q->count == 0) {
711 /* NOTE: if no data left, we return the last keyboard one
712 (needed for EMM386) */
713 /* XXX: need a timer to do things correctly */
714 index = q->rptr - 1;
715 if (index < 0)
716 index = PS2_QUEUE_SIZE - 1;
717 val = q->data[index];
718 } else {
719 val = q->data[q->rptr];
720 if (++q->rptr == PS2_QUEUE_SIZE)
721 q->rptr = 0;
722 q->count--;
723 /* reading deasserts IRQ */
724 s->update_irq(s->update_arg, 0);
725 /* reassert IRQs if data left */
726 s->update_irq(s->update_arg, q->count != 0);
728 return val;
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);
741 s->scan_enabled = 1;
742 s->scancode_set = 2;
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) {
753 default:
754 case -1:
755 switch(val) {
756 case 0x00:
757 ps2_queue(&s->common, KBD_REPLY_ACK);
758 break;
759 case 0x05:
760 ps2_queue(&s->common, KBD_REPLY_RESEND);
761 break;
762 case KBD_CMD_GET_ID:
763 ps2_queue(&s->common, KBD_REPLY_ACK);
764 /* We emulate a MF2 AT keyboard here */
765 ps2_queue(&s->common, KBD_REPLY_ID);
766 if (s->translate)
767 ps2_queue(&s->common, 0x41);
768 else
769 ps2_queue(&s->common, 0x83);
770 break;
771 case KBD_CMD_ECHO:
772 ps2_queue(&s->common, KBD_CMD_ECHO);
773 break;
774 case KBD_CMD_ENABLE:
775 s->scan_enabled = 1;
776 ps2_queue(&s->common, KBD_REPLY_ACK);
777 break;
778 case KBD_CMD_SCANCODE:
779 case KBD_CMD_SET_LEDS:
780 case KBD_CMD_SET_RATE:
781 s->common.write_cmd = val;
782 ps2_queue(&s->common, KBD_REPLY_ACK);
783 break;
784 case KBD_CMD_RESET_DISABLE:
785 ps2_reset_keyboard(s);
786 s->scan_enabled = 0;
787 ps2_queue(&s->common, KBD_REPLY_ACK);
788 break;
789 case KBD_CMD_RESET_ENABLE:
790 ps2_reset_keyboard(s);
791 s->scan_enabled = 1;
792 ps2_queue(&s->common, KBD_REPLY_ACK);
793 break;
794 case KBD_CMD_RESET:
795 ps2_reset_keyboard(s);
796 ps2_queue(&s->common, KBD_REPLY_ACK);
797 ps2_queue(&s->common, KBD_REPLY_POR);
798 break;
799 default:
800 ps2_queue(&s->common, KBD_REPLY_RESEND);
801 break;
803 break;
804 case KBD_CMD_SCANCODE:
805 if (val == 0) {
806 ps2_queue(&s->common, KBD_REPLY_ACK);
807 ps2_put_keycode(s, s->scancode_set);
808 } else if (val >= 1 && val <= 3) {
809 s->scancode_set = val;
810 ps2_queue(&s->common, KBD_REPLY_ACK);
811 } else {
812 ps2_queue(&s->common, KBD_REPLY_RESEND);
814 s->common.write_cmd = -1;
815 break;
816 case KBD_CMD_SET_LEDS:
817 ps2_set_ledstate(s, val);
818 ps2_queue(&s->common, KBD_REPLY_ACK);
819 s->common.write_cmd = -1;
820 break;
821 case KBD_CMD_SET_RATE:
822 ps2_queue(&s->common, KBD_REPLY_ACK);
823 s->common.write_cmd = -1;
824 break;
828 /* Set the scancode translation mode.
829 0 = raw scancodes.
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);
836 s->translate = mode;
839 static void ps2_mouse_send_packet(PS2MouseState *s)
841 unsigned int b;
842 int dx1, dy1, dz1;
844 dx1 = s->mouse_dx;
845 dy1 = s->mouse_dy;
846 dz1 = s->mouse_dz;
847 /* XXX: increase range to 8 bits ? */
848 if (dx1 > 127)
849 dx1 = 127;
850 else if (dx1 < -127)
851 dx1 = -127;
852 if (dy1 > 127)
853 dy1 = 127;
854 else if (dy1 < -127)
855 dy1 = -127;
856 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
857 ps2_queue(&s->common, b);
858 ps2_queue(&s->common, dx1 & 0xff);
859 ps2_queue(&s->common, dy1 & 0xff);
860 /* extra byte for IMPS/2 or IMEX */
861 switch(s->mouse_type) {
862 default:
863 break;
864 case 3:
865 if (dz1 > 127)
866 dz1 = 127;
867 else if (dz1 < -127)
868 dz1 = -127;
869 ps2_queue(&s->common, dz1 & 0xff);
870 break;
871 case 4:
872 if (dz1 > 7)
873 dz1 = 7;
874 else if (dz1 < -7)
875 dz1 = -7;
876 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
877 ps2_queue(&s->common, b);
878 break;
881 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
882 /* update deltas */
883 s->mouse_dx -= dx1;
884 s->mouse_dy -= dy1;
885 s->mouse_dz -= dz1;
888 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
889 InputEvent *evt)
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;
900 InputBtnEvent *btn;
902 /* check if deltas are recorded when disabled */
903 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
904 return;
906 switch (evt->type) {
907 case INPUT_EVENT_KIND_REL:
908 move = evt->u.rel.data;
909 if (move->axis == INPUT_AXIS_X) {
910 s->mouse_dx += move->value;
911 } else if (move->axis == INPUT_AXIS_Y) {
912 s->mouse_dy -= move->value;
914 break;
916 case INPUT_EVENT_KIND_BTN:
917 btn = evt->u.btn.data;
918 if (btn->down) {
919 s->mouse_buttons |= bmap[btn->button];
920 if (btn->button == INPUT_BUTTON_WHEEL_UP) {
921 s->mouse_dz--;
922 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
923 s->mouse_dz++;
925 } else {
926 s->mouse_buttons &= ~bmap[btn->button];
928 break;
930 default:
931 /* keep gcc happy */
932 break;
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
946 too big deltas */
947 ps2_mouse_send_packet(s);
948 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
949 break;
954 void ps2_mouse_fake_event(void *opaque)
956 PS2MouseState *s = opaque;
957 trace_ps2_mouse_fake_event(opaque);
958 s->mouse_dx++;
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);
967 #ifdef DEBUG_MOUSE
968 printf("kbd: write mouse 0x%02x\n", val);
969 #endif
970 switch(s->common.write_cmd) {
971 default:
972 case -1:
973 /* mouse command */
974 if (s->mouse_wrap) {
975 if (val == AUX_RESET_WRAP) {
976 s->mouse_wrap = 0;
977 ps2_queue(&s->common, AUX_ACK);
978 return;
979 } else if (val != AUX_RESET) {
980 ps2_queue(&s->common, val);
981 return;
984 switch(val) {
985 case AUX_SET_SCALE11:
986 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
987 ps2_queue(&s->common, AUX_ACK);
988 break;
989 case AUX_SET_SCALE21:
990 s->mouse_status |= MOUSE_STATUS_SCALE21;
991 ps2_queue(&s->common, AUX_ACK);
992 break;
993 case AUX_SET_STREAM:
994 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
995 ps2_queue(&s->common, AUX_ACK);
996 break;
997 case AUX_SET_WRAP:
998 s->mouse_wrap = 1;
999 ps2_queue(&s->common, AUX_ACK);
1000 break;
1001 case AUX_SET_REMOTE:
1002 s->mouse_status |= MOUSE_STATUS_REMOTE;
1003 ps2_queue(&s->common, AUX_ACK);
1004 break;
1005 case AUX_GET_TYPE:
1006 ps2_queue(&s->common, AUX_ACK);
1007 ps2_queue(&s->common, s->mouse_type);
1008 break;
1009 case AUX_SET_RES:
1010 case AUX_SET_SAMPLE:
1011 s->common.write_cmd = val;
1012 ps2_queue(&s->common, AUX_ACK);
1013 break;
1014 case AUX_GET_SCALE:
1015 ps2_queue(&s->common, AUX_ACK);
1016 ps2_queue(&s->common, s->mouse_status);
1017 ps2_queue(&s->common, s->mouse_resolution);
1018 ps2_queue(&s->common, s->mouse_sample_rate);
1019 break;
1020 case AUX_POLL:
1021 ps2_queue(&s->common, AUX_ACK);
1022 ps2_mouse_send_packet(s);
1023 break;
1024 case AUX_ENABLE_DEV:
1025 s->mouse_status |= MOUSE_STATUS_ENABLED;
1026 ps2_queue(&s->common, AUX_ACK);
1027 break;
1028 case AUX_DISABLE_DEV:
1029 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
1030 ps2_queue(&s->common, AUX_ACK);
1031 break;
1032 case AUX_SET_DEFAULT:
1033 s->mouse_sample_rate = 100;
1034 s->mouse_resolution = 2;
1035 s->mouse_status = 0;
1036 ps2_queue(&s->common, AUX_ACK);
1037 break;
1038 case AUX_RESET:
1039 s->mouse_sample_rate = 100;
1040 s->mouse_resolution = 2;
1041 s->mouse_status = 0;
1042 s->mouse_type = 0;
1043 ps2_queue(&s->common, AUX_ACK);
1044 ps2_queue(&s->common, 0xaa);
1045 ps2_queue(&s->common, s->mouse_type);
1046 break;
1047 default:
1048 break;
1050 break;
1051 case AUX_SET_SAMPLE:
1052 s->mouse_sample_rate = val;
1053 /* detect IMPS/2 or IMEX */
1054 switch(s->mouse_detect_state) {
1055 default:
1056 case 0:
1057 if (val == 200)
1058 s->mouse_detect_state = 1;
1059 break;
1060 case 1:
1061 if (val == 100)
1062 s->mouse_detect_state = 2;
1063 else if (val == 200)
1064 s->mouse_detect_state = 3;
1065 else
1066 s->mouse_detect_state = 0;
1067 break;
1068 case 2:
1069 if (val == 80)
1070 s->mouse_type = 3; /* IMPS/2 */
1071 s->mouse_detect_state = 0;
1072 break;
1073 case 3:
1074 if (val == 80)
1075 s->mouse_type = 4; /* IMEX */
1076 s->mouse_detect_state = 0;
1077 break;
1079 ps2_queue(&s->common, AUX_ACK);
1080 s->common.write_cmd = -1;
1081 break;
1082 case AUX_SET_RES:
1083 s->mouse_resolution = val;
1084 ps2_queue(&s->common, AUX_ACK);
1085 s->common.write_cmd = -1;
1086 break;
1090 static void ps2_common_reset(PS2State *s)
1092 s->write_cmd = -1;
1093 ps2_reset_queue(s);
1094 s->update_irq(s->update_arg, 0);
1097 static void ps2_common_post_load(PS2State *s)
1099 PS2Queue *q = &s->queue;
1100 int size;
1101 int i;
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 */
1108 if (size > 0) {
1109 for (i = 0; i < size; i++) {
1110 /* move the queue elements to the temporary buffer */
1111 tmp_data[i] = q->data[q->rptr];
1112 if (++q->rptr == 256) {
1113 q->rptr = 0;
1116 memcpy(q->data, tmp_data, size);
1118 /* reset rptr/wptr/count */
1119 q->rptr = 0;
1120 q->wptr = size;
1121 q->count = size;
1122 s->update_irq(s->update_arg, q->count != 0);
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;
1132 s->translate = 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;
1145 s->mouse_wrap = 0;
1146 s->mouse_type = 0;
1147 s->mouse_detect_state = 0;
1148 s->mouse_dx = 0;
1149 s->mouse_dy = 0;
1150 s->mouse_dz = 0;
1151 s->mouse_buttons = 0;
1154 static const VMStateDescription vmstate_ps2_common = {
1155 .name = "PS2 Common State",
1156 .version_id = 3,
1157 .minimum_version_id = 2,
1158 .fields = (VMStateField[]) {
1159 VMSTATE_INT32(write_cmd, PS2State),
1160 VMSTATE_INT32(queue.rptr, PS2State),
1161 VMSTATE_INT32(queue.wptr, PS2State),
1162 VMSTATE_INT32(queue.count, PS2State),
1163 VMSTATE_BUFFER(queue.data, PS2State),
1164 VMSTATE_END_OF_LIST()
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);
1180 return 0;
1183 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1184 .name = "ps2kbd/ledstate",
1185 .version_id = 3,
1186 .minimum_version_id = 2,
1187 .post_load = ps2_kbd_ledstate_post_load,
1188 .needed = ps2_keyboard_ledstate_needed,
1189 .fields = (VMStateField[]) {
1190 VMSTATE_INT32(ledstate, PS2KbdState),
1191 VMSTATE_END_OF_LIST()
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",
1203 .version_id = 1,
1204 .minimum_version_id = 1,
1205 .needed = ps2_keyboard_need_high_bit_needed,
1206 .fields = (VMStateField[]) {
1207 VMSTATE_BOOL(need_high_bit, PS2KbdState),
1208 VMSTATE_END_OF_LIST()
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)
1218 s->scancode_set=2;
1220 ps2_common_post_load(ps2);
1222 return 0;
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 = {
1234 .name = "ps2kbd",
1235 .version_id = 3,
1236 .minimum_version_id = 2,
1237 .post_load = ps2_kbd_post_load,
1238 .pre_save = ps2_kbd_pre_save,
1239 .fields = (VMStateField[]) {
1240 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1241 VMSTATE_INT32(scan_enabled, PS2KbdState),
1242 VMSTATE_INT32(translate, PS2KbdState),
1243 VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1244 VMSTATE_END_OF_LIST()
1246 .subsections = (const VMStateDescription*[]) {
1247 &vmstate_ps2_keyboard_ledstate,
1248 &vmstate_ps2_keyboard_need_high_bit,
1249 NULL
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);
1260 return 0;
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 = {
1272 .name = "ps2mouse",
1273 .version_id = 2,
1274 .minimum_version_id = 2,
1275 .post_load = ps2_mouse_post_load,
1276 .pre_save = ps2_mouse_pre_save,
1277 .fields = (VMStateField[]) {
1278 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1279 VMSTATE_UINT8(mouse_status, PS2MouseState),
1280 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1281 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1282 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1283 VMSTATE_UINT8(mouse_type, PS2MouseState),
1284 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1285 VMSTATE_INT32(mouse_dx, PS2MouseState),
1286 VMSTATE_INT32(mouse_dy, PS2MouseState),
1287 VMSTATE_INT32(mouse_dz, PS2MouseState),
1288 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1289 VMSTATE_END_OF_LIST()
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);
1311 return 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);
1332 return s;