find -type f | xargs sed -i 's/[\t ]$//g' # on most files
[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_mouse_fake_event(void *opaque)
328 {
329     ps2_mouse_event(opaque, 1, 0, 0, 0);
330 }
331
332 void ps2_write_mouse(void *opaque, int val)
333 {
334     PS2MouseState *s = (PS2MouseState *)opaque;
335 #ifdef DEBUG_MOUSE
336     printf("kbd: write mouse 0x%02x\n", val);
337 #endif
338     switch(s->common.write_cmd) {
339     default:
340     case -1:
341         /* mouse command */
342         if (s->mouse_wrap) {
343             if (val == AUX_RESET_WRAP) {
344                 s->mouse_wrap = 0;
345                 ps2_queue(&s->common, AUX_ACK);
346                 return;
347             } else if (val != AUX_RESET) {
348                 ps2_queue(&s->common, val);
349                 return;
350             }
351         }
352         switch(val) {
353         case AUX_SET_SCALE11:
354             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
355             ps2_queue(&s->common, AUX_ACK);
356             break;
357         case AUX_SET_SCALE21:
358             s->mouse_status |= MOUSE_STATUS_SCALE21;
359             ps2_queue(&s->common, AUX_ACK);
360             break;
361         case AUX_SET_STREAM:
362             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
363             ps2_queue(&s->common, AUX_ACK);
364             break;
365         case AUX_SET_WRAP:
366             s->mouse_wrap = 1;
367             ps2_queue(&s->common, AUX_ACK);
368             break;
369         case AUX_SET_REMOTE:
370             s->mouse_status |= MOUSE_STATUS_REMOTE;
371             ps2_queue(&s->common, AUX_ACK);
372             break;
373         case AUX_GET_TYPE:
374             ps2_queue(&s->common, AUX_ACK);
375             ps2_queue(&s->common, s->mouse_type);
376             break;
377         case AUX_SET_RES:
378         case AUX_SET_SAMPLE:
379             s->common.write_cmd = val;
380             ps2_queue(&s->common, AUX_ACK);
381             break;
382         case AUX_GET_SCALE:
383             ps2_queue(&s->common, AUX_ACK);
384             ps2_queue(&s->common, s->mouse_status);
385             ps2_queue(&s->common, s->mouse_resolution);
386             ps2_queue(&s->common, s->mouse_sample_rate);
387             break;
388         case AUX_POLL:
389             ps2_queue(&s->common, AUX_ACK);
390             ps2_mouse_send_packet(s);
391             break;
392         case AUX_ENABLE_DEV:
393             s->mouse_status |= MOUSE_STATUS_ENABLED;
394             ps2_queue(&s->common, AUX_ACK);
395             break;
396         case AUX_DISABLE_DEV:
397             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
398             ps2_queue(&s->common, AUX_ACK);
399             break;
400         case AUX_SET_DEFAULT:
401             s->mouse_sample_rate = 100;
402             s->mouse_resolution = 2;
403             s->mouse_status = 0;
404             ps2_queue(&s->common, AUX_ACK);
405             break;
406         case AUX_RESET:
407             s->mouse_sample_rate = 100;
408             s->mouse_resolution = 2;
409             s->mouse_status = 0;
410             s->mouse_type = 0;
411             ps2_queue(&s->common, AUX_ACK);
412             ps2_queue(&s->common, 0xaa);
413             ps2_queue(&s->common, s->mouse_type);
414             break;
415         default:
416             break;
417         }
418         break;
419     case AUX_SET_SAMPLE:
420         s->mouse_sample_rate = val;
421         /* detect IMPS/2 or IMEX */
422         switch(s->mouse_detect_state) {
423         default:
424         case 0:
425             if (val == 200)
426                 s->mouse_detect_state = 1;
427             break;
428         case 1:
429             if (val == 100)
430                 s->mouse_detect_state = 2;
431             else if (val == 200)
432                 s->mouse_detect_state = 3;
433             else
434                 s->mouse_detect_state = 0;
435             break;
436         case 2:
437             if (val == 80)
438                 s->mouse_type = 3; /* IMPS/2 */
439             s->mouse_detect_state = 0;
440             break;
441         case 3:
442             if (val == 80)
443                 s->mouse_type = 4; /* IMEX */
444             s->mouse_detect_state = 0;
445             break;
446         }
447         ps2_queue(&s->common, AUX_ACK);
448         s->common.write_cmd = -1;
449         break;
450     case AUX_SET_RES:
451         s->mouse_resolution = val;
452         ps2_queue(&s->common, AUX_ACK);
453         s->common.write_cmd = -1;
454         break;
455     }
456 }
457
458 static void ps2_reset(void *opaque)
459 {
460     PS2State *s = (PS2State *)opaque;
461     PS2Queue *q;
462     s->write_cmd = -1;
463     q = &s->queue;
464     q->rptr = 0;
465     q->wptr = 0;
466     q->count = 0;
467 }
468
469 static void ps2_common_save (QEMUFile *f, PS2State *s)
470 {
471     qemu_put_be32s (f, &s->write_cmd);
472     qemu_put_be32s (f, &s->queue.rptr);
473     qemu_put_be32s (f, &s->queue.wptr);
474     qemu_put_be32s (f, &s->queue.count);
475     qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
476 }
477
478 static void ps2_common_load (QEMUFile *f, PS2State *s)
479 {
480     qemu_get_be32s (f, &s->write_cmd);
481     qemu_get_be32s (f, &s->queue.rptr);
482     qemu_get_be32s (f, &s->queue.wptr);
483     qemu_get_be32s (f, &s->queue.count);
484     qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
485 }
486
487 static void ps2_kbd_save(QEMUFile* f, void* opaque)
488 {
489     PS2KbdState *s = (PS2KbdState*)opaque;
490
491     ps2_common_save (f, &s->common);
492     qemu_put_be32s(f, &s->scan_enabled);
493     qemu_put_be32s(f, &s->translate);
494 }
495
496 static void ps2_mouse_save(QEMUFile* f, void* opaque)
497 {
498     PS2MouseState *s = (PS2MouseState*)opaque;
499
500     ps2_common_save (f, &s->common);
501     qemu_put_8s(f, &s->mouse_status);
502     qemu_put_8s(f, &s->mouse_resolution);
503     qemu_put_8s(f, &s->mouse_sample_rate);
504     qemu_put_8s(f, &s->mouse_wrap);
505     qemu_put_8s(f, &s->mouse_type);
506     qemu_put_8s(f, &s->mouse_detect_state);
507     qemu_put_be32s(f, &s->mouse_dx);
508     qemu_put_be32s(f, &s->mouse_dy);
509     qemu_put_be32s(f, &s->mouse_dz);
510     qemu_put_8s(f, &s->mouse_buttons);
511 }
512
513 static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
514 {
515     PS2KbdState *s = (PS2KbdState*)opaque;
516
517     if (version_id != 2)
518         return -EINVAL;
519
520     ps2_common_load (f, &s->common);
521     qemu_get_be32s(f, &s->scan_enabled);
522     qemu_get_be32s(f, &s->translate);
523     return 0;
524 }
525
526 static int ps2_mouse_load(QEMUFile* f, void* opaque, int version_id)
527 {
528     PS2MouseState *s = (PS2MouseState*)opaque;
529
530     if (version_id != 2)
531         return -EINVAL;
532
533     ps2_common_load (f, &s->common);
534     qemu_get_8s(f, &s->mouse_status);
535     qemu_get_8s(f, &s->mouse_resolution);
536     qemu_get_8s(f, &s->mouse_sample_rate);
537     qemu_get_8s(f, &s->mouse_wrap);
538     qemu_get_8s(f, &s->mouse_type);
539     qemu_get_8s(f, &s->mouse_detect_state);
540     qemu_get_be32s(f, &s->mouse_dx);
541     qemu_get_be32s(f, &s->mouse_dy);
542     qemu_get_be32s(f, &s->mouse_dz);
543     qemu_get_8s(f, &s->mouse_buttons);
544     return 0;
545 }
546
547 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
548 {
549     PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
550
551     s->common.update_irq = update_irq;
552     s->common.update_arg = update_arg;
553     ps2_reset(&s->common);
554     register_savevm("ps2kbd", 0, 2, ps2_kbd_save, ps2_kbd_load, s);
555     qemu_add_kbd_event_handler(ps2_put_keycode, s);
556     qemu_register_reset(ps2_reset, &s->common);
557     return s;
558 }
559
560 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
561 {
562     PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
563
564     s->common.update_irq = update_irq;
565     s->common.update_arg = update_arg;
566     ps2_reset(&s->common);
567     register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
568     qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
569     qemu_register_reset(ps2_reset, &s->common);
570     return s;
571 }