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 /* debug PC keyboard */
39 /* debug PC keyboard : only mouse */
42 /* Keyboard Commands */
43 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
44 #define KBD_CMD_ECHO 0xEE
45 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
46 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
47 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
48 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
49 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
50 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
51 #define KBD_CMD_RESET 0xFF /* Reset */
53 /* Keyboard Replies */
54 #define KBD_REPLY_POR 0xAA /* Power on reset */
55 #define KBD_REPLY_ID 0xAB /* Keyboard ID */
56 #define KBD_REPLY_ACK 0xFA /* Command ACK */
57 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
60 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
61 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
62 #define AUX_SET_RES 0xE8 /* Set resolution */
63 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
64 #define AUX_SET_STREAM 0xEA /* Set stream mode */
65 #define AUX_POLL 0xEB /* Poll */
66 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
67 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
68 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
69 #define AUX_GET_TYPE 0xF2 /* Get type */
70 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
71 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
72 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
73 #define AUX_SET_DEFAULT 0xF6
74 #define AUX_RESET 0xFF /* Reset aux device */
75 #define AUX_ACK 0xFA /* Command byte ACK. */
77 #define MOUSE_STATUS_REMOTE 0x40
78 #define MOUSE_STATUS_ENABLED 0x20
79 #define MOUSE_STATUS_SCALE21 0x10
81 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */
83 /* Bits for 'modifiers' field in PS2KbdState */
84 #define MOD_CTRL_L (1 << 0)
85 #define MOD_SHIFT_L (1 << 1)
86 #define MOD_ALT_L (1 << 2)
87 #define MOD_CTRL_R (1 << 3)
88 #define MOD_SHIFT_R (1 << 4)
89 #define MOD_ALT_R (1 << 5)
92 /* Keep the data array 256 bytes long, which compatibility
93 with older qemu versions. */
95 int rptr
, wptr
, 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 */
126 uint8_t mouse_buttons
;
129 static uint8_t translate_table
[256] = {
130 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
131 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
132 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
133 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
134 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
135 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
136 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
137 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
138 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
139 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
140 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
141 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
142 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
143 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
144 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
145 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
146 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
147 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
148 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
149 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
150 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
151 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
152 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
153 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
154 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
155 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
156 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
157 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
158 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
159 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
160 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
161 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
164 static unsigned int ps2_modifier_bit(QKeyCode key
)
167 case Q_KEY_CODE_CTRL
:
169 case Q_KEY_CODE_CTRL_R
:
171 case Q_KEY_CODE_SHIFT
:
173 case Q_KEY_CODE_SHIFT_R
:
177 case Q_KEY_CODE_ALT_R
:
184 static void ps2_reset_queue(PS2State
*s
)
186 PS2Queue
*q
= &s
->queue
;
193 void ps2_queue_noirq(PS2State
*s
, int b
)
195 PS2Queue
*q
= &s
->queue
;
197 if (q
->count
== PS2_QUEUE_SIZE
) {
201 q
->data
[q
->wptr
] = b
;
202 if (++q
->wptr
== PS2_QUEUE_SIZE
)
207 void ps2_raise_irq(PS2State
*s
)
209 s
->update_irq(s
->update_arg
, 1);
212 void ps2_queue(PS2State
*s
, int b
)
214 ps2_queue_noirq(s
, b
);
215 s
->update_irq(s
->update_arg
, 1);
218 void ps2_queue_2(PS2State
*s
, int b1
, int b2
)
220 if (PS2_QUEUE_SIZE
- s
->queue
.count
< 2) {
224 ps2_queue_noirq(s
, b1
);
225 ps2_queue_noirq(s
, b2
);
226 s
->update_irq(s
->update_arg
, 1);
229 void ps2_queue_3(PS2State
*s
, int b1
, int b2
, int b3
)
231 if (PS2_QUEUE_SIZE
- s
->queue
.count
< 3) {
235 ps2_queue_noirq(s
, b1
);
236 ps2_queue_noirq(s
, b2
);
237 ps2_queue_noirq(s
, b3
);
238 s
->update_irq(s
->update_arg
, 1);
241 void ps2_queue_4(PS2State
*s
, int b1
, int b2
, int b3
, int b4
)
243 if (PS2_QUEUE_SIZE
- s
->queue
.count
< 4) {
247 ps2_queue_noirq(s
, b1
);
248 ps2_queue_noirq(s
, b2
);
249 ps2_queue_noirq(s
, b3
);
250 ps2_queue_noirq(s
, b4
);
251 s
->update_irq(s
->update_arg
, 1);
254 /* keycode is the untranslated scancode in the current scancode set. */
255 static void ps2_put_keycode(void *opaque
, int keycode
)
257 PS2KbdState
*s
= opaque
;
259 trace_ps2_put_keycode(opaque
, keycode
);
260 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
, NULL
);
263 if (keycode
== 0xf0) {
264 s
->need_high_bit
= true;
265 } else if (s
->need_high_bit
) {
266 ps2_queue(&s
->common
, translate_table
[keycode
] | 0x80);
267 s
->need_high_bit
= false;
269 ps2_queue(&s
->common
, translate_table
[keycode
]);
272 ps2_queue(&s
->common
, keycode
);
276 static void ps2_keyboard_event(DeviceState
*dev
, QemuConsole
*src
,
279 PS2KbdState
*s
= (PS2KbdState
*)dev
;
280 InputKeyEvent
*key
= evt
->u
.key
.data
;
282 uint16_t keycode
= 0;
285 /* do not process events while disabled to prevent stream corruption */
286 if (!s
->scan_enabled
) {
290 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
, NULL
);
291 assert(evt
->type
== INPUT_EVENT_KIND_KEY
);
292 qcode
= qemu_input_key_value_to_qcode(key
->key
);
294 mod
= ps2_modifier_bit(qcode
);
295 trace_ps2_keyboard_event(s
, qcode
, key
->down
, mod
, s
->modifiers
);
299 s
->modifiers
&= ~mod
;
302 if (s
->scancode_set
== 1) {
303 if (qcode
== Q_KEY_CODE_PAUSE
) {
304 if (s
->modifiers
& (MOD_CTRL_L
| MOD_CTRL_R
)) {
306 ps2_put_keycode(s
, 0xe0);
307 ps2_put_keycode(s
, 0x46);
308 ps2_put_keycode(s
, 0xe0);
309 ps2_put_keycode(s
, 0xc6);
313 ps2_put_keycode(s
, 0xe1);
314 ps2_put_keycode(s
, 0x1d);
315 ps2_put_keycode(s
, 0x45);
316 ps2_put_keycode(s
, 0xe1);
317 ps2_put_keycode(s
, 0x9d);
318 ps2_put_keycode(s
, 0xc5);
321 } else if (qcode
== Q_KEY_CODE_PRINT
) {
322 if (s
->modifiers
& MOD_ALT_L
) {
324 ps2_put_keycode(s
, 0xb8);
325 ps2_put_keycode(s
, 0x38);
326 ps2_put_keycode(s
, 0x54);
328 ps2_put_keycode(s
, 0xd4);
329 ps2_put_keycode(s
, 0xb8);
330 ps2_put_keycode(s
, 0x38);
332 } else if (s
->modifiers
& MOD_ALT_R
) {
334 ps2_put_keycode(s
, 0xe0);
335 ps2_put_keycode(s
, 0xb8);
336 ps2_put_keycode(s
, 0xe0);
337 ps2_put_keycode(s
, 0x38);
338 ps2_put_keycode(s
, 0x54);
340 ps2_put_keycode(s
, 0xd4);
341 ps2_put_keycode(s
, 0xe0);
342 ps2_put_keycode(s
, 0xb8);
343 ps2_put_keycode(s
, 0xe0);
344 ps2_put_keycode(s
, 0x38);
346 } else if (s
->modifiers
& (MOD_SHIFT_L
| MOD_CTRL_L
|
347 MOD_SHIFT_R
| MOD_CTRL_R
)) {
349 ps2_put_keycode(s
, 0xe0);
350 ps2_put_keycode(s
, 0x37);
352 ps2_put_keycode(s
, 0xe0);
353 ps2_put_keycode(s
, 0xb7);
357 ps2_put_keycode(s
, 0xe0);
358 ps2_put_keycode(s
, 0x2a);
359 ps2_put_keycode(s
, 0xe0);
360 ps2_put_keycode(s
, 0x37);
362 ps2_put_keycode(s
, 0xe0);
363 ps2_put_keycode(s
, 0xb7);
364 ps2_put_keycode(s
, 0xe0);
365 ps2_put_keycode(s
, 0xaa);
369 if (qcode
< qemu_input_map_qcode_to_atset1_len
)
370 keycode
= qemu_input_map_qcode_to_atset1
[qcode
];
372 if (keycode
& 0xff00) {
373 ps2_put_keycode(s
, keycode
>> 8);
378 ps2_put_keycode(s
, keycode
& 0xff);
380 qemu_log_mask(LOG_UNIMP
,
381 "ps2: ignoring key with qcode %d\n", qcode
);
384 } else if (s
->scancode_set
== 2) {
385 if (qcode
== Q_KEY_CODE_PAUSE
) {
386 if (s
->modifiers
& (MOD_CTRL_L
| MOD_CTRL_R
)) {
388 ps2_put_keycode(s
, 0xe0);
389 ps2_put_keycode(s
, 0x7e);
390 ps2_put_keycode(s
, 0xe0);
391 ps2_put_keycode(s
, 0xf0);
392 ps2_put_keycode(s
, 0x7e);
396 ps2_put_keycode(s
, 0xe1);
397 ps2_put_keycode(s
, 0x14);
398 ps2_put_keycode(s
, 0x77);
399 ps2_put_keycode(s
, 0xe1);
400 ps2_put_keycode(s
, 0xf0);
401 ps2_put_keycode(s
, 0x14);
402 ps2_put_keycode(s
, 0xf0);
403 ps2_put_keycode(s
, 0x77);
406 } else if (qcode
== Q_KEY_CODE_PRINT
) {
407 if (s
->modifiers
& MOD_ALT_L
) {
409 ps2_put_keycode(s
, 0xf0);
410 ps2_put_keycode(s
, 0x11);
411 ps2_put_keycode(s
, 0x11);
412 ps2_put_keycode(s
, 0x84);
414 ps2_put_keycode(s
, 0xf0);
415 ps2_put_keycode(s
, 0x84);
416 ps2_put_keycode(s
, 0xf0);
417 ps2_put_keycode(s
, 0x11);
418 ps2_put_keycode(s
, 0x11);
420 } else if (s
->modifiers
& MOD_ALT_R
) {
422 ps2_put_keycode(s
, 0xe0);
423 ps2_put_keycode(s
, 0xf0);
424 ps2_put_keycode(s
, 0x11);
425 ps2_put_keycode(s
, 0xe0);
426 ps2_put_keycode(s
, 0x11);
427 ps2_put_keycode(s
, 0x84);
429 ps2_put_keycode(s
, 0xf0);
430 ps2_put_keycode(s
, 0x84);
431 ps2_put_keycode(s
, 0xe0);
432 ps2_put_keycode(s
, 0xf0);
433 ps2_put_keycode(s
, 0x11);
434 ps2_put_keycode(s
, 0xe0);
435 ps2_put_keycode(s
, 0x11);
437 } else if (s
->modifiers
& (MOD_SHIFT_L
| MOD_CTRL_L
|
438 MOD_SHIFT_R
| MOD_CTRL_R
)) {
440 ps2_put_keycode(s
, 0xe0);
441 ps2_put_keycode(s
, 0x7c);
443 ps2_put_keycode(s
, 0xe0);
444 ps2_put_keycode(s
, 0xf0);
445 ps2_put_keycode(s
, 0x7c);
449 ps2_put_keycode(s
, 0xe0);
450 ps2_put_keycode(s
, 0x12);
451 ps2_put_keycode(s
, 0xe0);
452 ps2_put_keycode(s
, 0x7c);
454 ps2_put_keycode(s
, 0xe0);
455 ps2_put_keycode(s
, 0xf0);
456 ps2_put_keycode(s
, 0x7c);
457 ps2_put_keycode(s
, 0xe0);
458 ps2_put_keycode(s
, 0xf0);
459 ps2_put_keycode(s
, 0x12);
463 if (qcode
< qemu_input_map_qcode_to_atset2_len
)
464 keycode
= qemu_input_map_qcode_to_atset2
[qcode
];
466 if (keycode
& 0xff00) {
467 ps2_put_keycode(s
, keycode
>> 8);
470 ps2_put_keycode(s
, 0xf0);
472 ps2_put_keycode(s
, keycode
& 0xff);
474 qemu_log_mask(LOG_UNIMP
,
475 "ps2: ignoring key with qcode %d\n", qcode
);
478 } else if (s
->scancode_set
== 3) {
479 if (qcode
< qemu_input_map_qcode_to_atset3_len
)
480 keycode
= qemu_input_map_qcode_to_atset3
[qcode
];
482 /* FIXME: break code should be configured on a key by key basis */
484 ps2_put_keycode(s
, 0xf0);
486 ps2_put_keycode(s
, keycode
);
488 qemu_log_mask(LOG_UNIMP
,
489 "ps2: ignoring key with qcode %d\n", qcode
);
494 uint32_t ps2_read_data(PS2State
*s
)
499 trace_ps2_read_data(s
);
502 /* NOTE: if no data left, we return the last keyboard one
503 (needed for EMM386) */
504 /* XXX: need a timer to do things correctly */
507 index
= PS2_QUEUE_SIZE
- 1;
508 val
= q
->data
[index
];
510 val
= q
->data
[q
->rptr
];
511 if (++q
->rptr
== PS2_QUEUE_SIZE
)
514 /* reading deasserts IRQ */
515 s
->update_irq(s
->update_arg
, 0);
516 /* reassert IRQs if data left */
517 s
->update_irq(s
->update_arg
, q
->count
!= 0);
522 static void ps2_set_ledstate(PS2KbdState
*s
, int ledstate
)
524 trace_ps2_set_ledstate(s
, ledstate
);
525 s
->ledstate
= ledstate
;
526 kbd_put_ledstate(ledstate
);
529 static void ps2_reset_keyboard(PS2KbdState
*s
)
531 trace_ps2_reset_keyboard(s
);
534 ps2_reset_queue(&s
->common
);
535 ps2_set_ledstate(s
, 0);
538 void ps2_write_keyboard(void *opaque
, int val
)
540 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
542 trace_ps2_write_keyboard(opaque
, val
);
543 switch(s
->common
.write_cmd
) {
548 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
551 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
554 /* We emulate a MF2 AT keyboard here */
556 ps2_queue_3(&s
->common
,
561 ps2_queue_3(&s
->common
,
567 ps2_queue(&s
->common
, KBD_CMD_ECHO
);
571 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
573 case KBD_CMD_SCANCODE
:
574 case KBD_CMD_SET_LEDS
:
575 case KBD_CMD_SET_RATE
:
576 s
->common
.write_cmd
= val
;
577 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
579 case KBD_CMD_RESET_DISABLE
:
580 ps2_reset_keyboard(s
);
582 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
584 case KBD_CMD_RESET_ENABLE
:
585 ps2_reset_keyboard(s
);
587 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
590 ps2_reset_keyboard(s
);
591 ps2_queue_2(&s
->common
,
596 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
600 case KBD_CMD_SCANCODE
:
602 if (s
->common
.queue
.count
<= PS2_QUEUE_SIZE
- 2) {
603 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
604 ps2_put_keycode(s
, s
->scancode_set
);
606 } else if (val
>= 1 && val
<= 3) {
607 s
->scancode_set
= val
;
608 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
610 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
612 s
->common
.write_cmd
= -1;
614 case KBD_CMD_SET_LEDS
:
615 ps2_set_ledstate(s
, val
);
616 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
617 s
->common
.write_cmd
= -1;
619 case KBD_CMD_SET_RATE
:
620 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
621 s
->common
.write_cmd
= -1;
626 /* Set the scancode translation mode.
628 1 = translated scancodes (used by qemu internally). */
630 void ps2_keyboard_set_translation(void *opaque
, int mode
)
632 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
633 trace_ps2_keyboard_set_translation(opaque
, mode
);
637 static int ps2_mouse_send_packet(PS2MouseState
*s
)
639 const int needed
= 3 + (s
->mouse_type
- 2);
643 if (PS2_QUEUE_SIZE
- s
->common
.queue
.count
< needed
) {
650 /* XXX: increase range to 8 bits ? */
659 b
= 0x08 | ((dx1
< 0) << 4) | ((dy1
< 0) << 5) | (s
->mouse_buttons
& 0x07);
660 ps2_queue_noirq(&s
->common
, b
);
661 ps2_queue_noirq(&s
->common
, dx1
& 0xff);
662 ps2_queue_noirq(&s
->common
, dy1
& 0xff);
663 /* extra byte for IMPS/2 or IMEX */
664 switch(s
->mouse_type
) {
672 ps2_queue_noirq(&s
->common
, dz1
& 0xff);
679 b
= (dz1
& 0x0f) | ((s
->mouse_buttons
& 0x18) << 1);
680 ps2_queue_noirq(&s
->common
, b
);
684 ps2_raise_irq(&s
->common
);
686 trace_ps2_mouse_send_packet(s
, dx1
, dy1
, dz1
, b
);
695 static void ps2_mouse_event(DeviceState
*dev
, QemuConsole
*src
,
698 static const int bmap
[INPUT_BUTTON__MAX
] = {
699 [INPUT_BUTTON_LEFT
] = PS2_MOUSE_BUTTON_LEFT
,
700 [INPUT_BUTTON_MIDDLE
] = PS2_MOUSE_BUTTON_MIDDLE
,
701 [INPUT_BUTTON_RIGHT
] = PS2_MOUSE_BUTTON_RIGHT
,
702 [INPUT_BUTTON_SIDE
] = PS2_MOUSE_BUTTON_SIDE
,
703 [INPUT_BUTTON_EXTRA
] = PS2_MOUSE_BUTTON_EXTRA
,
705 PS2MouseState
*s
= (PS2MouseState
*)dev
;
706 InputMoveEvent
*move
;
709 /* check if deltas are recorded when disabled */
710 if (!(s
->mouse_status
& MOUSE_STATUS_ENABLED
))
714 case INPUT_EVENT_KIND_REL
:
715 move
= evt
->u
.rel
.data
;
716 if (move
->axis
== INPUT_AXIS_X
) {
717 s
->mouse_dx
+= move
->value
;
718 } else if (move
->axis
== INPUT_AXIS_Y
) {
719 s
->mouse_dy
-= move
->value
;
723 case INPUT_EVENT_KIND_BTN
:
724 btn
= evt
->u
.btn
.data
;
726 s
->mouse_buttons
|= bmap
[btn
->button
];
727 if (btn
->button
== INPUT_BUTTON_WHEEL_UP
) {
729 } else if (btn
->button
== INPUT_BUTTON_WHEEL_DOWN
) {
733 s
->mouse_buttons
&= ~bmap
[btn
->button
];
743 static void ps2_mouse_sync(DeviceState
*dev
)
745 PS2MouseState
*s
= (PS2MouseState
*)dev
;
747 /* do not sync while disabled to prevent stream corruption */
748 if (!(s
->mouse_status
& MOUSE_STATUS_ENABLED
)) {
752 if (s
->mouse_buttons
) {
753 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
, NULL
);
755 if (!(s
->mouse_status
& MOUSE_STATUS_REMOTE
)) {
756 /* if not remote, send event. Multiple events are sent if
758 while (ps2_mouse_send_packet(s
)) {
759 if (s
->mouse_dx
== 0 && s
->mouse_dy
== 0 && s
->mouse_dz
== 0)
765 void ps2_mouse_fake_event(void *opaque
)
767 PS2MouseState
*s
= opaque
;
768 trace_ps2_mouse_fake_event(opaque
);
770 ps2_mouse_sync(opaque
);
773 void ps2_write_mouse(void *opaque
, int val
)
775 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
777 trace_ps2_write_mouse(opaque
, val
);
779 printf("kbd: write mouse 0x%02x\n", val
);
781 switch(s
->common
.write_cmd
) {
786 if (val
== AUX_RESET_WRAP
) {
788 ps2_queue(&s
->common
, AUX_ACK
);
790 } else if (val
!= AUX_RESET
) {
791 ps2_queue(&s
->common
, val
);
796 case AUX_SET_SCALE11
:
797 s
->mouse_status
&= ~MOUSE_STATUS_SCALE21
;
798 ps2_queue(&s
->common
, AUX_ACK
);
800 case AUX_SET_SCALE21
:
801 s
->mouse_status
|= MOUSE_STATUS_SCALE21
;
802 ps2_queue(&s
->common
, AUX_ACK
);
805 s
->mouse_status
&= ~MOUSE_STATUS_REMOTE
;
806 ps2_queue(&s
->common
, AUX_ACK
);
810 ps2_queue(&s
->common
, AUX_ACK
);
813 s
->mouse_status
|= MOUSE_STATUS_REMOTE
;
814 ps2_queue(&s
->common
, AUX_ACK
);
817 ps2_queue_2(&s
->common
,
823 s
->common
.write_cmd
= val
;
824 ps2_queue(&s
->common
, AUX_ACK
);
827 ps2_queue_4(&s
->common
,
831 s
->mouse_sample_rate
);
834 ps2_queue(&s
->common
, AUX_ACK
);
835 ps2_mouse_send_packet(s
);
838 s
->mouse_status
|= MOUSE_STATUS_ENABLED
;
839 ps2_queue(&s
->common
, AUX_ACK
);
841 case AUX_DISABLE_DEV
:
842 s
->mouse_status
&= ~MOUSE_STATUS_ENABLED
;
843 ps2_queue(&s
->common
, AUX_ACK
);
845 case AUX_SET_DEFAULT
:
846 s
->mouse_sample_rate
= 100;
847 s
->mouse_resolution
= 2;
849 ps2_queue(&s
->common
, AUX_ACK
);
852 s
->mouse_sample_rate
= 100;
853 s
->mouse_resolution
= 2;
856 ps2_reset_queue(&s
->common
);
857 ps2_queue_3(&s
->common
,
867 s
->mouse_sample_rate
= val
;
868 /* detect IMPS/2 or IMEX */
869 switch(s
->mouse_detect_state
) {
873 s
->mouse_detect_state
= 1;
877 s
->mouse_detect_state
= 2;
879 s
->mouse_detect_state
= 3;
881 s
->mouse_detect_state
= 0;
885 s
->mouse_type
= 3; /* IMPS/2 */
886 s
->mouse_detect_state
= 0;
890 s
->mouse_type
= 4; /* IMEX */
891 s
->mouse_detect_state
= 0;
894 ps2_queue(&s
->common
, AUX_ACK
);
895 s
->common
.write_cmd
= -1;
898 s
->mouse_resolution
= val
;
899 ps2_queue(&s
->common
, AUX_ACK
);
900 s
->common
.write_cmd
= -1;
905 static void ps2_common_reset(PS2State
*s
)
909 s
->update_irq(s
->update_arg
, 0);
912 static void ps2_common_post_load(PS2State
*s
)
914 PS2Queue
*q
= &s
->queue
;
916 uint8_t tmp_data
[PS2_QUEUE_SIZE
];
918 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
922 } else if (q
->count
> PS2_QUEUE_SIZE
) {
923 size
= PS2_QUEUE_SIZE
;
926 /* move the queue elements to the start of data array */
927 for (i
= 0; i
< size
; i
++) {
928 if (q
->rptr
< 0 || q
->rptr
>= sizeof(q
->data
)) {
931 tmp_data
[i
] = q
->data
[q
->rptr
++];
933 memcpy(q
->data
, tmp_data
, size
);
935 /* reset rptr/wptr/count */
937 q
->wptr
= (size
== PS2_QUEUE_SIZE
) ? 0 : size
;
941 static void ps2_kbd_reset(void *opaque
)
943 PS2KbdState
*s
= (PS2KbdState
*) opaque
;
945 trace_ps2_kbd_reset(opaque
);
946 ps2_common_reset(&s
->common
);
953 static void ps2_mouse_reset(void *opaque
)
955 PS2MouseState
*s
= (PS2MouseState
*) opaque
;
957 trace_ps2_mouse_reset(opaque
);
958 ps2_common_reset(&s
->common
);
960 s
->mouse_resolution
= 0;
961 s
->mouse_sample_rate
= 0;
964 s
->mouse_detect_state
= 0;
968 s
->mouse_buttons
= 0;
971 static const VMStateDescription vmstate_ps2_common
= {
972 .name
= "PS2 Common State",
974 .minimum_version_id
= 2,
975 .fields
= (VMStateField
[]) {
976 VMSTATE_INT32(write_cmd
, PS2State
),
977 VMSTATE_INT32(queue
.rptr
, PS2State
),
978 VMSTATE_INT32(queue
.wptr
, PS2State
),
979 VMSTATE_INT32(queue
.count
, PS2State
),
980 VMSTATE_BUFFER(queue
.data
, PS2State
),
981 VMSTATE_END_OF_LIST()
985 static bool ps2_keyboard_ledstate_needed(void *opaque
)
987 PS2KbdState
*s
= opaque
;
989 return s
->ledstate
!= 0; /* 0 is default state */
992 static int ps2_kbd_ledstate_post_load(void *opaque
, int version_id
)
994 PS2KbdState
*s
= opaque
;
996 kbd_put_ledstate(s
->ledstate
);
1000 static const VMStateDescription vmstate_ps2_keyboard_ledstate
= {
1001 .name
= "ps2kbd/ledstate",
1003 .minimum_version_id
= 2,
1004 .post_load
= ps2_kbd_ledstate_post_load
,
1005 .needed
= ps2_keyboard_ledstate_needed
,
1006 .fields
= (VMStateField
[]) {
1007 VMSTATE_INT32(ledstate
, PS2KbdState
),
1008 VMSTATE_END_OF_LIST()
1012 static bool ps2_keyboard_need_high_bit_needed(void *opaque
)
1014 PS2KbdState
*s
= opaque
;
1015 return s
->need_high_bit
!= 0; /* 0 is the usual state */
1018 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit
= {
1019 .name
= "ps2kbd/need_high_bit",
1021 .minimum_version_id
= 1,
1022 .needed
= ps2_keyboard_need_high_bit_needed
,
1023 .fields
= (VMStateField
[]) {
1024 VMSTATE_BOOL(need_high_bit
, PS2KbdState
),
1025 VMSTATE_END_OF_LIST()
1029 static int ps2_kbd_post_load(void* opaque
, int version_id
)
1031 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1032 PS2State
*ps2
= &s
->common
;
1034 if (version_id
== 2)
1037 ps2_common_post_load(ps2
);
1042 static int ps2_kbd_pre_save(void *opaque
)
1044 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1045 PS2State
*ps2
= &s
->common
;
1047 ps2_common_post_load(ps2
);
1052 static const VMStateDescription vmstate_ps2_keyboard
= {
1055 .minimum_version_id
= 2,
1056 .post_load
= ps2_kbd_post_load
,
1057 .pre_save
= ps2_kbd_pre_save
,
1058 .fields
= (VMStateField
[]) {
1059 VMSTATE_STRUCT(common
, PS2KbdState
, 0, vmstate_ps2_common
, PS2State
),
1060 VMSTATE_INT32(scan_enabled
, PS2KbdState
),
1061 VMSTATE_INT32(translate
, PS2KbdState
),
1062 VMSTATE_INT32_V(scancode_set
, PS2KbdState
,3),
1063 VMSTATE_END_OF_LIST()
1065 .subsections
= (const VMStateDescription
*[]) {
1066 &vmstate_ps2_keyboard_ledstate
,
1067 &vmstate_ps2_keyboard_need_high_bit
,
1072 static int ps2_mouse_post_load(void *opaque
, int version_id
)
1074 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1075 PS2State
*ps2
= &s
->common
;
1077 ps2_common_post_load(ps2
);
1082 static int ps2_mouse_pre_save(void *opaque
)
1084 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1085 PS2State
*ps2
= &s
->common
;
1087 ps2_common_post_load(ps2
);
1092 static const VMStateDescription vmstate_ps2_mouse
= {
1095 .minimum_version_id
= 2,
1096 .post_load
= ps2_mouse_post_load
,
1097 .pre_save
= ps2_mouse_pre_save
,
1098 .fields
= (VMStateField
[]) {
1099 VMSTATE_STRUCT(common
, PS2MouseState
, 0, vmstate_ps2_common
, PS2State
),
1100 VMSTATE_UINT8(mouse_status
, PS2MouseState
),
1101 VMSTATE_UINT8(mouse_resolution
, PS2MouseState
),
1102 VMSTATE_UINT8(mouse_sample_rate
, PS2MouseState
),
1103 VMSTATE_UINT8(mouse_wrap
, PS2MouseState
),
1104 VMSTATE_UINT8(mouse_type
, PS2MouseState
),
1105 VMSTATE_UINT8(mouse_detect_state
, PS2MouseState
),
1106 VMSTATE_INT32(mouse_dx
, PS2MouseState
),
1107 VMSTATE_INT32(mouse_dy
, PS2MouseState
),
1108 VMSTATE_INT32(mouse_dz
, PS2MouseState
),
1109 VMSTATE_UINT8(mouse_buttons
, PS2MouseState
),
1110 VMSTATE_END_OF_LIST()
1114 static QemuInputHandler ps2_keyboard_handler
= {
1115 .name
= "QEMU PS/2 Keyboard",
1116 .mask
= INPUT_EVENT_MASK_KEY
,
1117 .event
= ps2_keyboard_event
,
1120 void *ps2_kbd_init(void (*update_irq
)(void *, int), void *update_arg
)
1122 PS2KbdState
*s
= (PS2KbdState
*)g_malloc0(sizeof(PS2KbdState
));
1124 trace_ps2_kbd_init(s
);
1125 s
->common
.update_irq
= update_irq
;
1126 s
->common
.update_arg
= update_arg
;
1127 s
->scancode_set
= 2;
1128 vmstate_register(NULL
, 0, &vmstate_ps2_keyboard
, s
);
1129 qemu_input_handler_register((DeviceState
*)s
,
1130 &ps2_keyboard_handler
);
1131 qemu_register_reset(ps2_kbd_reset
, s
);
1135 static QemuInputHandler ps2_mouse_handler
= {
1136 .name
= "QEMU PS/2 Mouse",
1137 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_REL
,
1138 .event
= ps2_mouse_event
,
1139 .sync
= ps2_mouse_sync
,
1142 void *ps2_mouse_init(void (*update_irq
)(void *, int), void *update_arg
)
1144 PS2MouseState
*s
= (PS2MouseState
*)g_malloc0(sizeof(PS2MouseState
));
1146 trace_ps2_mouse_init(s
);
1147 s
->common
.update_irq
= update_irq
;
1148 s
->common
.update_arg
= update_arg
;
1149 vmstate_register(NULL
, 0, &vmstate_ps2_mouse
, s
);
1150 qemu_input_handler_register((DeviceState
*)s
,
1151 &ps2_mouse_handler
);
1152 qemu_register_reset(ps2_mouse_reset
, s
);