softfloat: Resolve type mismatches between declaration and implementation
[qemu/opensuse.git] / hw / ps2.c
blob91b73e08ae357058ca69f408f073d12b0649c6c0
1 /*
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
22 * THE SOFTWARE.
24 #include "hw.h"
25 #include "ps2.h"
26 #include "console.h"
28 /* debug PC keyboard */
29 //#define DEBUG_KBD
31 /* debug PC keyboard : only mouse */
32 //#define DEBUG_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_ID 0xAB /* Keyboard ID */
48 #define KBD_REPLY_ACK 0xFA /* Command ACK */
49 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
51 /* Mouse Commands */
52 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
53 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
54 #define AUX_SET_RES 0xE8 /* Set resolution */
55 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */
56 #define AUX_SET_STREAM 0xEA /* Set stream mode */
57 #define AUX_POLL 0xEB /* Poll */
58 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */
59 #define AUX_SET_WRAP 0xEE /* Set wrap mode */
60 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */
61 #define AUX_GET_TYPE 0xF2 /* Get type */
62 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
63 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
64 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
65 #define AUX_SET_DEFAULT 0xF6
66 #define AUX_RESET 0xFF /* Reset aux device */
67 #define AUX_ACK 0xFA /* Command byte ACK. */
69 #define MOUSE_STATUS_REMOTE 0x40
70 #define MOUSE_STATUS_ENABLED 0x20
71 #define MOUSE_STATUS_SCALE21 0x10
73 #define PS2_QUEUE_SIZE 256
75 typedef struct {
76 uint8_t data[PS2_QUEUE_SIZE];
77 int rptr, wptr, count;
78 } PS2Queue;
80 typedef struct {
81 PS2Queue queue;
82 int32_t write_cmd;
83 void (*update_irq)(void *, int);
84 void *update_arg;
85 } PS2State;
87 typedef struct {
88 PS2State common;
89 int scan_enabled;
90 /* Qemu uses translated PC scancodes internally. To avoid multiple
91 conversions we do the translation (if any) in the PS/2 emulation
92 not the keyboard controller. */
93 int translate;
94 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
95 } PS2KbdState;
97 typedef struct {
98 PS2State common;
99 uint8_t mouse_status;
100 uint8_t mouse_resolution;
101 uint8_t mouse_sample_rate;
102 uint8_t mouse_wrap;
103 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
104 uint8_t mouse_detect_state;
105 int mouse_dx; /* current values, needed for 'poll' mode */
106 int mouse_dy;
107 int mouse_dz;
108 uint8_t mouse_buttons;
109 } PS2MouseState;
111 /* Table to convert from PC scancodes to raw scancodes. */
112 static const unsigned char ps2_raw_keycode[128] = {
113 0, 118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
114 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
115 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
116 50, 49, 58, 65, 73, 74, 89, 124, 17, 41, 88, 5, 6, 4, 12, 3,
117 11, 2, 10, 1, 9, 119, 126, 108, 117, 125, 123, 107, 115, 116, 121, 105,
118 114, 122, 112, 113, 127, 96, 97, 120, 7, 15, 23, 31, 39, 47, 55, 63,
119 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
120 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
122 static const unsigned char ps2_raw_keycode_set3[128] = {
123 0, 8, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
124 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,
125 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,
126 50, 49, 58, 65, 73, 74, 89, 126, 25, 41, 20, 7, 15, 23, 31, 39,
127 47, 2, 63, 71, 79, 118, 95, 108, 117, 125, 132, 107, 115, 116, 124, 105,
128 114, 122, 112, 113, 127, 96, 97, 86, 94, 15, 23, 31, 39, 47, 55, 63,
129 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
130 19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
133 void ps2_queue(void *opaque, int b)
135 PS2State *s = (PS2State *)opaque;
136 PS2Queue *q = &s->queue;
138 if (q->count >= PS2_QUEUE_SIZE)
139 return;
140 q->data[q->wptr] = b;
141 if (++q->wptr == PS2_QUEUE_SIZE)
142 q->wptr = 0;
143 q->count++;
144 s->update_irq(s->update_arg, 1);
148 keycode is expressed as follow:
149 bit 7 - 0 key pressed, 1 = key released
150 bits 6-0 - translated scancode set 2
152 static void ps2_put_keycode(void *opaque, int keycode)
154 PS2KbdState *s = opaque;
156 /* XXX: add support for scancode set 1 */
157 if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) {
158 if (keycode & 0x80) {
159 ps2_queue(&s->common, 0xf0);
161 if (s->scancode_set == 2) {
162 keycode = ps2_raw_keycode[keycode & 0x7f];
163 } else if (s->scancode_set == 3) {
164 keycode = ps2_raw_keycode_set3[keycode & 0x7f];
167 ps2_queue(&s->common, keycode);
170 uint32_t ps2_read_data(void *opaque)
172 PS2State *s = (PS2State *)opaque;
173 PS2Queue *q;
174 int val, index;
176 q = &s->queue;
177 if (q->count == 0) {
178 /* NOTE: if no data left, we return the last keyboard one
179 (needed for EMM386) */
180 /* XXX: need a timer to do things correctly */
181 index = q->rptr - 1;
182 if (index < 0)
183 index = PS2_QUEUE_SIZE - 1;
184 val = q->data[index];
185 } else {
186 val = q->data[q->rptr];
187 if (++q->rptr == PS2_QUEUE_SIZE)
188 q->rptr = 0;
189 q->count--;
190 /* reading deasserts IRQ */
191 s->update_irq(s->update_arg, 0);
192 /* reassert IRQs if data left */
193 s->update_irq(s->update_arg, q->count != 0);
195 return val;
198 static void ps2_reset_keyboard(PS2KbdState *s)
200 s->scan_enabled = 1;
201 s->scancode_set = 2;
202 kbd_put_ledstate(0);
205 void ps2_write_keyboard(void *opaque, int val)
207 PS2KbdState *s = (PS2KbdState *)opaque;
209 switch(s->common.write_cmd) {
210 default:
211 case -1:
212 switch(val) {
213 case 0x00:
214 ps2_queue(&s->common, KBD_REPLY_ACK);
215 break;
216 case 0x05:
217 ps2_queue(&s->common, KBD_REPLY_RESEND);
218 break;
219 case KBD_CMD_GET_ID:
220 ps2_queue(&s->common, KBD_REPLY_ACK);
221 /* We emulate a MF2 AT keyboard here */
222 ps2_queue(&s->common, KBD_REPLY_ID);
223 if (s->translate)
224 ps2_queue(&s->common, 0x41);
225 else
226 ps2_queue(&s->common, 0x83);
227 break;
228 case KBD_CMD_ECHO:
229 ps2_queue(&s->common, KBD_CMD_ECHO);
230 break;
231 case KBD_CMD_ENABLE:
232 s->scan_enabled = 1;
233 ps2_queue(&s->common, KBD_REPLY_ACK);
234 break;
235 case KBD_CMD_SCANCODE:
236 case KBD_CMD_SET_LEDS:
237 case KBD_CMD_SET_RATE:
238 s->common.write_cmd = val;
239 ps2_queue(&s->common, KBD_REPLY_ACK);
240 break;
241 case KBD_CMD_RESET_DISABLE:
242 ps2_reset_keyboard(s);
243 s->scan_enabled = 0;
244 ps2_queue(&s->common, KBD_REPLY_ACK);
245 break;
246 case KBD_CMD_RESET_ENABLE:
247 ps2_reset_keyboard(s);
248 s->scan_enabled = 1;
249 ps2_queue(&s->common, KBD_REPLY_ACK);
250 break;
251 case KBD_CMD_RESET:
252 ps2_reset_keyboard(s);
253 ps2_queue(&s->common, KBD_REPLY_ACK);
254 ps2_queue(&s->common, KBD_REPLY_POR);
255 break;
256 default:
257 ps2_queue(&s->common, KBD_REPLY_ACK);
258 break;
260 break;
261 case KBD_CMD_SCANCODE:
262 if (val == 0) {
263 if (s->scancode_set == 1)
264 ps2_put_keycode(s, 0x43);
265 else if (s->scancode_set == 2)
266 ps2_put_keycode(s, 0x41);
267 else if (s->scancode_set == 3)
268 ps2_put_keycode(s, 0x3f);
269 } else {
270 if (val >= 1 && val <= 3)
271 s->scancode_set = val;
272 ps2_queue(&s->common, KBD_REPLY_ACK);
274 s->common.write_cmd = -1;
275 break;
276 case KBD_CMD_SET_LEDS:
277 kbd_put_ledstate(val);
278 ps2_queue(&s->common, KBD_REPLY_ACK);
279 s->common.write_cmd = -1;
280 break;
281 case KBD_CMD_SET_RATE:
282 ps2_queue(&s->common, KBD_REPLY_ACK);
283 s->common.write_cmd = -1;
284 break;
288 /* Set the scancode translation mode.
289 0 = raw scancodes.
290 1 = translated scancodes (used by qemu internally). */
292 void ps2_keyboard_set_translation(void *opaque, int mode)
294 PS2KbdState *s = (PS2KbdState *)opaque;
295 s->translate = mode;
298 static void ps2_mouse_send_packet(PS2MouseState *s)
300 unsigned int b;
301 int dx1, dy1, dz1;
303 dx1 = s->mouse_dx;
304 dy1 = s->mouse_dy;
305 dz1 = s->mouse_dz;
306 /* XXX: increase range to 8 bits ? */
307 if (dx1 > 127)
308 dx1 = 127;
309 else if (dx1 < -127)
310 dx1 = -127;
311 if (dy1 > 127)
312 dy1 = 127;
313 else if (dy1 < -127)
314 dy1 = -127;
315 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
316 ps2_queue(&s->common, b);
317 ps2_queue(&s->common, dx1 & 0xff);
318 ps2_queue(&s->common, dy1 & 0xff);
319 /* extra byte for IMPS/2 or IMEX */
320 switch(s->mouse_type) {
321 default:
322 break;
323 case 3:
324 if (dz1 > 127)
325 dz1 = 127;
326 else if (dz1 < -127)
327 dz1 = -127;
328 ps2_queue(&s->common, dz1 & 0xff);
329 break;
330 case 4:
331 if (dz1 > 7)
332 dz1 = 7;
333 else if (dz1 < -7)
334 dz1 = -7;
335 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
336 ps2_queue(&s->common, b);
337 break;
340 /* update deltas */
341 s->mouse_dx -= dx1;
342 s->mouse_dy -= dy1;
343 s->mouse_dz -= dz1;
346 static void ps2_mouse_event(void *opaque,
347 int dx, int dy, int dz, int buttons_state)
349 PS2MouseState *s = opaque;
351 /* check if deltas are recorded when disabled */
352 if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
353 return;
355 s->mouse_dx += dx;
356 s->mouse_dy -= dy;
357 s->mouse_dz += dz;
358 /* XXX: SDL sometimes generates nul events: we delete them */
359 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
360 s->mouse_buttons == buttons_state)
361 return;
362 s->mouse_buttons = buttons_state;
364 if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
365 (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
366 for(;;) {
367 /* if not remote, send event. Multiple events are sent if
368 too big deltas */
369 ps2_mouse_send_packet(s);
370 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
371 break;
376 void ps2_mouse_fake_event(void *opaque)
378 ps2_mouse_event(opaque, 1, 0, 0, 0);
381 void ps2_write_mouse(void *opaque, int val)
383 PS2MouseState *s = (PS2MouseState *)opaque;
384 #ifdef DEBUG_MOUSE
385 printf("kbd: write mouse 0x%02x\n", val);
386 #endif
387 switch(s->common.write_cmd) {
388 default:
389 case -1:
390 /* mouse command */
391 if (s->mouse_wrap) {
392 if (val == AUX_RESET_WRAP) {
393 s->mouse_wrap = 0;
394 ps2_queue(&s->common, AUX_ACK);
395 return;
396 } else if (val != AUX_RESET) {
397 ps2_queue(&s->common, val);
398 return;
401 switch(val) {
402 case AUX_SET_SCALE11:
403 s->mouse_status &= ~MOUSE_STATUS_SCALE21;
404 ps2_queue(&s->common, AUX_ACK);
405 break;
406 case AUX_SET_SCALE21:
407 s->mouse_status |= MOUSE_STATUS_SCALE21;
408 ps2_queue(&s->common, AUX_ACK);
409 break;
410 case AUX_SET_STREAM:
411 s->mouse_status &= ~MOUSE_STATUS_REMOTE;
412 ps2_queue(&s->common, AUX_ACK);
413 break;
414 case AUX_SET_WRAP:
415 s->mouse_wrap = 1;
416 ps2_queue(&s->common, AUX_ACK);
417 break;
418 case AUX_SET_REMOTE:
419 s->mouse_status |= MOUSE_STATUS_REMOTE;
420 ps2_queue(&s->common, AUX_ACK);
421 break;
422 case AUX_GET_TYPE:
423 ps2_queue(&s->common, AUX_ACK);
424 ps2_queue(&s->common, s->mouse_type);
425 break;
426 case AUX_SET_RES:
427 case AUX_SET_SAMPLE:
428 s->common.write_cmd = val;
429 ps2_queue(&s->common, AUX_ACK);
430 break;
431 case AUX_GET_SCALE:
432 ps2_queue(&s->common, AUX_ACK);
433 ps2_queue(&s->common, s->mouse_status);
434 ps2_queue(&s->common, s->mouse_resolution);
435 ps2_queue(&s->common, s->mouse_sample_rate);
436 break;
437 case AUX_POLL:
438 ps2_queue(&s->common, AUX_ACK);
439 ps2_mouse_send_packet(s);
440 break;
441 case AUX_ENABLE_DEV:
442 s->mouse_status |= MOUSE_STATUS_ENABLED;
443 ps2_queue(&s->common, AUX_ACK);
444 break;
445 case AUX_DISABLE_DEV:
446 s->mouse_status &= ~MOUSE_STATUS_ENABLED;
447 ps2_queue(&s->common, AUX_ACK);
448 break;
449 case AUX_SET_DEFAULT:
450 s->mouse_sample_rate = 100;
451 s->mouse_resolution = 2;
452 s->mouse_status = 0;
453 ps2_queue(&s->common, AUX_ACK);
454 break;
455 case AUX_RESET:
456 s->mouse_sample_rate = 100;
457 s->mouse_resolution = 2;
458 s->mouse_status = 0;
459 s->mouse_type = 0;
460 ps2_queue(&s->common, AUX_ACK);
461 ps2_queue(&s->common, 0xaa);
462 ps2_queue(&s->common, s->mouse_type);
463 break;
464 default:
465 break;
467 break;
468 case AUX_SET_SAMPLE:
469 s->mouse_sample_rate = val;
470 /* detect IMPS/2 or IMEX */
471 switch(s->mouse_detect_state) {
472 default:
473 case 0:
474 if (val == 200)
475 s->mouse_detect_state = 1;
476 break;
477 case 1:
478 if (val == 100)
479 s->mouse_detect_state = 2;
480 else if (val == 200)
481 s->mouse_detect_state = 3;
482 else
483 s->mouse_detect_state = 0;
484 break;
485 case 2:
486 if (val == 80)
487 s->mouse_type = 3; /* IMPS/2 */
488 s->mouse_detect_state = 0;
489 break;
490 case 3:
491 if (val == 80)
492 s->mouse_type = 4; /* IMEX */
493 s->mouse_detect_state = 0;
494 break;
496 ps2_queue(&s->common, AUX_ACK);
497 s->common.write_cmd = -1;
498 break;
499 case AUX_SET_RES:
500 s->mouse_resolution = val;
501 ps2_queue(&s->common, AUX_ACK);
502 s->common.write_cmd = -1;
503 break;
507 static void ps2_common_reset(PS2State *s)
509 PS2Queue *q;
510 s->write_cmd = -1;
511 q = &s->queue;
512 q->rptr = 0;
513 q->wptr = 0;
514 q->count = 0;
515 s->update_irq(s->update_arg, 0);
518 static void ps2_kbd_reset(void *opaque)
520 PS2KbdState *s = (PS2KbdState *) opaque;
522 ps2_common_reset(&s->common);
523 s->scan_enabled = 0;
524 s->translate = 0;
525 s->scancode_set = 0;
528 static void ps2_mouse_reset(void *opaque)
530 PS2MouseState *s = (PS2MouseState *) opaque;
532 ps2_common_reset(&s->common);
533 s->mouse_status = 0;
534 s->mouse_resolution = 0;
535 s->mouse_sample_rate = 0;
536 s->mouse_wrap = 0;
537 s->mouse_type = 0;
538 s->mouse_detect_state = 0;
539 s->mouse_dx = 0;
540 s->mouse_dy = 0;
541 s->mouse_dz = 0;
542 s->mouse_buttons = 0;
545 static const VMStateDescription vmstate_ps2_common = {
546 .name = "PS2 Common State",
547 .version_id = 3,
548 .minimum_version_id = 2,
549 .minimum_version_id_old = 2,
550 .fields = (VMStateField []) {
551 VMSTATE_INT32(write_cmd, PS2State),
552 VMSTATE_INT32(queue.rptr, PS2State),
553 VMSTATE_INT32(queue.wptr, PS2State),
554 VMSTATE_INT32(queue.count, PS2State),
555 VMSTATE_BUFFER(queue.data, PS2State),
556 VMSTATE_END_OF_LIST()
560 static int ps2_kbd_post_load(void* opaque, int version_id)
562 PS2KbdState *s = (PS2KbdState*)opaque;
564 if (version_id == 2)
565 s->scancode_set=2;
566 return 0;
569 static const VMStateDescription vmstate_ps2_keyboard = {
570 .name = "ps2kbd",
571 .version_id = 3,
572 .minimum_version_id = 2,
573 .minimum_version_id_old = 2,
574 .post_load = ps2_kbd_post_load,
575 .fields = (VMStateField []) {
576 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
577 VMSTATE_INT32(scan_enabled, PS2KbdState),
578 VMSTATE_INT32(translate, PS2KbdState),
579 VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
580 VMSTATE_END_OF_LIST()
584 static const VMStateDescription vmstate_ps2_mouse = {
585 .name = "ps2mouse",
586 .version_id = 2,
587 .minimum_version_id = 2,
588 .minimum_version_id_old = 2,
589 .fields = (VMStateField []) {
590 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
591 VMSTATE_UINT8(mouse_status, PS2MouseState),
592 VMSTATE_UINT8(mouse_resolution, PS2MouseState),
593 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
594 VMSTATE_UINT8(mouse_wrap, PS2MouseState),
595 VMSTATE_UINT8(mouse_type, PS2MouseState),
596 VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
597 VMSTATE_INT32(mouse_dx, PS2MouseState),
598 VMSTATE_INT32(mouse_dy, PS2MouseState),
599 VMSTATE_INT32(mouse_dz, PS2MouseState),
600 VMSTATE_UINT8(mouse_buttons, PS2MouseState),
601 VMSTATE_END_OF_LIST()
605 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
607 PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
609 s->common.update_irq = update_irq;
610 s->common.update_arg = update_arg;
611 s->scancode_set = 2;
612 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
613 qemu_add_kbd_event_handler(ps2_put_keycode, s);
614 qemu_register_reset(ps2_kbd_reset, s);
615 return s;
618 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
620 PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
622 s->common.update_irq = update_irq;
623 s->common.update_arg = update_arg;
624 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
625 qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
626 qemu_register_reset(ps2_mouse_reset, s);
627 return s;