]> git.proxmox.com Git - mirror_qemu.git/blob - hw/input/ps2.c
Include migration/vmstate.h less
[mirror_qemu.git] / hw / input / ps2.c
1 /*
2 * QEMU PS/2 keyboard/mouse emulation
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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.
23 */
24
25 #include "qemu/osdep.h"
26 #include "qemu/log.h"
27 #include "hw/hw.h"
28 #include "hw/input/ps2.h"
29 #include "migration/vmstate.h"
30 #include "ui/console.h"
31 #include "ui/input.h"
32 #include "sysemu/reset.h"
33 #include "sysemu/sysemu.h"
34
35 #include "trace.h"
36
37 /* debug PC keyboard */
38 //#define DEBUG_KBD
39
40 /* debug PC keyboard : only mouse */
41 //#define DEBUG_MOUSE
42
43 /* Keyboard Commands */
44 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
45 #define KBD_CMD_ECHO 0xEE
46 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
47 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
48 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
49 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
50 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
51 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
52 #define KBD_CMD_RESET 0xFF /* Reset */
53
54 /* Keyboard Replies */
55 #define KBD_REPLY_POR 0xAA /* Power on reset */
56 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
57 #define KBD_REPLY_ACK 0xFA /* Command ACK */
58 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
59
60 /* Mouse Commands */
61 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
62 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
63 #define AUX_SET_RES 0xE8 /* Set resolution */
64 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
65 #define AUX_SET_STREAM 0xEA /* Set stream mode */
66 #define AUX_POLL 0xEB /* Poll */
67 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
68 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
69 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
70 #define AUX_GET_TYPE 0xF2 /* Get type */
71 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
72 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
73 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
74 #define AUX_SET_DEFAULT 0xF6
75 #define AUX_RESET 0xFF /* Reset aux device */
76 #define AUX_ACK 0xFA /* Command byte ACK. */
77
78 #define MOUSE_STATUS_REMOTE 0x40
79 #define MOUSE_STATUS_ENABLED 0x20
80 #define MOUSE_STATUS_SCALE21 0x10
81
82 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
83
84 /* Bits for 'modifiers' field in PS2KbdState */
85 #define MOD_CTRL_L (1 << 0)
86 #define MOD_SHIFT_L (1 << 1)
87 #define MOD_ALT_L (1 << 2)
88 #define MOD_CTRL_R (1 << 3)
89 #define MOD_SHIFT_R (1 << 4)
90 #define MOD_ALT_R (1 << 5)
91
92 typedef struct {
93 /* Keep the data array 256 bytes long, which compatibility
94 with older qemu versions. */
95 uint8_t data[256];
96 int rptr, wptr, count;
97 } PS2Queue;
98
99 struct PS2State {
100 PS2Queue queue;
101 int32_t write_cmd;
102 void (*update_irq)(void *, int);
103 void *update_arg;
104 };
105
106 typedef struct {
107 PS2State common;
108 int scan_enabled;
109 int translate;
110 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
111 int ledstate;
112 bool need_high_bit;
113 unsigned int modifiers; /* bitmask of MOD_* constants above */
114 } PS2KbdState;
115
116 typedef struct {
117 PS2State common;
118 uint8_t mouse_status;
119 uint8_t mouse_resolution;
120 uint8_t mouse_sample_rate;
121 uint8_t mouse_wrap;
122 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
123 uint8_t mouse_detect_state;
124 int mouse_dx; /* current values, needed for 'poll' mode */
125 int mouse_dy;
126 int mouse_dz;
127 uint8_t mouse_buttons;
128 } PS2MouseState;
129
130 static uint8_t translate_table[256] = {
131 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
132 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
133 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
134 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
135 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
136 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
137 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
138 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
139 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
140 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
141 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
142 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
143 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
144 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
145 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
146 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
147 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
148 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
149 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
150 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
151 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
152 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
153 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
154 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
155 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
156 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
157 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
158 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
159 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
160 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
161 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
162 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
163 };
164
165 static unsigned int ps2_modifier_bit(QKeyCode key)
166 {
167 switch (key) {
168 case Q_KEY_CODE_CTRL:
169 return MOD_CTRL_L;
170 case Q_KEY_CODE_CTRL_R:
171 return MOD_CTRL_R;
172 case Q_KEY_CODE_SHIFT:
173 return MOD_SHIFT_L;
174 case Q_KEY_CODE_SHIFT_R:
175 return MOD_SHIFT_R;
176 case Q_KEY_CODE_ALT:
177 return MOD_ALT_L;
178 case Q_KEY_CODE_ALT_R:
179 return MOD_ALT_R;
180 default:
181 return 0;
182 }
183 }
184
185 static void ps2_reset_queue(PS2State *s)
186 {
187 PS2Queue *q = &s->queue;
188
189 q->rptr = 0;
190 q->wptr = 0;
191 q->count = 0;
192 }
193
194 void ps2_queue_noirq(PS2State *s, int b)
195 {
196 PS2Queue *q = &s->queue;
197
198 if (q->count == PS2_QUEUE_SIZE) {
199 return;
200 }
201
202 q->data[q->wptr] = b;
203 if (++q->wptr == PS2_QUEUE_SIZE)
204 q->wptr = 0;
205 q->count++;
206 }
207
208 void ps2_raise_irq(PS2State *s)
209 {
210 s->update_irq(s->update_arg, 1);
211 }
212
213 void ps2_queue(PS2State *s, int b)
214 {
215 ps2_queue_noirq(s, b);
216 s->update_irq(s->update_arg, 1);
217 }
218
219 void ps2_queue_2(PS2State *s, int b1, int b2)
220 {
221 if (PS2_QUEUE_SIZE - s->queue.count < 2) {
222 return;
223 }
224
225 ps2_queue_noirq(s, b1);
226 ps2_queue_noirq(s, b2);
227 s->update_irq(s->update_arg, 1);
228 }
229
230 void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
231 {
232 if (PS2_QUEUE_SIZE - s->queue.count < 3) {
233 return;
234 }
235
236 ps2_queue_noirq(s, b1);
237 ps2_queue_noirq(s, b2);
238 ps2_queue_noirq(s, b3);
239 s->update_irq(s->update_arg, 1);
240 }
241
242 void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
243 {
244 if (PS2_QUEUE_SIZE - s->queue.count < 4) {
245 return;
246 }
247
248 ps2_queue_noirq(s, b1);
249 ps2_queue_noirq(s, b2);
250 ps2_queue_noirq(s, b3);
251 ps2_queue_noirq(s, b4);
252 s->update_irq(s->update_arg, 1);
253 }
254
255 /* keycode is the untranslated scancode in the current scancode set. */
256 static void ps2_put_keycode(void *opaque, int keycode)
257 {
258 PS2KbdState *s = opaque;
259
260 trace_ps2_put_keycode(opaque, keycode);
261 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
262
263 if (s->translate) {
264 if (keycode == 0xf0) {
265 s->need_high_bit = true;
266 } else if (s->need_high_bit) {
267 ps2_queue(&s->common, translate_table[keycode] | 0x80);
268 s->need_high_bit = false;
269 } else {
270 ps2_queue(&s->common, translate_table[keycode]);
271 }
272 } else {
273 ps2_queue(&s->common, keycode);
274 }
275 }
276
277 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
278 InputEvent *evt)
279 {
280 PS2KbdState *s = (PS2KbdState *)dev;
281 InputKeyEvent *key = evt->u.key.data;
282 int qcode;
283 uint16_t keycode = 0;
284 int mod;
285
286 /* do not process events while disabled to prevent stream corruption */
287 if (!s->scan_enabled) {
288 return;
289 }
290
291 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
292 assert(evt->type == INPUT_EVENT_KIND_KEY);
293 qcode = qemu_input_key_value_to_qcode(key->key);
294
295 mod = ps2_modifier_bit(qcode);
296 trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
297 if (key->down) {
298 s->modifiers |= mod;
299 } else {
300 s->modifiers &= ~mod;
301 }
302
303 if (s->scancode_set == 1) {
304 if (qcode == Q_KEY_CODE_PAUSE) {
305 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
306 if (key->down) {
307 ps2_put_keycode(s, 0xe0);
308 ps2_put_keycode(s, 0x46);
309 ps2_put_keycode(s, 0xe0);
310 ps2_put_keycode(s, 0xc6);
311 }
312 } else {
313 if (key->down) {
314 ps2_put_keycode(s, 0xe1);
315 ps2_put_keycode(s, 0x1d);
316 ps2_put_keycode(s, 0x45);
317 ps2_put_keycode(s, 0xe1);
318 ps2_put_keycode(s, 0x9d);
319 ps2_put_keycode(s, 0xc5);
320 }
321 }
322 } else if (qcode == Q_KEY_CODE_PRINT) {
323 if (s->modifiers & MOD_ALT_L) {
324 if (key->down) {
325 ps2_put_keycode(s, 0xb8);
326 ps2_put_keycode(s, 0x38);
327 ps2_put_keycode(s, 0x54);
328 } else {
329 ps2_put_keycode(s, 0xd4);
330 ps2_put_keycode(s, 0xb8);
331 ps2_put_keycode(s, 0x38);
332 }
333 } else if (s->modifiers & MOD_ALT_R) {
334 if (key->down) {
335 ps2_put_keycode(s, 0xe0);
336 ps2_put_keycode(s, 0xb8);
337 ps2_put_keycode(s, 0xe0);
338 ps2_put_keycode(s, 0x38);
339 ps2_put_keycode(s, 0x54);
340 } else {
341 ps2_put_keycode(s, 0xd4);
342 ps2_put_keycode(s, 0xe0);
343 ps2_put_keycode(s, 0xb8);
344 ps2_put_keycode(s, 0xe0);
345 ps2_put_keycode(s, 0x38);
346 }
347 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
348 MOD_SHIFT_R | MOD_CTRL_R)) {
349 if (key->down) {
350 ps2_put_keycode(s, 0xe0);
351 ps2_put_keycode(s, 0x37);
352 } else {
353 ps2_put_keycode(s, 0xe0);
354 ps2_put_keycode(s, 0xb7);
355 }
356 } else {
357 if (key->down) {
358 ps2_put_keycode(s, 0xe0);
359 ps2_put_keycode(s, 0x2a);
360 ps2_put_keycode(s, 0xe0);
361 ps2_put_keycode(s, 0x37);
362 } else {
363 ps2_put_keycode(s, 0xe0);
364 ps2_put_keycode(s, 0xb7);
365 ps2_put_keycode(s, 0xe0);
366 ps2_put_keycode(s, 0xaa);
367 }
368 }
369 } else {
370 if (qcode < qemu_input_map_qcode_to_atset1_len)
371 keycode = qemu_input_map_qcode_to_atset1[qcode];
372 if (keycode) {
373 if (keycode & 0xff00) {
374 ps2_put_keycode(s, keycode >> 8);
375 }
376 if (!key->down) {
377 keycode |= 0x80;
378 }
379 ps2_put_keycode(s, keycode & 0xff);
380 } else {
381 qemu_log_mask(LOG_UNIMP,
382 "ps2: ignoring key with qcode %d\n", qcode);
383 }
384 }
385 } else if (s->scancode_set == 2) {
386 if (qcode == Q_KEY_CODE_PAUSE) {
387 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
388 if (key->down) {
389 ps2_put_keycode(s, 0xe0);
390 ps2_put_keycode(s, 0x7e);
391 ps2_put_keycode(s, 0xe0);
392 ps2_put_keycode(s, 0xf0);
393 ps2_put_keycode(s, 0x7e);
394 }
395 } else {
396 if (key->down) {
397 ps2_put_keycode(s, 0xe1);
398 ps2_put_keycode(s, 0x14);
399 ps2_put_keycode(s, 0x77);
400 ps2_put_keycode(s, 0xe1);
401 ps2_put_keycode(s, 0xf0);
402 ps2_put_keycode(s, 0x14);
403 ps2_put_keycode(s, 0xf0);
404 ps2_put_keycode(s, 0x77);
405 }
406 }
407 } else if (qcode == Q_KEY_CODE_PRINT) {
408 if (s->modifiers & MOD_ALT_L) {
409 if (key->down) {
410 ps2_put_keycode(s, 0xf0);
411 ps2_put_keycode(s, 0x11);
412 ps2_put_keycode(s, 0x11);
413 ps2_put_keycode(s, 0x84);
414 } else {
415 ps2_put_keycode(s, 0xf0);
416 ps2_put_keycode(s, 0x84);
417 ps2_put_keycode(s, 0xf0);
418 ps2_put_keycode(s, 0x11);
419 ps2_put_keycode(s, 0x11);
420 }
421 } else if (s->modifiers & MOD_ALT_R) {
422 if (key->down) {
423 ps2_put_keycode(s, 0xe0);
424 ps2_put_keycode(s, 0xf0);
425 ps2_put_keycode(s, 0x11);
426 ps2_put_keycode(s, 0xe0);
427 ps2_put_keycode(s, 0x11);
428 ps2_put_keycode(s, 0x84);
429 } else {
430 ps2_put_keycode(s, 0xf0);
431 ps2_put_keycode(s, 0x84);
432 ps2_put_keycode(s, 0xe0);
433 ps2_put_keycode(s, 0xf0);
434 ps2_put_keycode(s, 0x11);
435 ps2_put_keycode(s, 0xe0);
436 ps2_put_keycode(s, 0x11);
437 }
438 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
439 MOD_SHIFT_R | MOD_CTRL_R)) {
440 if (key->down) {
441 ps2_put_keycode(s, 0xe0);
442 ps2_put_keycode(s, 0x7c);
443 } else {
444 ps2_put_keycode(s, 0xe0);
445 ps2_put_keycode(s, 0xf0);
446 ps2_put_keycode(s, 0x7c);
447 }
448 } else {
449 if (key->down) {
450 ps2_put_keycode(s, 0xe0);
451 ps2_put_keycode(s, 0x12);
452 ps2_put_keycode(s, 0xe0);
453 ps2_put_keycode(s, 0x7c);
454 } else {
455 ps2_put_keycode(s, 0xe0);
456 ps2_put_keycode(s, 0xf0);
457 ps2_put_keycode(s, 0x7c);
458 ps2_put_keycode(s, 0xe0);
459 ps2_put_keycode(s, 0xf0);
460 ps2_put_keycode(s, 0x12);
461 }
462 }
463 } else {
464 if (qcode < qemu_input_map_qcode_to_atset2_len)
465 keycode = qemu_input_map_qcode_to_atset2[qcode];
466 if (keycode) {
467 if (keycode & 0xff00) {
468 ps2_put_keycode(s, keycode >> 8);
469 }
470 if (!key->down) {
471 ps2_put_keycode(s, 0xf0);
472 }
473 ps2_put_keycode(s, keycode & 0xff);
474 } else {
475 qemu_log_mask(LOG_UNIMP,
476 "ps2: ignoring key with qcode %d\n", qcode);
477 }
478 }
479 } else if (s->scancode_set == 3) {
480 if (qcode < qemu_input_map_qcode_to_atset3_len)
481 keycode = qemu_input_map_qcode_to_atset3[qcode];
482 if (keycode) {
483 /* FIXME: break code should be configured on a key by key basis */
484 if (!key->down) {
485 ps2_put_keycode(s, 0xf0);
486 }
487 ps2_put_keycode(s, keycode);
488 } else {
489 qemu_log_mask(LOG_UNIMP,
490 "ps2: ignoring key with qcode %d\n", qcode);
491 }
492 }
493 }
494
495 uint32_t ps2_read_data(PS2State *s)
496 {
497 PS2Queue *q;
498 int val, index;
499
500 trace_ps2_read_data(s);
501 q = &s->queue;
502 if (q->count == 0) {
503 /* NOTE: if no data left, we return the last keyboard one
504 (needed for EMM386) */
505 /* XXX: need a timer to do things correctly */
506 index = q->rptr - 1;
507 if (index < 0)
508 index = PS2_QUEUE_SIZE - 1;
509 val = q->data[index];
510 } else {
511 val = q->data[q->rptr];
512 if (++q->rptr == PS2_QUEUE_SIZE)
513 q->rptr = 0;
514 q->count--;
515 /* reading deasserts IRQ */
516 s->update_irq(s->update_arg, 0);
517 /* reassert IRQs if data left */
518 s->update_irq(s->update_arg, q->count != 0);
519 }
520 return val;
521 }
522
523 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
524 {
525 trace_ps2_set_ledstate(s, ledstate);
526 s->ledstate = ledstate;
527 kbd_put_ledstate(ledstate);
528 }
529
530 static void ps2_reset_keyboard(PS2KbdState *s)
531 {
532 trace_ps2_reset_keyboard(s);
533 s->scan_enabled = 1;
534 s->scancode_set = 2;
535 ps2_reset_queue(&s->common);
536 ps2_set_ledstate(s, 0);
537 }
538
539 void ps2_write_keyboard(void *opaque, int val)
540 {
541 PS2KbdState *s = (PS2KbdState *)opaque;
542
543 trace_ps2_write_keyboard(opaque, val);
544 switch(s->common.write_cmd) {
545 default:
546 case -1:
547 switch(val) {
548 case 0x00:
549 ps2_queue(&s->common, KBD_REPLY_ACK);
550 break;
551 case 0x05:
552 ps2_queue(&s->common, KBD_REPLY_RESEND);
553 break;
554 case KBD_CMD_GET_ID:
555 /* We emulate a MF2 AT keyboard here */
556 if (s->translate)
557 ps2_queue_3(&s->common,
558 KBD_REPLY_ACK,
559 KBD_REPLY_ID,
560 0x41);
561 else
562 ps2_queue_3(&s->common,
563 KBD_REPLY_ACK,
564 KBD_REPLY_ID,
565 0x83);
566 break;
567 case KBD_CMD_ECHO:
568 ps2_queue(&s->common, KBD_CMD_ECHO);
569 break;
570 case KBD_CMD_ENABLE:
571 s->scan_enabled = 1;
572 ps2_queue(&s->common, KBD_REPLY_ACK);
573 break;
574 case KBD_CMD_SCANCODE:
575 case KBD_CMD_SET_LEDS:
576 case KBD_CMD_SET_RATE:
577 s->common.write_cmd = val;
578 ps2_queue(&s->common, KBD_REPLY_ACK);
579 break;
580 case KBD_CMD_RESET_DISABLE:
581 ps2_reset_keyboard(s);
582 s->scan_enabled = 0;
583 ps2_queue(&s->common, KBD_REPLY_ACK);
584 break;
585 case KBD_CMD_RESET_ENABLE:
586 ps2_reset_keyboard(s);
587 s->scan_enabled = 1;
588 ps2_queue(&s->common, KBD_REPLY_ACK);
589 break;
590 case KBD_CMD_RESET:
591 ps2_reset_keyboard(s);
592 ps2_queue_2(&s->common,
593 KBD_REPLY_ACK,
594 KBD_REPLY_POR);
595 break;
596 default:
597 ps2_queue(&s->common, KBD_REPLY_RESEND);
598 break;
599 }
600 break;
601 case KBD_CMD_SCANCODE:
602 if (val == 0) {
603 if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
604 ps2_queue(&s->common, KBD_REPLY_ACK);
605 ps2_put_keycode(s, s->scancode_set);
606 }
607 } else if (val >= 1 && val <= 3) {
608 s->scancode_set = val;
609 ps2_queue(&s->common, KBD_REPLY_ACK);
610 } else {
611 ps2_queue(&s->common, KBD_REPLY_RESEND);
612 }
613 s->common.write_cmd = -1;
614 break;
615 case KBD_CMD_SET_LEDS:
616 ps2_set_ledstate(s, val);
617 ps2_queue(&s->common, KBD_REPLY_ACK);
618 s->common.write_cmd = -1;
619 break;
620 case KBD_CMD_SET_RATE:
621 ps2_queue(&s->common, KBD_REPLY_ACK);
622 s->common.write_cmd = -1;
623 break;
624 }
625 }
626
627 /* Set the scancode translation mode.
628 0 = raw scancodes.
629 1 = translated scancodes (used by qemu internally). */
630
631 void ps2_keyboard_set_translation(void *opaque, int mode)
632 {
633 PS2KbdState *s = (PS2KbdState *)opaque;
634 trace_ps2_keyboard_set_translation(opaque, mode);
635 s->translate = mode;
636 }
637
638 static int ps2_mouse_send_packet(PS2MouseState *s)
639 {
640 const int needed = 3 + (s->mouse_type - 2);
641 unsigned int b;
642 int dx1, dy1, dz1;
643
644 if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
645 return 0;
646 }
647
648 dx1 = s->mouse_dx;
649 dy1 = s->mouse_dy;
650 dz1 = s->mouse_dz;
651 /* XXX: increase range to 8 bits ? */
652 if (dx1 > 127)
653 dx1 = 127;
654 else if (dx1 < -127)
655 dx1 = -127;
656 if (dy1 > 127)
657 dy1 = 127;
658 else if (dy1 < -127)
659 dy1 = -127;
660 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
661 ps2_queue_noirq(&s->common, b);
662 ps2_queue_noirq(&s->common, dx1 & 0xff);
663 ps2_queue_noirq(&s->common, dy1 & 0xff);
664 /* extra byte for IMPS/2 or IMEX */
665 switch(s->mouse_type) {
666 default:
667 break;
668 case 3:
669 if (dz1 > 127)
670 dz1 = 127;
671 else if (dz1 < -127)
672 dz1 = -127;
673 ps2_queue_noirq(&s->common, dz1 & 0xff);
674 break;
675 case 4:
676 if (dz1 > 7)
677 dz1 = 7;
678 else if (dz1 < -7)
679 dz1 = -7;
680 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
681 ps2_queue_noirq(&s->common, b);
682 break;
683 }
684
685 ps2_raise_irq(&s->common);
686
687 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
688 /* update deltas */
689 s->mouse_dx -= dx1;
690 s->mouse_dy -= dy1;
691 s->mouse_dz -= dz1;
692
693 return 1;
694 }
695
696 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
697 InputEvent *evt)
698 {
699 static const int bmap[INPUT_BUTTON__MAX] = {
700 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT,
701 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
702 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT,
703 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE,
704 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA,
705 };
706 PS2MouseState *s = (PS2MouseState *)dev;
707 InputMoveEvent *move;
708 InputBtnEvent *btn;
709
710 /* check if deltas are recorded when disabled */
711 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
712 return;
713
714 switch (evt->type) {
715 case INPUT_EVENT_KIND_REL:
716 move = evt->u.rel.data;
717 if (move->axis == INPUT_AXIS_X) {
718 s->mouse_dx += move->value;
719 } else if (move->axis == INPUT_AXIS_Y) {
720 s->mouse_dy -= move->value;
721 }
722 break;
723
724 case INPUT_EVENT_KIND_BTN:
725 btn = evt->u.btn.data;
726 if (btn->down) {
727 s->mouse_buttons |= bmap[btn->button];
728 if (btn->button == INPUT_BUTTON_WHEEL_UP) {
729 s->mouse_dz--;
730 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
731 s->mouse_dz++;
732 }
733 } else {
734 s->mouse_buttons &= ~bmap[btn->button];
735 }
736 break;
737
738 default:
739 /* keep gcc happy */
740 break;
741 }
742 }
743
744 static void ps2_mouse_sync(DeviceState *dev)
745 {
746 PS2MouseState *s = (PS2MouseState *)dev;
747
748 /* do not sync while disabled to prevent stream corruption */
749 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
750 return;
751 }
752
753 if (s->mouse_buttons) {
754 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
755 }
756 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
757 /* if not remote, send event. Multiple events are sent if
758 too big deltas */
759 while (ps2_mouse_send_packet(s)) {
760 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
761 break;
762 }
763 }
764 }
765
766 void ps2_mouse_fake_event(void *opaque)
767 {
768 PS2MouseState *s = opaque;
769 trace_ps2_mouse_fake_event(opaque);
770 s->mouse_dx++;
771 ps2_mouse_sync(opaque);
772 }
773
774 void ps2_write_mouse(void *opaque, int val)
775 {
776 PS2MouseState *s = (PS2MouseState *)opaque;
777
778 trace_ps2_write_mouse(opaque, val);
779 #ifdef DEBUG_MOUSE
780 printf("kbd: write mouse 0x%02x\n", val);
781 #endif
782 switch(s->common.write_cmd) {
783 default:
784 case -1:
785 /* mouse command */
786 if (s->mouse_wrap) {
787 if (val == AUX_RESET_WRAP) {
788 s->mouse_wrap = 0;
789 ps2_queue(&s->common, AUX_ACK);
790 return;
791 } else if (val != AUX_RESET) {
792 ps2_queue(&s->common, val);
793 return;
794 }
795 }
796 switch(val) {
797 case AUX_SET_SCALE11:
798 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
799 ps2_queue(&s->common, AUX_ACK);
800 break;
801 case AUX_SET_SCALE21:
802 s->mouse_status |= MOUSE_STATUS_SCALE21;
803 ps2_queue(&s->common, AUX_ACK);
804 break;
805 case AUX_SET_STREAM:
806 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
807 ps2_queue(&s->common, AUX_ACK);
808 break;
809 case AUX_SET_WRAP:
810 s->mouse_wrap = 1;
811 ps2_queue(&s->common, AUX_ACK);
812 break;
813 case AUX_SET_REMOTE:
814 s->mouse_status |= MOUSE_STATUS_REMOTE;
815 ps2_queue(&s->common, AUX_ACK);
816 break;
817 case AUX_GET_TYPE:
818 ps2_queue_2(&s->common,
819 AUX_ACK,
820 s->mouse_type);
821 break;
822 case AUX_SET_RES:
823 case AUX_SET_SAMPLE:
824 s->common.write_cmd = val;
825 ps2_queue(&s->common, AUX_ACK);
826 break;
827 case AUX_GET_SCALE:
828 ps2_queue_4(&s->common,
829 AUX_ACK,
830 s->mouse_status,
831 s->mouse_resolution,
832 s->mouse_sample_rate);
833 break;
834 case AUX_POLL:
835 ps2_queue(&s->common, AUX_ACK);
836 ps2_mouse_send_packet(s);
837 break;
838 case AUX_ENABLE_DEV:
839 s->mouse_status |= MOUSE_STATUS_ENABLED;
840 ps2_queue(&s->common, AUX_ACK);
841 break;
842 case AUX_DISABLE_DEV:
843 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
844 ps2_queue(&s->common, AUX_ACK);
845 break;
846 case AUX_SET_DEFAULT:
847 s->mouse_sample_rate = 100;
848 s->mouse_resolution = 2;
849 s->mouse_status = 0;
850 ps2_queue(&s->common, AUX_ACK);
851 break;
852 case AUX_RESET:
853 s->mouse_sample_rate = 100;
854 s->mouse_resolution = 2;
855 s->mouse_status = 0;
856 s->mouse_type = 0;
857 ps2_reset_queue(&s->common);
858 ps2_queue_3(&s->common,
859 AUX_ACK,
860 0xaa,
861 s->mouse_type);
862 break;
863 default:
864 break;
865 }
866 break;
867 case AUX_SET_SAMPLE:
868 s->mouse_sample_rate = val;
869 /* detect IMPS/2 or IMEX */
870 switch(s->mouse_detect_state) {
871 default:
872 case 0:
873 if (val == 200)
874 s->mouse_detect_state = 1;
875 break;
876 case 1:
877 if (val == 100)
878 s->mouse_detect_state = 2;
879 else if (val == 200)
880 s->mouse_detect_state = 3;
881 else
882 s->mouse_detect_state = 0;
883 break;
884 case 2:
885 if (val == 80)
886 s->mouse_type = 3; /* IMPS/2 */
887 s->mouse_detect_state = 0;
888 break;
889 case 3:
890 if (val == 80)
891 s->mouse_type = 4; /* IMEX */
892 s->mouse_detect_state = 0;
893 break;
894 }
895 ps2_queue(&s->common, AUX_ACK);
896 s->common.write_cmd = -1;
897 break;
898 case AUX_SET_RES:
899 s->mouse_resolution = val;
900 ps2_queue(&s->common, AUX_ACK);
901 s->common.write_cmd = -1;
902 break;
903 }
904 }
905
906 static void ps2_common_reset(PS2State *s)
907 {
908 s->write_cmd = -1;
909 ps2_reset_queue(s);
910 s->update_irq(s->update_arg, 0);
911 }
912
913 static void ps2_common_post_load(PS2State *s)
914 {
915 PS2Queue *q = &s->queue;
916 uint8_t i, size;
917 uint8_t tmp_data[PS2_QUEUE_SIZE];
918
919 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
920 size = q->count;
921 if (q->count < 0) {
922 size = 0;
923 } else if (q->count > PS2_QUEUE_SIZE) {
924 size = PS2_QUEUE_SIZE;
925 }
926
927 /* move the queue elements to the start of data array */
928 for (i = 0; i < size; i++) {
929 if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
930 q->rptr = 0;
931 }
932 tmp_data[i] = q->data[q->rptr++];
933 }
934 memcpy(q->data, tmp_data, size);
935
936 /* reset rptr/wptr/count */
937 q->rptr = 0;
938 q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
939 q->count = size;
940 }
941
942 static void ps2_kbd_reset(void *opaque)
943 {
944 PS2KbdState *s = (PS2KbdState *) opaque;
945
946 trace_ps2_kbd_reset(opaque);
947 ps2_common_reset(&s->common);
948 s->scan_enabled = 1;
949 s->translate = 0;
950 s->scancode_set = 2;
951 s->modifiers = 0;
952 }
953
954 static void ps2_mouse_reset(void *opaque)
955 {
956 PS2MouseState *s = (PS2MouseState *) opaque;
957
958 trace_ps2_mouse_reset(opaque);
959 ps2_common_reset(&s->common);
960 s->mouse_status = 0;
961 s->mouse_resolution = 0;
962 s->mouse_sample_rate = 0;
963 s->mouse_wrap = 0;
964 s->mouse_type = 0;
965 s->mouse_detect_state = 0;
966 s->mouse_dx = 0;
967 s->mouse_dy = 0;
968 s->mouse_dz = 0;
969 s->mouse_buttons = 0;
970 }
971
972 static const VMStateDescription vmstate_ps2_common = {
973 .name = "PS2 Common State",
974 .version_id = 3,
975 .minimum_version_id = 2,
976 .fields = (VMStateField[]) {
977 VMSTATE_INT32(write_cmd, PS2State),
978 VMSTATE_INT32(queue.rptr, PS2State),
979 VMSTATE_INT32(queue.wptr, PS2State),
980 VMSTATE_INT32(queue.count, PS2State),
981 VMSTATE_BUFFER(queue.data, PS2State),
982 VMSTATE_END_OF_LIST()
983 }
984 };
985
986 static bool ps2_keyboard_ledstate_needed(void *opaque)
987 {
988 PS2KbdState *s = opaque;
989
990 return s->ledstate != 0; /* 0 is default state */
991 }
992
993 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
994 {
995 PS2KbdState *s = opaque;
996
997 kbd_put_ledstate(s->ledstate);
998 return 0;
999 }
1000
1001 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1002 .name = "ps2kbd/ledstate",
1003 .version_id = 3,
1004 .minimum_version_id = 2,
1005 .post_load = ps2_kbd_ledstate_post_load,
1006 .needed = ps2_keyboard_ledstate_needed,
1007 .fields = (VMStateField[]) {
1008 VMSTATE_INT32(ledstate, PS2KbdState),
1009 VMSTATE_END_OF_LIST()
1010 }
1011 };
1012
1013 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1014 {
1015 PS2KbdState *s = opaque;
1016 return s->need_high_bit != 0; /* 0 is the usual state */
1017 }
1018
1019 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1020 .name = "ps2kbd/need_high_bit",
1021 .version_id = 1,
1022 .minimum_version_id = 1,
1023 .needed = ps2_keyboard_need_high_bit_needed,
1024 .fields = (VMStateField[]) {
1025 VMSTATE_BOOL(need_high_bit, PS2KbdState),
1026 VMSTATE_END_OF_LIST()
1027 }
1028 };
1029
1030 static int ps2_kbd_post_load(void* opaque, int version_id)
1031 {
1032 PS2KbdState *s = (PS2KbdState*)opaque;
1033 PS2State *ps2 = &s->common;
1034
1035 if (version_id == 2)
1036 s->scancode_set=2;
1037
1038 ps2_common_post_load(ps2);
1039
1040 return 0;
1041 }
1042
1043 static int ps2_kbd_pre_save(void *opaque)
1044 {
1045 PS2KbdState *s = (PS2KbdState *)opaque;
1046 PS2State *ps2 = &s->common;
1047
1048 ps2_common_post_load(ps2);
1049
1050 return 0;
1051 }
1052
1053 static const VMStateDescription vmstate_ps2_keyboard = {
1054 .name = "ps2kbd",
1055 .version_id = 3,
1056 .minimum_version_id = 2,
1057 .post_load = ps2_kbd_post_load,
1058 .pre_save = ps2_kbd_pre_save,
1059 .fields = (VMStateField[]) {
1060 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1061 VMSTATE_INT32(scan_enabled, PS2KbdState),
1062 VMSTATE_INT32(translate, PS2KbdState),
1063 VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1064 VMSTATE_END_OF_LIST()
1065 },
1066 .subsections = (const VMStateDescription*[]) {
1067 &vmstate_ps2_keyboard_ledstate,
1068 &vmstate_ps2_keyboard_need_high_bit,
1069 NULL
1070 }
1071 };
1072
1073 static int ps2_mouse_post_load(void *opaque, int version_id)
1074 {
1075 PS2MouseState *s = (PS2MouseState *)opaque;
1076 PS2State *ps2 = &s->common;
1077
1078 ps2_common_post_load(ps2);
1079
1080 return 0;
1081 }
1082
1083 static int ps2_mouse_pre_save(void *opaque)
1084 {
1085 PS2MouseState *s = (PS2MouseState *)opaque;
1086 PS2State *ps2 = &s->common;
1087
1088 ps2_common_post_load(ps2);
1089
1090 return 0;
1091 }
1092
1093 static const VMStateDescription vmstate_ps2_mouse = {
1094 .name = "ps2mouse",
1095 .version_id = 2,
1096 .minimum_version_id = 2,
1097 .post_load = ps2_mouse_post_load,
1098 .pre_save = ps2_mouse_pre_save,
1099 .fields = (VMStateField[]) {
1100 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1101 VMSTATE_UINT8(mouse_status, PS2MouseState),
1102 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1103 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1104 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1105 VMSTATE_UINT8(mouse_type, PS2MouseState),
1106 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1107 VMSTATE_INT32(mouse_dx, PS2MouseState),
1108 VMSTATE_INT32(mouse_dy, PS2MouseState),
1109 VMSTATE_INT32(mouse_dz, PS2MouseState),
1110 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1111 VMSTATE_END_OF_LIST()
1112 }
1113 };
1114
1115 static QemuInputHandler ps2_keyboard_handler = {
1116 .name = "QEMU PS/2 Keyboard",
1117 .mask = INPUT_EVENT_MASK_KEY,
1118 .event = ps2_keyboard_event,
1119 };
1120
1121 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1122 {
1123 PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1124
1125 trace_ps2_kbd_init(s);
1126 s->common.update_irq = update_irq;
1127 s->common.update_arg = update_arg;
1128 s->scancode_set = 2;
1129 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1130 qemu_input_handler_register((DeviceState *)s,
1131 &ps2_keyboard_handler);
1132 qemu_register_reset(ps2_kbd_reset, s);
1133 return s;
1134 }
1135
1136 static QemuInputHandler ps2_mouse_handler = {
1137 .name = "QEMU PS/2 Mouse",
1138 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1139 .event = ps2_mouse_event,
1140 .sync = ps2_mouse_sync,
1141 };
1142
1143 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1144 {
1145 PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1146
1147 trace_ps2_mouse_init(s);
1148 s->common.update_irq = update_irq;
1149 s->common.update_arg = update_arg;
1150 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1151 qemu_input_handler_register((DeviceState *)s,
1152 &ps2_mouse_handler);
1153 qemu_register_reset(ps2_mouse_reset, s);
1154 return s;
1155 }