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_noirq(PS2State
*s
, int b
)
193 PS2Queue
*q
= &s
->queue
;
195 if (q
->count
== PS2_QUEUE_SIZE
) {
199 q
->data
[q
->wptr
] = b
;
200 if (++q
->wptr
== PS2_QUEUE_SIZE
)
205 void ps2_raise_irq(PS2State
*s
)
207 s
->update_irq(s
->update_arg
, 1);
210 void ps2_queue(PS2State
*s
, int b
)
212 ps2_queue_noirq(s
, b
);
213 s
->update_irq(s
->update_arg
, 1);
216 void ps2_queue_2(PS2State
*s
, int b1
, int b2
)
218 if (PS2_QUEUE_SIZE
- s
->queue
.count
< 2) {
222 ps2_queue_noirq(s
, b1
);
223 ps2_queue_noirq(s
, b2
);
224 s
->update_irq(s
->update_arg
, 1);
227 void ps2_queue_3(PS2State
*s
, int b1
, int b2
, int b3
)
229 if (PS2_QUEUE_SIZE
- s
->queue
.count
< 3) {
233 ps2_queue_noirq(s
, b1
);
234 ps2_queue_noirq(s
, b2
);
235 ps2_queue_noirq(s
, b3
);
236 s
->update_irq(s
->update_arg
, 1);
239 void ps2_queue_4(PS2State
*s
, int b1
, int b2
, int b3
, int b4
)
241 if (PS2_QUEUE_SIZE
- s
->queue
.count
< 4) {
245 ps2_queue_noirq(s
, b1
);
246 ps2_queue_noirq(s
, b2
);
247 ps2_queue_noirq(s
, b3
);
248 ps2_queue_noirq(s
, b4
);
249 s
->update_irq(s
->update_arg
, 1);
252 /* keycode is the untranslated scancode in the current scancode set. */
253 static void ps2_put_keycode(void *opaque
, int keycode
)
255 PS2KbdState
*s
= opaque
;
257 trace_ps2_put_keycode(opaque
, keycode
);
258 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
261 if (keycode
== 0xf0) {
262 s
->need_high_bit
= true;
263 } else if (s
->need_high_bit
) {
264 ps2_queue(&s
->common
, translate_table
[keycode
] | 0x80);
265 s
->need_high_bit
= false;
267 ps2_queue(&s
->common
, translate_table
[keycode
]);
270 ps2_queue(&s
->common
, keycode
);
274 static void ps2_keyboard_event(DeviceState
*dev
, QemuConsole
*src
,
277 PS2KbdState
*s
= (PS2KbdState
*)dev
;
278 InputKeyEvent
*key
= evt
->u
.key
.data
;
280 uint16_t keycode
= 0;
283 /* do not process events while disabled to prevent stream corruption */
284 if (!s
->scan_enabled
) {
288 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
289 assert(evt
->type
== INPUT_EVENT_KIND_KEY
);
290 qcode
= qemu_input_key_value_to_qcode(key
->key
);
292 mod
= ps2_modifier_bit(qcode
);
293 trace_ps2_keyboard_event(s
, qcode
, key
->down
, mod
, s
->modifiers
);
297 s
->modifiers
&= ~mod
;
300 if (s
->scancode_set
== 1) {
301 if (qcode
== Q_KEY_CODE_PAUSE
) {
302 if (s
->modifiers
& (MOD_CTRL_L
| MOD_CTRL_R
)) {
304 ps2_put_keycode(s
, 0xe0);
305 ps2_put_keycode(s
, 0x46);
306 ps2_put_keycode(s
, 0xe0);
307 ps2_put_keycode(s
, 0xc6);
311 ps2_put_keycode(s
, 0xe1);
312 ps2_put_keycode(s
, 0x1d);
313 ps2_put_keycode(s
, 0x45);
314 ps2_put_keycode(s
, 0xe1);
315 ps2_put_keycode(s
, 0x9d);
316 ps2_put_keycode(s
, 0xc5);
319 } else if (qcode
== Q_KEY_CODE_PRINT
) {
320 if (s
->modifiers
& MOD_ALT_L
) {
322 ps2_put_keycode(s
, 0xb8);
323 ps2_put_keycode(s
, 0x38);
324 ps2_put_keycode(s
, 0x54);
326 ps2_put_keycode(s
, 0xd4);
327 ps2_put_keycode(s
, 0xb8);
328 ps2_put_keycode(s
, 0x38);
330 } else if (s
->modifiers
& MOD_ALT_R
) {
332 ps2_put_keycode(s
, 0xe0);
333 ps2_put_keycode(s
, 0xb8);
334 ps2_put_keycode(s
, 0xe0);
335 ps2_put_keycode(s
, 0x38);
336 ps2_put_keycode(s
, 0x54);
338 ps2_put_keycode(s
, 0xd4);
339 ps2_put_keycode(s
, 0xe0);
340 ps2_put_keycode(s
, 0xb8);
341 ps2_put_keycode(s
, 0xe0);
342 ps2_put_keycode(s
, 0x38);
344 } else if (s
->modifiers
& (MOD_SHIFT_L
| MOD_CTRL_L
|
345 MOD_SHIFT_R
| MOD_CTRL_R
)) {
347 ps2_put_keycode(s
, 0xe0);
348 ps2_put_keycode(s
, 0x37);
350 ps2_put_keycode(s
, 0xe0);
351 ps2_put_keycode(s
, 0xb7);
355 ps2_put_keycode(s
, 0xe0);
356 ps2_put_keycode(s
, 0x2a);
357 ps2_put_keycode(s
, 0xe0);
358 ps2_put_keycode(s
, 0x37);
360 ps2_put_keycode(s
, 0xe0);
361 ps2_put_keycode(s
, 0xb7);
362 ps2_put_keycode(s
, 0xe0);
363 ps2_put_keycode(s
, 0xaa);
367 if (qcode
< qemu_input_map_qcode_to_atset1_len
)
368 keycode
= qemu_input_map_qcode_to_atset1
[qcode
];
370 if (keycode
& 0xff00) {
371 ps2_put_keycode(s
, keycode
>> 8);
376 ps2_put_keycode(s
, keycode
& 0xff);
378 qemu_log_mask(LOG_UNIMP
,
379 "ps2: ignoring key with qcode %d\n", qcode
);
382 } else if (s
->scancode_set
== 2) {
383 if (qcode
== Q_KEY_CODE_PAUSE
) {
384 if (s
->modifiers
& (MOD_CTRL_L
| MOD_CTRL_R
)) {
386 ps2_put_keycode(s
, 0xe0);
387 ps2_put_keycode(s
, 0x7e);
388 ps2_put_keycode(s
, 0xe0);
389 ps2_put_keycode(s
, 0xf0);
390 ps2_put_keycode(s
, 0x7e);
394 ps2_put_keycode(s
, 0xe1);
395 ps2_put_keycode(s
, 0x14);
396 ps2_put_keycode(s
, 0x77);
397 ps2_put_keycode(s
, 0xe1);
398 ps2_put_keycode(s
, 0xf0);
399 ps2_put_keycode(s
, 0x14);
400 ps2_put_keycode(s
, 0xf0);
401 ps2_put_keycode(s
, 0x77);
404 } else if (qcode
== Q_KEY_CODE_PRINT
) {
405 if (s
->modifiers
& MOD_ALT_L
) {
407 ps2_put_keycode(s
, 0xf0);
408 ps2_put_keycode(s
, 0x11);
409 ps2_put_keycode(s
, 0x11);
410 ps2_put_keycode(s
, 0x84);
412 ps2_put_keycode(s
, 0xf0);
413 ps2_put_keycode(s
, 0x84);
414 ps2_put_keycode(s
, 0xf0);
415 ps2_put_keycode(s
, 0x11);
416 ps2_put_keycode(s
, 0x11);
418 } else if (s
->modifiers
& MOD_ALT_R
) {
420 ps2_put_keycode(s
, 0xe0);
421 ps2_put_keycode(s
, 0xf0);
422 ps2_put_keycode(s
, 0x11);
423 ps2_put_keycode(s
, 0xe0);
424 ps2_put_keycode(s
, 0x11);
425 ps2_put_keycode(s
, 0x84);
427 ps2_put_keycode(s
, 0xf0);
428 ps2_put_keycode(s
, 0x84);
429 ps2_put_keycode(s
, 0xe0);
430 ps2_put_keycode(s
, 0xf0);
431 ps2_put_keycode(s
, 0x11);
432 ps2_put_keycode(s
, 0xe0);
433 ps2_put_keycode(s
, 0x11);
435 } else if (s
->modifiers
& (MOD_SHIFT_L
| MOD_CTRL_L
|
436 MOD_SHIFT_R
| MOD_CTRL_R
)) {
438 ps2_put_keycode(s
, 0xe0);
439 ps2_put_keycode(s
, 0x7c);
441 ps2_put_keycode(s
, 0xe0);
442 ps2_put_keycode(s
, 0xf0);
443 ps2_put_keycode(s
, 0x7c);
447 ps2_put_keycode(s
, 0xe0);
448 ps2_put_keycode(s
, 0x12);
449 ps2_put_keycode(s
, 0xe0);
450 ps2_put_keycode(s
, 0x7c);
452 ps2_put_keycode(s
, 0xe0);
453 ps2_put_keycode(s
, 0xf0);
454 ps2_put_keycode(s
, 0x7c);
455 ps2_put_keycode(s
, 0xe0);
456 ps2_put_keycode(s
, 0xf0);
457 ps2_put_keycode(s
, 0x12);
461 if (qcode
< qemu_input_map_qcode_to_atset2_len
)
462 keycode
= qemu_input_map_qcode_to_atset2
[qcode
];
464 if (keycode
& 0xff00) {
465 ps2_put_keycode(s
, keycode
>> 8);
468 ps2_put_keycode(s
, 0xf0);
470 ps2_put_keycode(s
, keycode
& 0xff);
472 qemu_log_mask(LOG_UNIMP
,
473 "ps2: ignoring key with qcode %d\n", qcode
);
476 } else if (s
->scancode_set
== 3) {
477 if (qcode
< qemu_input_map_qcode_to_atset3_len
)
478 keycode
= qemu_input_map_qcode_to_atset3
[qcode
];
480 /* FIXME: break code should be configured on a key by key basis */
482 ps2_put_keycode(s
, 0xf0);
484 ps2_put_keycode(s
, keycode
);
486 qemu_log_mask(LOG_UNIMP
,
487 "ps2: ignoring key with qcode %d\n", qcode
);
492 uint32_t ps2_read_data(PS2State
*s
)
497 trace_ps2_read_data(s
);
500 /* NOTE: if no data left, we return the last keyboard one
501 (needed for EMM386) */
502 /* XXX: need a timer to do things correctly */
505 index
= PS2_QUEUE_SIZE
- 1;
506 val
= q
->data
[index
];
508 val
= q
->data
[q
->rptr
];
509 if (++q
->rptr
== PS2_QUEUE_SIZE
)
512 /* reading deasserts IRQ */
513 s
->update_irq(s
->update_arg
, 0);
514 /* reassert IRQs if data left */
515 s
->update_irq(s
->update_arg
, q
->count
!= 0);
520 static void ps2_set_ledstate(PS2KbdState
*s
, int ledstate
)
522 trace_ps2_set_ledstate(s
, ledstate
);
523 s
->ledstate
= ledstate
;
524 kbd_put_ledstate(ledstate
);
527 static void ps2_reset_keyboard(PS2KbdState
*s
)
529 trace_ps2_reset_keyboard(s
);
532 ps2_reset_queue(&s
->common
);
533 ps2_set_ledstate(s
, 0);
536 void ps2_write_keyboard(void *opaque
, int val
)
538 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
540 trace_ps2_write_keyboard(opaque
, val
);
541 switch(s
->common
.write_cmd
) {
546 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
549 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
552 /* We emulate a MF2 AT keyboard here */
554 ps2_queue_3(&s
->common
,
559 ps2_queue_3(&s
->common
,
565 ps2_queue(&s
->common
, KBD_CMD_ECHO
);
569 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
571 case KBD_CMD_SCANCODE
:
572 case KBD_CMD_SET_LEDS
:
573 case KBD_CMD_SET_RATE
:
574 s
->common
.write_cmd
= val
;
575 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
577 case KBD_CMD_RESET_DISABLE
:
578 ps2_reset_keyboard(s
);
580 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
582 case KBD_CMD_RESET_ENABLE
:
583 ps2_reset_keyboard(s
);
585 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
588 ps2_reset_keyboard(s
);
589 ps2_queue_2(&s
->common
,
594 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
598 case KBD_CMD_SCANCODE
:
600 if (s
->common
.queue
.count
<= PS2_QUEUE_SIZE
- 2) {
601 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
602 ps2_put_keycode(s
, s
->scancode_set
);
604 } else if (val
>= 1 && val
<= 3) {
605 s
->scancode_set
= val
;
606 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
608 ps2_queue(&s
->common
, KBD_REPLY_RESEND
);
610 s
->common
.write_cmd
= -1;
612 case KBD_CMD_SET_LEDS
:
613 ps2_set_ledstate(s
, val
);
614 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
615 s
->common
.write_cmd
= -1;
617 case KBD_CMD_SET_RATE
:
618 ps2_queue(&s
->common
, KBD_REPLY_ACK
);
619 s
->common
.write_cmd
= -1;
624 /* Set the scancode translation mode.
626 1 = translated scancodes (used by qemu internally). */
628 void ps2_keyboard_set_translation(void *opaque
, int mode
)
630 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
631 trace_ps2_keyboard_set_translation(opaque
, mode
);
635 static int ps2_mouse_send_packet(PS2MouseState
*s
)
637 const int needed
= 3 + (s
->mouse_type
- 2);
641 if (PS2_QUEUE_SIZE
- s
->common
.queue
.count
< needed
) {
648 /* XXX: increase range to 8 bits ? */
657 b
= 0x08 | ((dx1
< 0) << 4) | ((dy1
< 0) << 5) | (s
->mouse_buttons
& 0x07);
658 ps2_queue_noirq(&s
->common
, b
);
659 ps2_queue_noirq(&s
->common
, dx1
& 0xff);
660 ps2_queue_noirq(&s
->common
, dy1
& 0xff);
661 /* extra byte for IMPS/2 or IMEX */
662 switch(s
->mouse_type
) {
670 ps2_queue_noirq(&s
->common
, dz1
& 0xff);
677 b
= (dz1
& 0x0f) | ((s
->mouse_buttons
& 0x18) << 1);
678 ps2_queue_noirq(&s
->common
, b
);
682 ps2_raise_irq(&s
->common
);
684 trace_ps2_mouse_send_packet(s
, dx1
, dy1
, dz1
, b
);
693 static void ps2_mouse_event(DeviceState
*dev
, QemuConsole
*src
,
696 static const int bmap
[INPUT_BUTTON__MAX
] = {
697 [INPUT_BUTTON_LEFT
] = PS2_MOUSE_BUTTON_LEFT
,
698 [INPUT_BUTTON_MIDDLE
] = PS2_MOUSE_BUTTON_MIDDLE
,
699 [INPUT_BUTTON_RIGHT
] = PS2_MOUSE_BUTTON_RIGHT
,
700 [INPUT_BUTTON_SIDE
] = PS2_MOUSE_BUTTON_SIDE
,
701 [INPUT_BUTTON_EXTRA
] = PS2_MOUSE_BUTTON_EXTRA
,
703 PS2MouseState
*s
= (PS2MouseState
*)dev
;
704 InputMoveEvent
*move
;
707 /* check if deltas are recorded when disabled */
708 if (!(s
->mouse_status
& MOUSE_STATUS_ENABLED
))
712 case INPUT_EVENT_KIND_REL
:
713 move
= evt
->u
.rel
.data
;
714 if (move
->axis
== INPUT_AXIS_X
) {
715 s
->mouse_dx
+= move
->value
;
716 } else if (move
->axis
== INPUT_AXIS_Y
) {
717 s
->mouse_dy
-= move
->value
;
721 case INPUT_EVENT_KIND_BTN
:
722 btn
= evt
->u
.btn
.data
;
724 s
->mouse_buttons
|= bmap
[btn
->button
];
725 if (btn
->button
== INPUT_BUTTON_WHEEL_UP
) {
727 } else if (btn
->button
== INPUT_BUTTON_WHEEL_DOWN
) {
731 s
->mouse_buttons
&= ~bmap
[btn
->button
];
741 static void ps2_mouse_sync(DeviceState
*dev
)
743 PS2MouseState
*s
= (PS2MouseState
*)dev
;
745 /* do not sync while disabled to prevent stream corruption */
746 if (!(s
->mouse_status
& MOUSE_STATUS_ENABLED
)) {
750 if (s
->mouse_buttons
) {
751 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER
);
753 if (!(s
->mouse_status
& MOUSE_STATUS_REMOTE
)) {
754 /* if not remote, send event. Multiple events are sent if
756 while (ps2_mouse_send_packet(s
)) {
757 if (s
->mouse_dx
== 0 && s
->mouse_dy
== 0 && s
->mouse_dz
== 0)
763 void ps2_mouse_fake_event(void *opaque
)
765 PS2MouseState
*s
= opaque
;
766 trace_ps2_mouse_fake_event(opaque
);
768 ps2_mouse_sync(opaque
);
771 void ps2_write_mouse(void *opaque
, int val
)
773 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
775 trace_ps2_write_mouse(opaque
, val
);
777 printf("kbd: write mouse 0x%02x\n", val
);
779 switch(s
->common
.write_cmd
) {
784 if (val
== AUX_RESET_WRAP
) {
786 ps2_queue(&s
->common
, AUX_ACK
);
788 } else if (val
!= AUX_RESET
) {
789 ps2_queue(&s
->common
, val
);
794 case AUX_SET_SCALE11
:
795 s
->mouse_status
&= ~MOUSE_STATUS_SCALE21
;
796 ps2_queue(&s
->common
, AUX_ACK
);
798 case AUX_SET_SCALE21
:
799 s
->mouse_status
|= MOUSE_STATUS_SCALE21
;
800 ps2_queue(&s
->common
, AUX_ACK
);
803 s
->mouse_status
&= ~MOUSE_STATUS_REMOTE
;
804 ps2_queue(&s
->common
, AUX_ACK
);
808 ps2_queue(&s
->common
, AUX_ACK
);
811 s
->mouse_status
|= MOUSE_STATUS_REMOTE
;
812 ps2_queue(&s
->common
, AUX_ACK
);
815 ps2_queue_2(&s
->common
,
821 s
->common
.write_cmd
= val
;
822 ps2_queue(&s
->common
, AUX_ACK
);
825 ps2_queue_4(&s
->common
,
829 s
->mouse_sample_rate
);
832 ps2_queue(&s
->common
, AUX_ACK
);
833 ps2_mouse_send_packet(s
);
836 s
->mouse_status
|= MOUSE_STATUS_ENABLED
;
837 ps2_queue(&s
->common
, AUX_ACK
);
839 case AUX_DISABLE_DEV
:
840 s
->mouse_status
&= ~MOUSE_STATUS_ENABLED
;
841 ps2_queue(&s
->common
, AUX_ACK
);
843 case AUX_SET_DEFAULT
:
844 s
->mouse_sample_rate
= 100;
845 s
->mouse_resolution
= 2;
847 ps2_queue(&s
->common
, AUX_ACK
);
850 s
->mouse_sample_rate
= 100;
851 s
->mouse_resolution
= 2;
854 ps2_reset_queue(&s
->common
);
855 ps2_queue_3(&s
->common
,
865 s
->mouse_sample_rate
= val
;
866 /* detect IMPS/2 or IMEX */
867 switch(s
->mouse_detect_state
) {
871 s
->mouse_detect_state
= 1;
875 s
->mouse_detect_state
= 2;
877 s
->mouse_detect_state
= 3;
879 s
->mouse_detect_state
= 0;
883 s
->mouse_type
= 3; /* IMPS/2 */
884 s
->mouse_detect_state
= 0;
888 s
->mouse_type
= 4; /* IMEX */
889 s
->mouse_detect_state
= 0;
892 ps2_queue(&s
->common
, AUX_ACK
);
893 s
->common
.write_cmd
= -1;
896 s
->mouse_resolution
= val
;
897 ps2_queue(&s
->common
, AUX_ACK
);
898 s
->common
.write_cmd
= -1;
903 static void ps2_common_reset(PS2State
*s
)
907 s
->update_irq(s
->update_arg
, 0);
910 static void ps2_common_post_load(PS2State
*s
)
912 PS2Queue
*q
= &s
->queue
;
914 uint8_t tmp_data
[PS2_QUEUE_SIZE
];
916 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
920 } else if (q
->count
> PS2_QUEUE_SIZE
) {
921 size
= PS2_QUEUE_SIZE
;
924 /* move the queue elements to the start of data array */
925 for (i
= 0; i
< size
; i
++) {
926 if (q
->rptr
< 0 || q
->rptr
>= sizeof(q
->data
)) {
929 tmp_data
[i
] = q
->data
[q
->rptr
++];
931 memcpy(q
->data
, tmp_data
, size
);
933 /* reset rptr/wptr/count */
935 q
->wptr
= (size
== PS2_QUEUE_SIZE
) ? 0 : size
;
939 static void ps2_kbd_reset(void *opaque
)
941 PS2KbdState
*s
= (PS2KbdState
*) opaque
;
943 trace_ps2_kbd_reset(opaque
);
944 ps2_common_reset(&s
->common
);
951 static void ps2_mouse_reset(void *opaque
)
953 PS2MouseState
*s
= (PS2MouseState
*) opaque
;
955 trace_ps2_mouse_reset(opaque
);
956 ps2_common_reset(&s
->common
);
958 s
->mouse_resolution
= 0;
959 s
->mouse_sample_rate
= 0;
962 s
->mouse_detect_state
= 0;
966 s
->mouse_buttons
= 0;
969 static const VMStateDescription vmstate_ps2_common
= {
970 .name
= "PS2 Common State",
972 .minimum_version_id
= 2,
973 .fields
= (VMStateField
[]) {
974 VMSTATE_INT32(write_cmd
, PS2State
),
975 VMSTATE_INT32(queue
.rptr
, PS2State
),
976 VMSTATE_INT32(queue
.wptr
, PS2State
),
977 VMSTATE_INT32(queue
.count
, PS2State
),
978 VMSTATE_BUFFER(queue
.data
, PS2State
),
979 VMSTATE_END_OF_LIST()
983 static bool ps2_keyboard_ledstate_needed(void *opaque
)
985 PS2KbdState
*s
= opaque
;
987 return s
->ledstate
!= 0; /* 0 is default state */
990 static int ps2_kbd_ledstate_post_load(void *opaque
, int version_id
)
992 PS2KbdState
*s
= opaque
;
994 kbd_put_ledstate(s
->ledstate
);
998 static const VMStateDescription vmstate_ps2_keyboard_ledstate
= {
999 .name
= "ps2kbd/ledstate",
1001 .minimum_version_id
= 2,
1002 .post_load
= ps2_kbd_ledstate_post_load
,
1003 .needed
= ps2_keyboard_ledstate_needed
,
1004 .fields
= (VMStateField
[]) {
1005 VMSTATE_INT32(ledstate
, PS2KbdState
),
1006 VMSTATE_END_OF_LIST()
1010 static bool ps2_keyboard_need_high_bit_needed(void *opaque
)
1012 PS2KbdState
*s
= opaque
;
1013 return s
->need_high_bit
!= 0; /* 0 is the usual state */
1016 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit
= {
1017 .name
= "ps2kbd/need_high_bit",
1019 .minimum_version_id
= 1,
1020 .needed
= ps2_keyboard_need_high_bit_needed
,
1021 .fields
= (VMStateField
[]) {
1022 VMSTATE_BOOL(need_high_bit
, PS2KbdState
),
1023 VMSTATE_END_OF_LIST()
1027 static int ps2_kbd_post_load(void* opaque
, int version_id
)
1029 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1030 PS2State
*ps2
= &s
->common
;
1032 if (version_id
== 2)
1035 ps2_common_post_load(ps2
);
1040 static int ps2_kbd_pre_save(void *opaque
)
1042 PS2KbdState
*s
= (PS2KbdState
*)opaque
;
1043 PS2State
*ps2
= &s
->common
;
1045 ps2_common_post_load(ps2
);
1050 static const VMStateDescription vmstate_ps2_keyboard
= {
1053 .minimum_version_id
= 2,
1054 .post_load
= ps2_kbd_post_load
,
1055 .pre_save
= ps2_kbd_pre_save
,
1056 .fields
= (VMStateField
[]) {
1057 VMSTATE_STRUCT(common
, PS2KbdState
, 0, vmstate_ps2_common
, PS2State
),
1058 VMSTATE_INT32(scan_enabled
, PS2KbdState
),
1059 VMSTATE_INT32(translate
, PS2KbdState
),
1060 VMSTATE_INT32_V(scancode_set
, PS2KbdState
,3),
1061 VMSTATE_END_OF_LIST()
1063 .subsections
= (const VMStateDescription
*[]) {
1064 &vmstate_ps2_keyboard_ledstate
,
1065 &vmstate_ps2_keyboard_need_high_bit
,
1070 static int ps2_mouse_post_load(void *opaque
, int version_id
)
1072 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1073 PS2State
*ps2
= &s
->common
;
1075 ps2_common_post_load(ps2
);
1080 static int ps2_mouse_pre_save(void *opaque
)
1082 PS2MouseState
*s
= (PS2MouseState
*)opaque
;
1083 PS2State
*ps2
= &s
->common
;
1085 ps2_common_post_load(ps2
);
1090 static const VMStateDescription vmstate_ps2_mouse
= {
1093 .minimum_version_id
= 2,
1094 .post_load
= ps2_mouse_post_load
,
1095 .pre_save
= ps2_mouse_pre_save
,
1096 .fields
= (VMStateField
[]) {
1097 VMSTATE_STRUCT(common
, PS2MouseState
, 0, vmstate_ps2_common
, PS2State
),
1098 VMSTATE_UINT8(mouse_status
, PS2MouseState
),
1099 VMSTATE_UINT8(mouse_resolution
, PS2MouseState
),
1100 VMSTATE_UINT8(mouse_sample_rate
, PS2MouseState
),
1101 VMSTATE_UINT8(mouse_wrap
, PS2MouseState
),
1102 VMSTATE_UINT8(mouse_type
, PS2MouseState
),
1103 VMSTATE_UINT8(mouse_detect_state
, PS2MouseState
),
1104 VMSTATE_INT32(mouse_dx
, PS2MouseState
),
1105 VMSTATE_INT32(mouse_dy
, PS2MouseState
),
1106 VMSTATE_INT32(mouse_dz
, PS2MouseState
),
1107 VMSTATE_UINT8(mouse_buttons
, PS2MouseState
),
1108 VMSTATE_END_OF_LIST()
1112 static QemuInputHandler ps2_keyboard_handler
= {
1113 .name
= "QEMU PS/2 Keyboard",
1114 .mask
= INPUT_EVENT_MASK_KEY
,
1115 .event
= ps2_keyboard_event
,
1118 void *ps2_kbd_init(void (*update_irq
)(void *, int), void *update_arg
)
1120 PS2KbdState
*s
= (PS2KbdState
*)g_malloc0(sizeof(PS2KbdState
));
1122 trace_ps2_kbd_init(s
);
1123 s
->common
.update_irq
= update_irq
;
1124 s
->common
.update_arg
= update_arg
;
1125 s
->scancode_set
= 2;
1126 vmstate_register(NULL
, 0, &vmstate_ps2_keyboard
, s
);
1127 qemu_input_handler_register((DeviceState
*)s
,
1128 &ps2_keyboard_handler
);
1129 qemu_register_reset(ps2_kbd_reset
, s
);
1133 static QemuInputHandler ps2_mouse_handler
= {
1134 .name
= "QEMU PS/2 Mouse",
1135 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_REL
,
1136 .event
= ps2_mouse_event
,
1137 .sync
= ps2_mouse_sync
,
1140 void *ps2_mouse_init(void (*update_irq
)(void *, int), void *update_arg
)
1142 PS2MouseState
*s
= (PS2MouseState
*)g_malloc0(sizeof(PS2MouseState
));
1144 trace_ps2_mouse_init(s
);
1145 s
->common
.update_irq
= update_irq
;
1146 s
->common
.update_arg
= update_arg
;
1147 vmstate_register(NULL
, 0, &vmstate_ps2_mouse
, s
);
1148 qemu_input_handler_register((DeviceState
*)s
,
1149 &ps2_mouse_handler
);
1150 qemu_register_reset(ps2_mouse_reset
, s
);