Add KBD_CMD_SCANCODE command.
[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 "hw.h"
25 #include "ps2.h"
26 #include "console.h"
27
28 /* debug PC keyboard */
29 //#define DEBUG_KBD
30
31 /* debug PC keyboard : only mouse */
32 //#define DEBUG_MOUSE
33
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 */
44
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 */
49
50 /* Mouse Commands */
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. */
67
68 #define MOUSE_STATUS_REMOTE     0x40
69 #define MOUSE_STATUS_ENABLED    0x20
70 #define MOUSE_STATUS_SCALE21    0x10
71
72 #define PS2_QUEUE_SIZE 256
73
74 typedef struct {
75     uint8_t data[PS2_QUEUE_SIZE];
76     int rptr, wptr, count;
77 } PS2Queue;
78
79 typedef struct {
80     PS2Queue queue;
81     int32_t write_cmd;
82     void (*update_irq)(void *, int);
83     void *update_arg;
84 } PS2State;
85
86 typedef struct {
87     PS2State common;
88     int scan_enabled;
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.  */
92     int translate;
93     int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
94 } PS2KbdState;
95
96 typedef struct {
97     PS2State common;
98     uint8_t mouse_status;
99     uint8_t mouse_resolution;
100     uint8_t mouse_sample_rate;
101     uint8_t mouse_wrap;
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 */
105     int mouse_dy;
106     int mouse_dz;
107     uint8_t mouse_buttons;
108 } PS2MouseState;
109
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
120 };
121
122 void ps2_queue(void *opaque, int b)
123 {
124     PS2State *s = (PS2State *)opaque;
125     PS2Queue *q = &s->queue;
126
127     if (q->count >= PS2_QUEUE_SIZE)
128         return;
129     q->data[q->wptr] = b;
130     if (++q->wptr == PS2_QUEUE_SIZE)
131         q->wptr = 0;
132     q->count++;
133     s->update_irq(s->update_arg, 1);
134 }
135
136 /* keycode is expressed in scancode set 2 */
137 static void ps2_put_keycode(void *opaque, int keycode)
138 {
139     PS2KbdState *s = opaque;
140
141     /* XXX: add support for scancode sets 1 and 3 */
142     if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
143       {
144         if (keycode & 0x80)
145             ps2_queue(&s->common, 0xf0);
146         keycode = ps2_raw_keycode[keycode & 0x7f];
147       }
148     ps2_queue(&s->common, keycode);
149 }
150
151 uint32_t ps2_read_data(void *opaque)
152 {
153     PS2State *s = (PS2State *)opaque;
154     PS2Queue *q;
155     int val, index;
156
157     q = &s->queue;
158     if (q->count == 0) {
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 */
162         index = q->rptr - 1;
163         if (index < 0)
164             index = PS2_QUEUE_SIZE - 1;
165         val = q->data[index];
166     } else {
167         val = q->data[q->rptr];
168         if (++q->rptr == PS2_QUEUE_SIZE)
169             q->rptr = 0;
170         q->count--;
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);
175     }
176     return val;
177 }
178
179 static void ps2_reset_keyboard(PS2KbdState *s)
180 {
181     s->scan_enabled = 1;
182     s->scancode_set = 2;
183 }
184
185 void ps2_write_keyboard(void *opaque, int val)
186 {
187     PS2KbdState *s = (PS2KbdState *)opaque;
188
189     switch(s->common.write_cmd) {
190     default:
191     case -1:
192         switch(val) {
193         case 0x00:
194             ps2_queue(&s->common, KBD_REPLY_ACK);
195             break;
196         case 0x05:
197             ps2_queue(&s->common, KBD_REPLY_RESEND);
198             break;
199         case KBD_CMD_GET_ID:
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);
204             break;
205         case KBD_CMD_ECHO:
206             ps2_queue(&s->common, KBD_CMD_ECHO);
207             break;
208         case KBD_CMD_ENABLE:
209             s->scan_enabled = 1;
210             ps2_queue(&s->common, KBD_REPLY_ACK);
211             break;
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);
217             break;
218         case KBD_CMD_RESET_DISABLE:
219             ps2_reset_keyboard(s);
220             s->scan_enabled = 0;
221             ps2_queue(&s->common, KBD_REPLY_ACK);
222             break;
223         case KBD_CMD_RESET_ENABLE:
224             ps2_reset_keyboard(s);
225             s->scan_enabled = 1;
226             ps2_queue(&s->common, KBD_REPLY_ACK);
227             break;
228         case KBD_CMD_RESET:
229             ps2_reset_keyboard(s);
230             ps2_queue(&s->common, KBD_REPLY_ACK);
231             ps2_queue(&s->common, KBD_REPLY_POR);
232             break;
233         default:
234             ps2_queue(&s->common, KBD_REPLY_ACK);
235             break;
236         }
237         break;
238     case KBD_CMD_SCANCODE:
239         if (val == 0) {
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);
246         } else {
247             if (val >= 1 && val <= 3)
248                 s->scancode_set = val;
249             ps2_queue(&s->common, KBD_REPLY_ACK);
250         }
251         s->common.write_cmd = -1;
252         break;
253     case KBD_CMD_SET_LEDS:
254         ps2_queue(&s->common, KBD_REPLY_ACK);
255         s->common.write_cmd = -1;
256         break;
257     case KBD_CMD_SET_RATE:
258         ps2_queue(&s->common, KBD_REPLY_ACK);
259         s->common.write_cmd = -1;
260         break;
261     }
262 }
263
264 /* Set the scancode translation mode.
265    0 = raw scancodes.
266    1 = translated scancodes (used by qemu internally).  */
267
268 void ps2_keyboard_set_translation(void *opaque, int mode)
269 {
270     PS2KbdState *s = (PS2KbdState *)opaque;
271     s->translate = mode;
272 }
273
274 static void ps2_mouse_send_packet(PS2MouseState *s)
275 {
276     unsigned int b;
277     int dx1, dy1, dz1;
278
279     dx1 = s->mouse_dx;
280     dy1 = s->mouse_dy;
281     dz1 = s->mouse_dz;
282     /* XXX: increase range to 8 bits ? */
283     if (dx1 > 127)
284         dx1 = 127;
285     else if (dx1 < -127)
286         dx1 = -127;
287     if (dy1 > 127)
288         dy1 = 127;
289     else if (dy1 < -127)
290         dy1 = -127;
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) {
297     default:
298         break;
299     case 3:
300         if (dz1 > 127)
301             dz1 = 127;
302         else if (dz1 < -127)
303                 dz1 = -127;
304         ps2_queue(&s->common, dz1 & 0xff);
305         break;
306     case 4:
307         if (dz1 > 7)
308             dz1 = 7;
309         else if (dz1 < -7)
310             dz1 = -7;
311         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
312         ps2_queue(&s->common, b);
313         break;
314     }
315
316     /* update deltas */
317     s->mouse_dx -= dx1;
318     s->mouse_dy -= dy1;
319     s->mouse_dz -= dz1;
320 }
321
322 static void ps2_mouse_event(void *opaque,
323                             int dx, int dy, int dz, int buttons_state)
324 {
325     PS2MouseState *s = opaque;
326
327     /* check if deltas are recorded when disabled */
328     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
329         return;
330
331     s->mouse_dx += dx;
332     s->mouse_dy -= dy;
333     s->mouse_dz += dz;
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)
337         return;
338     s->mouse_buttons = buttons_state;
339
340     if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
341         (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
342         for(;;) {
343             /* if not remote, send event. Multiple events are sent if
344                too big deltas */
345             ps2_mouse_send_packet(s);
346             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
347                 break;
348         }
349     }
350 }
351
352 void ps2_mouse_fake_event(void *opaque)
353 {
354     ps2_mouse_event(opaque, 1, 0, 0, 0);
355 }
356
357 void ps2_write_mouse(void *opaque, int val)
358 {
359     PS2MouseState *s = (PS2MouseState *)opaque;
360 #ifdef DEBUG_MOUSE
361     printf("kbd: write mouse 0x%02x\n", val);
362 #endif
363     switch(s->common.write_cmd) {
364     default:
365     case -1:
366         /* mouse command */
367         if (s->mouse_wrap) {
368             if (val == AUX_RESET_WRAP) {
369                 s->mouse_wrap = 0;
370                 ps2_queue(&s->common, AUX_ACK);
371                 return;
372             } else if (val != AUX_RESET) {
373                 ps2_queue(&s->common, val);
374                 return;
375             }
376         }
377         switch(val) {
378         case AUX_SET_SCALE11:
379             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
380             ps2_queue(&s->common, AUX_ACK);
381             break;
382         case AUX_SET_SCALE21:
383             s->mouse_status |= MOUSE_STATUS_SCALE21;
384             ps2_queue(&s->common, AUX_ACK);
385             break;
386         case AUX_SET_STREAM:
387             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
388             ps2_queue(&s->common, AUX_ACK);
389             break;
390         case AUX_SET_WRAP:
391             s->mouse_wrap = 1;
392             ps2_queue(&s->common, AUX_ACK);
393             break;
394         case AUX_SET_REMOTE:
395             s->mouse_status |= MOUSE_STATUS_REMOTE;
396             ps2_queue(&s->common, AUX_ACK);
397             break;
398         case AUX_GET_TYPE:
399             ps2_queue(&s->common, AUX_ACK);
400             ps2_queue(&s->common, s->mouse_type);
401             break;
402         case AUX_SET_RES:
403         case AUX_SET_SAMPLE:
404             s->common.write_cmd = val;
405             ps2_queue(&s->common, AUX_ACK);
406             break;
407         case AUX_GET_SCALE:
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);
412             break;
413         case AUX_POLL:
414             ps2_queue(&s->common, AUX_ACK);
415             ps2_mouse_send_packet(s);
416             break;
417         case AUX_ENABLE_DEV:
418             s->mouse_status |= MOUSE_STATUS_ENABLED;
419             ps2_queue(&s->common, AUX_ACK);
420             break;
421         case AUX_DISABLE_DEV:
422             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
423             ps2_queue(&s->common, AUX_ACK);
424             break;
425         case AUX_SET_DEFAULT:
426             s->mouse_sample_rate = 100;
427             s->mouse_resolution = 2;
428             s->mouse_status = 0;
429             ps2_queue(&s->common, AUX_ACK);
430             break;
431         case AUX_RESET:
432             s->mouse_sample_rate = 100;
433             s->mouse_resolution = 2;
434             s->mouse_status = 0;
435             s->mouse_type = 0;
436             ps2_queue(&s->common, AUX_ACK);
437             ps2_queue(&s->common, 0xaa);
438             ps2_queue(&s->common, s->mouse_type);
439             break;
440         default:
441             break;
442         }
443         break;
444     case AUX_SET_SAMPLE:
445         s->mouse_sample_rate = val;
446         /* detect IMPS/2 or IMEX */
447         switch(s->mouse_detect_state) {
448         default:
449         case 0:
450             if (val == 200)
451                 s->mouse_detect_state = 1;
452             break;
453         case 1:
454             if (val == 100)
455                 s->mouse_detect_state = 2;
456             else if (val == 200)
457                 s->mouse_detect_state = 3;
458             else
459                 s->mouse_detect_state = 0;
460             break;
461         case 2:
462             if (val == 80)
463                 s->mouse_type = 3; /* IMPS/2 */
464             s->mouse_detect_state = 0;
465             break;
466         case 3:
467             if (val == 80)
468                 s->mouse_type = 4; /* IMEX */
469             s->mouse_detect_state = 0;
470             break;
471         }
472         ps2_queue(&s->common, AUX_ACK);
473         s->common.write_cmd = -1;
474         break;
475     case AUX_SET_RES:
476         s->mouse_resolution = val;
477         ps2_queue(&s->common, AUX_ACK);
478         s->common.write_cmd = -1;
479         break;
480     }
481 }
482
483 static void ps2_reset(void *opaque)
484 {
485     PS2State *s = (PS2State *)opaque;
486     PS2Queue *q;
487     s->write_cmd = -1;
488     q = &s->queue;
489     q->rptr = 0;
490     q->wptr = 0;
491     q->count = 0;
492 }
493
494 static void ps2_common_save (QEMUFile *f, PS2State *s)
495 {
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));
501 }
502
503 static void ps2_common_load (QEMUFile *f, PS2State *s)
504 {
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));
510 }
511
512 static void ps2_kbd_save(QEMUFile* f, void* opaque)
513 {
514     PS2KbdState *s = (PS2KbdState*)opaque;
515
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);
520 }
521
522 static void ps2_mouse_save(QEMUFile* f, void* opaque)
523 {
524     PS2MouseState *s = (PS2MouseState*)opaque;
525
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);
537 }
538
539 static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
540 {
541     PS2KbdState *s = (PS2KbdState*)opaque;
542
543     if (version_id != 2 && version_id != 3)
544         return -EINVAL;
545
546     ps2_common_load (f, &s->common);
547     s->scan_enabled=qemu_get_be32(f);
548     s->translate=qemu_get_be32(f);
549     if (version_id == 3)
550         s->scancode_set=qemu_get_be32(f);
551     else
552         s->scancode_set=2;
553     return 0;
554 }
555
556 static int ps2_mouse_load(QEMUFile* f, void* opaque, int version_id)
557 {
558     PS2MouseState *s = (PS2MouseState*)opaque;
559
560     if (version_id != 2)
561         return -EINVAL;
562
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);
574     return 0;
575 }
576
577 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
578 {
579     PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
580
581     s->common.update_irq = update_irq;
582     s->common.update_arg = update_arg;
583     s->scancode_set = 2;
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);
588     return s;
589 }
590
591 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
592 {
593     PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
594
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);
601     return s;
602 }