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 "qemu/osdep.h"
25 #include "qemu/log.h"
26 #include "hw/hw.h"
27 #include "hw/input/ps2.h"
28 #include "ui/console.h"
29 #include "ui/input.h"
30 #include "sysemu/sysemu.h"
31 
32 #include "trace.h"
33 
34 /* debug PC keyboard */
35 //#define DEBUG_KBD
36 
37 /* debug PC keyboard : only mouse */
38 //#define DEBUG_MOUSE
39 
40 /* Keyboard Commands */
41 #define KBD_CMD_SET_LEDS	0xED	/* Set keyboard leds */
42 #define KBD_CMD_ECHO     	0xEE
43 #define KBD_CMD_SCANCODE	0xF0	/* Get/set scancode set */
44 #define KBD_CMD_GET_ID 	        0xF2	/* get keyboard ID */
45 #define KBD_CMD_SET_RATE	0xF3	/* Set typematic rate */
46 #define KBD_CMD_ENABLE		0xF4	/* Enable scanning */
47 #define KBD_CMD_RESET_DISABLE	0xF5	/* reset and disable scanning */
48 #define KBD_CMD_RESET_ENABLE   	0xF6    /* reset and enable scanning */
49 #define KBD_CMD_RESET		0xFF	/* Reset */
50 
51 /* Keyboard Replies */
52 #define KBD_REPLY_POR		0xAA	/* Power on reset */
53 #define KBD_REPLY_ID		0xAB	/* Keyboard ID */
54 #define KBD_REPLY_ACK		0xFA	/* Command ACK */
55 #define KBD_REPLY_RESEND	0xFE	/* Command NACK, send the cmd again */
56 
57 /* Mouse Commands */
58 #define AUX_SET_SCALE11		0xE6	/* Set 1:1 scaling */
59 #define AUX_SET_SCALE21		0xE7	/* Set 2:1 scaling */
60 #define AUX_SET_RES		0xE8	/* Set resolution */
61 #define AUX_GET_SCALE		0xE9	/* Get scaling factor */
62 #define AUX_SET_STREAM		0xEA	/* Set stream mode */
63 #define AUX_POLL		0xEB	/* Poll */
64 #define AUX_RESET_WRAP		0xEC	/* Reset wrap mode */
65 #define AUX_SET_WRAP		0xEE	/* Set wrap mode */
66 #define AUX_SET_REMOTE		0xF0	/* Set remote mode */
67 #define AUX_GET_TYPE		0xF2	/* Get type */
68 #define AUX_SET_SAMPLE		0xF3	/* Set sample rate */
69 #define AUX_ENABLE_DEV		0xF4	/* Enable aux device */
70 #define AUX_DISABLE_DEV		0xF5	/* Disable aux device */
71 #define AUX_SET_DEFAULT		0xF6
72 #define AUX_RESET		0xFF	/* Reset aux device */
73 #define AUX_ACK			0xFA	/* Command byte ACK. */
74 
75 #define MOUSE_STATUS_REMOTE     0x40
76 #define MOUSE_STATUS_ENABLED    0x20
77 #define MOUSE_STATUS_SCALE21    0x10
78 
79 #define PS2_QUEUE_SIZE 16  /* Buffer size required by PS/2 protocol */
80 
81 /* Bits for 'modifiers' field in PS2KbdState */
82 #define MOD_CTRL_L  (1 << 0)
83 #define MOD_SHIFT_L (1 << 1)
84 #define MOD_ALT_L   (1 << 2)
85 #define MOD_CTRL_R  (1 << 3)
86 #define MOD_SHIFT_R (1 << 4)
87 #define MOD_ALT_R   (1 << 5)
88 
89 typedef struct {
90     /* Keep the data array 256 bytes long, which compatibility
91      with older qemu versions. */
92     uint8_t data[256];
93     int rptr, wptr, count;
94 } PS2Queue;
95 
96 struct PS2State {
97     PS2Queue queue;
98     int32_t write_cmd;
99     void (*update_irq)(void *, int);
100     void *update_arg;
101 };
102 
103 typedef struct {
104     PS2State common;
105     int scan_enabled;
106     int translate;
107     int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
108     int ledstate;
109     bool need_high_bit;
110     unsigned int modifiers; /* bitmask of MOD_* constants above */
111 } PS2KbdState;
112 
113 typedef struct {
114     PS2State common;
115     uint8_t mouse_status;
116     uint8_t mouse_resolution;
117     uint8_t mouse_sample_rate;
118     uint8_t mouse_wrap;
119     uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
120     uint8_t mouse_detect_state;
121     int mouse_dx; /* current values, needed for 'poll' mode */
122     int mouse_dy;
123     int mouse_dz;
124     uint8_t mouse_buttons;
125 } PS2MouseState;
126 
127 static uint8_t translate_table[256] = {
128     0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
129     0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
130     0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
131     0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
132     0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
133     0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
134     0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
135     0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
136     0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
137     0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
138     0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
139     0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
140     0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
141     0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
142     0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
143     0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
144     0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
145     0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
146     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
147     0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
148     0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
149     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
150     0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
151     0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
152     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
153     0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
154     0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
155     0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
156     0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
157     0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
158     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
159     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
160 };
161 
ps2_modifier_bit(QKeyCode key)162 static unsigned int ps2_modifier_bit(QKeyCode key)
163 {
164     switch (key) {
165     case Q_KEY_CODE_CTRL:
166         return MOD_CTRL_L;
167     case Q_KEY_CODE_CTRL_R:
168         return MOD_CTRL_R;
169     case Q_KEY_CODE_SHIFT:
170         return MOD_SHIFT_L;
171     case Q_KEY_CODE_SHIFT_R:
172         return MOD_SHIFT_R;
173     case Q_KEY_CODE_ALT:
174         return MOD_ALT_L;
175     case Q_KEY_CODE_ALT_R:
176         return MOD_ALT_R;
177     default:
178         return 0;
179     }
180 }
181 
ps2_reset_queue(PS2State * s)182 static void ps2_reset_queue(PS2State *s)
183 {
184     PS2Queue *q = &s->queue;
185 
186     q->rptr = 0;
187     q->wptr = 0;
188     q->count = 0;
189 }
190 
ps2_queue_noirq(PS2State * s,int b)191 void ps2_queue_noirq(PS2State *s, int b)
192 {
193     PS2Queue *q = &s->queue;
194 
195     if (q->count == PS2_QUEUE_SIZE) {
196         return;
197     }
198 
199     q->data[q->wptr] = b;
200     if (++q->wptr == PS2_QUEUE_SIZE)
201         q->wptr = 0;
202     q->count++;
203 }
204 
ps2_raise_irq(PS2State * s)205 void ps2_raise_irq(PS2State *s)
206 {
207     s->update_irq(s->update_arg, 1);
208 }
209 
ps2_queue(PS2State * s,int b)210 void ps2_queue(PS2State *s, int b)
211 {
212     ps2_queue_noirq(s, b);
213     s->update_irq(s->update_arg, 1);
214 }
215 
ps2_queue_2(PS2State * s,int b1,int b2)216 void ps2_queue_2(PS2State *s, int b1, int b2)
217 {
218     if (PS2_QUEUE_SIZE - s->queue.count < 2) {
219         return;
220     }
221 
222     ps2_queue_noirq(s, b1);
223     ps2_queue_noirq(s, b2);
224     s->update_irq(s->update_arg, 1);
225 }
226 
ps2_queue_3(PS2State * s,int b1,int b2,int b3)227 void ps2_queue_3(PS2State *s, int b1, int b2, int b3)
228 {
229     if (PS2_QUEUE_SIZE - s->queue.count < 3) {
230         return;
231     }
232 
233     ps2_queue_noirq(s, b1);
234     ps2_queue_noirq(s, b2);
235     ps2_queue_noirq(s, b3);
236     s->update_irq(s->update_arg, 1);
237 }
238 
ps2_queue_4(PS2State * s,int b1,int b2,int b3,int b4)239 void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4)
240 {
241     if (PS2_QUEUE_SIZE - s->queue.count < 4) {
242         return;
243     }
244 
245     ps2_queue_noirq(s, b1);
246     ps2_queue_noirq(s, b2);
247     ps2_queue_noirq(s, b3);
248     ps2_queue_noirq(s, b4);
249     s->update_irq(s->update_arg, 1);
250 }
251 
252 /* keycode is the untranslated scancode in the current scancode set. */
ps2_put_keycode(void * opaque,int keycode)253 static void ps2_put_keycode(void *opaque, int keycode)
254 {
255     PS2KbdState *s = opaque;
256 
257     trace_ps2_put_keycode(opaque, keycode);
258     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
259 
260     if (s->translate) {
261         if (keycode == 0xf0) {
262             s->need_high_bit = true;
263         } else if (s->need_high_bit) {
264             ps2_queue(&s->common, translate_table[keycode] | 0x80);
265             s->need_high_bit = false;
266         } else {
267             ps2_queue(&s->common, translate_table[keycode]);
268         }
269     } else {
270         ps2_queue(&s->common, keycode);
271     }
272 }
273 
ps2_keyboard_event(DeviceState * dev,QemuConsole * src,InputEvent * evt)274 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
275                                InputEvent *evt)
276 {
277     PS2KbdState *s = (PS2KbdState *)dev;
278     InputKeyEvent *key = evt->u.key.data;
279     int qcode;
280     uint16_t keycode = 0;
281     int mod;
282 
283     /* do not process events while disabled to prevent stream corruption */
284     if (!s->scan_enabled) {
285         return;
286     }
287 
288     qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
289     assert(evt->type == INPUT_EVENT_KIND_KEY);
290     qcode = qemu_input_key_value_to_qcode(key->key);
291 
292     mod = ps2_modifier_bit(qcode);
293     trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers);
294     if (key->down) {
295         s->modifiers |= mod;
296     } else {
297         s->modifiers &= ~mod;
298     }
299 
300     if (s->scancode_set == 1) {
301         if (qcode == Q_KEY_CODE_PAUSE) {
302             if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
303                 if (key->down) {
304                     ps2_put_keycode(s, 0xe0);
305                     ps2_put_keycode(s, 0x46);
306                     ps2_put_keycode(s, 0xe0);
307                     ps2_put_keycode(s, 0xc6);
308                 }
309             } else {
310                 if (key->down) {
311                     ps2_put_keycode(s, 0xe1);
312                     ps2_put_keycode(s, 0x1d);
313                     ps2_put_keycode(s, 0x45);
314                     ps2_put_keycode(s, 0xe1);
315                     ps2_put_keycode(s, 0x9d);
316                     ps2_put_keycode(s, 0xc5);
317                 }
318             }
319         } else if (qcode == Q_KEY_CODE_PRINT) {
320             if (s->modifiers & MOD_ALT_L) {
321                 if (key->down) {
322                     ps2_put_keycode(s, 0xb8);
323                     ps2_put_keycode(s, 0x38);
324                     ps2_put_keycode(s, 0x54);
325                 } else {
326                     ps2_put_keycode(s, 0xd4);
327                     ps2_put_keycode(s, 0xb8);
328                     ps2_put_keycode(s, 0x38);
329                 }
330             } else if (s->modifiers & MOD_ALT_R) {
331                 if (key->down) {
332                     ps2_put_keycode(s, 0xe0);
333                     ps2_put_keycode(s, 0xb8);
334                     ps2_put_keycode(s, 0xe0);
335                     ps2_put_keycode(s, 0x38);
336                     ps2_put_keycode(s, 0x54);
337                 } else {
338                     ps2_put_keycode(s, 0xd4);
339                     ps2_put_keycode(s, 0xe0);
340                     ps2_put_keycode(s, 0xb8);
341                     ps2_put_keycode(s, 0xe0);
342                     ps2_put_keycode(s, 0x38);
343                 }
344             } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
345                                        MOD_SHIFT_R | MOD_CTRL_R)) {
346                 if (key->down) {
347                     ps2_put_keycode(s, 0xe0);
348                     ps2_put_keycode(s, 0x37);
349                 } else {
350                     ps2_put_keycode(s, 0xe0);
351                     ps2_put_keycode(s, 0xb7);
352                 }
353             } else {
354                 if (key->down) {
355                     ps2_put_keycode(s, 0xe0);
356                     ps2_put_keycode(s, 0x2a);
357                     ps2_put_keycode(s, 0xe0);
358                     ps2_put_keycode(s, 0x37);
359                 } else {
360                     ps2_put_keycode(s, 0xe0);
361                     ps2_put_keycode(s, 0xb7);
362                     ps2_put_keycode(s, 0xe0);
363                     ps2_put_keycode(s, 0xaa);
364                 }
365             }
366         } else {
367             if (qcode < qemu_input_map_qcode_to_atset1_len)
368                 keycode = qemu_input_map_qcode_to_atset1[qcode];
369             if (keycode) {
370                 if (keycode & 0xff00) {
371                     ps2_put_keycode(s, keycode >> 8);
372                 }
373                 if (!key->down) {
374                     keycode |= 0x80;
375                 }
376                 ps2_put_keycode(s, keycode & 0xff);
377             } else {
378                 qemu_log_mask(LOG_UNIMP,
379                               "ps2: ignoring key with qcode %d\n", qcode);
380             }
381         }
382     } else if (s->scancode_set == 2) {
383         if (qcode == Q_KEY_CODE_PAUSE) {
384             if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) {
385                 if (key->down) {
386                     ps2_put_keycode(s, 0xe0);
387                     ps2_put_keycode(s, 0x7e);
388                     ps2_put_keycode(s, 0xe0);
389                     ps2_put_keycode(s, 0xf0);
390                     ps2_put_keycode(s, 0x7e);
391                 }
392             } else {
393                 if (key->down) {
394                     ps2_put_keycode(s, 0xe1);
395                     ps2_put_keycode(s, 0x14);
396                     ps2_put_keycode(s, 0x77);
397                     ps2_put_keycode(s, 0xe1);
398                     ps2_put_keycode(s, 0xf0);
399                     ps2_put_keycode(s, 0x14);
400                     ps2_put_keycode(s, 0xf0);
401                     ps2_put_keycode(s, 0x77);
402                 }
403             }
404         } else if (qcode == Q_KEY_CODE_PRINT) {
405             if (s->modifiers & MOD_ALT_L) {
406                 if (key->down) {
407                     ps2_put_keycode(s, 0xf0);
408                     ps2_put_keycode(s, 0x11);
409                     ps2_put_keycode(s, 0x11);
410                     ps2_put_keycode(s, 0x84);
411                 } else {
412                     ps2_put_keycode(s, 0xf0);
413                     ps2_put_keycode(s, 0x84);
414                     ps2_put_keycode(s, 0xf0);
415                     ps2_put_keycode(s, 0x11);
416                     ps2_put_keycode(s, 0x11);
417                 }
418             } else if (s->modifiers & MOD_ALT_R) {
419                 if (key->down) {
420                     ps2_put_keycode(s, 0xe0);
421                     ps2_put_keycode(s, 0xf0);
422                     ps2_put_keycode(s, 0x11);
423                     ps2_put_keycode(s, 0xe0);
424                     ps2_put_keycode(s, 0x11);
425                     ps2_put_keycode(s, 0x84);
426                 } else {
427                     ps2_put_keycode(s, 0xf0);
428                     ps2_put_keycode(s, 0x84);
429                     ps2_put_keycode(s, 0xe0);
430                     ps2_put_keycode(s, 0xf0);
431                     ps2_put_keycode(s, 0x11);
432                     ps2_put_keycode(s, 0xe0);
433                     ps2_put_keycode(s, 0x11);
434                 }
435             } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L |
436                                        MOD_SHIFT_R | MOD_CTRL_R)) {
437                 if (key->down) {
438                     ps2_put_keycode(s, 0xe0);
439                     ps2_put_keycode(s, 0x7c);
440                 } else {
441                     ps2_put_keycode(s, 0xe0);
442                     ps2_put_keycode(s, 0xf0);
443                     ps2_put_keycode(s, 0x7c);
444                 }
445             } else {
446                 if (key->down) {
447                     ps2_put_keycode(s, 0xe0);
448                     ps2_put_keycode(s, 0x12);
449                     ps2_put_keycode(s, 0xe0);
450                     ps2_put_keycode(s, 0x7c);
451                 } else {
452                     ps2_put_keycode(s, 0xe0);
453                     ps2_put_keycode(s, 0xf0);
454                     ps2_put_keycode(s, 0x7c);
455                     ps2_put_keycode(s, 0xe0);
456                     ps2_put_keycode(s, 0xf0);
457                     ps2_put_keycode(s, 0x12);
458                 }
459             }
460         } else {
461             if (qcode < qemu_input_map_qcode_to_atset2_len)
462                 keycode = qemu_input_map_qcode_to_atset2[qcode];
463             if (keycode) {
464                 if (keycode & 0xff00) {
465                     ps2_put_keycode(s, keycode >> 8);
466                 }
467                 if (!key->down) {
468                     ps2_put_keycode(s, 0xf0);
469                 }
470                 ps2_put_keycode(s, keycode & 0xff);
471             } else {
472                 qemu_log_mask(LOG_UNIMP,
473                               "ps2: ignoring key with qcode %d\n", qcode);
474             }
475         }
476     } else if (s->scancode_set == 3) {
477         if (qcode < qemu_input_map_qcode_to_atset3_len)
478             keycode = qemu_input_map_qcode_to_atset3[qcode];
479         if (keycode) {
480             /* FIXME: break code should be configured on a key by key basis */
481             if (!key->down) {
482                 ps2_put_keycode(s, 0xf0);
483             }
484             ps2_put_keycode(s, keycode);
485         } else {
486             qemu_log_mask(LOG_UNIMP,
487                           "ps2: ignoring key with qcode %d\n", qcode);
488         }
489     }
490 }
491 
ps2_read_data(PS2State * s)492 uint32_t ps2_read_data(PS2State *s)
493 {
494     PS2Queue *q;
495     int val, index;
496 
497     trace_ps2_read_data(s);
498     q = &s->queue;
499     if (q->count == 0) {
500         /* NOTE: if no data left, we return the last keyboard one
501            (needed for EMM386) */
502         /* XXX: need a timer to do things correctly */
503         index = q->rptr - 1;
504         if (index < 0)
505             index = PS2_QUEUE_SIZE - 1;
506         val = q->data[index];
507     } else {
508         val = q->data[q->rptr];
509         if (++q->rptr == PS2_QUEUE_SIZE)
510             q->rptr = 0;
511         q->count--;
512         /* reading deasserts IRQ */
513         s->update_irq(s->update_arg, 0);
514         /* reassert IRQs if data left */
515         s->update_irq(s->update_arg, q->count != 0);
516     }
517     return val;
518 }
519 
ps2_set_ledstate(PS2KbdState * s,int ledstate)520 static void ps2_set_ledstate(PS2KbdState *s, int ledstate)
521 {
522     trace_ps2_set_ledstate(s, ledstate);
523     s->ledstate = ledstate;
524     kbd_put_ledstate(ledstate);
525 }
526 
ps2_reset_keyboard(PS2KbdState * s)527 static void ps2_reset_keyboard(PS2KbdState *s)
528 {
529     trace_ps2_reset_keyboard(s);
530     s->scan_enabled = 1;
531     s->scancode_set = 2;
532     ps2_reset_queue(&s->common);
533     ps2_set_ledstate(s, 0);
534 }
535 
ps2_write_keyboard(void * opaque,int val)536 void ps2_write_keyboard(void *opaque, int val)
537 {
538     PS2KbdState *s = (PS2KbdState *)opaque;
539 
540     trace_ps2_write_keyboard(opaque, val);
541     switch(s->common.write_cmd) {
542     default:
543     case -1:
544         switch(val) {
545         case 0x00:
546             ps2_queue(&s->common, KBD_REPLY_ACK);
547             break;
548         case 0x05:
549             ps2_queue(&s->common, KBD_REPLY_RESEND);
550             break;
551         case KBD_CMD_GET_ID:
552             /* We emulate a MF2 AT keyboard here */
553             if (s->translate)
554                 ps2_queue_3(&s->common,
555                     KBD_REPLY_ACK,
556                     KBD_REPLY_ID,
557                     0x41);
558             else
559                 ps2_queue_3(&s->common,
560                     KBD_REPLY_ACK,
561                     KBD_REPLY_ID,
562                     0x83);
563             break;
564         case KBD_CMD_ECHO:
565             ps2_queue(&s->common, KBD_CMD_ECHO);
566             break;
567         case KBD_CMD_ENABLE:
568             s->scan_enabled = 1;
569             ps2_queue(&s->common, KBD_REPLY_ACK);
570             break;
571         case KBD_CMD_SCANCODE:
572         case KBD_CMD_SET_LEDS:
573         case KBD_CMD_SET_RATE:
574             s->common.write_cmd = val;
575             ps2_queue(&s->common, KBD_REPLY_ACK);
576             break;
577         case KBD_CMD_RESET_DISABLE:
578             ps2_reset_keyboard(s);
579             s->scan_enabled = 0;
580             ps2_queue(&s->common, KBD_REPLY_ACK);
581             break;
582         case KBD_CMD_RESET_ENABLE:
583             ps2_reset_keyboard(s);
584             s->scan_enabled = 1;
585             ps2_queue(&s->common, KBD_REPLY_ACK);
586             break;
587         case KBD_CMD_RESET:
588             ps2_reset_keyboard(s);
589             ps2_queue_2(&s->common,
590                 KBD_REPLY_ACK,
591                 KBD_REPLY_POR);
592             break;
593         default:
594             ps2_queue(&s->common, KBD_REPLY_RESEND);
595             break;
596         }
597         break;
598     case KBD_CMD_SCANCODE:
599         if (val == 0) {
600             if (s->common.queue.count <= PS2_QUEUE_SIZE - 2) {
601                 ps2_queue(&s->common, KBD_REPLY_ACK);
602                 ps2_put_keycode(s, s->scancode_set);
603             }
604         } else if (val >= 1 && val <= 3) {
605             s->scancode_set = val;
606             ps2_queue(&s->common, KBD_REPLY_ACK);
607         } else {
608             ps2_queue(&s->common, KBD_REPLY_RESEND);
609         }
610         s->common.write_cmd = -1;
611         break;
612     case KBD_CMD_SET_LEDS:
613         ps2_set_ledstate(s, val);
614         ps2_queue(&s->common, KBD_REPLY_ACK);
615         s->common.write_cmd = -1;
616         break;
617     case KBD_CMD_SET_RATE:
618         ps2_queue(&s->common, KBD_REPLY_ACK);
619         s->common.write_cmd = -1;
620         break;
621     }
622 }
623 
624 /* Set the scancode translation mode.
625    0 = raw scancodes.
626    1 = translated scancodes (used by qemu internally).  */
627 
ps2_keyboard_set_translation(void * opaque,int mode)628 void ps2_keyboard_set_translation(void *opaque, int mode)
629 {
630     PS2KbdState *s = (PS2KbdState *)opaque;
631     trace_ps2_keyboard_set_translation(opaque, mode);
632     s->translate = mode;
633 }
634 
ps2_mouse_send_packet(PS2MouseState * s)635 static int ps2_mouse_send_packet(PS2MouseState *s)
636 {
637     const int needed = 3 + (s->mouse_type - 2);
638     unsigned int b;
639     int dx1, dy1, dz1;
640 
641     if (PS2_QUEUE_SIZE - s->common.queue.count < needed) {
642         return 0;
643     }
644 
645     dx1 = s->mouse_dx;
646     dy1 = s->mouse_dy;
647     dz1 = s->mouse_dz;
648     /* XXX: increase range to 8 bits ? */
649     if (dx1 > 127)
650         dx1 = 127;
651     else if (dx1 < -127)
652         dx1 = -127;
653     if (dy1 > 127)
654         dy1 = 127;
655     else if (dy1 < -127)
656         dy1 = -127;
657     b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
658     ps2_queue_noirq(&s->common, b);
659     ps2_queue_noirq(&s->common, dx1 & 0xff);
660     ps2_queue_noirq(&s->common, dy1 & 0xff);
661     /* extra byte for IMPS/2 or IMEX */
662     switch(s->mouse_type) {
663     default:
664         break;
665     case 3:
666         if (dz1 > 127)
667             dz1 = 127;
668         else if (dz1 < -127)
669                 dz1 = -127;
670         ps2_queue_noirq(&s->common, dz1 & 0xff);
671         break;
672     case 4:
673         if (dz1 > 7)
674             dz1 = 7;
675         else if (dz1 < -7)
676             dz1 = -7;
677         b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
678         ps2_queue_noirq(&s->common, b);
679         break;
680     }
681 
682     ps2_raise_irq(&s->common);
683 
684     trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b);
685     /* update deltas */
686     s->mouse_dx -= dx1;
687     s->mouse_dy -= dy1;
688     s->mouse_dz -= dz1;
689 
690     return 1;
691 }
692 
ps2_mouse_event(DeviceState * dev,QemuConsole * src,InputEvent * evt)693 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src,
694                             InputEvent *evt)
695 {
696     static const int bmap[INPUT_BUTTON__MAX] = {
697         [INPUT_BUTTON_LEFT]   = PS2_MOUSE_BUTTON_LEFT,
698         [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE,
699         [INPUT_BUTTON_RIGHT]  = PS2_MOUSE_BUTTON_RIGHT,
700         [INPUT_BUTTON_SIDE]   = PS2_MOUSE_BUTTON_SIDE,
701         [INPUT_BUTTON_EXTRA]  = PS2_MOUSE_BUTTON_EXTRA,
702     };
703     PS2MouseState *s = (PS2MouseState *)dev;
704     InputMoveEvent *move;
705     InputBtnEvent *btn;
706 
707     /* check if deltas are recorded when disabled */
708     if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
709         return;
710 
711     switch (evt->type) {
712     case INPUT_EVENT_KIND_REL:
713         move = evt->u.rel.data;
714         if (move->axis == INPUT_AXIS_X) {
715             s->mouse_dx += move->value;
716         } else if (move->axis == INPUT_AXIS_Y) {
717             s->mouse_dy -= move->value;
718         }
719         break;
720 
721     case INPUT_EVENT_KIND_BTN:
722         btn = evt->u.btn.data;
723         if (btn->down) {
724             s->mouse_buttons |= bmap[btn->button];
725             if (btn->button == INPUT_BUTTON_WHEEL_UP) {
726                 s->mouse_dz--;
727             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
728                 s->mouse_dz++;
729             }
730         } else {
731             s->mouse_buttons &= ~bmap[btn->button];
732         }
733         break;
734 
735     default:
736         /* keep gcc happy */
737         break;
738     }
739 }
740 
ps2_mouse_sync(DeviceState * dev)741 static void ps2_mouse_sync(DeviceState *dev)
742 {
743     PS2MouseState *s = (PS2MouseState *)dev;
744 
745     /* do not sync while disabled to prevent stream corruption */
746     if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) {
747         return;
748     }
749 
750     if (s->mouse_buttons) {
751         qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
752     }
753     if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) {
754         /* if not remote, send event. Multiple events are sent if
755            too big deltas */
756         while (ps2_mouse_send_packet(s)) {
757             if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
758                 break;
759         }
760     }
761 }
762 
ps2_mouse_fake_event(void * opaque)763 void ps2_mouse_fake_event(void *opaque)
764 {
765     PS2MouseState *s = opaque;
766     trace_ps2_mouse_fake_event(opaque);
767     s->mouse_dx++;
768     ps2_mouse_sync(opaque);
769 }
770 
ps2_write_mouse(void * opaque,int val)771 void ps2_write_mouse(void *opaque, int val)
772 {
773     PS2MouseState *s = (PS2MouseState *)opaque;
774 
775     trace_ps2_write_mouse(opaque, val);
776 #ifdef DEBUG_MOUSE
777     printf("kbd: write mouse 0x%02x\n", val);
778 #endif
779     switch(s->common.write_cmd) {
780     default:
781     case -1:
782         /* mouse command */
783         if (s->mouse_wrap) {
784             if (val == AUX_RESET_WRAP) {
785                 s->mouse_wrap = 0;
786                 ps2_queue(&s->common, AUX_ACK);
787                 return;
788             } else if (val != AUX_RESET) {
789                 ps2_queue(&s->common, val);
790                 return;
791             }
792         }
793         switch(val) {
794         case AUX_SET_SCALE11:
795             s->mouse_status &= ~MOUSE_STATUS_SCALE21;
796             ps2_queue(&s->common, AUX_ACK);
797             break;
798         case AUX_SET_SCALE21:
799             s->mouse_status |= MOUSE_STATUS_SCALE21;
800             ps2_queue(&s->common, AUX_ACK);
801             break;
802         case AUX_SET_STREAM:
803             s->mouse_status &= ~MOUSE_STATUS_REMOTE;
804             ps2_queue(&s->common, AUX_ACK);
805             break;
806         case AUX_SET_WRAP:
807             s->mouse_wrap = 1;
808             ps2_queue(&s->common, AUX_ACK);
809             break;
810         case AUX_SET_REMOTE:
811             s->mouse_status |= MOUSE_STATUS_REMOTE;
812             ps2_queue(&s->common, AUX_ACK);
813             break;
814         case AUX_GET_TYPE:
815             ps2_queue_2(&s->common,
816                 AUX_ACK,
817                 s->mouse_type);
818             break;
819         case AUX_SET_RES:
820         case AUX_SET_SAMPLE:
821             s->common.write_cmd = val;
822             ps2_queue(&s->common, AUX_ACK);
823             break;
824         case AUX_GET_SCALE:
825             ps2_queue_4(&s->common,
826                 AUX_ACK,
827                 s->mouse_status,
828                 s->mouse_resolution,
829                 s->mouse_sample_rate);
830             break;
831         case AUX_POLL:
832             ps2_queue(&s->common, AUX_ACK);
833             ps2_mouse_send_packet(s);
834             break;
835         case AUX_ENABLE_DEV:
836             s->mouse_status |= MOUSE_STATUS_ENABLED;
837             ps2_queue(&s->common, AUX_ACK);
838             break;
839         case AUX_DISABLE_DEV:
840             s->mouse_status &= ~MOUSE_STATUS_ENABLED;
841             ps2_queue(&s->common, AUX_ACK);
842             break;
843         case AUX_SET_DEFAULT:
844             s->mouse_sample_rate = 100;
845             s->mouse_resolution = 2;
846             s->mouse_status = 0;
847             ps2_queue(&s->common, AUX_ACK);
848             break;
849         case AUX_RESET:
850             s->mouse_sample_rate = 100;
851             s->mouse_resolution = 2;
852             s->mouse_status = 0;
853             s->mouse_type = 0;
854             ps2_reset_queue(&s->common);
855             ps2_queue_3(&s->common,
856                 AUX_ACK,
857                 0xaa,
858                 s->mouse_type);
859             break;
860         default:
861             break;
862         }
863         break;
864     case AUX_SET_SAMPLE:
865         s->mouse_sample_rate = val;
866         /* detect IMPS/2 or IMEX */
867         switch(s->mouse_detect_state) {
868         default:
869         case 0:
870             if (val == 200)
871                 s->mouse_detect_state = 1;
872             break;
873         case 1:
874             if (val == 100)
875                 s->mouse_detect_state = 2;
876             else if (val == 200)
877                 s->mouse_detect_state = 3;
878             else
879                 s->mouse_detect_state = 0;
880             break;
881         case 2:
882             if (val == 80)
883                 s->mouse_type = 3; /* IMPS/2 */
884             s->mouse_detect_state = 0;
885             break;
886         case 3:
887             if (val == 80)
888                 s->mouse_type = 4; /* IMEX */
889             s->mouse_detect_state = 0;
890             break;
891         }
892         ps2_queue(&s->common, AUX_ACK);
893         s->common.write_cmd = -1;
894         break;
895     case AUX_SET_RES:
896         s->mouse_resolution = val;
897         ps2_queue(&s->common, AUX_ACK);
898         s->common.write_cmd = -1;
899         break;
900     }
901 }
902 
ps2_common_reset(PS2State * s)903 static void ps2_common_reset(PS2State *s)
904 {
905     s->write_cmd = -1;
906     ps2_reset_queue(s);
907     s->update_irq(s->update_arg, 0);
908 }
909 
ps2_common_post_load(PS2State * s)910 static void ps2_common_post_load(PS2State *s)
911 {
912     PS2Queue *q = &s->queue;
913     uint8_t i, size;
914     uint8_t tmp_data[PS2_QUEUE_SIZE];
915 
916     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
917     size = q->count;
918     if (q->count < 0) {
919         size = 0;
920     } else if (q->count > PS2_QUEUE_SIZE) {
921         size = PS2_QUEUE_SIZE;
922     }
923 
924     /* move the queue elements to the start of data array */
925     for (i = 0; i < size; i++) {
926         if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
927             q->rptr = 0;
928         }
929         tmp_data[i] = q->data[q->rptr++];
930     }
931     memcpy(q->data, tmp_data, size);
932 
933     /* reset rptr/wptr/count */
934     q->rptr = 0;
935     q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
936     q->count = size;
937 }
938 
ps2_kbd_reset(void * opaque)939 static void ps2_kbd_reset(void *opaque)
940 {
941     PS2KbdState *s = (PS2KbdState *) opaque;
942 
943     trace_ps2_kbd_reset(opaque);
944     ps2_common_reset(&s->common);
945     s->scan_enabled = 0;
946     s->translate = 0;
947     s->scancode_set = 2;
948     s->modifiers = 0;
949 }
950 
ps2_mouse_reset(void * opaque)951 static void ps2_mouse_reset(void *opaque)
952 {
953     PS2MouseState *s = (PS2MouseState *) opaque;
954 
955     trace_ps2_mouse_reset(opaque);
956     ps2_common_reset(&s->common);
957     s->mouse_status = 0;
958     s->mouse_resolution = 0;
959     s->mouse_sample_rate = 0;
960     s->mouse_wrap = 0;
961     s->mouse_type = 0;
962     s->mouse_detect_state = 0;
963     s->mouse_dx = 0;
964     s->mouse_dy = 0;
965     s->mouse_dz = 0;
966     s->mouse_buttons = 0;
967 }
968 
969 static const VMStateDescription vmstate_ps2_common = {
970     .name = "PS2 Common State",
971     .version_id = 3,
972     .minimum_version_id = 2,
973     .fields = (VMStateField[]) {
974         VMSTATE_INT32(write_cmd, PS2State),
975         VMSTATE_INT32(queue.rptr, PS2State),
976         VMSTATE_INT32(queue.wptr, PS2State),
977         VMSTATE_INT32(queue.count, PS2State),
978         VMSTATE_BUFFER(queue.data, PS2State),
979         VMSTATE_END_OF_LIST()
980     }
981 };
982 
ps2_keyboard_ledstate_needed(void * opaque)983 static bool ps2_keyboard_ledstate_needed(void *opaque)
984 {
985     PS2KbdState *s = opaque;
986 
987     return s->ledstate != 0; /* 0 is default state */
988 }
989 
ps2_kbd_ledstate_post_load(void * opaque,int version_id)990 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
991 {
992     PS2KbdState *s = opaque;
993 
994     kbd_put_ledstate(s->ledstate);
995     return 0;
996 }
997 
998 static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
999     .name = "ps2kbd/ledstate",
1000     .version_id = 3,
1001     .minimum_version_id = 2,
1002     .post_load = ps2_kbd_ledstate_post_load,
1003     .needed = ps2_keyboard_ledstate_needed,
1004     .fields = (VMStateField[]) {
1005         VMSTATE_INT32(ledstate, PS2KbdState),
1006         VMSTATE_END_OF_LIST()
1007     }
1008 };
1009 
ps2_keyboard_need_high_bit_needed(void * opaque)1010 static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1011 {
1012     PS2KbdState *s = opaque;
1013     return s->need_high_bit != 0; /* 0 is the usual state */
1014 }
1015 
1016 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1017     .name = "ps2kbd/need_high_bit",
1018     .version_id = 1,
1019     .minimum_version_id = 1,
1020     .needed = ps2_keyboard_need_high_bit_needed,
1021     .fields = (VMStateField[]) {
1022         VMSTATE_BOOL(need_high_bit, PS2KbdState),
1023         VMSTATE_END_OF_LIST()
1024     }
1025 };
1026 
ps2_kbd_post_load(void * opaque,int version_id)1027 static int ps2_kbd_post_load(void* opaque, int version_id)
1028 {
1029     PS2KbdState *s = (PS2KbdState*)opaque;
1030     PS2State *ps2 = &s->common;
1031 
1032     if (version_id == 2)
1033         s->scancode_set=2;
1034 
1035     ps2_common_post_load(ps2);
1036 
1037     return 0;
1038 }
1039 
ps2_kbd_pre_save(void * opaque)1040 static int ps2_kbd_pre_save(void *opaque)
1041 {
1042     PS2KbdState *s = (PS2KbdState *)opaque;
1043     PS2State *ps2 = &s->common;
1044 
1045     ps2_common_post_load(ps2);
1046 
1047     return 0;
1048 }
1049 
1050 static const VMStateDescription vmstate_ps2_keyboard = {
1051     .name = "ps2kbd",
1052     .version_id = 3,
1053     .minimum_version_id = 2,
1054     .post_load = ps2_kbd_post_load,
1055     .pre_save = ps2_kbd_pre_save,
1056     .fields = (VMStateField[]) {
1057         VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1058         VMSTATE_INT32(scan_enabled, PS2KbdState),
1059         VMSTATE_INT32(translate, PS2KbdState),
1060         VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1061         VMSTATE_END_OF_LIST()
1062     },
1063     .subsections = (const VMStateDescription*[]) {
1064         &vmstate_ps2_keyboard_ledstate,
1065         &vmstate_ps2_keyboard_need_high_bit,
1066         NULL
1067     }
1068 };
1069 
ps2_mouse_post_load(void * opaque,int version_id)1070 static int ps2_mouse_post_load(void *opaque, int version_id)
1071 {
1072     PS2MouseState *s = (PS2MouseState *)opaque;
1073     PS2State *ps2 = &s->common;
1074 
1075     ps2_common_post_load(ps2);
1076 
1077     return 0;
1078 }
1079 
ps2_mouse_pre_save(void * opaque)1080 static int ps2_mouse_pre_save(void *opaque)
1081 {
1082     PS2MouseState *s = (PS2MouseState *)opaque;
1083     PS2State *ps2 = &s->common;
1084 
1085     ps2_common_post_load(ps2);
1086 
1087     return 0;
1088 }
1089 
1090 static const VMStateDescription vmstate_ps2_mouse = {
1091     .name = "ps2mouse",
1092     .version_id = 2,
1093     .minimum_version_id = 2,
1094     .post_load = ps2_mouse_post_load,
1095     .pre_save = ps2_mouse_pre_save,
1096     .fields = (VMStateField[]) {
1097         VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1098         VMSTATE_UINT8(mouse_status, PS2MouseState),
1099         VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1100         VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1101         VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1102         VMSTATE_UINT8(mouse_type, PS2MouseState),
1103         VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1104         VMSTATE_INT32(mouse_dx, PS2MouseState),
1105         VMSTATE_INT32(mouse_dy, PS2MouseState),
1106         VMSTATE_INT32(mouse_dz, PS2MouseState),
1107         VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1108         VMSTATE_END_OF_LIST()
1109     }
1110 };
1111 
1112 static QemuInputHandler ps2_keyboard_handler = {
1113     .name  = "QEMU PS/2 Keyboard",
1114     .mask  = INPUT_EVENT_MASK_KEY,
1115     .event = ps2_keyboard_event,
1116 };
1117 
ps2_kbd_init(void (* update_irq)(void *,int),void * update_arg)1118 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1119 {
1120     PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1121 
1122     trace_ps2_kbd_init(s);
1123     s->common.update_irq = update_irq;
1124     s->common.update_arg = update_arg;
1125     s->scancode_set = 2;
1126     vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1127     qemu_input_handler_register((DeviceState *)s,
1128                                 &ps2_keyboard_handler);
1129     qemu_register_reset(ps2_kbd_reset, s);
1130     return s;
1131 }
1132 
1133 static QemuInputHandler ps2_mouse_handler = {
1134     .name  = "QEMU PS/2 Mouse",
1135     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1136     .event = ps2_mouse_event,
1137     .sync  = ps2_mouse_sync,
1138 };
1139 
ps2_mouse_init(void (* update_irq)(void *,int),void * update_arg)1140 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1141 {
1142     PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1143 
1144     trace_ps2_mouse_init(s);
1145     s->common.update_irq = update_irq;
1146     s->common.update_arg = update_arg;
1147     vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1148     qemu_input_handler_register((DeviceState *)s,
1149                                 &ps2_mouse_handler);
1150     qemu_register_reset(ps2_mouse_reset, s);
1151     return s;
1152 }
1153