2 * QEMU PS/2 keyboard/mouse emulation
4 * Copyright (c) 2003 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "qemu/osdep.h"
27 #include "hw/input/ps2.h"
28 #include "migration/vmstate.h"
29 #include "ui/console.h"
31 #include "sysemu/reset.h"
32 #include "sysemu/runstate.h"
36 /* Keyboard Commands */
37 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
38 #define KBD_CMD_ECHO 0xEE
39 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
40 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
41 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
42 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
43 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
44 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
45 #define KBD_CMD_RESET 0xFF /* Reset */
46 #define KBD_CMD_SET_MAKE_BREAK 0xFC /* Set Make and Break mode */
47 #define KBD_CMD_SET_TYPEMATIC 0xFA /* Set Typematic Make and Break mode */
49 /* Keyboard Replies */
50 #define KBD_REPLY_POR 0xAA /* Power on reset */
51 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
52 #define KBD_REPLY_ACK 0xFA /* Command ACK */
53 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
56 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
57 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
58 #define AUX_SET_RES 0xE8 /* Set resolution */
59 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
60 #define AUX_SET_STREAM 0xEA /* Set stream mode */
61 #define AUX_POLL 0xEB /* Poll */
62 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
63 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
64 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
65 #define AUX_GET_TYPE 0xF2 /* Get type */
66 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
67 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
68 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
69 #define AUX_SET_DEFAULT 0xF6
70 #define AUX_RESET 0xFF /* Reset aux device */
71 #define AUX_ACK 0xFA /* Command byte ACK. */
73 #define MOUSE_STATUS_REMOTE 0x40
74 #define MOUSE_STATUS_ENABLED 0x20
75 #define MOUSE_STATUS_SCALE21 0x10
78 * PS/2 buffer size. Keep 256 bytes for compatibility with
79 * older QEMU versions.
81 #define PS2_BUFFER_SIZE 256
82 #define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */
83 #define PS2_QUEUE_HEADROOM 8 /* Queue size for keyboard command replies */
85 /* Bits for 'modifiers' field in PS2KbdState */
86 #define MOD_CTRL_L (1 << 0)
87 #define MOD_SHIFT_L (1 << 1)
88 #define MOD_ALT_L (1 << 2)
89 #define MOD_CTRL_R (1 << 3)
90 #define MOD_SHIFT_R (1 << 4)
91 #define MOD_ALT_R (1 << 5)
94 uint8_t data[PS2_BUFFER_SIZE];
95 int rptr, wptr, cwptr, count;
101 void (*update_irq)(void *, int);
109 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
112 unsigned int modifiers; /* bitmask of MOD_* constants above */
117 uint8_t mouse_status;
118 uint8_t mouse_resolution;
119 uint8_t mouse_sample_rate;
121 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
122 uint8_t mouse_detect_state;
123 int mouse_dx; /* current values, needed for 'poll' mode */
127 uint8_t mouse_buttons;
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,
165 static unsigned int ps2_modifier_bit(QKeyCode key)
168 case Q_KEY_CODE_CTRL:
170 case Q_KEY_CODE_CTRL_R:
172 case Q_KEY_CODE_SHIFT:
174 case Q_KEY_CODE_SHIFT_R:
178 case Q_KEY_CODE_ALT_R:
185 static void ps2_reset_queue(PS2State *s)
187 PS2Queue *q = &s->queue;
195 int ps2_queue_empty(PS2State *s)
197 return s->queue.count == 0;
200 void ps2_queue_noirq(PS2State *s, int b)
202 PS2Queue *q = &s->queue;
204 if (q->count >= PS2_QUEUE_SIZE) {
208 q->data[q->wptr] = b;
209 if (++q->wptr == PS2_BUFFER_SIZE) {
215 void ps2_raise_irq(PS2State *s)
217 s->update_irq(s->update_arg, 1);
220 void ps2_queue(PS2State *s, int b)
222 if (PS2_QUEUE_SIZE - s->queue.count < 1) {
226 ps2_queue_noirq(s, b);
230 void ps2_queue_2(PS2State *s, int b1, int b2)
232 if (PS2_QUEUE_SIZE - s->queue.count < 2) {
236 ps2_queue_noirq(s, b1);
237 ps2_queue_noirq(s, b2);
241 void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
243 if (PS2_QUEUE_SIZE - s->queue.count < 3) {
247 ps2_queue_noirq(s, b1);
248 ps2_queue_noirq(s, b2);
249 ps2_queue_noirq(s, b3);
253 void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
255 if (PS2_QUEUE_SIZE - s->queue.count < 4) {
259 ps2_queue_noirq(s, b1);
260 ps2_queue_noirq(s, b2);
261 ps2_queue_noirq(s, b3);
262 ps2_queue_noirq(s, b4);
266 static void ps2_cqueue_data(PS2Queue *q, int b)
268 q->data[q->cwptr] = b;
269 if (++q->cwptr >= PS2_BUFFER_SIZE) {
275 static void ps2_cqueue_1(PS2State *s, int b1)
277 PS2Queue *q = &s->queue;
279 q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1);
281 ps2_cqueue_data(q, b1);
285 static void ps2_cqueue_2(PS2State *s, int b1, int b2)
287 PS2Queue *q = &s->queue;
289 q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1);
291 ps2_cqueue_data(q, b1);
292 ps2_cqueue_data(q, b2);
296 static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3)
298 PS2Queue *q = &s->queue;
300 q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1);
302 ps2_cqueue_data(q, b1);
303 ps2_cqueue_data(q, b2);
304 ps2_cqueue_data(q, b3);
308 static void ps2_cqueue_reset(PS2State *s)
310 PS2Queue *q = &s->queue;
313 if (q->cwptr == -1) {
317 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
323 /* keycode is the untranslated scancode in the current scancode set. */
324 static void ps2_put_keycode(void *opaque, int keycode)
326 PS2KbdState *s = opaque;
328 trace_ps2_put_keycode(opaque, keycode);
329 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
332 if (keycode == 0xf0) {
333 s->need_high_bit = true;
334 } else if (s->need_high_bit) {
335 ps2_queue(&s->common, translate_table[keycode] | 0x80);
336 s->need_high_bit = false;
338 ps2_queue(&s->common, translate_table[keycode]);
341 ps2_queue(&s->common, keycode);
345 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
348 PS2KbdState *s = (PS2KbdState *)dev;
349 InputKeyEvent *key = evt->u.key.data;
351 uint16_t keycode = 0;
354 /* do not process events while disabled to prevent stream corruption */
355 if (!s->scan_enabled) {
359 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
360 assert(evt->type == INPUT_EVENT_KIND_KEY);
361 qcode = qemu_input_key_value_to_qcode(key->key);
363 mod = ps2_modifier_bit(qcode);
364 trace_ps2_keyboard_event(s, qcode, key->down, mod,
365 s->modifiers, s->scancode_set, s->translate);
369 s->modifiers &= ~mod;
372 if (s->scancode_set == 1) {
373 if (qcode == Q_KEY_CODE_PAUSE) {
374 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
376 ps2_put_keycode(s, 0xe0);
377 ps2_put_keycode(s, 0x46);
378 ps2_put_keycode(s, 0xe0);
379 ps2_put_keycode(s, 0xc6);
383 ps2_put_keycode(s, 0xe1);
384 ps2_put_keycode(s, 0x1d);
385 ps2_put_keycode(s, 0x45);
386 ps2_put_keycode(s, 0xe1);
387 ps2_put_keycode(s, 0x9d);
388 ps2_put_keycode(s, 0xc5);
391 } else if (qcode == Q_KEY_CODE_PRINT) {
392 if (s->modifiers & MOD_ALT_L) {
394 ps2_put_keycode(s, 0xb8);
395 ps2_put_keycode(s, 0x38);
396 ps2_put_keycode(s, 0x54);
398 ps2_put_keycode(s, 0xd4);
399 ps2_put_keycode(s, 0xb8);
400 ps2_put_keycode(s, 0x38);
402 } else if (s->modifiers & MOD_ALT_R) {
404 ps2_put_keycode(s, 0xe0);
405 ps2_put_keycode(s, 0xb8);
406 ps2_put_keycode(s, 0xe0);
407 ps2_put_keycode(s, 0x38);
408 ps2_put_keycode(s, 0x54);
410 ps2_put_keycode(s, 0xd4);
411 ps2_put_keycode(s, 0xe0);
412 ps2_put_keycode(s, 0xb8);
413 ps2_put_keycode(s, 0xe0);
414 ps2_put_keycode(s, 0x38);
416 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
417 MOD_SHIFT_R | MOD_CTRL_R)) {
419 ps2_put_keycode(s, 0xe0);
420 ps2_put_keycode(s, 0x37);
422 ps2_put_keycode(s, 0xe0);
423 ps2_put_keycode(s, 0xb7);
427 ps2_put_keycode(s, 0xe0);
428 ps2_put_keycode(s, 0x2a);
429 ps2_put_keycode(s, 0xe0);
430 ps2_put_keycode(s, 0x37);
432 ps2_put_keycode(s, 0xe0);
433 ps2_put_keycode(s, 0xb7);
434 ps2_put_keycode(s, 0xe0);
435 ps2_put_keycode(s, 0xaa);
439 if (qcode < qemu_input_map_qcode_to_atset1_len)
440 keycode = qemu_input_map_qcode_to_atset1[qcode];
442 if (keycode & 0xff00) {
443 ps2_put_keycode(s, keycode >> 8);
448 ps2_put_keycode(s, keycode & 0xff);
450 qemu_log_mask(LOG_UNIMP,
451 "ps2: ignoring key with qcode %d\n", qcode);
454 } else if (s->scancode_set == 2) {
455 if (qcode == Q_KEY_CODE_PAUSE) {
456 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
458 ps2_put_keycode(s, 0xe0);
459 ps2_put_keycode(s, 0x7e);
460 ps2_put_keycode(s, 0xe0);
461 ps2_put_keycode(s, 0xf0);
462 ps2_put_keycode(s, 0x7e);
466 ps2_put_keycode(s, 0xe1);
467 ps2_put_keycode(s, 0x14);
468 ps2_put_keycode(s, 0x77);
469 ps2_put_keycode(s, 0xe1);
470 ps2_put_keycode(s, 0xf0);
471 ps2_put_keycode(s, 0x14);
472 ps2_put_keycode(s, 0xf0);
473 ps2_put_keycode(s, 0x77);
476 } else if (qcode == Q_KEY_CODE_PRINT) {
477 if (s->modifiers & MOD_ALT_L) {
479 ps2_put_keycode(s, 0xf0);
480 ps2_put_keycode(s, 0x11);
481 ps2_put_keycode(s, 0x11);
482 ps2_put_keycode(s, 0x84);
484 ps2_put_keycode(s, 0xf0);
485 ps2_put_keycode(s, 0x84);
486 ps2_put_keycode(s, 0xf0);
487 ps2_put_keycode(s, 0x11);
488 ps2_put_keycode(s, 0x11);
490 } else if (s->modifiers & MOD_ALT_R) {
492 ps2_put_keycode(s, 0xe0);
493 ps2_put_keycode(s, 0xf0);
494 ps2_put_keycode(s, 0x11);
495 ps2_put_keycode(s, 0xe0);
496 ps2_put_keycode(s, 0x11);
497 ps2_put_keycode(s, 0x84);
499 ps2_put_keycode(s, 0xf0);
500 ps2_put_keycode(s, 0x84);
501 ps2_put_keycode(s, 0xe0);
502 ps2_put_keycode(s, 0xf0);
503 ps2_put_keycode(s, 0x11);
504 ps2_put_keycode(s, 0xe0);
505 ps2_put_keycode(s, 0x11);
507 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
508 MOD_SHIFT_R | MOD_CTRL_R)) {
510 ps2_put_keycode(s, 0xe0);
511 ps2_put_keycode(s, 0x7c);
513 ps2_put_keycode(s, 0xe0);
514 ps2_put_keycode(s, 0xf0);
515 ps2_put_keycode(s, 0x7c);
519 ps2_put_keycode(s, 0xe0);
520 ps2_put_keycode(s, 0x12);
521 ps2_put_keycode(s, 0xe0);
522 ps2_put_keycode(s, 0x7c);
524 ps2_put_keycode(s, 0xe0);
525 ps2_put_keycode(s, 0xf0);
526 ps2_put_keycode(s, 0x7c);
527 ps2_put_keycode(s, 0xe0);
528 ps2_put_keycode(s, 0xf0);
529 ps2_put_keycode(s, 0x12);
533 if (qcode < qemu_input_map_qcode_to_atset2_len)
534 keycode = qemu_input_map_qcode_to_atset2[qcode];
536 if (keycode & 0xff00) {
537 ps2_put_keycode(s, keycode >> 8);
540 ps2_put_keycode(s, 0xf0);
542 ps2_put_keycode(s, keycode & 0xff);
544 qemu_log_mask(LOG_UNIMP,
545 "ps2: ignoring key with qcode %d\n", qcode);
548 } else if (s->scancode_set == 3) {
549 if (qcode < qemu_input_map_qcode_to_atset3_len)
550 keycode = qemu_input_map_qcode_to_atset3[qcode];
552 /* FIXME: break code should be configured on a key by key basis */
554 ps2_put_keycode(s, 0xf0);
556 ps2_put_keycode(s, keycode);
558 qemu_log_mask(LOG_UNIMP,
559 "ps2: ignoring key with qcode %d\n", qcode);
564 uint32_t ps2_read_data(PS2State *s)
569 trace_ps2_read_data(s);
572 /* NOTE: if no data left, we return the last keyboard one
573 (needed for EMM386) */
574 /* XXX: need a timer to do things correctly */
577 index = PS2_BUFFER_SIZE - 1;
579 val = q->data[index];
581 val = q->data[q->rptr];
582 if (++q->rptr == PS2_BUFFER_SIZE) {
586 if (q->rptr == q->cwptr) {
587 /* command reply queue is empty */
590 /* reading deasserts IRQ */
591 s->update_irq(s->update_arg, 0);
592 /* reassert IRQs if data left */
594 s->update_irq(s->update_arg, 1);
600 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
602 trace_ps2_set_ledstate(s, ledstate);
603 s->ledstate = ledstate;
604 kbd_put_ledstate(ledstate);
607 static void ps2_reset_keyboard(PS2KbdState *s)
609 trace_ps2_reset_keyboard(s);
612 ps2_reset_queue(&s->common);
613 ps2_set_ledstate(s, 0);
616 void ps2_write_keyboard(void *opaque, int val)
618 PS2KbdState *s = (PS2KbdState *)opaque;
620 trace_ps2_write_keyboard(opaque, val);
621 ps2_cqueue_reset(&s->common);
622 switch(s->common.write_cmd) {
627 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
630 ps2_cqueue_1(&s->common, KBD_REPLY_RESEND);
633 /* We emulate a MF2 AT keyboard here */
634 ps2_cqueue_3(&s->common, KBD_REPLY_ACK, KBD_REPLY_ID,
635 s->translate ? 0x41 : 0x83);
638 ps2_cqueue_1(&s->common, KBD_CMD_ECHO);
642 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
644 case KBD_CMD_SCANCODE:
645 case KBD_CMD_SET_LEDS:
646 case KBD_CMD_SET_RATE:
647 case KBD_CMD_SET_MAKE_BREAK:
648 s->common.write_cmd = val;
649 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
651 case KBD_CMD_RESET_DISABLE:
652 ps2_reset_keyboard(s);
654 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
656 case KBD_CMD_RESET_ENABLE:
657 ps2_reset_keyboard(s);
659 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
662 ps2_reset_keyboard(s);
663 ps2_cqueue_2(&s->common,
667 case KBD_CMD_SET_TYPEMATIC:
668 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
671 ps2_cqueue_1(&s->common, KBD_REPLY_RESEND);
675 case KBD_CMD_SET_MAKE_BREAK:
676 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
677 s->common.write_cmd = -1;
679 case KBD_CMD_SCANCODE:
681 ps2_cqueue_2(&s->common, KBD_REPLY_ACK, s->translate ?
682 translate_table[s->scancode_set] : s->scancode_set);
683 } else if (val >= 1 && val <= 3) {
684 s->scancode_set = val;
685 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
687 ps2_cqueue_1(&s->common, KBD_REPLY_RESEND);
689 s->common.write_cmd = -1;
691 case KBD_CMD_SET_LEDS:
692 ps2_set_ledstate(s, val);
693 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
694 s->common.write_cmd = -1;
696 case KBD_CMD_SET_RATE:
697 ps2_cqueue_1(&s->common, KBD_REPLY_ACK);
698 s->common.write_cmd = -1;
703 /* Set the scancode translation mode.
705 1 = translated scancodes (used by qemu internally). */
707 void ps2_keyboard_set_translation(void *opaque, int mode)
709 PS2KbdState *s = (PS2KbdState *)opaque;
710 trace_ps2_keyboard_set_translation(opaque, mode);
714 static int ps2_mouse_send_packet(PS2MouseState *s)
716 /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */
717 const int needed = s->mouse_type ? 4 : 3;
719 int dx1, dy1, dz1, dw1;
721 if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
729 /* XXX: increase range to 8 bits ? */
738 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
739 ps2_queue_noirq(&s->common, b);
740 ps2_queue_noirq(&s->common, dx1 & 0xff);
741 ps2_queue_noirq(&s->common, dy1 & 0xff);
742 /* extra byte for IMPS/2 or IMEX */
743 switch(s->mouse_type) {
745 /* Just ignore the wheels if not supported */
754 ps2_queue_noirq(&s->common, dz1 & 0xff);
760 * This matches what the Linux kernel expects for exps/2 in
761 * drivers/input/mouse/psmouse-base.c. Note, if you happen to
762 * press/release the 4th or 5th buttons at the same moment as a
763 * horizontal wheel scroll, those button presses will get lost. I'm not
764 * sure what to do about that, since by this point we don't know
765 * whether those buttons actually changed state.
770 } else if (dw1 < -31) {
775 * linux kernel expects first 6 bits to represent the value
776 * for horizontal scroll
778 b = (dw1 & 0x3f) | 0x40;
783 } else if (dz1 < -7) {
787 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
790 ps2_queue_noirq(&s->common, b);
794 ps2_raise_irq(&s->common);
796 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
804 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
807 static const int bmap[INPUT_BUTTON__MAX] = {
808 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT,
809 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
810 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT,
811 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE,
812 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA,
814 PS2MouseState *s = (PS2MouseState *)dev;
815 InputMoveEvent *move;
818 /* check if deltas are recorded when disabled */
819 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
823 case INPUT_EVENT_KIND_REL:
824 move = evt->u.rel.data;
825 if (move->axis == INPUT_AXIS_X) {
826 s->mouse_dx += move->value;
827 } else if (move->axis == INPUT_AXIS_Y) {
828 s->mouse_dy -= move->value;
832 case INPUT_EVENT_KIND_BTN:
833 btn = evt->u.btn.data;
835 s->mouse_buttons |= bmap[btn->button];
836 if (btn->button == INPUT_BUTTON_WHEEL_UP) {
838 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
842 if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) {
844 } else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) {
848 s->mouse_buttons &= ~bmap[btn->button];
858 static void ps2_mouse_sync(DeviceState *dev)
860 PS2MouseState *s = (PS2MouseState *)dev;
862 /* do not sync while disabled to prevent stream corruption */
863 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
867 if (s->mouse_buttons) {
868 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL);
870 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
871 /* if not remote, send event. Multiple events are sent if
873 while (ps2_mouse_send_packet(s)) {
874 if (s->mouse_dx == 0 && s->mouse_dy == 0
875 && s->mouse_dz == 0 && s->mouse_dw == 0) {
882 void ps2_mouse_fake_event(void *opaque)
884 PS2MouseState *s = opaque;
885 trace_ps2_mouse_fake_event(opaque);
887 ps2_mouse_sync(opaque);
890 void ps2_write_mouse(void *opaque, int val)
892 PS2MouseState *s = (PS2MouseState *)opaque;
894 trace_ps2_write_mouse(opaque, val);
895 switch(s->common.write_cmd) {
900 if (val == AUX_RESET_WRAP) {
902 ps2_queue(&s->common, AUX_ACK);
904 } else if (val != AUX_RESET) {
905 ps2_queue(&s->common, val);
910 case AUX_SET_SCALE11:
911 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
912 ps2_queue(&s->common, AUX_ACK);
914 case AUX_SET_SCALE21:
915 s->mouse_status |= MOUSE_STATUS_SCALE21;
916 ps2_queue(&s->common, AUX_ACK);
919 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
920 ps2_queue(&s->common, AUX_ACK);
924 ps2_queue(&s->common, AUX_ACK);
927 s->mouse_status |= MOUSE_STATUS_REMOTE;
928 ps2_queue(&s->common, AUX_ACK);
931 ps2_queue_2(&s->common,
937 s->common.write_cmd = val;
938 ps2_queue(&s->common, AUX_ACK);
941 ps2_queue_4(&s->common,
945 s->mouse_sample_rate);
948 ps2_queue(&s->common, AUX_ACK);
949 ps2_mouse_send_packet(s);
952 s->mouse_status |= MOUSE_STATUS_ENABLED;
953 ps2_queue(&s->common, AUX_ACK);
955 case AUX_DISABLE_DEV:
956 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
957 ps2_queue(&s->common, AUX_ACK);
959 case AUX_SET_DEFAULT:
960 s->mouse_sample_rate = 100;
961 s->mouse_resolution = 2;
963 ps2_queue(&s->common, AUX_ACK);
966 s->mouse_sample_rate = 100;
967 s->mouse_resolution = 2;
970 ps2_reset_queue(&s->common);
971 ps2_queue_3(&s->common,
981 s->mouse_sample_rate = val;
982 /* detect IMPS/2 or IMEX */
983 switch(s->mouse_detect_state) {
987 s->mouse_detect_state = 1;
991 s->mouse_detect_state = 2;
993 s->mouse_detect_state = 3;
995 s->mouse_detect_state = 0;
999 s->mouse_type = 3; /* IMPS/2 */
1000 s->mouse_detect_state = 0;
1004 s->mouse_type = 4; /* IMEX */
1005 s->mouse_detect_state = 0;
1008 ps2_queue(&s->common, AUX_ACK);
1009 s->common.write_cmd = -1;
1012 s->mouse_resolution = val;
1013 ps2_queue(&s->common, AUX_ACK);
1014 s->common.write_cmd = -1;
1019 static void ps2_common_reset(PS2State *s)
1023 s->update_irq(s->update_arg, 0);
1026 static void ps2_common_post_load(PS2State *s)
1028 PS2Queue *q = &s->queue;
1031 /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */
1032 if (q->cwptr != -1) {
1033 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1);
1034 if (ccount > PS2_QUEUE_HEADROOM) {
1035 ccount = PS2_QUEUE_HEADROOM;
1039 /* limit the scancode queue size to PS2_QUEUE_SIZE */
1040 if (q->count < ccount) {
1042 } else if (q->count > ccount + PS2_QUEUE_SIZE) {
1043 q->count = ccount + PS2_QUEUE_SIZE;
1046 /* sanitize rptr and recalculate wptr and cwptr */
1047 q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1);
1048 q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1);
1049 q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1;
1052 static void ps2_kbd_reset(void *opaque)
1054 PS2KbdState *s = (PS2KbdState *) opaque;
1056 trace_ps2_kbd_reset(opaque);
1057 ps2_common_reset(&s->common);
1058 s->scan_enabled = 1;
1060 s->scancode_set = 2;
1064 static void ps2_mouse_reset(void *opaque)
1066 PS2MouseState *s = (PS2MouseState *) opaque;
1068 trace_ps2_mouse_reset(opaque);
1069 ps2_common_reset(&s->common);
1070 s->mouse_status = 0;
1071 s->mouse_resolution = 0;
1072 s->mouse_sample_rate = 0;
1075 s->mouse_detect_state = 0;
1080 s->mouse_buttons = 0;
1083 static const VMStateDescription vmstate_ps2_common = {
1084 .name = "PS2 Common State",
1086 .minimum_version_id = 2,
1087 .fields = (VMStateField[]) {
1088 VMSTATE_INT32(write_cmd, PS2State),
1089 VMSTATE_INT32(queue.rptr, PS2State),
1090 VMSTATE_INT32(queue.wptr, PS2State),
1091 VMSTATE_INT32(queue.count, PS2State),
1092 VMSTATE_BUFFER(queue.data, PS2State),
1093 VMSTATE_END_OF_LIST()
1097 static bool ps2_keyboard_ledstate_needed(void *opaque)
1099 PS2KbdState *s = opaque;
1101 return s->ledstate != 0; /* 0 is default state */
1104 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
1106 PS2KbdState *s = opaque;
1108 kbd_put_ledstate(s->ledstate);
1112 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
1113 .name = "ps2kbd/ledstate",
1115 .minimum_version_id = 2,
1116 .post_load = ps2_kbd_ledstate_post_load,
1117 .needed = ps2_keyboard_ledstate_needed,
1118 .fields = (VMStateField[]) {
1119 VMSTATE_INT32(ledstate, PS2KbdState),
1120 VMSTATE_END_OF_LIST()
1124 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1126 PS2KbdState *s = opaque;
1127 return s->need_high_bit != 0; /* 0 is the usual state */
1130 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1131 .name = "ps2kbd/need_high_bit",
1133 .minimum_version_id = 1,
1134 .needed = ps2_keyboard_need_high_bit_needed,
1135 .fields = (VMStateField[]) {
1136 VMSTATE_BOOL(need_high_bit, PS2KbdState),
1137 VMSTATE_END_OF_LIST()
1141 static bool ps2_keyboard_cqueue_needed(void *opaque)
1143 PS2KbdState *s = opaque;
1145 return s->common.queue.cwptr != -1; /* the queue is mostly empty */
1148 static const VMStateDescription vmstate_ps2_keyboard_cqueue = {
1149 .name = "ps2kbd/command_reply_queue",
1150 .needed = ps2_keyboard_cqueue_needed,
1151 .fields = (VMStateField[]) {
1152 VMSTATE_INT32(common.queue.cwptr, PS2KbdState),
1153 VMSTATE_END_OF_LIST()
1157 static int ps2_kbd_post_load(void* opaque, int version_id)
1159 PS2KbdState *s = (PS2KbdState*)opaque;
1160 PS2State *ps2 = &s->common;
1162 if (version_id == 2)
1165 ps2_common_post_load(ps2);
1170 static const VMStateDescription vmstate_ps2_keyboard = {
1173 .minimum_version_id = 2,
1174 .post_load = ps2_kbd_post_load,
1175 .fields = (VMStateField[]) {
1176 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1177 VMSTATE_INT32(scan_enabled, PS2KbdState),
1178 VMSTATE_INT32(translate, PS2KbdState),
1179 VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1180 VMSTATE_END_OF_LIST()
1182 .subsections = (const VMStateDescription*[]) {
1183 &vmstate_ps2_keyboard_ledstate,
1184 &vmstate_ps2_keyboard_need_high_bit,
1185 &vmstate_ps2_keyboard_cqueue,
1190 static int ps2_mouse_post_load(void *opaque, int version_id)
1192 PS2MouseState *s = (PS2MouseState *)opaque;
1193 PS2State *ps2 = &s->common;
1195 ps2_common_post_load(ps2);
1200 static const VMStateDescription vmstate_ps2_mouse = {
1203 .minimum_version_id = 2,
1204 .post_load = ps2_mouse_post_load,
1205 .fields = (VMStateField[]) {
1206 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1207 VMSTATE_UINT8(mouse_status, PS2MouseState),
1208 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1209 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1210 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1211 VMSTATE_UINT8(mouse_type, PS2MouseState),
1212 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1213 VMSTATE_INT32(mouse_dx, PS2MouseState),
1214 VMSTATE_INT32(mouse_dy, PS2MouseState),
1215 VMSTATE_INT32(mouse_dz, PS2MouseState),
1216 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1217 VMSTATE_END_OF_LIST()
1221 static QemuInputHandler ps2_keyboard_handler = {
1222 .name = "QEMU PS/2 Keyboard",
1223 .mask = INPUT_EVENT_MASK_KEY,
1224 .event = ps2_keyboard_event,
1227 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1229 PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1231 trace_ps2_kbd_init(s);
1232 s->common.update_irq = update_irq;
1233 s->common.update_arg = update_arg;
1234 s->scancode_set = 2;
1235 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1236 qemu_input_handler_register((DeviceState *)s,
1237 &ps2_keyboard_handler);
1238 qemu_register_reset(ps2_kbd_reset, s);
1242 static QemuInputHandler ps2_mouse_handler = {
1243 .name = "QEMU PS/2 Mouse",
1244 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1245 .event = ps2_mouse_event,
1246 .sync = ps2_mouse_sync,
1249 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1251 PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1253 trace_ps2_mouse_init(s);
1254 s->common.update_irq = update_irq;
1255 s->common.update_arg = update_arg;
1256 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1257 qemu_input_handler_register((DeviceState *)s,
1258 &ps2_mouse_handler);
1259 qemu_register_reset(ps2_mouse_reset, s);