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
24 #include "qemu/osdep.h"
27 #include "hw/input/ps2.h"
28 #include "ui/console.h"
30 #include "sysemu/sysemu.h"
34 /* debug PC keyboard */
37 /* debug PC keyboard : only mouse */
40 /* Keyboard Commands */
41 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
42 #define KBD_CMD_ECHO 0xEE
43 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
44 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
45 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
46 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
47 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
48 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
49 #define KBD_CMD_RESET 0xFF /* Reset */
51 /* Keyboard Replies */
52 #define KBD_REPLY_POR 0xAA /* Power on reset */
53 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
54 #define KBD_REPLY_ACK 0xFA /* Command ACK */
55 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
58 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
59 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
60 #define AUX_SET_RES 0xE8 /* Set resolution */
61 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
62 #define AUX_SET_STREAM 0xEA /* Set stream mode */
63 #define AUX_POLL 0xEB /* Poll */
64 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
65 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
66 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
67 #define AUX_GET_TYPE 0xF2 /* Get type */
68 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
69 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
70 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
71 #define AUX_SET_DEFAULT 0xF6
72 #define AUX_RESET 0xFF /* Reset aux device */
73 #define AUX_ACK 0xFA /* Command byte ACK. */
75 #define MOUSE_STATUS_REMOTE 0x40
76 #define MOUSE_STATUS_ENABLED 0x20
77 #define MOUSE_STATUS_SCALE21 0x10
79 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
81 /* Bits for 'modifiers' field in PS2KbdState */
82 #define MOD_CTRL_L (1 << 0)
83 #define MOD_SHIFT_L (1 << 1)
84 #define MOD_ALT_L (1 << 2)
85 #define MOD_CTRL_R (1 << 3)
86 #define MOD_SHIFT_R (1 << 4)
87 #define MOD_ALT_R (1 << 5)
90 /* Keep the data array 256 bytes long, which compatibility
91 with older qemu versions. */
93 int rptr, wptr, count;
99 void (*update_irq)(void *, int);
107 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
110 unsigned int modifiers; /* bitmask of MOD_* constants above */
115 uint8_t mouse_status;
116 uint8_t mouse_resolution;
117 uint8_t mouse_sample_rate;
119 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
120 uint8_t mouse_detect_state;
121 int mouse_dx; /* current values, needed for 'poll' mode */
124 uint8_t mouse_buttons;
127 static uint8_t translate_table[256] = {
128 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
129 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
130 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
131 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
132 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
133 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
134 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
135 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
136 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
137 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
138 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
139 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
140 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
141 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
142 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
143 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
144 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
145 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
146 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
147 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
148 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
149 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
150 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
151 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
152 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
153 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
154 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
155 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
156 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
157 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
158 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
159 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
162 static unsigned int ps2_modifier_bit(QKeyCode key)
165 case Q_KEY_CODE_CTRL:
167 case Q_KEY_CODE_CTRL_R:
169 case Q_KEY_CODE_SHIFT:
171 case Q_KEY_CODE_SHIFT_R:
175 case Q_KEY_CODE_ALT_R:
182 static void ps2_reset_queue(PS2State *s)
184 PS2Queue *q = &s->queue;
191 void ps2_queue(PS2State *s, int b)
193 PS2Queue *q = &s->queue;
195 if (q->count >= PS2_QUEUE_SIZE - 1)
197 q->data[q->wptr] = b;
198 if (++q->wptr == PS2_QUEUE_SIZE)
201 s->update_irq(s->update_arg, 1);
204 /* keycode is the untranslated scancode in the current scancode set. */
205 static void ps2_put_keycode(void *opaque, int keycode)
207 PS2KbdState *s = opaque;
209 trace_ps2_put_keycode(opaque, keycode);
210 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
213 if (keycode == 0xf0) {
214 s->need_high_bit = true;
215 } else if (s->need_high_bit) {
216 ps2_queue(&s->common, translate_table[keycode] | 0x80);
217 s->need_high_bit = false;
219 ps2_queue(&s->common, translate_table[keycode]);
222 ps2_queue(&s->common, keycode);
226 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
229 PS2KbdState *s = (PS2KbdState *)dev;
230 InputKeyEvent *key = evt->u.key.data;
232 uint16_t keycode = 0;
235 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
236 assert(evt->type == INPUT_EVENT_KIND_KEY);
237 qcode = qemu_input_key_value_to_qcode(key->key);
239 mod = ps2_modifier_bit(qcode);
240 trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
244 s->modifiers &= ~mod;
247 if (s->scancode_set == 1) {
248 if (qcode == Q_KEY_CODE_PAUSE) {
249 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
251 ps2_put_keycode(s, 0xe0);
252 ps2_put_keycode(s, 0x46);
253 ps2_put_keycode(s, 0xe0);
254 ps2_put_keycode(s, 0xc6);
258 ps2_put_keycode(s, 0xe1);
259 ps2_put_keycode(s, 0x1d);
260 ps2_put_keycode(s, 0x45);
261 ps2_put_keycode(s, 0xe1);
262 ps2_put_keycode(s, 0x9d);
263 ps2_put_keycode(s, 0xc5);
266 } else if (qcode == Q_KEY_CODE_PRINT) {
267 if (s->modifiers & MOD_ALT_L) {
269 ps2_put_keycode(s, 0xb8);
270 ps2_put_keycode(s, 0x38);
271 ps2_put_keycode(s, 0x54);
273 ps2_put_keycode(s, 0xd4);
274 ps2_put_keycode(s, 0xb8);
275 ps2_put_keycode(s, 0x38);
277 } else if (s->modifiers & MOD_ALT_R) {
279 ps2_put_keycode(s, 0xe0);
280 ps2_put_keycode(s, 0xb8);
281 ps2_put_keycode(s, 0xe0);
282 ps2_put_keycode(s, 0x38);
283 ps2_put_keycode(s, 0x54);
285 ps2_put_keycode(s, 0xd4);
286 ps2_put_keycode(s, 0xe0);
287 ps2_put_keycode(s, 0xb8);
288 ps2_put_keycode(s, 0xe0);
289 ps2_put_keycode(s, 0x38);
291 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
292 MOD_SHIFT_R | MOD_CTRL_R)) {
294 ps2_put_keycode(s, 0xe0);
295 ps2_put_keycode(s, 0x37);
297 ps2_put_keycode(s, 0xe0);
298 ps2_put_keycode(s, 0xb7);
302 ps2_put_keycode(s, 0xe0);
303 ps2_put_keycode(s, 0x2a);
304 ps2_put_keycode(s, 0xe0);
305 ps2_put_keycode(s, 0x37);
307 ps2_put_keycode(s, 0xe0);
308 ps2_put_keycode(s, 0xb7);
309 ps2_put_keycode(s, 0xe0);
310 ps2_put_keycode(s, 0xaa);
314 if (qcode < qemu_input_map_qcode_to_atset1_len)
315 keycode = qemu_input_map_qcode_to_atset1[qcode];
317 if (keycode & 0xff00) {
318 ps2_put_keycode(s, keycode >> 8);
323 ps2_put_keycode(s, keycode & 0xff);
325 qemu_log_mask(LOG_UNIMP,
326 "ps2: ignoring key with qcode %d\n", qcode);
329 } else if (s->scancode_set == 2) {
330 if (qcode == Q_KEY_CODE_PAUSE) {
331 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
333 ps2_put_keycode(s, 0xe0);
334 ps2_put_keycode(s, 0x7e);
335 ps2_put_keycode(s, 0xe0);
336 ps2_put_keycode(s, 0xf0);
337 ps2_put_keycode(s, 0x7e);
341 ps2_put_keycode(s, 0xe1);
342 ps2_put_keycode(s, 0x14);
343 ps2_put_keycode(s, 0x77);
344 ps2_put_keycode(s, 0xe1);
345 ps2_put_keycode(s, 0xf0);
346 ps2_put_keycode(s, 0x14);
347 ps2_put_keycode(s, 0xf0);
348 ps2_put_keycode(s, 0x77);
351 } else if (qcode == Q_KEY_CODE_PRINT) {
352 if (s->modifiers & MOD_ALT_L) {
354 ps2_put_keycode(s, 0xf0);
355 ps2_put_keycode(s, 0x11);
356 ps2_put_keycode(s, 0x11);
357 ps2_put_keycode(s, 0x84);
359 ps2_put_keycode(s, 0xf0);
360 ps2_put_keycode(s, 0x84);
361 ps2_put_keycode(s, 0xf0);
362 ps2_put_keycode(s, 0x11);
363 ps2_put_keycode(s, 0x11);
365 } else if (s->modifiers & MOD_ALT_R) {
367 ps2_put_keycode(s, 0xe0);
368 ps2_put_keycode(s, 0xf0);
369 ps2_put_keycode(s, 0x11);
370 ps2_put_keycode(s, 0xe0);
371 ps2_put_keycode(s, 0x11);
372 ps2_put_keycode(s, 0x84);
374 ps2_put_keycode(s, 0xf0);
375 ps2_put_keycode(s, 0x84);
376 ps2_put_keycode(s, 0xe0);
377 ps2_put_keycode(s, 0xf0);
378 ps2_put_keycode(s, 0x11);
379 ps2_put_keycode(s, 0xe0);
380 ps2_put_keycode(s, 0x11);
382 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
383 MOD_SHIFT_R | MOD_CTRL_R)) {
385 ps2_put_keycode(s, 0xe0);
386 ps2_put_keycode(s, 0x7c);
388 ps2_put_keycode(s, 0xe0);
389 ps2_put_keycode(s, 0xf0);
390 ps2_put_keycode(s, 0x7c);
394 ps2_put_keycode(s, 0xe0);
395 ps2_put_keycode(s, 0x12);
396 ps2_put_keycode(s, 0xe0);
397 ps2_put_keycode(s, 0x7c);
399 ps2_put_keycode(s, 0xe0);
400 ps2_put_keycode(s, 0xf0);
401 ps2_put_keycode(s, 0x7c);
402 ps2_put_keycode(s, 0xe0);
403 ps2_put_keycode(s, 0xf0);
404 ps2_put_keycode(s, 0x12);
408 if (qcode < qemu_input_map_qcode_to_atset2_len)
409 keycode = qemu_input_map_qcode_to_atset2[qcode];
411 if (keycode & 0xff00) {
412 ps2_put_keycode(s, keycode >> 8);
415 ps2_put_keycode(s, 0xf0);
417 ps2_put_keycode(s, keycode & 0xff);
419 qemu_log_mask(LOG_UNIMP,
420 "ps2: ignoring key with qcode %d\n", qcode);
423 } else if (s->scancode_set == 3) {
424 if (qcode < qemu_input_map_qcode_to_atset3_len)
425 keycode = qemu_input_map_qcode_to_atset3[qcode];
427 /* FIXME: break code should be configured on a key by key basis */
429 ps2_put_keycode(s, 0xf0);
431 ps2_put_keycode(s, keycode);
433 qemu_log_mask(LOG_UNIMP,
434 "ps2: ignoring key with qcode %d\n", qcode);
439 uint32_t ps2_read_data(PS2State *s)
444 trace_ps2_read_data(s);
447 /* NOTE: if no data left, we return the last keyboard one
448 (needed for EMM386) */
449 /* XXX: need a timer to do things correctly */
452 index = PS2_QUEUE_SIZE - 1;
453 val = q->data[index];
455 val = q->data[q->rptr];
456 if (++q->rptr == PS2_QUEUE_SIZE)
459 /* reading deasserts IRQ */
460 s->update_irq(s->update_arg, 0);
461 /* reassert IRQs if data left */
462 s->update_irq(s->update_arg, q->count != 0);
467 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
469 trace_ps2_set_ledstate(s, ledstate);
470 s->ledstate = ledstate;
471 kbd_put_ledstate(ledstate);
474 static void ps2_reset_keyboard(PS2KbdState *s)
476 trace_ps2_reset_keyboard(s);
479 ps2_reset_queue(&s->common);
480 ps2_set_ledstate(s, 0);
483 void ps2_write_keyboard(void *opaque, int val)
485 PS2KbdState *s = (PS2KbdState *)opaque;
487 trace_ps2_write_keyboard(opaque, val);
488 switch(s->common.write_cmd) {
493 ps2_queue(&s->common, KBD_REPLY_ACK);
496 ps2_queue(&s->common, KBD_REPLY_RESEND);
499 ps2_queue(&s->common, KBD_REPLY_ACK);
500 /* We emulate a MF2 AT keyboard here */
501 ps2_queue(&s->common, KBD_REPLY_ID);
503 ps2_queue(&s->common, 0x41);
505 ps2_queue(&s->common, 0x83);
508 ps2_queue(&s->common, KBD_CMD_ECHO);
512 ps2_queue(&s->common, KBD_REPLY_ACK);
514 case KBD_CMD_SCANCODE:
515 case KBD_CMD_SET_LEDS:
516 case KBD_CMD_SET_RATE:
517 s->common.write_cmd = val;
518 ps2_queue(&s->common, KBD_REPLY_ACK);
520 case KBD_CMD_RESET_DISABLE:
521 ps2_reset_keyboard(s);
523 ps2_queue(&s->common, KBD_REPLY_ACK);
525 case KBD_CMD_RESET_ENABLE:
526 ps2_reset_keyboard(s);
528 ps2_queue(&s->common, KBD_REPLY_ACK);
531 ps2_reset_keyboard(s);
532 ps2_queue(&s->common, KBD_REPLY_ACK);
533 ps2_queue(&s->common, KBD_REPLY_POR);
536 ps2_queue(&s->common, KBD_REPLY_RESEND);
540 case KBD_CMD_SCANCODE:
542 ps2_queue(&s->common, KBD_REPLY_ACK);
543 ps2_put_keycode(s, s->scancode_set);
544 } else if (val >= 1 && val <= 3) {
545 s->scancode_set = val;
546 ps2_queue(&s->common, KBD_REPLY_ACK);
548 ps2_queue(&s->common, KBD_REPLY_RESEND);
550 s->common.write_cmd = -1;
552 case KBD_CMD_SET_LEDS:
553 ps2_set_ledstate(s, val);
554 ps2_queue(&s->common, KBD_REPLY_ACK);
555 s->common.write_cmd = -1;
557 case KBD_CMD_SET_RATE:
558 ps2_queue(&s->common, KBD_REPLY_ACK);
559 s->common.write_cmd = -1;
564 /* Set the scancode translation mode.
566 1 = translated scancodes (used by qemu internally). */
568 void ps2_keyboard_set_translation(void *opaque, int mode)
570 PS2KbdState *s = (PS2KbdState *)opaque;
571 trace_ps2_keyboard_set_translation(opaque, mode);
575 static void ps2_mouse_send_packet(PS2MouseState *s)
583 /* XXX: increase range to 8 bits ? */
592 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
593 ps2_queue(&s->common, b);
594 ps2_queue(&s->common, dx1 & 0xff);
595 ps2_queue(&s->common, dy1 & 0xff);
596 /* extra byte for IMPS/2 or IMEX */
597 switch(s->mouse_type) {
605 ps2_queue(&s->common, dz1 & 0xff);
612 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
613 ps2_queue(&s->common, b);
617 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
624 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
627 static const int bmap[INPUT_BUTTON__MAX] = {
628 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT,
629 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
630 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT,
631 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE,
632 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA,
634 PS2MouseState *s = (PS2MouseState *)dev;
635 InputMoveEvent *move;
638 /* check if deltas are recorded when disabled */
639 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
643 case INPUT_EVENT_KIND_REL:
644 move = evt->u.rel.data;
645 if (move->axis == INPUT_AXIS_X) {
646 s->mouse_dx += move->value;
647 } else if (move->axis == INPUT_AXIS_Y) {
648 s->mouse_dy -= move->value;
652 case INPUT_EVENT_KIND_BTN:
653 btn = evt->u.btn.data;
655 s->mouse_buttons |= bmap[btn->button];
656 if (btn->button == INPUT_BUTTON_WHEEL_UP) {
658 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
662 s->mouse_buttons &= ~bmap[btn->button];
672 static void ps2_mouse_sync(DeviceState *dev)
674 PS2MouseState *s = (PS2MouseState *)dev;
676 if (s->mouse_buttons) {
677 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
679 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
680 while (s->common.queue.count < PS2_QUEUE_SIZE - 4) {
681 /* if not remote, send event. Multiple events are sent if
683 ps2_mouse_send_packet(s);
684 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
690 void ps2_mouse_fake_event(void *opaque)
692 PS2MouseState *s = opaque;
693 trace_ps2_mouse_fake_event(opaque);
695 ps2_mouse_sync(opaque);
698 void ps2_write_mouse(void *opaque, int val)
700 PS2MouseState *s = (PS2MouseState *)opaque;
702 trace_ps2_write_mouse(opaque, val);
704 printf("kbd: write mouse 0x%02x\n", val);
706 switch(s->common.write_cmd) {
711 if (val == AUX_RESET_WRAP) {
713 ps2_queue(&s->common, AUX_ACK);
715 } else if (val != AUX_RESET) {
716 ps2_queue(&s->common, val);
721 case AUX_SET_SCALE11:
722 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
723 ps2_queue(&s->common, AUX_ACK);
725 case AUX_SET_SCALE21:
726 s->mouse_status |= MOUSE_STATUS_SCALE21;
727 ps2_queue(&s->common, AUX_ACK);
730 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
731 ps2_queue(&s->common, AUX_ACK);
735 ps2_queue(&s->common, AUX_ACK);
738 s->mouse_status |= MOUSE_STATUS_REMOTE;
739 ps2_queue(&s->common, AUX_ACK);
742 ps2_queue(&s->common, AUX_ACK);
743 ps2_queue(&s->common, s->mouse_type);
747 s->common.write_cmd = val;
748 ps2_queue(&s->common, AUX_ACK);
751 ps2_queue(&s->common, AUX_ACK);
752 ps2_queue(&s->common, s->mouse_status);
753 ps2_queue(&s->common, s->mouse_resolution);
754 ps2_queue(&s->common, s->mouse_sample_rate);
757 ps2_queue(&s->common, AUX_ACK);
758 ps2_mouse_send_packet(s);
761 s->mouse_status |= MOUSE_STATUS_ENABLED;
762 ps2_queue(&s->common, AUX_ACK);
764 case AUX_DISABLE_DEV:
765 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
766 ps2_queue(&s->common, AUX_ACK);
768 case AUX_SET_DEFAULT:
769 s->mouse_sample_rate = 100;
770 s->mouse_resolution = 2;
772 ps2_queue(&s->common, AUX_ACK);
775 s->mouse_sample_rate = 100;
776 s->mouse_resolution = 2;
779 ps2_queue(&s->common, AUX_ACK);
780 ps2_queue(&s->common, 0xaa);
781 ps2_queue(&s->common, s->mouse_type);
788 s->mouse_sample_rate = val;
789 /* detect IMPS/2 or IMEX */
790 switch(s->mouse_detect_state) {
794 s->mouse_detect_state = 1;
798 s->mouse_detect_state = 2;
800 s->mouse_detect_state = 3;
802 s->mouse_detect_state = 0;
806 s->mouse_type = 3; /* IMPS/2 */
807 s->mouse_detect_state = 0;
811 s->mouse_type = 4; /* IMEX */
812 s->mouse_detect_state = 0;
815 ps2_queue(&s->common, AUX_ACK);
816 s->common.write_cmd = -1;
819 s->mouse_resolution = val;
820 ps2_queue(&s->common, AUX_ACK);
821 s->common.write_cmd = -1;
826 static void ps2_common_reset(PS2State *s)
830 s->update_irq(s->update_arg, 0);
833 static void ps2_common_post_load(PS2State *s)
835 PS2Queue *q = &s->queue;
837 uint8_t tmp_data[PS2_QUEUE_SIZE];
839 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
840 size = (q->count < 0 || q->count > PS2_QUEUE_SIZE) ? 0 : q->count;
842 /* move the queue elements to the start of data array */
843 for (i = 0; i < size; i++) {
844 if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
847 tmp_data[i] = q->data[q->rptr++];
849 memcpy(q->data, tmp_data, size);
851 /* reset rptr/wptr/count */
855 s->update_irq(s->update_arg, q->count != 0);
858 static void ps2_kbd_reset(void *opaque)
860 PS2KbdState *s = (PS2KbdState *) opaque;
862 trace_ps2_kbd_reset(opaque);
863 ps2_common_reset(&s->common);
870 static void ps2_mouse_reset(void *opaque)
872 PS2MouseState *s = (PS2MouseState *) opaque;
874 trace_ps2_mouse_reset(opaque);
875 ps2_common_reset(&s->common);
877 s->mouse_resolution = 0;
878 s->mouse_sample_rate = 0;
881 s->mouse_detect_state = 0;
885 s->mouse_buttons = 0;
888 static const VMStateDescription vmstate_ps2_common = {
889 .name = "PS2 Common State",
891 .minimum_version_id = 2,
892 .fields = (VMStateField[]) {
893 VMSTATE_INT32(write_cmd, PS2State),
894 VMSTATE_INT32(queue.rptr, PS2State),
895 VMSTATE_INT32(queue.wptr, PS2State),
896 VMSTATE_INT32(queue.count, PS2State),
897 VMSTATE_BUFFER(queue.data, PS2State),
898 VMSTATE_END_OF_LIST()
902 static bool ps2_keyboard_ledstate_needed(void *opaque)
904 PS2KbdState *s = opaque;
906 return s->ledstate != 0; /* 0 is default state */
909 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
911 PS2KbdState *s = opaque;
913 kbd_put_ledstate(s->ledstate);
917 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
918 .name = "ps2kbd/ledstate",
920 .minimum_version_id = 2,
921 .post_load = ps2_kbd_ledstate_post_load,
922 .needed = ps2_keyboard_ledstate_needed,
923 .fields = (VMStateField[]) {
924 VMSTATE_INT32(ledstate, PS2KbdState),
925 VMSTATE_END_OF_LIST()
929 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
931 PS2KbdState *s = opaque;
932 return s->need_high_bit != 0; /* 0 is the usual state */
935 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
936 .name = "ps2kbd/need_high_bit",
938 .minimum_version_id = 1,
939 .needed = ps2_keyboard_need_high_bit_needed,
940 .fields = (VMStateField[]) {
941 VMSTATE_BOOL(need_high_bit, PS2KbdState),
942 VMSTATE_END_OF_LIST()
946 static int ps2_kbd_post_load(void* opaque, int version_id)
948 PS2KbdState *s = (PS2KbdState*)opaque;
949 PS2State *ps2 = &s->common;
954 ps2_common_post_load(ps2);
959 static int ps2_kbd_pre_save(void *opaque)
961 PS2KbdState *s = (PS2KbdState *)opaque;
962 PS2State *ps2 = &s->common;
964 ps2_common_post_load(ps2);
969 static const VMStateDescription vmstate_ps2_keyboard = {
972 .minimum_version_id = 2,
973 .post_load = ps2_kbd_post_load,
974 .pre_save = ps2_kbd_pre_save,
975 .fields = (VMStateField[]) {
976 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
977 VMSTATE_INT32(scan_enabled, PS2KbdState),
978 VMSTATE_INT32(translate, PS2KbdState),
979 VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
980 VMSTATE_END_OF_LIST()
982 .subsections = (const VMStateDescription*[]) {
983 &vmstate_ps2_keyboard_ledstate,
984 &vmstate_ps2_keyboard_need_high_bit,
989 static int ps2_mouse_post_load(void *opaque, int version_id)
991 PS2MouseState *s = (PS2MouseState *)opaque;
992 PS2State *ps2 = &s->common;
994 ps2_common_post_load(ps2);
999 static int ps2_mouse_pre_save(void *opaque)
1001 PS2MouseState *s = (PS2MouseState *)opaque;
1002 PS2State *ps2 = &s->common;
1004 ps2_common_post_load(ps2);
1009 static const VMStateDescription vmstate_ps2_mouse = {
1012 .minimum_version_id = 2,
1013 .post_load = ps2_mouse_post_load,
1014 .pre_save = ps2_mouse_pre_save,
1015 .fields = (VMStateField[]) {
1016 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1017 VMSTATE_UINT8(mouse_status, PS2MouseState),
1018 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1019 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1020 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1021 VMSTATE_UINT8(mouse_type, PS2MouseState),
1022 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1023 VMSTATE_INT32(mouse_dx, PS2MouseState),
1024 VMSTATE_INT32(mouse_dy, PS2MouseState),
1025 VMSTATE_INT32(mouse_dz, PS2MouseState),
1026 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1027 VMSTATE_END_OF_LIST()
1031 static QemuInputHandler ps2_keyboard_handler = {
1032 .name = "QEMU PS/2 Keyboard",
1033 .mask = INPUT_EVENT_MASK_KEY,
1034 .event = ps2_keyboard_event,
1037 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1039 PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1041 trace_ps2_kbd_init(s);
1042 s->common.update_irq = update_irq;
1043 s->common.update_arg = update_arg;
1044 s->scancode_set = 2;
1045 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1046 qemu_input_handler_register((DeviceState *)s,
1047 &ps2_keyboard_handler);
1048 qemu_register_reset(ps2_kbd_reset, s);
1052 static QemuInputHandler ps2_mouse_handler = {
1053 .name = "QEMU PS/2 Mouse",
1054 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1055 .event = ps2_mouse_event,
1056 .sync = ps2_mouse_sync,
1059 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1061 PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1063 trace_ps2_mouse_init(s);
1064 s->common.update_irq = update_irq;
1065 s->common.update_arg = update_arg;
1066 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1067 qemu_input_handler_register((DeviceState *)s,
1068 &ps2_mouse_handler);
1069 qemu_register_reset(ps2_mouse_reset, s);