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
28 /* debug PC keyboard */
31 /* debug PC keyboard : only mouse */
34 /* Keyboard Commands */
35 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
36 #define KBD_CMD_ECHO 0xEE
37 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */
38 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */
39 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
40 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
41 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */
42 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */
43 #define KBD_CMD_RESET 0xFF /* Reset */
45 /* Keyboard Replies */
46 #define KBD_REPLY_POR 0xAA /* Power on reset */
47 #define KBD_REPLY_ACK 0xFA /* Command ACK */
48 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
51 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
52 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
53 #define AUX_SET_RES 0xE8 /* Set resolution */
54 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
55 #define AUX_SET_STREAM 0xEA /* Set stream mode */
56 #define AUX_POLL 0xEB /* Poll */
57 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
58 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
59 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
60 #define AUX_GET_TYPE 0xF2 /* Get type */
61 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
62 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
63 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
64 #define AUX_SET_DEFAULT 0xF6
65 #define AUX_RESET 0xFF /* Reset aux device */
66 #define AUX_ACK 0xFA /* Command byte ACK. */
68 #define MOUSE_STATUS_REMOTE 0x40
69 #define MOUSE_STATUS_ENABLED 0x20
70 #define MOUSE_STATUS_SCALE21 0x10
72 #define PS2_QUEUE_SIZE 256
75 uint8_t data[PS2_QUEUE_SIZE];
76 int rptr, wptr, count;
82 void (*update_irq)(void *, int);
89 /* Qemu uses translated PC scancodes internally. To avoid multiple
90 conversions we do the translation (if any) in the PS/2 emulation
91 not the keyboard controller. */
93 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
99 uint8_t mouse_resolution;
100 uint8_t mouse_sample_rate;
102 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
103 uint8_t mouse_detect_state;
104 int mouse_dx; /* current values, needed for 'poll' mode */
107 uint8_t mouse_buttons;
110 /* Table to convert from PC scancodes to raw scancodes. */
111 static const unsigned char ps2_raw_keycode[128] = {
112 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
113 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
114 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
115 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,
116 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,
117 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,
118 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
119 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
122 void ps2_queue(void *opaque, int b)
124 PS2State *s = (PS2State *)opaque;
125 PS2Queue *q = &s->queue;
127 if (q->count >= PS2_QUEUE_SIZE)
129 q->data[q->wptr] = b;
130 if (++q->wptr == PS2_QUEUE_SIZE)
133 s->update_irq(s->update_arg, 1);
136 /* keycode is expressed in scancode set 2 */
137 static void ps2_put_keycode(void *opaque, int keycode)
139 PS2KbdState *s = opaque;
141 /* XXX: add support for scancode sets 1 and 3 */
142 if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
145 ps2_queue(&s->common, 0xf0);
146 keycode = ps2_raw_keycode[keycode & 0x7f];
148 ps2_queue(&s->common, keycode);
151 uint32_t ps2_read_data(void *opaque)
153 PS2State *s = (PS2State *)opaque;
159 /* NOTE: if no data left, we return the last keyboard one
160 (needed for EMM386) */
161 /* XXX: need a timer to do things correctly */
164 index = PS2_QUEUE_SIZE - 1;
165 val = q->data[index];
167 val = q->data[q->rptr];
168 if (++q->rptr == PS2_QUEUE_SIZE)
171 /* reading deasserts IRQ */
172 s->update_irq(s->update_arg, 0);
173 /* reassert IRQs if data left */
174 s->update_irq(s->update_arg, q->count != 0);
179 static void ps2_reset_keyboard(PS2KbdState *s)
185 void ps2_write_keyboard(void *opaque, int val)
187 PS2KbdState *s = (PS2KbdState *)opaque;
189 switch(s->common.write_cmd) {
194 ps2_queue(&s->common, KBD_REPLY_ACK);
197 ps2_queue(&s->common, KBD_REPLY_RESEND);
200 ps2_queue(&s->common, KBD_REPLY_ACK);
201 /* We emulate a MF2 AT keyboard here */
202 ps2_put_keycode(s, 0xab);
203 ps2_put_keycode(s, 0x83);
206 ps2_queue(&s->common, KBD_CMD_ECHO);
210 ps2_queue(&s->common, KBD_REPLY_ACK);
212 case KBD_CMD_SCANCODE:
213 case KBD_CMD_SET_LEDS:
214 case KBD_CMD_SET_RATE:
215 s->common.write_cmd = val;
216 ps2_queue(&s->common, KBD_REPLY_ACK);
218 case KBD_CMD_RESET_DISABLE:
219 ps2_reset_keyboard(s);
221 ps2_queue(&s->common, KBD_REPLY_ACK);
223 case KBD_CMD_RESET_ENABLE:
224 ps2_reset_keyboard(s);
226 ps2_queue(&s->common, KBD_REPLY_ACK);
229 ps2_reset_keyboard(s);
230 ps2_queue(&s->common, KBD_REPLY_ACK);
231 ps2_queue(&s->common, KBD_REPLY_POR);
234 ps2_queue(&s->common, KBD_REPLY_ACK);
238 case KBD_CMD_SCANCODE:
240 if (s->scancode_set == 1)
241 ps2_put_keycode(s, 0x43);
242 else if (s->scancode_set == 2)
243 ps2_put_keycode(s, 0x41);
244 else if (s->scancode_set == 3)
245 ps2_put_keycode(s, 0x3f);
247 if (val >= 1 && val <= 3)
248 s->scancode_set = val;
249 ps2_queue(&s->common, KBD_REPLY_ACK);
251 s->common.write_cmd = -1;
253 case KBD_CMD_SET_LEDS:
254 ps2_queue(&s->common, KBD_REPLY_ACK);
255 s->common.write_cmd = -1;
257 case KBD_CMD_SET_RATE:
258 ps2_queue(&s->common, KBD_REPLY_ACK);
259 s->common.write_cmd = -1;
264 /* Set the scancode translation mode.
266 1 = translated scancodes (used by qemu internally). */
268 void ps2_keyboard_set_translation(void *opaque, int mode)
270 PS2KbdState *s = (PS2KbdState *)opaque;
274 static void ps2_mouse_send_packet(PS2MouseState *s)
282 /* XXX: increase range to 8 bits ? */
291 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
292 ps2_queue(&s->common, b);
293 ps2_queue(&s->common, dx1 & 0xff);
294 ps2_queue(&s->common, dy1 & 0xff);
295 /* extra byte for IMPS/2 or IMEX */
296 switch(s->mouse_type) {
304 ps2_queue(&s->common, dz1 & 0xff);
311 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
312 ps2_queue(&s->common, b);
322 static void ps2_mouse_event(void *opaque,
323 int dx, int dy, int dz, int buttons_state)
325 PS2MouseState *s = opaque;
327 /* check if deltas are recorded when disabled */
328 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
334 /* XXX: SDL sometimes generates nul events: we delete them */
335 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
336 s->mouse_buttons == buttons_state)
338 s->mouse_buttons = buttons_state;
340 if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
341 (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
343 /* if not remote, send event. Multiple events are sent if
345 ps2_mouse_send_packet(s);
346 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
352 void ps2_mouse_fake_event(void *opaque)
354 ps2_mouse_event(opaque, 1, 0, 0, 0);
357 void ps2_write_mouse(void *opaque, int val)
359 PS2MouseState *s = (PS2MouseState *)opaque;
361 printf("kbd: write mouse 0x%02x\n", val);
363 switch(s->common.write_cmd) {
368 if (val == AUX_RESET_WRAP) {
370 ps2_queue(&s->common, AUX_ACK);
372 } else if (val != AUX_RESET) {
373 ps2_queue(&s->common, val);
378 case AUX_SET_SCALE11:
379 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
380 ps2_queue(&s->common, AUX_ACK);
382 case AUX_SET_SCALE21:
383 s->mouse_status |= MOUSE_STATUS_SCALE21;
384 ps2_queue(&s->common, AUX_ACK);
387 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
388 ps2_queue(&s->common, AUX_ACK);
392 ps2_queue(&s->common, AUX_ACK);
395 s->mouse_status |= MOUSE_STATUS_REMOTE;
396 ps2_queue(&s->common, AUX_ACK);
399 ps2_queue(&s->common, AUX_ACK);
400 ps2_queue(&s->common, s->mouse_type);
404 s->common.write_cmd = val;
405 ps2_queue(&s->common, AUX_ACK);
408 ps2_queue(&s->common, AUX_ACK);
409 ps2_queue(&s->common, s->mouse_status);
410 ps2_queue(&s->common, s->mouse_resolution);
411 ps2_queue(&s->common, s->mouse_sample_rate);
414 ps2_queue(&s->common, AUX_ACK);
415 ps2_mouse_send_packet(s);
418 s->mouse_status |= MOUSE_STATUS_ENABLED;
419 ps2_queue(&s->common, AUX_ACK);
421 case AUX_DISABLE_DEV:
422 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
423 ps2_queue(&s->common, AUX_ACK);
425 case AUX_SET_DEFAULT:
426 s->mouse_sample_rate = 100;
427 s->mouse_resolution = 2;
429 ps2_queue(&s->common, AUX_ACK);
432 s->mouse_sample_rate = 100;
433 s->mouse_resolution = 2;
436 ps2_queue(&s->common, AUX_ACK);
437 ps2_queue(&s->common, 0xaa);
438 ps2_queue(&s->common, s->mouse_type);
445 s->mouse_sample_rate = val;
446 /* detect IMPS/2 or IMEX */
447 switch(s->mouse_detect_state) {
451 s->mouse_detect_state = 1;
455 s->mouse_detect_state = 2;
457 s->mouse_detect_state = 3;
459 s->mouse_detect_state = 0;
463 s->mouse_type = 3; /* IMPS/2 */
464 s->mouse_detect_state = 0;
468 s->mouse_type = 4; /* IMEX */
469 s->mouse_detect_state = 0;
472 ps2_queue(&s->common, AUX_ACK);
473 s->common.write_cmd = -1;
476 s->mouse_resolution = val;
477 ps2_queue(&s->common, AUX_ACK);
478 s->common.write_cmd = -1;
483 static void ps2_reset(void *opaque)
485 PS2State *s = (PS2State *)opaque;
494 static void ps2_common_save (QEMUFile *f, PS2State *s)
496 qemu_put_be32 (f, s->write_cmd);
497 qemu_put_be32 (f, s->queue.rptr);
498 qemu_put_be32 (f, s->queue.wptr);
499 qemu_put_be32 (f, s->queue.count);
500 qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
503 static void ps2_common_load (QEMUFile *f, PS2State *s)
505 s->write_cmd=qemu_get_be32 (f);
506 s->queue.rptr=qemu_get_be32 (f);
507 s->queue.wptr=qemu_get_be32 (f);
508 s->queue.count=qemu_get_be32 (f);
509 qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
512 static void ps2_kbd_save(QEMUFile* f, void* opaque)
514 PS2KbdState *s = (PS2KbdState*)opaque;
516 ps2_common_save (f, &s->common);
517 qemu_put_be32(f, s->scan_enabled);
518 qemu_put_be32(f, s->translate);
519 qemu_put_be32(f, s->scancode_set);
522 static void ps2_mouse_save(QEMUFile* f, void* opaque)
524 PS2MouseState *s = (PS2MouseState*)opaque;
526 ps2_common_save (f, &s->common);
527 qemu_put_8s(f, &s->mouse_status);
528 qemu_put_8s(f, &s->mouse_resolution);
529 qemu_put_8s(f, &s->mouse_sample_rate);
530 qemu_put_8s(f, &s->mouse_wrap);
531 qemu_put_8s(f, &s->mouse_type);
532 qemu_put_8s(f, &s->mouse_detect_state);
533 qemu_put_be32(f, s->mouse_dx);
534 qemu_put_be32(f, s->mouse_dy);
535 qemu_put_be32(f, s->mouse_dz);
536 qemu_put_8s(f, &s->mouse_buttons);
539 static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
541 PS2KbdState *s = (PS2KbdState*)opaque;
543 if (version_id != 2 && version_id != 3)
546 ps2_common_load (f, &s->common);
547 s->scan_enabled=qemu_get_be32(f);
548 s->translate=qemu_get_be32(f);
550 s->scancode_set=qemu_get_be32(f);
556 static int ps2_mouse_load(QEMUFile* f, void* opaque, int version_id)
558 PS2MouseState *s = (PS2MouseState*)opaque;
563 ps2_common_load (f, &s->common);
564 qemu_get_8s(f, &s->mouse_status);
565 qemu_get_8s(f, &s->mouse_resolution);
566 qemu_get_8s(f, &s->mouse_sample_rate);
567 qemu_get_8s(f, &s->mouse_wrap);
568 qemu_get_8s(f, &s->mouse_type);
569 qemu_get_8s(f, &s->mouse_detect_state);
570 s->mouse_dx=qemu_get_be32(f);
571 s->mouse_dy=qemu_get_be32(f);
572 s->mouse_dz=qemu_get_be32(f);
573 qemu_get_8s(f, &s->mouse_buttons);
577 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
579 PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
581 s->common.update_irq = update_irq;
582 s->common.update_arg = update_arg;
584 ps2_reset(&s->common);
585 register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s);
586 qemu_add_kbd_event_handler(ps2_put_keycode, s);
587 qemu_register_reset(ps2_reset, &s->common);
591 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
593 PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
595 s->common.update_irq = update_irq;
596 s->common.update_arg = update_arg;
597 ps2_reset(&s->common);
598 register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
599 qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
600 qemu_register_reset(ps2_reset, &s->common);