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