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_ID		0xAB	/* Keyboard ID */
48#define KBD_REPLY_ACK		0xFA	/* Command ACK */
49#define KBD_REPLY_RESEND	0xFE	/* Command NACK, send the cmd again */
50
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. */
68
69#define MOUSE_STATUS_REMOTE     0x40
70#define MOUSE_STATUS_ENABLED    0x20
71#define MOUSE_STATUS_SCALE21    0x10
72
73#define PS2_QUEUE_SIZE 256
74
75typedef struct {
76    uint8_t data[PS2_QUEUE_SIZE];
77    int rptr, wptr, count;
78} PS2Queue;
79
80typedef struct {
81    PS2Queue queue;
82    int32_t write_cmd;
83    void (*update_irq)(void *, int);
84    void *update_arg;
85} PS2State;
86
87typedef 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;
96
97typedef 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;
110
111/* Table to convert from PC scancodes to raw scancodes.  */
112static 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
121};
122
123void ps2_queue(void *opaque, int b)
124{
125    PS2State *s = (PS2State *)opaque;
126    PS2Queue *q = &s->queue;
127
128    if (q->count >= PS2_QUEUE_SIZE)
129        return;
130    q->data[q->wptr] = b;
131    if (++q->wptr == PS2_QUEUE_SIZE)
132        q->wptr = 0;
133    q->count++;
134    s->update_irq(s->update_arg, 1);
135}
136
137/*
138   keycode is expressed as follow:
139   bit 7    - 0 key pressed, 1 = key released
140   bits 6-0 - translated scancode set 2
141 */
142static void ps2_put_keycode(void *opaque, int keycode)
143{
144    PS2KbdState *s = opaque;
145
146    /* XXX: add support for scancode sets 1 and 3 */
147    if (!s->translate && keycode < 0xe0 && s->scancode_set == 2)
148      {
149        if (keycode & 0x80)
150            ps2_queue(&s->common, 0xf0);
151        keycode = ps2_raw_keycode[keycode & 0x7f];
152      }
153    ps2_queue(&s->common, keycode);
154}
155
156uint32_t ps2_read_data(void *opaque)
157{
158    PS2State *s = (PS2State *)opaque;
159    PS2Queue *q;
160    int val, index;
161
162    q = &s->queue;
163    if (q->count == 0) {
164        /* NOTE: if no data left, we return the last keyboard one
165           (needed for EMM386) */
166        /* XXX: need a timer to do things correctly */
167        index = q->rptr - 1;
168        if (index < 0)
169            index = PS2_QUEUE_SIZE - 1;
170        val = q->data[index];
171    } else {
172        val = q->data[q->rptr];
173        if (++q->rptr == PS2_QUEUE_SIZE)
174            q->rptr = 0;
175        q->count--;
176        /* reading deasserts IRQ */
177        s->update_irq(s->update_arg, 0);
178        /* reassert IRQs if data left */
179        s->update_irq(s->update_arg, q->count != 0);
180    }
181    return val;
182}
183
184static void ps2_reset_keyboard(PS2KbdState *s)
185{
186    s->scan_enabled = 1;
187    s->scancode_set = 2;
188}
189
190void ps2_write_keyboard(void *opaque, int val)
191{
192    PS2KbdState *s = (PS2KbdState *)opaque;
193
194    switch(s->common.write_cmd) {
195    default:
196    case -1:
197        switch(val) {
198        case 0x00:
199            ps2_queue(&s->common, KBD_REPLY_ACK);
200            break;
201        case 0x05:
202            ps2_queue(&s->common, KBD_REPLY_RESEND);
203            break;
204        case KBD_CMD_GET_ID:
205            ps2_queue(&s->common, KBD_REPLY_ACK);
206            /* We emulate a MF2 AT keyboard here */
207            ps2_queue(&s->common, KBD_REPLY_ID);
208            if (s->translate)
209                ps2_queue(&s->common, 0x41);
210            else
211                ps2_queue(&s->common, 0x83);
212            break;
213        case KBD_CMD_ECHO:
214            ps2_queue(&s->common, KBD_CMD_ECHO);
215            break;
216        case KBD_CMD_ENABLE:
217            s->scan_enabled = 1;
218            ps2_queue(&s->common, KBD_REPLY_ACK);
219            break;
220        case KBD_CMD_SCANCODE:
221        case KBD_CMD_SET_LEDS:
222        case KBD_CMD_SET_RATE:
223            s->common.write_cmd = val;
224            ps2_queue(&s->common, KBD_REPLY_ACK);
225            break;
226        case KBD_CMD_RESET_DISABLE:
227            ps2_reset_keyboard(s);
228            s->scan_enabled = 0;
229            ps2_queue(&s->common, KBD_REPLY_ACK);
230            break;
231        case KBD_CMD_RESET_ENABLE:
232            ps2_reset_keyboard(s);
233            s->scan_enabled = 1;
234            ps2_queue(&s->common, KBD_REPLY_ACK);
235            break;
236        case KBD_CMD_RESET:
237            ps2_reset_keyboard(s);
238            ps2_queue(&s->common, KBD_REPLY_ACK);
239            ps2_queue(&s->common, KBD_REPLY_POR);
240            break;
241        default:
242            ps2_queue(&s->common, KBD_REPLY_ACK);
243            break;
244        }
245        break;
246    case KBD_CMD_SCANCODE:
247        if (val == 0) {
248            if (s->scancode_set == 1)
249                ps2_put_keycode(s, 0x43);
250            else if (s->scancode_set == 2)
251                ps2_put_keycode(s, 0x41);
252            else if (s->scancode_set == 3)
253                ps2_put_keycode(s, 0x3f);
254        } else {
255            if (val >= 1 && val <= 3)
256                s->scancode_set = val;
257            ps2_queue(&s->common, KBD_REPLY_ACK);
258        }
259        s->common.write_cmd = -1;
260        break;
261    case KBD_CMD_SET_LEDS:
262        ps2_queue(&s->common, KBD_REPLY_ACK);
263        s->common.write_cmd = -1;
264        break;
265    case KBD_CMD_SET_RATE:
266        ps2_queue(&s->common, KBD_REPLY_ACK);
267        s->common.write_cmd = -1;
268        break;
269    }
270}
271
272/* Set the scancode translation mode.
273   0 = raw scancodes.
274   1 = translated scancodes (used by qemu internally).  */
275
276void ps2_keyboard_set_translation(void *opaque, int mode)
277{
278    PS2KbdState *s = (PS2KbdState *)opaque;
279    s->translate = mode;
280}
281
282static void ps2_mouse_send_packet(PS2MouseState *s)
283{
284    unsigned int b;
285    int dx1, dy1, dz1;
286
287    dx1 = s->mouse_dx;
288    dy1 = s->mouse_dy;
289    dz1 = s->mouse_dz;
290    /* XXX: increase range to 8 bits ? */
291    if (dx1 > 127)
292        dx1 = 127;
293    else if (dx1 < -127)
294        dx1 = -127;
295    if (dy1 > 127)
296        dy1 = 127;
297    else if (dy1 < -127)
298        dy1 = -127;
299    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
300    ps2_queue(&s->common, b);
301    ps2_queue(&s->common, dx1 & 0xff);
302    ps2_queue(&s->common, dy1 & 0xff);
303    /* extra byte for IMPS/2 or IMEX */
304    switch(s->mouse_type) {
305    default:
306        break;
307    case 3:
308        if (dz1 > 127)
309            dz1 = 127;
310        else if (dz1 < -127)
311                dz1 = -127;
312        ps2_queue(&s->common, dz1 & 0xff);
313        break;
314    case 4:
315        if (dz1 > 7)
316            dz1 = 7;
317        else if (dz1 < -7)
318            dz1 = -7;
319        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
320        ps2_queue(&s->common, b);
321        break;
322    }
323
324    /* update deltas */
325    s->mouse_dx -= dx1;
326    s->mouse_dy -= dy1;
327    s->mouse_dz -= dz1;
328}
329
330static void ps2_mouse_event(void *opaque,
331                            int dx, int dy, int dz, int buttons_state)
332{
333    PS2MouseState *s = opaque;
334
335    /* check if deltas are recorded when disabled */
336    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
337        return;
338
339    s->mouse_dx += dx;
340    s->mouse_dy -= dy;
341    s->mouse_dz += dz;
342    /* XXX: SDL sometimes generates nul events: we delete them */
343    if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
344        s->mouse_buttons == buttons_state)
345	return;
346    s->mouse_buttons = buttons_state;
347
348    if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
349        (s->common.queue.count < (PS2_QUEUE_SIZE - 16))) {
350        for(;;) {
351            /* if not remote, send event. Multiple events are sent if
352               too big deltas */
353            ps2_mouse_send_packet(s);
354            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
355                break;
356        }
357    }
358}
359
360void ps2_mouse_fake_event(void *opaque)
361{
362    ps2_mouse_event(opaque, 1, 0, 0, 0);
363}
364
365void ps2_write_mouse(void *opaque, int val)
366{
367    PS2MouseState *s = (PS2MouseState *)opaque;
368#ifdef DEBUG_MOUSE
369    printf("kbd: write mouse 0x%02x\n", val);
370#endif
371    switch(s->common.write_cmd) {
372    default:
373    case -1:
374        /* mouse command */
375        if (s->mouse_wrap) {
376            if (val == AUX_RESET_WRAP) {
377                s->mouse_wrap = 0;
378                ps2_queue(&s->common, AUX_ACK);
379                return;
380            } else if (val != AUX_RESET) {
381                ps2_queue(&s->common, val);
382                return;
383            }
384        }
385        switch(val) {
386        case AUX_SET_SCALE11:
387            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
388            ps2_queue(&s->common, AUX_ACK);
389            break;
390        case AUX_SET_SCALE21:
391            s->mouse_status |= MOUSE_STATUS_SCALE21;
392            ps2_queue(&s->common, AUX_ACK);
393            break;
394        case AUX_SET_STREAM:
395            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
396            ps2_queue(&s->common, AUX_ACK);
397            break;
398        case AUX_SET_WRAP:
399            s->mouse_wrap = 1;
400            ps2_queue(&s->common, AUX_ACK);
401            break;
402        case AUX_SET_REMOTE:
403            s->mouse_status |= MOUSE_STATUS_REMOTE;
404            ps2_queue(&s->common, AUX_ACK);
405            break;
406        case AUX_GET_TYPE:
407            ps2_queue(&s->common, AUX_ACK);
408            ps2_queue(&s->common, s->mouse_type);
409            break;
410        case AUX_SET_RES:
411        case AUX_SET_SAMPLE:
412            s->common.write_cmd = val;
413            ps2_queue(&s->common, AUX_ACK);
414            break;
415        case AUX_GET_SCALE:
416            ps2_queue(&s->common, AUX_ACK);
417            ps2_queue(&s->common, s->mouse_status);
418            ps2_queue(&s->common, s->mouse_resolution);
419            ps2_queue(&s->common, s->mouse_sample_rate);
420            break;
421        case AUX_POLL:
422            ps2_queue(&s->common, AUX_ACK);
423            ps2_mouse_send_packet(s);
424            break;
425        case AUX_ENABLE_DEV:
426            s->mouse_status |= MOUSE_STATUS_ENABLED;
427            ps2_queue(&s->common, AUX_ACK);
428            break;
429        case AUX_DISABLE_DEV:
430            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
431            ps2_queue(&s->common, AUX_ACK);
432            break;
433        case AUX_SET_DEFAULT:
434            s->mouse_sample_rate = 100;
435            s->mouse_resolution = 2;
436            s->mouse_status = 0;
437            ps2_queue(&s->common, AUX_ACK);
438            break;
439        case AUX_RESET:
440            s->mouse_sample_rate = 100;
441            s->mouse_resolution = 2;
442            s->mouse_status = 0;
443            s->mouse_type = 0;
444            ps2_queue(&s->common, AUX_ACK);
445            ps2_queue(&s->common, 0xaa);
446            ps2_queue(&s->common, s->mouse_type);
447            break;
448        default:
449            break;
450        }
451        break;
452    case AUX_SET_SAMPLE:
453        s->mouse_sample_rate = val;
454        /* detect IMPS/2 or IMEX */
455        switch(s->mouse_detect_state) {
456        default:
457        case 0:
458            if (val == 200)
459                s->mouse_detect_state = 1;
460            break;
461        case 1:
462            if (val == 100)
463                s->mouse_detect_state = 2;
464            else if (val == 200)
465                s->mouse_detect_state = 3;
466            else
467                s->mouse_detect_state = 0;
468            break;
469        case 2:
470            if (val == 80)
471                s->mouse_type = 3; /* IMPS/2 */
472            s->mouse_detect_state = 0;
473            break;
474        case 3:
475            if (val == 80)
476                s->mouse_type = 4; /* IMEX */
477            s->mouse_detect_state = 0;
478            break;
479        }
480        ps2_queue(&s->common, AUX_ACK);
481        s->common.write_cmd = -1;
482        break;
483    case AUX_SET_RES:
484        s->mouse_resolution = val;
485        ps2_queue(&s->common, AUX_ACK);
486        s->common.write_cmd = -1;
487        break;
488    }
489}
490
491static void ps2_reset(void *opaque)
492{
493    PS2State *s = (PS2State *)opaque;
494    PS2Queue *q;
495    s->write_cmd = -1;
496    q = &s->queue;
497    q->rptr = 0;
498    q->wptr = 0;
499    q->count = 0;
500    s->update_irq(s->update_arg, 0);
501}
502
503static void ps2_common_save (QEMUFile *f, PS2State *s)
504{
505    qemu_put_be32 (f, s->write_cmd);
506    qemu_put_be32 (f, s->queue.rptr);
507    qemu_put_be32 (f, s->queue.wptr);
508    qemu_put_be32 (f, s->queue.count);
509    qemu_put_buffer (f, s->queue.data, sizeof (s->queue.data));
510}
511
512static void ps2_common_load (QEMUFile *f, PS2State *s)
513{
514    s->write_cmd=qemu_get_be32 (f);
515    s->queue.rptr=qemu_get_be32 (f);
516    s->queue.wptr=qemu_get_be32 (f);
517    s->queue.count=qemu_get_be32 (f);
518    qemu_get_buffer (f, s->queue.data, sizeof (s->queue.data));
519}
520
521static void ps2_kbd_save(QEMUFile* f, void* opaque)
522{
523    PS2KbdState *s = (PS2KbdState*)opaque;
524
525    ps2_common_save (f, &s->common);
526    qemu_put_be32(f, s->scan_enabled);
527    qemu_put_be32(f, s->translate);
528    qemu_put_be32(f, s->scancode_set);
529}
530
531static void ps2_mouse_save(QEMUFile* f, void* opaque)
532{
533    PS2MouseState *s = (PS2MouseState*)opaque;
534
535    ps2_common_save (f, &s->common);
536    qemu_put_8s(f, &s->mouse_status);
537    qemu_put_8s(f, &s->mouse_resolution);
538    qemu_put_8s(f, &s->mouse_sample_rate);
539    qemu_put_8s(f, &s->mouse_wrap);
540    qemu_put_8s(f, &s->mouse_type);
541    qemu_put_8s(f, &s->mouse_detect_state);
542    qemu_put_be32(f, s->mouse_dx);
543    qemu_put_be32(f, s->mouse_dy);
544    qemu_put_be32(f, s->mouse_dz);
545    qemu_put_8s(f, &s->mouse_buttons);
546}
547
548static int ps2_kbd_load(QEMUFile* f, void* opaque, int version_id)
549{
550    PS2KbdState *s = (PS2KbdState*)opaque;
551
552    if (version_id != 2 && version_id != 3)
553        return -EINVAL;
554
555    ps2_common_load (f, &s->common);
556    s->scan_enabled=qemu_get_be32(f);
557    s->translate=qemu_get_be32(f);
558    if (version_id == 3)
559        s->scancode_set=qemu_get_be32(f);
560    else
561        s->scancode_set=2;
562    return 0;
563}
564
565static int ps2_mouse_load(QEMUFile* f, void* opaque, int version_id)
566{
567    PS2MouseState *s = (PS2MouseState*)opaque;
568
569    if (version_id != 2)
570        return -EINVAL;
571
572    ps2_common_load (f, &s->common);
573    qemu_get_8s(f, &s->mouse_status);
574    qemu_get_8s(f, &s->mouse_resolution);
575    qemu_get_8s(f, &s->mouse_sample_rate);
576    qemu_get_8s(f, &s->mouse_wrap);
577    qemu_get_8s(f, &s->mouse_type);
578    qemu_get_8s(f, &s->mouse_detect_state);
579    s->mouse_dx=qemu_get_be32(f);
580    s->mouse_dy=qemu_get_be32(f);
581    s->mouse_dz=qemu_get_be32(f);
582    qemu_get_8s(f, &s->mouse_buttons);
583    return 0;
584}
585
586void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
587{
588    PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
589
590    s->common.update_irq = update_irq;
591    s->common.update_arg = update_arg;
592    s->scancode_set = 2;
593    ps2_reset(&s->common);
594    register_savevm("ps2kbd", 0, 3, ps2_kbd_save, ps2_kbd_load, s);
595    //qemu_add_kbd_event_handler(ps2_put_keycode, s);
596    qemu_register_reset(ps2_reset, 0, &s->common);
597    return s;
598}
599
600void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
601{
602    PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
603
604    s->common.update_irq = update_irq;
605    s->common.update_arg = update_arg;
606    ps2_reset(&s->common);
607    register_savevm("ps2mouse", 0, 2, ps2_mouse_save, ps2_mouse_load, s);
608    //qemu_add_mouse_event_handler(ps2_mouse_event, s, 0, "QEMU PS/2 Mouse");
609    qemu_register_reset(ps2_reset, 0, &s->common);
610    return s;
611}
612