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