qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

pckbd.c (28208B)


      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 ? PS2_DEVICE(&s->ps2mouse) : PS2_DEVICE(&s->ps2kbd), 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(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 
    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 
    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 
    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 
    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 
    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 = (VMStateField[]) {
    514         VMSTATE_UINT8(outport, KBDState),
    515         VMSTATE_END_OF_LIST()
    516     }
    517 };
    518 
    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 
    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 
    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 = (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 
    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 
    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 
    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 = (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 * []) {
    630         &vmstate_kbd_outport,
    631         &vmstate_kbd_extended_state,
    632         NULL
    633     }
    634 };
    635 
    636 /* Memory mapped interface */
    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 
    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 
    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 
    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 
    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 
    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 
    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 = (VMStateField[]) {
    749         VMSTATE_STRUCT(kbd, MMIOKBDState, 0, vmstate_kbd, KBDState),
    750         VMSTATE_END_OF_LIST()
    751     }
    752 };
    753 
    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     dc->reset = 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 
    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 void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out)
    781 {
    782     qdev_connect_gpio_out_named(DEVICE(dev), I8042_A20_LINE, 0, a20_out);
    783 }
    784 
    785 static const VMStateDescription vmstate_kbd_isa = {
    786     .name = "pckbd",
    787     .version_id = 3,
    788     .minimum_version_id = 3,
    789     .fields = (VMStateField[]) {
    790         VMSTATE_STRUCT(kbd, ISAKBDState, 0, vmstate_kbd, KBDState),
    791         VMSTATE_END_OF_LIST()
    792     }
    793 };
    794 
    795 static const MemoryRegionOps i8042_data_ops = {
    796     .read = kbd_read_data,
    797     .write = kbd_write_data,
    798     .impl = {
    799         .min_access_size = 1,
    800         .max_access_size = 1,
    801     },
    802     .endianness = DEVICE_LITTLE_ENDIAN,
    803 };
    804 
    805 static const MemoryRegionOps i8042_cmd_ops = {
    806     .read = kbd_read_status,
    807     .write = kbd_write_command,
    808     .impl = {
    809         .min_access_size = 1,
    810         .max_access_size = 1,
    811     },
    812     .endianness = DEVICE_LITTLE_ENDIAN,
    813 };
    814 
    815 static void i8042_set_kbd_irq(void *opaque, int n, int level)
    816 {
    817     ISAKBDState *s = I8042(opaque);
    818     KBDState *ks = &s->kbd;
    819 
    820     kbd_update_kbd_irq(ks, level);
    821 }
    822 
    823 static void i8042_set_mouse_irq(void *opaque, int n, int level)
    824 {
    825     ISAKBDState *s = I8042(opaque);
    826     KBDState *ks = &s->kbd;
    827 
    828     kbd_update_aux_irq(ks, level);
    829 }
    830 
    831 
    832 static void i8042_reset(DeviceState *dev)
    833 {
    834     ISAKBDState *s = I8042(dev);
    835     KBDState *ks = &s->kbd;
    836 
    837     kbd_reset(ks);
    838 }
    839 
    840 static void i8042_initfn(Object *obj)
    841 {
    842     ISAKBDState *isa_s = I8042(obj);
    843     KBDState *s = &isa_s->kbd;
    844 
    845     memory_region_init_io(isa_s->io + 0, obj, &i8042_data_ops, s,
    846                           "i8042-data", 1);
    847     memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s,
    848                           "i8042-cmd", 1);
    849 
    850     object_initialize_child(obj, "ps2kbd", &s->ps2kbd, TYPE_PS2_KBD_DEVICE);
    851     object_initialize_child(obj, "ps2mouse", &s->ps2mouse,
    852                             TYPE_PS2_MOUSE_DEVICE);
    853 
    854     qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1);
    855 
    856     qdev_init_gpio_out(DEVICE(obj), s->irqs, 2);
    857     qdev_init_gpio_in_named(DEVICE(obj), i8042_set_kbd_irq,
    858                             "ps2-kbd-input-irq", 1);
    859     qdev_init_gpio_in_named(DEVICE(obj), i8042_set_mouse_irq,
    860                             "ps2-mouse-input-irq", 1);
    861 }
    862 
    863 static void i8042_realizefn(DeviceState *dev, Error **errp)
    864 {
    865     ISADevice *isadev = ISA_DEVICE(dev);
    866     ISAKBDState *isa_s = I8042(dev);
    867     KBDState *s = &isa_s->kbd;
    868 
    869     if (isa_s->kbd_irq >= ISA_NUM_IRQS) {
    870         error_setg(errp, "Maximum value for \"kbd-irq\" is: %u",
    871                    ISA_NUM_IRQS - 1);
    872         return;
    873     }
    874 
    875     if (isa_s->mouse_irq >= ISA_NUM_IRQS) {
    876         error_setg(errp, "Maximum value for \"mouse-irq\" is: %u",
    877                    ISA_NUM_IRQS - 1);
    878         return;
    879     }
    880 
    881     isa_connect_gpio_out(isadev, I8042_KBD_IRQ, isa_s->kbd_irq);
    882     isa_connect_gpio_out(isadev, I8042_MOUSE_IRQ, isa_s->mouse_irq);
    883 
    884     isa_register_ioport(isadev, isa_s->io + 0, 0x60);
    885     isa_register_ioport(isadev, isa_s->io + 1, 0x64);
    886 
    887     if (!sysbus_realize(SYS_BUS_DEVICE(&s->ps2kbd), errp)) {
    888         return;
    889     }
    890 
    891     qdev_connect_gpio_out(DEVICE(&s->ps2kbd), PS2_DEVICE_IRQ,
    892                           qdev_get_gpio_in_named(dev, "ps2-kbd-input-irq",
    893                                                  0));
    894 
    895     if (!sysbus_realize(SYS_BUS_DEVICE(&s->ps2mouse), errp)) {
    896         return;
    897     }
    898 
    899     qdev_connect_gpio_out(DEVICE(&s->ps2mouse), PS2_DEVICE_IRQ,
    900                           qdev_get_gpio_in_named(dev, "ps2-mouse-input-irq",
    901                                                  0));
    902 
    903     if (isa_s->kbd_throttle && !isa_s->kbd.extended_state) {
    904         warn_report(TYPE_I8042 ": can't enable kbd-throttle without"
    905                     " extended-state, disabling kbd-throttle");
    906     } else if (isa_s->kbd_throttle) {
    907         s->throttle_timer = timer_new_us(QEMU_CLOCK_VIRTUAL,
    908                                          kbd_throttle_timeout, s);
    909     }
    910 }
    911 
    912 static void i8042_build_aml(AcpiDevAmlIf *adev, Aml *scope)
    913 {
    914     ISAKBDState *isa_s = I8042(adev);
    915     Aml *kbd;
    916     Aml *mou;
    917     Aml *crs;
    918 
    919     crs = aml_resource_template();
    920     aml_append(crs, aml_io(AML_DECODE16, 0x0060, 0x0060, 0x01, 0x01));
    921     aml_append(crs, aml_io(AML_DECODE16, 0x0064, 0x0064, 0x01, 0x01));
    922     aml_append(crs, aml_irq_no_flags(isa_s->kbd_irq));
    923 
    924     kbd = aml_device("KBD");
    925     aml_append(kbd, aml_name_decl("_HID", aml_eisaid("PNP0303")));
    926     aml_append(kbd, aml_name_decl("_STA", aml_int(0xf)));
    927     aml_append(kbd, aml_name_decl("_CRS", crs));
    928 
    929     crs = aml_resource_template();
    930     aml_append(crs, aml_irq_no_flags(isa_s->mouse_irq));
    931 
    932     mou = aml_device("MOU");
    933     aml_append(mou, aml_name_decl("_HID", aml_eisaid("PNP0F13")));
    934     aml_append(mou, aml_name_decl("_STA", aml_int(0xf)));
    935     aml_append(mou, aml_name_decl("_CRS", crs));
    936 
    937     aml_append(scope, kbd);
    938     aml_append(scope, mou);
    939 }
    940 
    941 static Property i8042_properties[] = {
    942     DEFINE_PROP_BOOL("extended-state", ISAKBDState, kbd.extended_state, true),
    943     DEFINE_PROP_BOOL("kbd-throttle", ISAKBDState, kbd_throttle, false),
    944     DEFINE_PROP_UINT8("kbd-irq", ISAKBDState, kbd_irq, 1),
    945     DEFINE_PROP_UINT8("mouse-irq", ISAKBDState, mouse_irq, 12),
    946     DEFINE_PROP_END_OF_LIST(),
    947 };
    948 
    949 static void i8042_class_initfn(ObjectClass *klass, void *data)
    950 {
    951     DeviceClass *dc = DEVICE_CLASS(klass);
    952     AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass);
    953 
    954     device_class_set_props(dc, i8042_properties);
    955     dc->reset = i8042_reset;
    956     dc->realize = i8042_realizefn;
    957     dc->vmsd = &vmstate_kbd_isa;
    958     adevc->build_dev_aml = i8042_build_aml;
    959     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
    960 }
    961 
    962 static const TypeInfo i8042_info = {
    963     .name          = TYPE_I8042,
    964     .parent        = TYPE_ISA_DEVICE,
    965     .instance_size = sizeof(ISAKBDState),
    966     .instance_init = i8042_initfn,
    967     .class_init    = i8042_class_initfn,
    968     .interfaces = (InterfaceInfo[]) {
    969         { TYPE_ACPI_DEV_AML_IF },
    970         { },
    971     },
    972 };
    973 
    974 static void i8042_register_types(void)
    975 {
    976     type_register_static(&i8042_info);
    977     type_register_static(&i8042_mmio_info);
    978 }
    979 
    980 type_init(i8042_register_types)