xref: /openbmc/qemu/hw/input/ps2.c (revision 429d3ae2)
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  
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  
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  
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  
205  void ps2_raise_irq(PS2State *s)
206  {
207      s->update_irq(s->update_arg, 1);
208  }
209  
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  
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  
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  
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. */
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  
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  
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  
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  
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  
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  
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  
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  
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  
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  
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  
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  
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  
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 < 0 || q->count > PS2_QUEUE_SIZE) ? 0 : q->count;
918  
919      /* move the queue elements to the start of data array */
920      for (i = 0; i < size; i++) {
921          if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
922              q->rptr = 0;
923          }
924          tmp_data[i] = q->data[q->rptr++];
925      }
926      memcpy(q->data, tmp_data, size);
927  
928      /* reset rptr/wptr/count */
929      q->rptr = 0;
930      q->wptr = (size == PS2_QUEUE_SIZE) ? 0 : size;
931      q->count = size;
932      s->update_irq(s->update_arg, q->count != 0);
933  }
934  
935  static void ps2_kbd_reset(void *opaque)
936  {
937      PS2KbdState *s = (PS2KbdState *) opaque;
938  
939      trace_ps2_kbd_reset(opaque);
940      ps2_common_reset(&s->common);
941      s->scan_enabled = 0;
942      s->translate = 0;
943      s->scancode_set = 2;
944      s->modifiers = 0;
945  }
946  
947  static void ps2_mouse_reset(void *opaque)
948  {
949      PS2MouseState *s = (PS2MouseState *) opaque;
950  
951      trace_ps2_mouse_reset(opaque);
952      ps2_common_reset(&s->common);
953      s->mouse_status = 0;
954      s->mouse_resolution = 0;
955      s->mouse_sample_rate = 0;
956      s->mouse_wrap = 0;
957      s->mouse_type = 0;
958      s->mouse_detect_state = 0;
959      s->mouse_dx = 0;
960      s->mouse_dy = 0;
961      s->mouse_dz = 0;
962      s->mouse_buttons = 0;
963  }
964  
965  static const VMStateDescription vmstate_ps2_common = {
966      .name = "PS2 Common State",
967      .version_id = 3,
968      .minimum_version_id = 2,
969      .fields = (VMStateField[]) {
970          VMSTATE_INT32(write_cmd, PS2State),
971          VMSTATE_INT32(queue.rptr, PS2State),
972          VMSTATE_INT32(queue.wptr, PS2State),
973          VMSTATE_INT32(queue.count, PS2State),
974          VMSTATE_BUFFER(queue.data, PS2State),
975          VMSTATE_END_OF_LIST()
976      }
977  };
978  
979  static bool ps2_keyboard_ledstate_needed(void *opaque)
980  {
981      PS2KbdState *s = opaque;
982  
983      return s->ledstate != 0; /* 0 is default state */
984  }
985  
986  static int ps2_kbd_ledstate_post_load(void *opaque, int version_id)
987  {
988      PS2KbdState *s = opaque;
989  
990      kbd_put_ledstate(s->ledstate);
991      return 0;
992  }
993  
994  static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
995      .name = "ps2kbd/ledstate",
996      .version_id = 3,
997      .minimum_version_id = 2,
998      .post_load = ps2_kbd_ledstate_post_load,
999      .needed = ps2_keyboard_ledstate_needed,
1000      .fields = (VMStateField[]) {
1001          VMSTATE_INT32(ledstate, PS2KbdState),
1002          VMSTATE_END_OF_LIST()
1003      }
1004  };
1005  
1006  static bool ps2_keyboard_need_high_bit_needed(void *opaque)
1007  {
1008      PS2KbdState *s = opaque;
1009      return s->need_high_bit != 0; /* 0 is the usual state */
1010  }
1011  
1012  static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
1013      .name = "ps2kbd/need_high_bit",
1014      .version_id = 1,
1015      .minimum_version_id = 1,
1016      .needed = ps2_keyboard_need_high_bit_needed,
1017      .fields = (VMStateField[]) {
1018          VMSTATE_BOOL(need_high_bit, PS2KbdState),
1019          VMSTATE_END_OF_LIST()
1020      }
1021  };
1022  
1023  static int ps2_kbd_post_load(void* opaque, int version_id)
1024  {
1025      PS2KbdState *s = (PS2KbdState*)opaque;
1026      PS2State *ps2 = &s->common;
1027  
1028      if (version_id == 2)
1029          s->scancode_set=2;
1030  
1031      ps2_common_post_load(ps2);
1032  
1033      return 0;
1034  }
1035  
1036  static int ps2_kbd_pre_save(void *opaque)
1037  {
1038      PS2KbdState *s = (PS2KbdState *)opaque;
1039      PS2State *ps2 = &s->common;
1040  
1041      ps2_common_post_load(ps2);
1042  
1043      return 0;
1044  }
1045  
1046  static const VMStateDescription vmstate_ps2_keyboard = {
1047      .name = "ps2kbd",
1048      .version_id = 3,
1049      .minimum_version_id = 2,
1050      .post_load = ps2_kbd_post_load,
1051      .pre_save = ps2_kbd_pre_save,
1052      .fields = (VMStateField[]) {
1053          VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State),
1054          VMSTATE_INT32(scan_enabled, PS2KbdState),
1055          VMSTATE_INT32(translate, PS2KbdState),
1056          VMSTATE_INT32_V(scancode_set, PS2KbdState,3),
1057          VMSTATE_END_OF_LIST()
1058      },
1059      .subsections = (const VMStateDescription*[]) {
1060          &vmstate_ps2_keyboard_ledstate,
1061          &vmstate_ps2_keyboard_need_high_bit,
1062          NULL
1063      }
1064  };
1065  
1066  static int ps2_mouse_post_load(void *opaque, int version_id)
1067  {
1068      PS2MouseState *s = (PS2MouseState *)opaque;
1069      PS2State *ps2 = &s->common;
1070  
1071      ps2_common_post_load(ps2);
1072  
1073      return 0;
1074  }
1075  
1076  static int ps2_mouse_pre_save(void *opaque)
1077  {
1078      PS2MouseState *s = (PS2MouseState *)opaque;
1079      PS2State *ps2 = &s->common;
1080  
1081      ps2_common_post_load(ps2);
1082  
1083      return 0;
1084  }
1085  
1086  static const VMStateDescription vmstate_ps2_mouse = {
1087      .name = "ps2mouse",
1088      .version_id = 2,
1089      .minimum_version_id = 2,
1090      .post_load = ps2_mouse_post_load,
1091      .pre_save = ps2_mouse_pre_save,
1092      .fields = (VMStateField[]) {
1093          VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
1094          VMSTATE_UINT8(mouse_status, PS2MouseState),
1095          VMSTATE_UINT8(mouse_resolution, PS2MouseState),
1096          VMSTATE_UINT8(mouse_sample_rate, PS2MouseState),
1097          VMSTATE_UINT8(mouse_wrap, PS2MouseState),
1098          VMSTATE_UINT8(mouse_type, PS2MouseState),
1099          VMSTATE_UINT8(mouse_detect_state, PS2MouseState),
1100          VMSTATE_INT32(mouse_dx, PS2MouseState),
1101          VMSTATE_INT32(mouse_dy, PS2MouseState),
1102          VMSTATE_INT32(mouse_dz, PS2MouseState),
1103          VMSTATE_UINT8(mouse_buttons, PS2MouseState),
1104          VMSTATE_END_OF_LIST()
1105      }
1106  };
1107  
1108  static QemuInputHandler ps2_keyboard_handler = {
1109      .name  = "QEMU PS/2 Keyboard",
1110      .mask  = INPUT_EVENT_MASK_KEY,
1111      .event = ps2_keyboard_event,
1112  };
1113  
1114  void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
1115  {
1116      PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
1117  
1118      trace_ps2_kbd_init(s);
1119      s->common.update_irq = update_irq;
1120      s->common.update_arg = update_arg;
1121      s->scancode_set = 2;
1122      vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s);
1123      qemu_input_handler_register((DeviceState *)s,
1124                                  &ps2_keyboard_handler);
1125      qemu_register_reset(ps2_kbd_reset, s);
1126      return s;
1127  }
1128  
1129  static QemuInputHandler ps2_mouse_handler = {
1130      .name  = "QEMU PS/2 Mouse",
1131      .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
1132      .event = ps2_mouse_event,
1133      .sync  = ps2_mouse_sync,
1134  };
1135  
1136  void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
1137  {
1138      PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
1139  
1140      trace_ps2_mouse_init(s);
1141      s->common.update_irq = update_irq;
1142      s->common.update_arg = update_arg;
1143      vmstate_register(NULL, 0, &vmstate_ps2_mouse, s);
1144      qemu_input_handler_register((DeviceState *)s,
1145                                  &ps2_mouse_handler);
1146      qemu_register_reset(ps2_mouse_reset, s);
1147      return s;
1148  }
1149