Dynamic handling of guest mice, by Lonnie Mendez.
[qemu] / hw / ps2.c
1 /*
2  * QEMU PS/2 keyboard/mouse emulation
3  * 
4  * Copyright (c) 2003 Fabrice Bellard
5  * 
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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.
23  */
24 #include "vl.h"
25
26 /* debug PC keyboard */
27 //#define DEBUG_KBD
28
29 /* debug PC keyboard : only mouse */
30 //#define DEBUG_MOUSE
31
32 /* Keyboard Commands */
33 #define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
34 #define KBD_CMD_ECHO            0xEE
35 #define KBD_CMD_GET_ID          0xF2    /* get keyboard ID */
36 #define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
37 #define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
38 #define KBD_CMD_RESET_DISABLE   0xF5    /* reset and disable scanning */
39 #define KBD_CMD_RESET_ENABLE    0xF6    /* reset and enable scanning */
40 #define KBD_CMD_RESET           0xFF    /* Reset */
41
42 /* Keyboard Replies */
43 #define KBD_REPLY_POR           0xAA    /* Power on reset */
44 #define KBD_REPLY_ACK           0xFA    /* Command ACK */
45 #define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
46
47 /* Mouse Commands */
48 #define AUX_SET_SCALE11         0xE6    /* Set 1:1 scaling */
49 #define AUX_SET_SCALE21         0xE7    /* Set 2:1 scaling */
50 #define AUX_SET_RES             0xE8    /* Set resolution */
51 #define AUX_GET_SCALE           0xE9    /* Get scaling factor */
52 #define AUX_SET_STREAM          0xEA    /* Set stream mode */
53 #define AUX_POLL                0xEB    /* Poll */
54 #define AUX_RESET_WRAP          0xEC    /* Reset wrap mode */
55 #define AUX_SET_WRAP            0xEE    /* Set wrap mode */
56 #define AUX_SET_REMOTE          0xF0    /* Set remote mode */
57 #define AUX_GET_TYPE            0xF2    /* Get type */
58 #define AUX_SET_SAMPLE          0xF3    /* Set sample rate */
59 #define AUX_ENABLE_DEV          0xF4    /* Enable aux device */
60 #define AUX_DISABLE_DEV         0xF5    /* Disable aux device */
61 #define AUX_SET_DEFAULT         0xF6
62 #define AUX_RESET               0xFF    /* Reset aux device */
63 #define AUX_ACK                 0xFA    /* Command byte ACK. */
64
65 #define MOUSE_STATUS_REMOTE     0x40
66 #define MOUSE_STATUS_ENABLED    0x20
67 #define MOUSE_STATUS_SCALE21    0x10
68
69 #define PS2_QUEUE_SIZE 256
70
71 typedef struct {
72     uint8_t data[PS2_QUEUE_SIZE];
73     int rptr, wptr, count;
74 } PS2Queue;
75
76 typedef struct {
77     PS2Queue queue;
78     int32_t write_cmd;
79     void (*update_irq)(void *, int);
80     void *update_arg;
81 } PS2State;
82
83 typedef struct {
84     PS2State common;
85     int scan_enabled;
86     /* Qemu uses translated PC scancodes internally.  To avoid multiple
87        conversions we do the translation (if any) in the PS/2 emulation
88        not the keyboard controller.  */
89     int translate;
90 } PS2KbdState;
91
92 typedef struct {
93     PS2State common;
94     uint8_t mouse_status;
95     uint8_t mouse_resolution;
96     uint8_t mouse_sample_rate;
97     uint8_t mouse_wrap;
98     uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
99     uint8_t mouse_detect_state;
100     int mouse_dx; /* current values, needed for 'poll' mode */
101     int mouse_dy;
102     int mouse_dz;
103     uint8_t mouse_buttons;
104 } PS2MouseState;
105
106 /* Table to convert from PC scancodes to raw scancodes.  */
107 static const unsigned char ps2_raw_keycode[128] = {
108           0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
109          21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
110          35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
111          50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3,
112          11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105,
113         114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63,
114          71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,
115          19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110
116 };
117
118 void ps2_queue(void *opaque, int b)
119 {
120     PS2State *s = (PS2State *)opaque;
121     PS2Queue *q = &s->queue;
122
123     if (q->count >= PS2_QUEUE_SIZE)
124         return;
125     q->data[q->wptr] = b;
126     if (++q->wptr == PS2_QUEUE_SIZE)
127         q->wptr = 0;
128     q->count++;
129     s->update_irq(s->update_arg, 1);
130 }
131
132 static void ps2_put_keycode(void *opaque, int keycode)
133 {
134     PS2KbdState *s = opaque;
135     if (!s->translate && keycode < 0xe0)
136       {
137         if (keycode & 0x80)
138             ps2_queue(&s->common, 0xf0);
139         keycode = ps2_raw_keycode[keycode & 0x7f];
140       }
141     ps2_queue(&s->common, keycode);
142 }
143
144 uint32_t ps2_read_data(void *opaque)
145 {
146     PS2State *s = (PS2State *)opaque;
147     PS2Queue *q;
148     int val, index;
149     
150     q = &s->queue;
151     if (q->count == 0) {
152         /* NOTE: if no data left, we return the last keyboard one
153            (needed for EMM386) */
154         /* XXX: need a timer to do things correctly */
155         index = q->rptr - 1;
156         if (index < 0)
157             index = PS2_QUEUE_SIZE - 1;
158         val = q->data[index];
159     } else {
160         val = q->data[q->rptr];
161         if (++q->rptr == PS2_QUEUE_SIZE)
162             q->rptr = 0;
163         q->count--;
164         /* reading deasserts IRQ */
165         s->update_irq(s->update_arg, 0);
166         /* reassert IRQs if data left */
167         s->update_irq(s->update_arg, q->count != 0);
168     }
169     return val;
170 }
171
172 static void ps2_reset_keyboard(PS2KbdState *s)
173 {
174     s->scan_enabled = 1;
175 }
176
177 void ps2_write_keyboard(void *opaque, int val)
178 {
179     PS2KbdState *s = (PS2KbdState *)opaque;
180
181     switch(s->common.write_cmd) {
182     default:
183     case -1:
184         switch(val) {
185         case 0x00:
186             ps2_queue(&s->common, KBD_REPLY_ACK);
187             break;
188         case 0x05:
189             ps2_queue(&s->common, KBD_REPLY_RESEND);
190             break;
191         case KBD_CMD_GET_ID:
192             ps2_queue(&s->common, KBD_REPLY_ACK);
193             ps2_queue(&s->common, 0xab);
194             ps2_queue(&s->common, 0x83);
195             break;
196         case KBD_CMD_ECHO:
197             ps2_queue(&s->common, KBD_CMD_ECHO);
198             break;
199         case KBD_CMD_ENABLE:
200             s->scan_enabled = 1;
201             ps2_queue(&s->common, KBD_REPLY_ACK);
202             break;
203         case KBD_CMD_SET_LEDS:
204         case KBD_CMD_SET_RATE:
205             s->common.write_cmd = val;
206             ps2_queue(&s->common, KBD_REPLY_ACK);
207             break;
208         case KBD_CMD_RESET_DISABLE:
209             ps2_reset_keyboard(s);
210             s->scan_enabled = 0;
211             ps2_queue(&s->common, KBD_REPLY_ACK);
212             break;
213         case KBD_CMD_RESET_ENABLE:
214             ps2_reset_keyboard(s);
215             s->scan_enabled = 1;
216             ps2_queue(&s->common, KBD_REPLY_ACK);
217             break;
218         case KBD_CMD_RESET:
219             ps2_reset_keyboard(s);
220             ps2_queue(&s->common, KBD_REPLY_ACK);
221             ps2_queue(&s->common, KBD_REPLY_POR);
222             break;
223         default:
224             ps2_queue(&s->common, KBD_REPLY_ACK);
225             break;
226         }
227         break;
228     case KBD_CMD_SET_LEDS:
229         ps2_queue(&s->common, KBD_REPLY_ACK);
230         s->common.write_cmd = -1;
231         break;
232     case KBD_CMD_SET_RATE:
233         ps2_queue(&s->common, KBD_REPLY_ACK);
234         s->common.write_cmd = -1;
235         break;
236     }
237 }
238
239 /* Set the scancode translation mode.
240    0 = raw scancodes.
241    1 = translated scancodes (used by qemu internally).  */
242
243 void ps2_keyboard_set_translation(void *opaque, int mode)
244 {
245     PS2KbdState *s = (PS2KbdState *)opaque;
246     s->translate = mode;
247 }
248
249 static void ps2_mouse_send_packet(PS2MouseState *s)
250 {
251     unsigned int b;
252     int dx1, dy1, dz1;
253
254     dx1 = s->mouse_dx;
255     dy1 = s->mouse_dy;
256     dz1 = s->mouse_dz;
257     /* XXX: increase range to 8 bits ? */
258     if (dx1 > 127)
259         dx1 = 127;
260     else if (dx1 < -127)
261         dx1 = -127;
262     if (dy1 > 127)
263         dy1 = 127;
264     else if (dy1 < -127)
265         dy1 = -127;
266     b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
267     ps2_queue(&s->common, b);
268     ps2_queue(&s->common, dx1 & 0xff);
269     ps2_queue(&s->common, dy1 & 0xff);
270     /* extra byte for IMPS/2 or IMEX */
271     switch(s->mouse_type) {
272     default:
273         break;
274     case 3:
275         if (dz1 > 127)
276             dz1 = 127;
277         else if (dz1 < -127)
278                 dz1 = -127;
279         ps2_queue(&s->common, dz1 & 0xff);
280         break;
281     case 4:
282         if (dz1 > 7)
283             dz1 = 7;
284         else if (dz1 < -7)
285             dz1 = -7;
286         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
287         ps2_queue(&s->common, b);
288         break;
289     }
290
291     /* update deltas */
292     s->mouse_dx -= dx1;
293     s->mouse_dy -= dy1;
294     s->mouse_dz -= dz1;
295 }
296
297 static void ps2_mouse_event(void *opaque, 
298                             int dx, int dy, int dz, int buttons_state)
299 {
300     PS2MouseState *s = opaque;
301
302     /* check if deltas are recorded when disabled */
303     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
304         return;
305
306     s->mouse_dx += dx;
307     s->mouse_dy -= dy;
308     s->mouse_dz += dz;
309     /* XXX: SDL sometimes generates nul events: we delete them */
310     if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
311         s->mouse_buttons == buttons_state)
312         return;
313     s->mouse_buttons = buttons_state;
314     
315     if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
316         (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
317         for(;;) {
318             /* if not remote, send event. Multiple events are sent if
319                too big deltas */
320             ps2_mouse_send_packet(s);
321             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
322                 break;
323         }
324     }
325 }
326
327 void ps2_write_mouse(void *opaque, int val)
328 {
329     PS2MouseState *s = (PS2MouseState *)opaque;
330 #ifdef DEBUG_MOUSE
331     printf("kbd: write mouse 0x%02x\n", val);
332 #endif
333     switch(s->common.write_cmd) {
334     default:
335     case -1:
336         /* mouse command */
337         if (s->mouse_wrap) {
338             if (val == AUX_RESET_WRAP) {
339                 s->mouse_wrap = 0;
340                 ps2_queue(&s->common, AUX_ACK);
341                 return;
342             } else if (val != AUX_RESET) {
343                 ps2_queue(&s->common, val);
344                 return;
345             }
346         }
347         switch(val) {
348         case AUX_SET_SCALE11:
349             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
350             ps2_queue(&s->common, AUX_ACK);
351             break;
352         case AUX_SET_SCALE21:
353             s->mouse_status |= MOUSE_STATUS_SCALE21;
354             ps2_queue(&s->common, AUX_ACK);
355             break;
356         case AUX_SET_STREAM:
357             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
358             ps2_queue(&s->common, AUX_ACK);
359             break;
360         case AUX_SET_WRAP:
361             s->mouse_wrap = 1;
362             ps2_queue(&s->common, AUX_ACK);
363             break;
364         case AUX_SET_REMOTE:
365             s->mouse_status |= MOUSE_STATUS_REMOTE;
366             ps2_queue(&s->common, AUX_ACK);
367             break;
368         case AUX_GET_TYPE:
369             ps2_queue(&s->common, AUX_ACK);
370             ps2_queue(&s->common, s->mouse_type);
371             break;
372         case AUX_SET_RES:
373         case AUX_SET_SAMPLE:
374             s->common.write_cmd = val;
375             ps2_queue(&s->common, AUX_ACK);
376             break;
377         case AUX_GET_SCALE:
378             ps2_queue(&s->common, AUX_ACK);
379             ps2_queue(&s->common, s->mouse_status);
380             ps2_queue(&s->common, s->mouse_resolution);
381             ps2_queue(&s->common, s->mouse_sample_rate);
382             break;
383         case AUX_POLL:
384             ps2_queue(&s->common, AUX_ACK);
385             ps2_mouse_send_packet(s);
386             break;
387         case AUX_ENABLE_DEV:
388             s->mouse_status |= MOUSE_STATUS_ENABLED;
389             ps2_queue(&s->common, AUX_ACK);
390             break;
391         case AUX_DISABLE_DEV:
392             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
393             ps2_queue(&s->common, AUX_ACK);
394             break;
395         case AUX_SET_DEFAULT:
396             s->mouse_sample_rate = 100;
397             s->mouse_resolution = 2;
398             s->mouse_status = 0;
399             ps2_queue(&s->common, AUX_ACK);
400             break;
401         case AUX_RESET:
402             s->mouse_sample_rate = 100;
403             s->mouse_resolution = 2;
404             s->mouse_status = 0;
405             s->mouse_type = 0;
406             ps2_queue(&s->common, AUX_ACK);
407             ps2_queue(&s->common, 0xaa);
408             ps2_queue(&s->common, s->mouse_type);
409             break;
410         default:
411             break;
412         }
413         break;
414     case AUX_SET_SAMPLE:
415         s->mouse_sample_rate = val;
416         /* detect IMPS/2 or IMEX */
417         switch(s->mouse_detect_state) {
418         default:
419         case 0:
420             if (val == 200)
421                 s->mouse_detect_state = 1;
422             break;
423         case 1:
424             if (val == 100)
425                 s->mouse_detect_state = 2;
426             else if (val == 200)
427                 s->mouse_detect_state = 3;
428             else
429                 s->mouse_detect_state = 0;
430             break;
431         case 2:
432             if (val == 80) 
433                 s->mouse_type = 3; /* IMPS/2 */
434             s->mouse_detect_state = 0;
435             break;
436         case 3:
437             if (val == 80) 
438                 s->mouse_type = 4; /* IMEX */
439             s->mouse_detect_state = 0;
440             break;
441         }
442         ps2_queue(&s->common, AUX_ACK);
443         s->common.write_cmd = -1;
444         break;
445     case AUX_SET_RES:
446         s->mouse_resolution = val;
447         ps2_queue(&s->common, AUX_ACK);
448         s->common.write_cmd = -1;
449         break;
450     }
451 }
452
453 static void ps2_reset(void *opaque)
454 {
455     PS2State *s = (PS2State *)opaque;
456     PS2Queue *q;
457     s->write_cmd = -1;
458     q = &s->queue;
459     q->rptr = 0;
460     q->wptr = 0;
461     q->count = 0;
462 }
463
464 static void ps2_common_save (QEMUFile *f, PS2State *s)
465 {
466     qemu_put_be32s (f, &s->write_cmd);
467     qemu_put_be32s (f, &s->queue.rptr);
468     qemu_put_be32s (f, &s->queue.wptr);
469     qemu_put_be32s (f, &s->queue.count);
470     qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
471 }
472
473 static void ps2_common_load (QEMUFile *f, PS2State *s)
474 {
475     qemu_get_be32s (f, &s->write_cmd);
476     qemu_get_be32s (f, &s->queue.rptr);
477     qemu_get_be32s (f, &s->queue.wptr);
478     qemu_get_be32s (f, &s->queue.count);
479     qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
480 }
481
482 static void ps2_kbd_save(QEMUFile* f, void* opaque)
483 {
484     PS2KbdState *s = (PS2KbdState*)opaque;
485
486     ps2_common_save (f, &s->common);
487     qemu_put_be32s(f, &s->scan_enabled);
488     qemu_put_be32s(f, &s->translate);
489 }
490
491 static void ps2_mouse_save(QEMUFile* f, void* opaque)
492 {
493     PS2MouseState *s = (PS2MouseState*)opaque;
494
495     ps2_common_save (f, &s->common);
496     qemu_put_8s(f, &s->mouse_status);
497     qemu_put_8s(f, &s->mouse_resolution);
498     qemu_put_8s(f, &s->mouse_sample_rate);
499     qemu_put_8s(f, &s->mouse_wrap);
500     qemu_put_8s(f, &s->mouse_type);
501     qemu_put_8s(f, &s->mouse_detect_state);
502     qemu_put_be32s(f, &s->mouse_dx);
503     qemu_put_be32s(f, &s->mouse_dy);
504     qemu_put_be32s(f, &s->mouse_dz);
505     qemu_put_8s(f, &s->mouse_buttons);
506 }
507
508 static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
509 {
510     PS2KbdState *s = (PS2KbdState*)opaque;
511
512     if (version_id != 2)
513         return -EINVAL;
514
515     ps2_common_load (f, &s->common);
516     qemu_get_be32s(f, &s->scan_enabled);
517     qemu_get_be32s(f, &s->translate);
518     return 0;
519 }
520
521 static int ps2_mouse_load(QEMUFile* f, void* opaque, int version_id)
522 {
523     PS2MouseState *s = (PS2MouseState*)opaque;
524
525     if (version_id != 2)
526         return -EINVAL;
527
528     ps2_common_load (f, &s->common);
529     qemu_get_8s(f, &s->mouse_status);
530     qemu_get_8s(f, &s->mouse_resolution);
531     qemu_get_8s(f, &s->mouse_sample_rate);
532     qemu_get_8s(f, &s->mouse_wrap);
533     qemu_get_8s(f, &s->mouse_type);
534     qemu_get_8s(f, &s->mouse_detect_state);
535     qemu_get_be32s(f, &s->mouse_dx);
536     qemu_get_be32s(f, &s->mouse_dy);
537     qemu_get_be32s(f, &s->mouse_dz);
538     qemu_get_8s(f, &s->mouse_buttons);
539     return 0;
540 }
541
542 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
543 {
544     PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
545
546     s->common.update_irq = update_irq;
547     s->common.update_arg = update_arg;
548     ps2_reset(&s->common);
549     register_savevm("ps2kbd", 0, 2, ps2_kbd_save, ps2_kbd_load, s);
550     qemu_add_kbd_event_handler(ps2_put_keycode, s);
551     qemu_register_reset(ps2_reset, &s->common);
552     return s;
553 }
554
555 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
556 {
557     PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
558
559     s->common.update_irq = update_irq;
560     s->common.update_arg = update_arg;
561     ps2_reset(&s->common);
562     register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
563     qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
564     qemu_register_reset(ps2_reset, &s->common);
565     return s;
566 }