xref: /qemu/hw/input/pckbd.c (revision 2116650254117a873ab316038803cef657ae2820)
1  /*
2   * QEMU PC keyboard 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  
25  #include "qemu/osdep.h"
26  #include "qemu/error-report.h"
27  #include "qemu/log.h"
28  #include "qemu/timer.h"
29  #include "qapi/error.h"
30  #include "hw/isa/isa.h"
31  #include "migration/vmstate.h"
32  #include "hw/acpi/acpi_aml_interface.h"
33  #include "hw/input/ps2.h"
34  #include "hw/irq.h"
35  #include "hw/input/i8042.h"
36  #include "hw/qdev-properties.h"
37  #include "sysemu/reset.h"
38  #include "sysemu/runstate.h"
39  
40  #include "trace.h"
41  
42  /* Keyboard Controller Commands */
43  
44  /* Read mode bits */
45  #define KBD_CCMD_READ_MODE         0x20
46  /* Write mode bits */
47  #define KBD_CCMD_WRITE_MODE        0x60
48  /* Get controller version */
49  #define KBD_CCMD_GET_VERSION       0xA1
50  /* Disable mouse interface */
51  #define KBD_CCMD_MOUSE_DISABLE     0xA7
52  /* Enable mouse interface */
53  #define KBD_CCMD_MOUSE_ENABLE      0xA8
54  /* Mouse interface test */
55  #define KBD_CCMD_TEST_MOUSE        0xA9
56  /* Controller self test */
57  #define KBD_CCMD_SELF_TEST         0xAA
58  /* Keyboard interface test */
59  #define KBD_CCMD_KBD_TEST          0xAB
60  /* Keyboard interface disable */
61  #define KBD_CCMD_KBD_DISABLE       0xAD
62  /* Keyboard interface enable */
63  #define KBD_CCMD_KBD_ENABLE        0xAE
64  /* read input port */
65  #define KBD_CCMD_READ_INPORT       0xC0
66  /* read output port */
67  #define KBD_CCMD_READ_OUTPORT      0xD0
68  /* write output port */
69  #define KBD_CCMD_WRITE_OUTPORT     0xD1
70  #define KBD_CCMD_WRITE_OBUF        0xD2
71  /* Write to output buffer as if initiated by the auxiliary device */
72  #define KBD_CCMD_WRITE_AUX_OBUF    0xD3
73  /* Write the following byte to the mouse */
74  #define KBD_CCMD_WRITE_MOUSE       0xD4
75  /* HP vectra only ? */
76  #define KBD_CCMD_DISABLE_A20       0xDD
77  /* HP vectra only ? */
78  #define KBD_CCMD_ENABLE_A20        0xDF
79  /* Pulse bits 3-0 of the output port P2. */
80  #define KBD_CCMD_PULSE_BITS_3_0    0xF0
81  /* Pulse bit 0 of the output port P2 = CPU reset. */
82  #define KBD_CCMD_RESET             0xFE
83  /* Pulse no bits of the output port P2. */
84  #define KBD_CCMD_NO_OP             0xFF
85  
86  /* Status Register Bits */
87  
88  /* Keyboard output buffer full */
89  #define KBD_STAT_OBF           0x01
90  /* Keyboard input buffer full */
91  #define KBD_STAT_IBF           0x02
92  /* Self test successful */
93  #define KBD_STAT_SELFTEST      0x04
94  /* Last write was a command write (0=data) */
95  #define KBD_STAT_CMD           0x08
96  /* Zero if keyboard locked */
97  #define KBD_STAT_UNLOCKED      0x10
98  /* Mouse output buffer full */
99  #define KBD_STAT_MOUSE_OBF     0x20
100  /* General receive/xmit timeout */
101  #define KBD_STAT_GTO           0x40
102  /* Parity error */
103  #define KBD_STAT_PERR          0x80
104  
105  /* Controller Mode Register Bits */
106  
107  /* Keyboard data generate IRQ1 */
108  #define KBD_MODE_KBD_INT       0x01
109  /* Mouse data generate IRQ12 */
110  #define KBD_MODE_MOUSE_INT     0x02
111  /* The system flag (?) */
112  #define KBD_MODE_SYS           0x04
113  /* The keylock doesn't affect the keyboard if set */
114  #define KBD_MODE_NO_KEYLOCK    0x08
115  /* Disable keyboard interface */
116  #define KBD_MODE_DISABLE_KBD   0x10
117  /* Disable mouse interface */
118  #define KBD_MODE_DISABLE_MOUSE 0x20
119  /* Scan code conversion to PC format */
120  #define KBD_MODE_KCC           0x40
121  #define KBD_MODE_RFU           0x80
122  
123  /* Output Port Bits */
124  #define KBD_OUT_RESET           0x01    /* 1=normal mode, 0=reset */
125  #define KBD_OUT_A20             0x02    /* x86 only */
126  #define KBD_OUT_OBF             0x10    /* Keyboard output buffer full */
127  #define KBD_OUT_MOUSE_OBF       0x20    /* Mouse output buffer full */
128  
129  /*
130   * OSes typically write 0xdd/0xdf to turn the A20 line off and on.
131   * We make the default value of the outport include these four bits,
132   * so that the subsection is rarely necessary.
133   */
134  #define KBD_OUT_ONES            0xcc
135  
136  #define KBD_PENDING_KBD_COMPAT  0x01
137  #define KBD_PENDING_AUX_COMPAT  0x02
138  #define KBD_PENDING_CTRL_KBD    0x04
139  #define KBD_PENDING_CTRL_AUX    0x08
140  #define KBD_PENDING_KBD         KBD_MODE_DISABLE_KBD    /* 0x10 */
141  #define KBD_PENDING_AUX         KBD_MODE_DISABLE_MOUSE  /* 0x20 */
142  
143  #define KBD_MIGR_TIMER_PENDING  0x1
144  
145  #define KBD_OBSRC_KBD           0x01
146  #define KBD_OBSRC_MOUSE         0x02
147  #define KBD_OBSRC_CTRL          0x04
148  
149  
150  /*
151   * XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
152   * incorrect, but it avoids having to simulate exact delays
153   */
154  static void kbd_update_irq_lines(KBDState *s)
155  {
156      int irq_kbd_level, irq_mouse_level;
157  
158      irq_kbd_level = 0;
159      irq_mouse_level = 0;
160  
161      if (s->status & KBD_STAT_OBF) {
162          if (s->status & KBD_STAT_MOUSE_OBF) {
163              if (s->mode & KBD_MODE_MOUSE_INT) {
164                  irq_mouse_level = 1;
165              }
166          } else {
167              if ((s->mode & KBD_MODE_KBD_INT) &&
168                  !(s->mode & KBD_MODE_DISABLE_KBD)) {
169                  irq_kbd_level = 1;
170              }
171          }
172      }
173      qemu_set_irq(s->irqs[I8042_KBD_IRQ], irq_kbd_level);
174      qemu_set_irq(s->irqs[I8042_MOUSE_IRQ], irq_mouse_level);
175  }
176  
177  static void kbd_deassert_irq(KBDState *s)
178  {
179      s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
180      s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF);
181      kbd_update_irq_lines(s);
182  }
183  
184  static uint8_t kbd_pending(KBDState *s)
185  {
186      if (s->extended_state) {
187          return s->pending & (~s->mode | ~(KBD_PENDING_KBD | KBD_PENDING_AUX));
188      } else {
189          return s->pending;
190      }
191  }
192  
193  /* update irq and KBD_STAT_[MOUSE_]OBF */
194  static void kbd_update_irq(KBDState *s)
195  {
196      uint8_t pending = kbd_pending(s);
197  
198      s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
199      s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF);
200      if (pending) {
201          s->status |= KBD_STAT_OBF;
202          s->outport |= KBD_OUT_OBF;
203          if (pending & KBD_PENDING_CTRL_KBD) {
204              s->obsrc = KBD_OBSRC_CTRL;
205          } else if (pending & KBD_PENDING_CTRL_AUX) {
206              s->status |= KBD_STAT_MOUSE_OBF;
207              s->outport |= KBD_OUT_MOUSE_OBF;
208              s->obsrc = KBD_OBSRC_CTRL;
209          } else if (pending & KBD_PENDING_KBD) {
210              s->obsrc = KBD_OBSRC_KBD;
211          } else {
212              s->status |= KBD_STAT_MOUSE_OBF;
213              s->outport |= KBD_OUT_MOUSE_OBF;
214              s->obsrc = KBD_OBSRC_MOUSE;
215          }
216      }
217      kbd_update_irq_lines(s);
218  }
219  
220  static void kbd_safe_update_irq(KBDState *s)
221  {
222      /*
223       * with KBD_STAT_OBF set, a call to kbd_read_data() will eventually call
224       * kbd_update_irq()
225       */
226      if (s->status & KBD_STAT_OBF) {
227          return;
228      }
229      /* the throttle timer is pending and will call kbd_update_irq() */
230      if (s->throttle_timer && timer_pending(s->throttle_timer)) {
231          return;
232      }
233      if (kbd_pending(s)) {
234          kbd_update_irq(s);
235      }
236  }
237  
238  static void kbd_update_kbd_irq(void *opaque, int level)
239  {
240      KBDState *s = opaque;
241  
242      if (level) {
243          s->pending |= KBD_PENDING_KBD;
244      } else {
245          s->pending &= ~KBD_PENDING_KBD;
246      }
247      kbd_safe_update_irq(s);
248  }
249  
250  static void kbd_update_aux_irq(void *opaque, int level)
251  {
252      KBDState *s = opaque;
253  
254      if (level) {
255          s->pending |= KBD_PENDING_AUX;
256      } else {
257          s->pending &= ~KBD_PENDING_AUX;
258      }
259      kbd_safe_update_irq(s);
260  }
261  
262  static void kbd_throttle_timeout(void *opaque)
263  {
264      KBDState *s = opaque;
265  
266      if (kbd_pending(s)) {
267          kbd_update_irq(s);
268      }
269  }
270  
271  static uint64_t kbd_read_status(void *opaque, hwaddr addr,
272                                  unsigned size)
273  {
274      KBDState *s = opaque;
275      int val;
276      val = s->status;
277      trace_pckbd_kbd_read_status(val);
278      return val;
279  }
280  
281  static void kbd_queue(KBDState *s, int b, int aux)
282  {
283      if (s->extended_state) {
284          s->cbdata = b;
285          s->pending &= ~KBD_PENDING_CTRL_KBD & ~KBD_PENDING_CTRL_AUX;
286          s->pending |= aux ? KBD_PENDING_CTRL_AUX : KBD_PENDING_CTRL_KBD;
287          kbd_safe_update_irq(s);
288      } else {
289          ps2_queue(aux ? s->mouse : s->kbd, b);
290      }
291  }
292  
293  static uint8_t kbd_dequeue(KBDState *s)
294  {
295      uint8_t b = s->cbdata;
296  
297      s->pending &= ~KBD_PENDING_CTRL_KBD & ~KBD_PENDING_CTRL_AUX;
298      if (kbd_pending(s)) {
299          kbd_update_irq(s);
300      }
301      return b;
302  }
303  
304  static void outport_write(KBDState *s, uint32_t val)
305  {
306      trace_pckbd_outport_write(val);
307      s->outport = val;
308      qemu_set_irq(s->a20_out, (val >> 1) & 1);
309      if (!(val & 1)) {
310          qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
311      }
312  }
313  
314  static void kbd_write_command(void *opaque, hwaddr addr,
315                                uint64_t val, unsigned size)
316  {
317      KBDState *s = opaque;
318  
319      trace_pckbd_kbd_write_command(val);
320  
321      /*
322       * Bits 3-0 of the output port P2 of the keyboard controller may be pulsed
323       * low for approximately 6 micro seconds. Bits 3-0 of the KBD_CCMD_PULSE
324       * command specify the output port bits to be pulsed.
325       * 0: Bit should be pulsed. 1: Bit should not be modified.
326       * The only useful version of this command is pulsing bit 0,
327       * which does a CPU reset.
328       */
329      if ((val & KBD_CCMD_PULSE_BITS_3_0) == KBD_CCMD_PULSE_BITS_3_0) {
330          if (!(val & 1)) {
331              val = KBD_CCMD_RESET;
332          } else {
333              val = KBD_CCMD_NO_OP;
334          }
335      }
336  
337      switch (val) {
338      case KBD_CCMD_READ_MODE:
339          kbd_queue(s, s->mode, 0);
340          break;
341      case KBD_CCMD_WRITE_MODE:
342      case KBD_CCMD_WRITE_OBUF:
343      case KBD_CCMD_WRITE_AUX_OBUF:
344      case KBD_CCMD_WRITE_MOUSE:
345      case KBD_CCMD_WRITE_OUTPORT:
346          s->write_cmd = val;
347          break;
348      case KBD_CCMD_MOUSE_DISABLE:
349          s->mode |= KBD_MODE_DISABLE_MOUSE;
350          break;
351      case KBD_CCMD_MOUSE_ENABLE:
352          s->mode &= ~KBD_MODE_DISABLE_MOUSE;
353          kbd_safe_update_irq(s);
354          break;
355      case KBD_CCMD_TEST_MOUSE:
356          kbd_queue(s, 0x00, 0);
357          break;
358      case KBD_CCMD_SELF_TEST:
359          s->status |= KBD_STAT_SELFTEST;
360          kbd_queue(s, 0x55, 0);
361          break;
362      case KBD_CCMD_KBD_TEST:
363          kbd_queue(s, 0x00, 0);
364          break;
365      case KBD_CCMD_KBD_DISABLE:
366          s->mode |= KBD_MODE_DISABLE_KBD;
367          break;
368      case KBD_CCMD_KBD_ENABLE:
369          s->mode &= ~KBD_MODE_DISABLE_KBD;
370          kbd_safe_update_irq(s);
371          break;
372      case KBD_CCMD_READ_INPORT:
373          kbd_queue(s, 0x80, 0);
374          break;
375      case KBD_CCMD_READ_OUTPORT:
376          kbd_queue(s, s->outport, 0);
377          break;
378      case KBD_CCMD_ENABLE_A20:
379          qemu_irq_raise(s->a20_out);
380          s->outport |= KBD_OUT_A20;
381          break;
382      case KBD_CCMD_DISABLE_A20:
383          qemu_irq_lower(s->a20_out);
384          s->outport &= ~KBD_OUT_A20;
385          break;
386      case KBD_CCMD_RESET:
387          qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
388          break;
389      case KBD_CCMD_NO_OP:
390          /* ignore that */
391          break;
392      default:
393          qemu_log_mask(LOG_GUEST_ERROR,
394                        "unsupported keyboard cmd=0x%02" PRIx64 "\n", val);
395          break;
396      }
397  }
398  
399  static uint64_t kbd_read_data(void *opaque, hwaddr addr,
400                                unsigned size)
401  {
402      KBDState *s = opaque;
403  
404      if (s->status & KBD_STAT_OBF) {
405          kbd_deassert_irq(s);
406          if (s->obsrc & KBD_OBSRC_KBD) {
407              if (s->throttle_timer) {
408                  timer_mod(s->throttle_timer,
409                            qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 1000);
410              }
411              s->obdata = ps2_read_data(s->kbd);
412          } else if (s->obsrc & KBD_OBSRC_MOUSE) {
413              s->obdata = ps2_read_data(s->mouse);
414          } else if (s->obsrc & KBD_OBSRC_CTRL) {
415              s->obdata = kbd_dequeue(s);
416          }
417      }
418  
419      trace_pckbd_kbd_read_data(s->obdata);
420      return s->obdata;
421  }
422  
423  static void kbd_write_data(void *opaque, hwaddr addr,
424                             uint64_t val, unsigned size)
425  {
426      KBDState *s = opaque;
427  
428      trace_pckbd_kbd_write_data(val);
429  
430      switch (s->write_cmd) {
431      case 0:
432          ps2_write_keyboard(s->kbd, val);
433          /* sending data to the keyboard reenables PS/2 communication */
434          s->mode &= ~KBD_MODE_DISABLE_KBD;
435          kbd_safe_update_irq(s);
436          break;
437      case KBD_CCMD_WRITE_MODE:
438          s->mode = val;
439          ps2_keyboard_set_translation(s->kbd, (s->mode & KBD_MODE_KCC) != 0);
440          /*
441           * a write to the mode byte interrupt enable flags directly updates
442           * the irq lines
443           */
444          kbd_update_irq_lines(s);
445          /*
446           * a write to the mode byte disable interface flags may raise
447           * an irq if there is pending data in the PS/2 queues.
448           */
449          kbd_safe_update_irq(s);
450          break;
451      case KBD_CCMD_WRITE_OBUF:
452          kbd_queue(s, val, 0);
453          break;
454      case KBD_CCMD_WRITE_AUX_OBUF:
455          kbd_queue(s, val, 1);
456          break;
457      case KBD_CCMD_WRITE_OUTPORT:
458          outport_write(s, val);
459          break;
460      case KBD_CCMD_WRITE_MOUSE:
461          ps2_write_mouse(s->mouse, val);
462          /* sending data to the mouse reenables PS/2 communication */
463          s->mode &= ~KBD_MODE_DISABLE_MOUSE;
464          kbd_safe_update_irq(s);
465          break;
466      default:
467          break;
468      }
469      s->write_cmd = 0;
470  }
471  
472  static void kbd_reset(void *opaque)
473  {
474      KBDState *s = opaque;
475  
476      s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
477      s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
478      s->outport = KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES;
479      s->pending = 0;
480      kbd_deassert_irq(s);
481      if (s->throttle_timer) {
482          timer_del(s->throttle_timer);
483      }
484  }
485  
486  static uint8_t kbd_outport_default(KBDState *s)
487  {
488      return KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES
489             | (s->status & KBD_STAT_OBF ? KBD_OUT_OBF : 0)
490             | (s->status & KBD_STAT_MOUSE_OBF ? KBD_OUT_MOUSE_OBF : 0);
491  }
492  
493  static int kbd_outport_post_load(void *opaque, int version_id)
494  {
495      KBDState *s = opaque;
496      s->outport_present = true;
497      return 0;
498  }
499  
500  static bool kbd_outport_needed(void *opaque)
501  {
502      KBDState *s = opaque;
503      return s->outport != kbd_outport_default(s);
504  }
505  
506  static const VMStateDescription vmstate_kbd_outport = {
507      .name = "pckbd_outport",
508      .version_id = 1,
509      .minimum_version_id = 1,
510      .post_load = kbd_outport_post_load,
511      .needed = kbd_outport_needed,
512      .fields = (VMStateField[]) {
513          VMSTATE_UINT8(outport, KBDState),
514          VMSTATE_END_OF_LIST()
515      }
516  };
517  
518  static int kbd_extended_state_pre_save(void *opaque)
519  {
520      KBDState *s = opaque;
521  
522      s->migration_flags = 0;
523      if (s->throttle_timer && timer_pending(s->throttle_timer)) {
524          s->migration_flags |= KBD_MIGR_TIMER_PENDING;
525      }
526  
527      return 0;
528  }
529  
530  static int kbd_extended_state_post_load(void *opaque, int version_id)
531  {
532      KBDState *s = opaque;
533  
534      if (s->migration_flags & KBD_MIGR_TIMER_PENDING) {
535          kbd_throttle_timeout(s);
536      }
537      s->extended_state_loaded = true;
538  
539      return 0;
540  }
541  
542  static bool kbd_extended_state_needed(void *opaque)
543  {
544      KBDState *s = opaque;
545  
546      return s->extended_state;
547  }
548  
549  static const VMStateDescription vmstate_kbd_extended_state = {
550      .name = "pckbd/extended_state",
551      .post_load = kbd_extended_state_post_load,
552      .pre_save = kbd_extended_state_pre_save,
553      .needed = kbd_extended_state_needed,
554      .fields = (VMStateField[]) {
555          VMSTATE_UINT32(migration_flags, KBDState),
556          VMSTATE_UINT32(obsrc, KBDState),
557          VMSTATE_UINT8(obdata, KBDState),
558          VMSTATE_UINT8(cbdata, KBDState),
559          VMSTATE_END_OF_LIST()
560      }
561  };
562  
563  static int kbd_pre_save(void *opaque)
564  {
565      KBDState *s = opaque;
566  
567      if (s->extended_state) {
568          s->pending_tmp = s->pending;
569      } else {
570          s->pending_tmp = 0;
571          if (s->pending & KBD_PENDING_KBD) {
572              s->pending_tmp |= KBD_PENDING_KBD_COMPAT;
573          }
574          if (s->pending & KBD_PENDING_AUX) {
575              s->pending_tmp |= KBD_PENDING_AUX_COMPAT;
576          }
577      }
578      return 0;
579  }
580  
581  static int kbd_pre_load(void *opaque)
582  {
583      KBDState *s = opaque;
584  
585      s->outport_present = false;
586      s->extended_state_loaded = false;
587      return 0;
588  }
589  
590  static int kbd_post_load(void *opaque, int version_id)
591  {
592      KBDState *s = opaque;
593      if (!s->outport_present) {
594          s->outport = kbd_outport_default(s);
595      }
596      s->pending = s->pending_tmp;
597      if (!s->extended_state_loaded) {
598          s->obsrc = s->status & KBD_STAT_OBF ?
599              (s->status & KBD_STAT_MOUSE_OBF ? KBD_OBSRC_MOUSE : KBD_OBSRC_KBD) :
600              0;
601          if (s->pending & KBD_PENDING_KBD_COMPAT) {
602              s->pending |= KBD_PENDING_KBD;
603          }
604          if (s->pending & KBD_PENDING_AUX_COMPAT) {
605              s->pending |= KBD_PENDING_AUX;
606          }
607      }
608      /* clear all unused flags */
609      s->pending &= KBD_PENDING_CTRL_KBD | KBD_PENDING_CTRL_AUX |
610                    KBD_PENDING_KBD | KBD_PENDING_AUX;
611      return 0;
612  }
613  
614  static const VMStateDescription vmstate_kbd = {
615      .name = "pckbd",
616      .version_id = 3,
617      .minimum_version_id = 3,
618      .pre_load = kbd_pre_load,
619      .post_load = kbd_post_load,
620      .pre_save = kbd_pre_save,
621      .fields = (VMStateField[]) {
622          VMSTATE_UINT8(write_cmd, KBDState),
623          VMSTATE_UINT8(status, KBDState),
624          VMSTATE_UINT8(mode, KBDState),
625          VMSTATE_UINT8(pending_tmp, KBDState),
626          VMSTATE_END_OF_LIST()
627      },
628      .subsections = (const VMStateDescription * []) {
629          &vmstate_kbd_outport,
630          &vmstate_kbd_extended_state,
631          NULL
632      }
633  };
634  
635  /* Memory mapped interface */
636  static uint64_t kbd_mm_readfn(void *opaque, hwaddr addr, unsigned size)
637  {
638      KBDState *s = opaque;
639  
640      if (addr & s->mask) {
641          return kbd_read_status(s, 0, 1) & 0xff;
642      } else {
643          return kbd_read_data(s, 0, 1) & 0xff;
644      }
645  }
646  
647  static void kbd_mm_writefn(void *opaque, hwaddr addr,
648                             uint64_t value, unsigned size)
649  {
650      KBDState *s = opaque;
651  
652      if (addr & s->mask) {
653          kbd_write_command(s, 0, value & 0xff, 1);
654      } else {
655          kbd_write_data(s, 0, value & 0xff, 1);
656      }
657  }
658  
659  
660  static const MemoryRegionOps i8042_mmio_ops = {
661      .read = kbd_mm_readfn,
662      .write = kbd_mm_writefn,
663      .valid.min_access_size = 1,
664      .valid.max_access_size = 4,
665      .endianness = DEVICE_NATIVE_ENDIAN,
666  };
667  
668  static void i8042_mmio_set_kbd_irq(void *opaque, int n, int level)
669  {
670      MMIOKBDState *s = I8042_MMIO(opaque);
671      KBDState *ks = &s->kbd;
672  
673      kbd_update_kbd_irq(ks, level);
674  }
675  
676  static void i8042_mmio_set_mouse_irq(void *opaque, int n, int level)
677  {
678      MMIOKBDState *s = I8042_MMIO(opaque);
679      KBDState *ks = &s->kbd;
680  
681      kbd_update_aux_irq(ks, level);
682  }
683  
684  static void i8042_mmio_reset(DeviceState *dev)
685  {
686      MMIOKBDState *s = I8042_MMIO(dev);
687      KBDState *ks = &s->kbd;
688  
689      kbd_reset(ks);
690  }
691  
692  static void i8042_mmio_realize(DeviceState *dev, Error **errp)
693  {
694      MMIOKBDState *s = I8042_MMIO(dev);
695      KBDState *ks = &s->kbd;
696  
697      memory_region_init_io(&s->region, OBJECT(dev), &i8042_mmio_ops, ks,
698                            "i8042", s->size);
699  
700      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->region);
701  
702      /* Note we can't use dc->vmsd without breaking migration compatibility */
703      vmstate_register(NULL, 0, &vmstate_kbd, ks);
704  
705      ks->kbd = ps2_kbd_init();
706      qdev_connect_gpio_out(DEVICE(ks->kbd), PS2_DEVICE_IRQ,
707                            qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
708                                                   0));
709      ks->mouse = ps2_mouse_init();
710      qdev_connect_gpio_out(DEVICE(ks->mouse), PS2_DEVICE_IRQ,
711                            qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
712                                                   0));
713  }
714  
715  static void i8042_mmio_init(Object *obj)
716  {
717      MMIOKBDState *s = I8042_MMIO(obj);
718      KBDState *ks = &s->kbd;
719  
720      ks->extended_state = true;
721  
722      qdev_init_gpio_out(DEVICE(obj), ks->irqs, 2);
723      qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_kbd_irq,
724                              "ps2-kbd-input-irq", 1);
725      qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_mouse_irq,
726                              "ps2-mouse-input-irq", 1);
727  }
728  
729  static Property i8042_mmio_properties[] = {
730      DEFINE_PROP_UINT64("mask", MMIOKBDState, kbd.mask, UINT64_MAX),
731      DEFINE_PROP_UINT32("size", MMIOKBDState, size, -1),
732      DEFINE_PROP_END_OF_LIST(),
733  };
734  
735  static void i8042_mmio_class_init(ObjectClass *klass, void *data)
736  {
737      DeviceClass *dc = DEVICE_CLASS(klass);
738  
739      dc->realize = i8042_mmio_realize;
740      dc->reset = i8042_mmio_reset;
741      device_class_set_props(dc, i8042_mmio_properties);
742      set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
743  }
744  
745  MMIOKBDState *i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
746                              ram_addr_t size, hwaddr mask)
747  {
748      DeviceState *dev;
749  
750      dev = qdev_new(TYPE_I8042_MMIO);
751      qdev_prop_set_uint64(dev, "mask", mask);
752      qdev_prop_set_uint32(dev, "size", size);
753      sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
754  
755      qdev_connect_gpio_out(dev, I8042_KBD_IRQ, kbd_irq);
756      qdev_connect_gpio_out(dev, I8042_MOUSE_IRQ, mouse_irq);
757  
758      return I8042_MMIO(dev);
759  }
760  
761  static const TypeInfo i8042_mmio_info = {
762      .name          = TYPE_I8042_MMIO,
763      .parent        = TYPE_SYS_BUS_DEVICE,
764      .instance_init = i8042_mmio_init,
765      .instance_size = sizeof(MMIOKBDState),
766      .class_init    = i8042_mmio_class_init
767  };
768  
769  void i8042_isa_mouse_fake_event(ISAKBDState *isa)
770  {
771      KBDState *s = &isa->kbd;
772  
773      ps2_mouse_fake_event(s->mouse);
774  }
775  
776  void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out)
777  {
778      qdev_connect_gpio_out_named(DEVICE(dev), I8042_A20_LINE, 0, a20_out);
779  }
780  
781  static const VMStateDescription vmstate_kbd_isa = {
782      .name = "pckbd",
783      .version_id = 3,
784      .minimum_version_id = 3,
785      .fields = (VMStateField[]) {
786          VMSTATE_STRUCT(kbd, ISAKBDState, 0, vmstate_kbd, KBDState),
787          VMSTATE_END_OF_LIST()
788      }
789  };
790  
791  static const MemoryRegionOps i8042_data_ops = {
792      .read = kbd_read_data,
793      .write = kbd_write_data,
794      .impl = {
795          .min_access_size = 1,
796          .max_access_size = 1,
797      },
798      .endianness = DEVICE_LITTLE_ENDIAN,
799  };
800  
801  static const MemoryRegionOps i8042_cmd_ops = {
802      .read = kbd_read_status,
803      .write = kbd_write_command,
804      .impl = {
805          .min_access_size = 1,
806          .max_access_size = 1,
807      },
808      .endianness = DEVICE_LITTLE_ENDIAN,
809  };
810  
811  static void i8042_set_kbd_irq(void *opaque, int n, int level)
812  {
813      ISAKBDState *s = I8042(opaque);
814      KBDState *ks = &s->kbd;
815  
816      kbd_update_kbd_irq(ks, level);
817  }
818  
819  static void i8042_set_mouse_irq(void *opaque, int n, int level)
820  {
821      ISAKBDState *s = I8042(opaque);
822      KBDState *ks = &s->kbd;
823  
824      kbd_update_aux_irq(ks, level);
825  }
826  
827  
828  static void i8042_reset(DeviceState *dev)
829  {
830      ISAKBDState *s = I8042(dev);
831      KBDState *ks = &s->kbd;
832  
833      kbd_reset(ks);
834  }
835  
836  static void i8042_initfn(Object *obj)
837  {
838      ISAKBDState *isa_s = I8042(obj);
839      KBDState *s = &isa_s->kbd;
840  
841      memory_region_init_io(isa_s->io + 0, obj, &i8042_data_ops, s,
842                            "i8042-data", 1);
843      memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s,
844                            "i8042-cmd", 1);
845  
846      qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1);
847  
848      qdev_init_gpio_out(DEVICE(obj), s->irqs, 2);
849      qdev_init_gpio_in_named(DEVICE(obj), i8042_set_kbd_irq,
850                              "ps2-kbd-input-irq", 1);
851      qdev_init_gpio_in_named(DEVICE(obj), i8042_set_mouse_irq,
852                              "ps2-mouse-input-irq", 1);
853  }
854  
855  static void i8042_realizefn(DeviceState *dev, Error **errp)
856  {
857      ISADevice *isadev = ISA_DEVICE(dev);
858      ISAKBDState *isa_s = I8042(dev);
859      KBDState *s = &isa_s->kbd;
860  
861      if (isa_s->kbd_irq >= ISA_NUM_IRQS) {
862          error_setg(errp, "Maximum value for \"kbd-irq\" is: %u",
863                     ISA_NUM_IRQS - 1);
864          return;
865      }
866  
867      if (isa_s->mouse_irq >= ISA_NUM_IRQS) {
868          error_setg(errp, "Maximum value for \"mouse-irq\" is: %u",
869                     ISA_NUM_IRQS - 1);
870          return;
871      }
872  
873      isa_connect_gpio_out(isadev, I8042_KBD_IRQ, isa_s->kbd_irq);
874      isa_connect_gpio_out(isadev, I8042_MOUSE_IRQ, isa_s->mouse_irq);
875  
876      isa_register_ioport(isadev, isa_s->io + 0, 0x60);
877      isa_register_ioport(isadev, isa_s->io + 1, 0x64);
878  
879      s->kbd = ps2_kbd_init();
880      qdev_connect_gpio_out(DEVICE(s->kbd), PS2_DEVICE_IRQ,
881                            qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
882                                                   0));
883      s->mouse = ps2_mouse_init();
884      qdev_connect_gpio_out(DEVICE(s->mouse), PS2_DEVICE_IRQ,
885                            qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
886                                                   0));
887      if (isa_s->kbd_throttle && !isa_s->kbd.extended_state) {
888          warn_report(TYPE_I8042 ": can't enable kbd-throttle without"
889                      " extended-state, disabling kbd-throttle");
890      } else if (isa_s->kbd_throttle) {
891          s->throttle_timer = timer_new_us(QEMU_CLOCK_VIRTUAL,
892                                           kbd_throttle_timeout, s);
893      }
894  }
895  
896  static void i8042_build_aml(AcpiDevAmlIf *adev, Aml *scope)
897  {
898      ISAKBDState *isa_s = I8042(adev);
899      Aml *kbd;
900      Aml *mou;
901      Aml *crs;
902  
903      crs = aml_resource_template();
904      aml_append(crs, aml_io(AML_DECODE16, 0x0060, 0x0060, 0x01, 0x01));
905      aml_append(crs, aml_io(AML_DECODE16, 0x0064, 0x0064, 0x01, 0x01));
906      aml_append(crs, aml_irq_no_flags(isa_s->kbd_irq));
907  
908      kbd = aml_device("KBD");
909      aml_append(kbd, aml_name_decl("_HID", aml_eisaid("PNP0303")));
910      aml_append(kbd, aml_name_decl("_STA", aml_int(0xf)));
911      aml_append(kbd, aml_name_decl("_CRS", crs));
912  
913      crs = aml_resource_template();
914      aml_append(crs, aml_irq_no_flags(isa_s->mouse_irq));
915  
916      mou = aml_device("MOU");
917      aml_append(mou, aml_name_decl("_HID", aml_eisaid("PNP0F13")));
918      aml_append(mou, aml_name_decl("_STA", aml_int(0xf)));
919      aml_append(mou, aml_name_decl("_CRS", crs));
920  
921      aml_append(scope, kbd);
922      aml_append(scope, mou);
923  }
924  
925  static Property i8042_properties[] = {
926      DEFINE_PROP_BOOL("extended-state", ISAKBDState, kbd.extended_state, true),
927      DEFINE_PROP_BOOL("kbd-throttle", ISAKBDState, kbd_throttle, false),
928      DEFINE_PROP_UINT8("kbd-irq", ISAKBDState, kbd_irq, 1),
929      DEFINE_PROP_UINT8("mouse-irq", ISAKBDState, mouse_irq, 12),
930      DEFINE_PROP_END_OF_LIST(),
931  };
932  
933  static void i8042_class_initfn(ObjectClass *klass, void *data)
934  {
935      DeviceClass *dc = DEVICE_CLASS(klass);
936      AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
937  
938      device_class_set_props(dc, i8042_properties);
939      dc->reset = i8042_reset;
940      dc->realize = i8042_realizefn;
941      dc->vmsd = &vmstate_kbd_isa;
942      adevc->build_dev_aml = i8042_build_aml;
943      set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
944  }
945  
946  static const TypeInfo i8042_info = {
947      .name          = TYPE_I8042,
948      .parent        = TYPE_ISA_DEVICE,
949      .instance_size = sizeof(ISAKBDState),
950      .instance_init = i8042_initfn,
951      .class_init    = i8042_class_initfn,
952      .interfaces = (InterfaceInfo[]) {
953          { TYPE_ACPI_DEV_AML_IF },
954          { },
955      },
956  };
957  
958  static void i8042_register_types(void)
959  {
960      type_register_static(&i8042_info);
961      type_register_static(&i8042_mmio_info);
962  }
963  
964  type_init(i8042_register_types)
965