xref: /openbmc/qemu/hw/input/pckbd.c (revision 28ae3179fc52d2e4d870b635c4a412aab99759e7)
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   */
kbd_update_irq_lines(KBDState * s)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  
kbd_deassert_irq(KBDState * s)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  
kbd_pending(KBDState * s)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 */
kbd_update_irq(KBDState * s)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  
kbd_safe_update_irq(KBDState * s)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  
kbd_update_kbd_irq(void * opaque,int level)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  
kbd_update_aux_irq(void * opaque,int level)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  
kbd_throttle_timeout(void * opaque)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  
kbd_read_status(void * opaque,hwaddr addr,unsigned size)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  
kbd_queue(KBDState * s,int b,int aux)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 ? PS2_DEVICE(&s->ps2mouse) : PS2_DEVICE(&s->ps2kbd), b);
290      }
291  }
292  
kbd_dequeue(KBDState * s)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  
outport_write(KBDState * s,uint32_t val)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  
kbd_write_command(void * opaque,hwaddr addr,uint64_t val,unsigned size)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  
kbd_read_data(void * opaque,hwaddr addr,unsigned size)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(PS2_DEVICE(&s->ps2kbd));
412          } else if (s->obsrc & KBD_OBSRC_MOUSE) {
413              s->obdata = ps2_read_data(PS2_DEVICE(&s->ps2mouse));
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  
kbd_write_data(void * opaque,hwaddr addr,uint64_t val,unsigned size)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->ps2kbd, 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->ps2kbd,
440                                       (s->mode & KBD_MODE_KCC) != 0);
441          /*
442           * a write to the mode byte interrupt enable flags directly updates
443           * the irq lines
444           */
445          kbd_update_irq_lines(s);
446          /*
447           * a write to the mode byte disable interface flags may raise
448           * an irq if there is pending data in the PS/2 queues.
449           */
450          kbd_safe_update_irq(s);
451          break;
452      case KBD_CCMD_WRITE_OBUF:
453          kbd_queue(s, val, 0);
454          break;
455      case KBD_CCMD_WRITE_AUX_OBUF:
456          kbd_queue(s, val, 1);
457          break;
458      case KBD_CCMD_WRITE_OUTPORT:
459          outport_write(s, val);
460          break;
461      case KBD_CCMD_WRITE_MOUSE:
462          ps2_write_mouse(&s->ps2mouse, val);
463          /* sending data to the mouse reenables PS/2 communication */
464          s->mode &= ~KBD_MODE_DISABLE_MOUSE;
465          kbd_safe_update_irq(s);
466          break;
467      default:
468          break;
469      }
470      s->write_cmd = 0;
471  }
472  
kbd_reset(void * opaque)473  static void kbd_reset(void *opaque)
474  {
475      KBDState *s = opaque;
476  
477      s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
478      s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
479      s->outport = KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES;
480      s->pending = 0;
481      kbd_deassert_irq(s);
482      if (s->throttle_timer) {
483          timer_del(s->throttle_timer);
484      }
485  }
486  
kbd_outport_default(KBDState * s)487  static uint8_t kbd_outport_default(KBDState *s)
488  {
489      return KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES
490             | (s->status & KBD_STAT_OBF ? KBD_OUT_OBF : 0)
491             | (s->status & KBD_STAT_MOUSE_OBF ? KBD_OUT_MOUSE_OBF : 0);
492  }
493  
kbd_outport_post_load(void * opaque,int version_id)494  static int kbd_outport_post_load(void *opaque, int version_id)
495  {
496      KBDState *s = opaque;
497      s->outport_present = true;
498      return 0;
499  }
500  
kbd_outport_needed(void * opaque)501  static bool kbd_outport_needed(void *opaque)
502  {
503      KBDState *s = opaque;
504      return s->outport != kbd_outport_default(s);
505  }
506  
507  static const VMStateDescription vmstate_kbd_outport = {
508      .name = "pckbd_outport",
509      .version_id = 1,
510      .minimum_version_id = 1,
511      .post_load = kbd_outport_post_load,
512      .needed = kbd_outport_needed,
513      .fields = (const VMStateField[]) {
514          VMSTATE_UINT8(outport, KBDState),
515          VMSTATE_END_OF_LIST()
516      }
517  };
518  
kbd_extended_state_pre_save(void * opaque)519  static int kbd_extended_state_pre_save(void *opaque)
520  {
521      KBDState *s = opaque;
522  
523      s->migration_flags = 0;
524      if (s->throttle_timer && timer_pending(s->throttle_timer)) {
525          s->migration_flags |= KBD_MIGR_TIMER_PENDING;
526      }
527  
528      return 0;
529  }
530  
kbd_extended_state_post_load(void * opaque,int version_id)531  static int kbd_extended_state_post_load(void *opaque, int version_id)
532  {
533      KBDState *s = opaque;
534  
535      if (s->migration_flags & KBD_MIGR_TIMER_PENDING) {
536          kbd_throttle_timeout(s);
537      }
538      s->extended_state_loaded = true;
539  
540      return 0;
541  }
542  
kbd_extended_state_needed(void * opaque)543  static bool kbd_extended_state_needed(void *opaque)
544  {
545      KBDState *s = opaque;
546  
547      return s->extended_state;
548  }
549  
550  static const VMStateDescription vmstate_kbd_extended_state = {
551      .name = "pckbd/extended_state",
552      .post_load = kbd_extended_state_post_load,
553      .pre_save = kbd_extended_state_pre_save,
554      .needed = kbd_extended_state_needed,
555      .fields = (const VMStateField[]) {
556          VMSTATE_UINT32(migration_flags, KBDState),
557          VMSTATE_UINT32(obsrc, KBDState),
558          VMSTATE_UINT8(obdata, KBDState),
559          VMSTATE_UINT8(cbdata, KBDState),
560          VMSTATE_END_OF_LIST()
561      }
562  };
563  
kbd_pre_save(void * opaque)564  static int kbd_pre_save(void *opaque)
565  {
566      KBDState *s = opaque;
567  
568      if (s->extended_state) {
569          s->pending_tmp = s->pending;
570      } else {
571          s->pending_tmp = 0;
572          if (s->pending & KBD_PENDING_KBD) {
573              s->pending_tmp |= KBD_PENDING_KBD_COMPAT;
574          }
575          if (s->pending & KBD_PENDING_AUX) {
576              s->pending_tmp |= KBD_PENDING_AUX_COMPAT;
577          }
578      }
579      return 0;
580  }
581  
kbd_pre_load(void * opaque)582  static int kbd_pre_load(void *opaque)
583  {
584      KBDState *s = opaque;
585  
586      s->outport_present = false;
587      s->extended_state_loaded = false;
588      return 0;
589  }
590  
kbd_post_load(void * opaque,int version_id)591  static int kbd_post_load(void *opaque, int version_id)
592  {
593      KBDState *s = opaque;
594      if (!s->outport_present) {
595          s->outport = kbd_outport_default(s);
596      }
597      s->pending = s->pending_tmp;
598      if (!s->extended_state_loaded) {
599          s->obsrc = s->status & KBD_STAT_OBF ?
600              (s->status & KBD_STAT_MOUSE_OBF ? KBD_OBSRC_MOUSE : KBD_OBSRC_KBD) :
601              0;
602          if (s->pending & KBD_PENDING_KBD_COMPAT) {
603              s->pending |= KBD_PENDING_KBD;
604          }
605          if (s->pending & KBD_PENDING_AUX_COMPAT) {
606              s->pending |= KBD_PENDING_AUX;
607          }
608      }
609      /* clear all unused flags */
610      s->pending &= KBD_PENDING_CTRL_KBD | KBD_PENDING_CTRL_AUX |
611                    KBD_PENDING_KBD | KBD_PENDING_AUX;
612      return 0;
613  }
614  
615  static const VMStateDescription vmstate_kbd = {
616      .name = "pckbd",
617      .version_id = 3,
618      .minimum_version_id = 3,
619      .pre_load = kbd_pre_load,
620      .post_load = kbd_post_load,
621      .pre_save = kbd_pre_save,
622      .fields = (const VMStateField[]) {
623          VMSTATE_UINT8(write_cmd, KBDState),
624          VMSTATE_UINT8(status, KBDState),
625          VMSTATE_UINT8(mode, KBDState),
626          VMSTATE_UINT8(pending_tmp, KBDState),
627          VMSTATE_END_OF_LIST()
628      },
629      .subsections = (const VMStateDescription * const []) {
630          &vmstate_kbd_outport,
631          &vmstate_kbd_extended_state,
632          NULL
633      }
634  };
635  
636  /* Memory mapped interface */
kbd_mm_readfn(void * opaque,hwaddr addr,unsigned size)637  static uint64_t kbd_mm_readfn(void *opaque, hwaddr addr, unsigned size)
638  {
639      KBDState *s = opaque;
640  
641      if (addr & s->mask) {
642          return kbd_read_status(s, 0, 1) & 0xff;
643      } else {
644          return kbd_read_data(s, 0, 1) & 0xff;
645      }
646  }
647  
kbd_mm_writefn(void * opaque,hwaddr addr,uint64_t value,unsigned size)648  static void kbd_mm_writefn(void *opaque, hwaddr addr,
649                             uint64_t value, unsigned size)
650  {
651      KBDState *s = opaque;
652  
653      if (addr & s->mask) {
654          kbd_write_command(s, 0, value & 0xff, 1);
655      } else {
656          kbd_write_data(s, 0, value & 0xff, 1);
657      }
658  }
659  
660  
661  static const MemoryRegionOps i8042_mmio_ops = {
662      .read = kbd_mm_readfn,
663      .write = kbd_mm_writefn,
664      .valid.min_access_size = 1,
665      .valid.max_access_size = 4,
666      .endianness = DEVICE_NATIVE_ENDIAN,
667  };
668  
i8042_mmio_set_kbd_irq(void * opaque,int n,int level)669  static void i8042_mmio_set_kbd_irq(void *opaque, int n, int level)
670  {
671      MMIOKBDState *s = I8042_MMIO(opaque);
672      KBDState *ks = &s->kbd;
673  
674      kbd_update_kbd_irq(ks, level);
675  }
676  
i8042_mmio_set_mouse_irq(void * opaque,int n,int level)677  static void i8042_mmio_set_mouse_irq(void *opaque, int n, int level)
678  {
679      MMIOKBDState *s = I8042_MMIO(opaque);
680      KBDState *ks = &s->kbd;
681  
682      kbd_update_aux_irq(ks, level);
683  }
684  
i8042_mmio_reset(DeviceState * dev)685  static void i8042_mmio_reset(DeviceState *dev)
686  {
687      MMIOKBDState *s = I8042_MMIO(dev);
688      KBDState *ks = &s->kbd;
689  
690      kbd_reset(ks);
691  }
692  
i8042_mmio_realize(DeviceState * dev,Error ** errp)693  static void i8042_mmio_realize(DeviceState *dev, Error **errp)
694  {
695      MMIOKBDState *s = I8042_MMIO(dev);
696      KBDState *ks = &s->kbd;
697  
698      memory_region_init_io(&s->region, OBJECT(dev), &i8042_mmio_ops, ks,
699                            "i8042", s->size);
700  
701      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->region);
702  
703      if (!sysbus_realize(SYS_BUS_DEVICE(&ks->ps2kbd), errp)) {
704          return;
705      }
706  
707      if (!sysbus_realize(SYS_BUS_DEVICE(&ks->ps2mouse), errp)) {
708          return;
709      }
710  
711      qdev_connect_gpio_out(DEVICE(&ks->ps2kbd), PS2_DEVICE_IRQ,
712                            qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
713                                                   0));
714  
715      qdev_connect_gpio_out(DEVICE(&ks->ps2mouse), PS2_DEVICE_IRQ,
716                            qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
717                                                   0));
718  }
719  
i8042_mmio_init(Object * obj)720  static void i8042_mmio_init(Object *obj)
721  {
722      MMIOKBDState *s = I8042_MMIO(obj);
723      KBDState *ks = &s->kbd;
724  
725      ks->extended_state = true;
726  
727      object_initialize_child(obj, "ps2kbd", &ks->ps2kbd, TYPE_PS2_KBD_DEVICE);
728      object_initialize_child(obj, "ps2mouse", &ks->ps2mouse,
729                              TYPE_PS2_MOUSE_DEVICE);
730  
731      qdev_init_gpio_out(DEVICE(obj), ks->irqs, 2);
732      qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_kbd_irq,
733                              "ps2-kbd-input-irq", 1);
734      qdev_init_gpio_in_named(DEVICE(obj), i8042_mmio_set_mouse_irq,
735                              "ps2-mouse-input-irq", 1);
736  }
737  
738  static Property i8042_mmio_properties[] = {
739      DEFINE_PROP_UINT64("mask", MMIOKBDState, kbd.mask, UINT64_MAX),
740      DEFINE_PROP_UINT32("size", MMIOKBDState, size, -1),
741      DEFINE_PROP_END_OF_LIST(),
742  };
743  
744  static const VMStateDescription vmstate_kbd_mmio = {
745      .name = "pckbd-mmio",
746      .version_id = 1,
747      .minimum_version_id = 1,
748      .fields = (const VMStateField[]) {
749          VMSTATE_STRUCT(kbd, MMIOKBDState, 0, vmstate_kbd, KBDState),
750          VMSTATE_END_OF_LIST()
751      }
752  };
753  
i8042_mmio_class_init(ObjectClass * klass,void * data)754  static void i8042_mmio_class_init(ObjectClass *klass, void *data)
755  {
756      DeviceClass *dc = DEVICE_CLASS(klass);
757  
758      dc->realize = i8042_mmio_realize;
759      device_class_set_legacy_reset(dc, i8042_mmio_reset);
760      dc->vmsd = &vmstate_kbd_mmio;
761      device_class_set_props(dc, i8042_mmio_properties);
762      set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
763  }
764  
765  static const TypeInfo i8042_mmio_info = {
766      .name          = TYPE_I8042_MMIO,
767      .parent        = TYPE_SYS_BUS_DEVICE,
768      .instance_init = i8042_mmio_init,
769      .instance_size = sizeof(MMIOKBDState),
770      .class_init    = i8042_mmio_class_init
771  };
772  
i8042_isa_mouse_fake_event(ISAKBDState * isa)773  void i8042_isa_mouse_fake_event(ISAKBDState *isa)
774  {
775      KBDState *s = &isa->kbd;
776  
777      ps2_mouse_fake_event(&s->ps2mouse);
778  }
779  
780  static const VMStateDescription vmstate_kbd_isa = {
781      .name = "pckbd",
782      .version_id = 3,
783      .minimum_version_id = 3,
784      .fields = (const VMStateField[]) {
785          VMSTATE_STRUCT(kbd, ISAKBDState, 0, vmstate_kbd, KBDState),
786          VMSTATE_END_OF_LIST()
787      }
788  };
789  
790  static const MemoryRegionOps i8042_data_ops = {
791      .read = kbd_read_data,
792      .write = kbd_write_data,
793      .impl = {
794          .min_access_size = 1,
795          .max_access_size = 1,
796      },
797      .endianness = DEVICE_LITTLE_ENDIAN,
798  };
799  
800  static const MemoryRegionOps i8042_cmd_ops = {
801      .read = kbd_read_status,
802      .write = kbd_write_command,
803      .impl = {
804          .min_access_size = 1,
805          .max_access_size = 1,
806      },
807      .endianness = DEVICE_LITTLE_ENDIAN,
808  };
809  
i8042_set_kbd_irq(void * opaque,int n,int level)810  static void i8042_set_kbd_irq(void *opaque, int n, int level)
811  {
812      ISAKBDState *s = I8042(opaque);
813      KBDState *ks = &s->kbd;
814  
815      kbd_update_kbd_irq(ks, level);
816  }
817  
i8042_set_mouse_irq(void * opaque,int n,int level)818  static void i8042_set_mouse_irq(void *opaque, int n, int level)
819  {
820      ISAKBDState *s = I8042(opaque);
821      KBDState *ks = &s->kbd;
822  
823      kbd_update_aux_irq(ks, level);
824  }
825  
826  
i8042_reset(DeviceState * dev)827  static void i8042_reset(DeviceState *dev)
828  {
829      ISAKBDState *s = I8042(dev);
830      KBDState *ks = &s->kbd;
831  
832      kbd_reset(ks);
833  }
834  
i8042_initfn(Object * obj)835  static void i8042_initfn(Object *obj)
836  {
837      ISAKBDState *isa_s = I8042(obj);
838      KBDState *s = &isa_s->kbd;
839  
840      memory_region_init_io(isa_s->io + 0, obj, &i8042_data_ops, s,
841                            "i8042-data", 1);
842      memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s,
843                            "i8042-cmd", 1);
844  
845      object_initialize_child(obj, "ps2kbd", &s->ps2kbd, TYPE_PS2_KBD_DEVICE);
846      object_initialize_child(obj, "ps2mouse", &s->ps2mouse,
847                              TYPE_PS2_MOUSE_DEVICE);
848  
849      qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1);
850  
851      qdev_init_gpio_out(DEVICE(obj), s->irqs, 2);
852      qdev_init_gpio_in_named(DEVICE(obj), i8042_set_kbd_irq,
853                              "ps2-kbd-input-irq", 1);
854      qdev_init_gpio_in_named(DEVICE(obj), i8042_set_mouse_irq,
855                              "ps2-mouse-input-irq", 1);
856  }
857  
i8042_realizefn(DeviceState * dev,Error ** errp)858  static void i8042_realizefn(DeviceState *dev, Error **errp)
859  {
860      ISADevice *isadev = ISA_DEVICE(dev);
861      ISAKBDState *isa_s = I8042(dev);
862      KBDState *s = &isa_s->kbd;
863  
864      if (isa_s->kbd_irq >= ISA_NUM_IRQS) {
865          error_setg(errp, "Maximum value for \"kbd-irq\" is: %u",
866                     ISA_NUM_IRQS - 1);
867          return;
868      }
869  
870      if (isa_s->mouse_irq >= ISA_NUM_IRQS) {
871          error_setg(errp, "Maximum value for \"mouse-irq\" is: %u",
872                     ISA_NUM_IRQS - 1);
873          return;
874      }
875  
876      isa_connect_gpio_out(isadev, I8042_KBD_IRQ, isa_s->kbd_irq);
877      isa_connect_gpio_out(isadev, I8042_MOUSE_IRQ, isa_s->mouse_irq);
878  
879      isa_register_ioport(isadev, isa_s->io + 0, 0x60);
880      isa_register_ioport(isadev, isa_s->io + 1, 0x64);
881  
882      if (!sysbus_realize(SYS_BUS_DEVICE(&s->ps2kbd), errp)) {
883          return;
884      }
885  
886      qdev_connect_gpio_out(DEVICE(&s->ps2kbd), PS2_DEVICE_IRQ,
887                            qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
888                                                   0));
889  
890      if (!sysbus_realize(SYS_BUS_DEVICE(&s->ps2mouse), errp)) {
891          return;
892      }
893  
894      qdev_connect_gpio_out(DEVICE(&s->ps2mouse), PS2_DEVICE_IRQ,
895                            qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
896                                                   0));
897  
898      if (isa_s->kbd_throttle && !isa_s->kbd.extended_state) {
899          warn_report(TYPE_I8042 ": can't enable kbd-throttle without"
900                      " extended-state, disabling kbd-throttle");
901      } else if (isa_s->kbd_throttle) {
902          s->throttle_timer = timer_new_us(QEMU_CLOCK_VIRTUAL,
903                                           kbd_throttle_timeout, s);
904      }
905  }
906  
i8042_build_aml(AcpiDevAmlIf * adev,Aml * scope)907  static void i8042_build_aml(AcpiDevAmlIf *adev, Aml *scope)
908  {
909      ISAKBDState *isa_s = I8042(adev);
910      Aml *kbd;
911      Aml *mou;
912      Aml *crs;
913  
914      crs = aml_resource_template();
915      aml_append(crs, aml_io(AML_DECODE16, 0x0060, 0x0060, 0x01, 0x01));
916      aml_append(crs, aml_io(AML_DECODE16, 0x0064, 0x0064, 0x01, 0x01));
917      aml_append(crs, aml_irq_no_flags(isa_s->kbd_irq));
918  
919      kbd = aml_device("KBD");
920      aml_append(kbd, aml_name_decl("_HID", aml_eisaid("PNP0303")));
921      aml_append(kbd, aml_name_decl("_STA", aml_int(0xf)));
922      aml_append(kbd, aml_name_decl("_CRS", crs));
923  
924      crs = aml_resource_template();
925      aml_append(crs, aml_irq_no_flags(isa_s->mouse_irq));
926  
927      mou = aml_device("MOU");
928      aml_append(mou, aml_name_decl("_HID", aml_eisaid("PNP0F13")));
929      aml_append(mou, aml_name_decl("_STA", aml_int(0xf)));
930      aml_append(mou, aml_name_decl("_CRS", crs));
931  
932      aml_append(scope, kbd);
933      aml_append(scope, mou);
934  }
935  
936  static Property i8042_properties[] = {
937      DEFINE_PROP_BOOL("extended-state", ISAKBDState, kbd.extended_state, true),
938      DEFINE_PROP_BOOL("kbd-throttle", ISAKBDState, kbd_throttle, false),
939      DEFINE_PROP_UINT8("kbd-irq", ISAKBDState, kbd_irq, 1),
940      DEFINE_PROP_UINT8("mouse-irq", ISAKBDState, mouse_irq, 12),
941      DEFINE_PROP_END_OF_LIST(),
942  };
943  
i8042_class_initfn(ObjectClass * klass,void * data)944  static void i8042_class_initfn(ObjectClass *klass, void *data)
945  {
946      DeviceClass *dc = DEVICE_CLASS(klass);
947      AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
948  
949      device_class_set_props(dc, i8042_properties);
950      device_class_set_legacy_reset(dc, i8042_reset);
951      dc->realize = i8042_realizefn;
952      dc->vmsd = &vmstate_kbd_isa;
953      adevc->build_dev_aml = i8042_build_aml;
954      set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
955  }
956  
957  static const TypeInfo i8042_info = {
958      .name          = TYPE_I8042,
959      .parent        = TYPE_ISA_DEVICE,
960      .instance_size = sizeof(ISAKBDState),
961      .instance_init = i8042_initfn,
962      .class_init    = i8042_class_initfn,
963      .interfaces = (InterfaceInfo[]) {
964          { TYPE_ACPI_DEV_AML_IF },
965          { },
966      },
967  };
968  
i8042_register_types(void)969  static void i8042_register_types(void)
970  {
971      type_register_static(&i8042_info);
972      type_register_static(&i8042_mmio_info);
973  }
974  
975  type_init(i8042_register_types)
976