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 typedef struct KBDState { 150 uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ 151 uint8_t status; 152 uint8_t mode; 153 uint8_t outport; 154 uint32_t migration_flags; 155 uint32_t obsrc; 156 bool outport_present; 157 bool extended_state; 158 bool extended_state_loaded; 159 /* Bitmask of devices with data available. */ 160 uint8_t pending; 161 uint8_t obdata; 162 uint8_t cbdata; 163 uint8_t pending_tmp; 164 void *kbd; 165 void *mouse; 166 QEMUTimer *throttle_timer; 167 168 qemu_irq irq_kbd; 169 qemu_irq irq_mouse; 170 qemu_irq a20_out; 171 hwaddr mask; 172 } KBDState; 173 174 /* 175 * XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be 176 * incorrect, but it avoids having to simulate exact delays 177 */ 178 static void kbd_update_irq_lines(KBDState *s) 179 { 180 int irq_kbd_level, irq_mouse_level; 181 182 irq_kbd_level = 0; 183 irq_mouse_level = 0; 184 185 if (s->status & KBD_STAT_OBF) { 186 if (s->status & KBD_STAT_MOUSE_OBF) { 187 if (s->mode & KBD_MODE_MOUSE_INT) { 188 irq_mouse_level = 1; 189 } 190 } else { 191 if ((s->mode & KBD_MODE_KBD_INT) && 192 !(s->mode & KBD_MODE_DISABLE_KBD)) { 193 irq_kbd_level = 1; 194 } 195 } 196 } 197 qemu_set_irq(s->irq_kbd, irq_kbd_level); 198 qemu_set_irq(s->irq_mouse, irq_mouse_level); 199 } 200 201 static void kbd_deassert_irq(KBDState *s) 202 { 203 s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); 204 s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF); 205 kbd_update_irq_lines(s); 206 } 207 208 static uint8_t kbd_pending(KBDState *s) 209 { 210 if (s->extended_state) { 211 return s->pending & (~s->mode | ~(KBD_PENDING_KBD | KBD_PENDING_AUX)); 212 } else { 213 return s->pending; 214 } 215 } 216 217 /* update irq and KBD_STAT_[MOUSE_]OBF */ 218 static void kbd_update_irq(KBDState *s) 219 { 220 uint8_t pending = kbd_pending(s); 221 222 s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); 223 s->outport &= ~(KBD_OUT_OBF | KBD_OUT_MOUSE_OBF); 224 if (pending) { 225 s->status |= KBD_STAT_OBF; 226 s->outport |= KBD_OUT_OBF; 227 if (pending & KBD_PENDING_CTRL_KBD) { 228 s->obsrc = KBD_OBSRC_CTRL; 229 } else if (pending & KBD_PENDING_CTRL_AUX) { 230 s->status |= KBD_STAT_MOUSE_OBF; 231 s->outport |= KBD_OUT_MOUSE_OBF; 232 s->obsrc = KBD_OBSRC_CTRL; 233 } else if (pending & KBD_PENDING_KBD) { 234 s->obsrc = KBD_OBSRC_KBD; 235 } else { 236 s->status |= KBD_STAT_MOUSE_OBF; 237 s->outport |= KBD_OUT_MOUSE_OBF; 238 s->obsrc = KBD_OBSRC_MOUSE; 239 } 240 } 241 kbd_update_irq_lines(s); 242 } 243 244 static void kbd_safe_update_irq(KBDState *s) 245 { 246 /* 247 * with KBD_STAT_OBF set, a call to kbd_read_data() will eventually call 248 * kbd_update_irq() 249 */ 250 if (s->status & KBD_STAT_OBF) { 251 return; 252 } 253 /* the throttle timer is pending and will call kbd_update_irq() */ 254 if (s->throttle_timer && timer_pending(s->throttle_timer)) { 255 return; 256 } 257 if (kbd_pending(s)) { 258 kbd_update_irq(s); 259 } 260 } 261 262 static void kbd_update_kbd_irq(void *opaque, int level) 263 { 264 KBDState *s = opaque; 265 266 if (level) { 267 s->pending |= KBD_PENDING_KBD; 268 } else { 269 s->pending &= ~KBD_PENDING_KBD; 270 } 271 kbd_safe_update_irq(s); 272 } 273 274 static void kbd_update_aux_irq(void *opaque, int level) 275 { 276 KBDState *s = opaque; 277 278 if (level) { 279 s->pending |= KBD_PENDING_AUX; 280 } else { 281 s->pending &= ~KBD_PENDING_AUX; 282 } 283 kbd_safe_update_irq(s); 284 } 285 286 static void kbd_throttle_timeout(void *opaque) 287 { 288 KBDState *s = opaque; 289 290 if (kbd_pending(s)) { 291 kbd_update_irq(s); 292 } 293 } 294 295 static uint64_t kbd_read_status(void *opaque, hwaddr addr, 296 unsigned size) 297 { 298 KBDState *s = opaque; 299 int val; 300 val = s->status; 301 trace_pckbd_kbd_read_status(val); 302 return val; 303 } 304 305 static void kbd_queue(KBDState *s, int b, int aux) 306 { 307 if (s->extended_state) { 308 s->cbdata = b; 309 s->pending &= ~KBD_PENDING_CTRL_KBD & ~KBD_PENDING_CTRL_AUX; 310 s->pending |= aux ? KBD_PENDING_CTRL_AUX : KBD_PENDING_CTRL_KBD; 311 kbd_safe_update_irq(s); 312 } else { 313 ps2_queue(aux ? s->mouse : s->kbd, b); 314 } 315 } 316 317 static uint8_t kbd_dequeue(KBDState *s) 318 { 319 uint8_t b = s->cbdata; 320 321 s->pending &= ~KBD_PENDING_CTRL_KBD & ~KBD_PENDING_CTRL_AUX; 322 if (kbd_pending(s)) { 323 kbd_update_irq(s); 324 } 325 return b; 326 } 327 328 static void outport_write(KBDState *s, uint32_t val) 329 { 330 trace_pckbd_outport_write(val); 331 s->outport = val; 332 qemu_set_irq(s->a20_out, (val >> 1) & 1); 333 if (!(val & 1)) { 334 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 335 } 336 } 337 338 static void kbd_write_command(void *opaque, hwaddr addr, 339 uint64_t val, unsigned size) 340 { 341 KBDState *s = opaque; 342 343 trace_pckbd_kbd_write_command(val); 344 345 /* 346 * Bits 3-0 of the output port P2 of the keyboard controller may be pulsed 347 * low for approximately 6 micro seconds. Bits 3-0 of the KBD_CCMD_PULSE 348 * command specify the output port bits to be pulsed. 349 * 0: Bit should be pulsed. 1: Bit should not be modified. 350 * The only useful version of this command is pulsing bit 0, 351 * which does a CPU reset. 352 */ 353 if ((val & KBD_CCMD_PULSE_BITS_3_0) == KBD_CCMD_PULSE_BITS_3_0) { 354 if (!(val & 1)) { 355 val = KBD_CCMD_RESET; 356 } else { 357 val = KBD_CCMD_NO_OP; 358 } 359 } 360 361 switch (val) { 362 case KBD_CCMD_READ_MODE: 363 kbd_queue(s, s->mode, 0); 364 break; 365 case KBD_CCMD_WRITE_MODE: 366 case KBD_CCMD_WRITE_OBUF: 367 case KBD_CCMD_WRITE_AUX_OBUF: 368 case KBD_CCMD_WRITE_MOUSE: 369 case KBD_CCMD_WRITE_OUTPORT: 370 s->write_cmd = val; 371 break; 372 case KBD_CCMD_MOUSE_DISABLE: 373 s->mode |= KBD_MODE_DISABLE_MOUSE; 374 break; 375 case KBD_CCMD_MOUSE_ENABLE: 376 s->mode &= ~KBD_MODE_DISABLE_MOUSE; 377 kbd_safe_update_irq(s); 378 break; 379 case KBD_CCMD_TEST_MOUSE: 380 kbd_queue(s, 0x00, 0); 381 break; 382 case KBD_CCMD_SELF_TEST: 383 s->status |= KBD_STAT_SELFTEST; 384 kbd_queue(s, 0x55, 0); 385 break; 386 case KBD_CCMD_KBD_TEST: 387 kbd_queue(s, 0x00, 0); 388 break; 389 case KBD_CCMD_KBD_DISABLE: 390 s->mode |= KBD_MODE_DISABLE_KBD; 391 break; 392 case KBD_CCMD_KBD_ENABLE: 393 s->mode &= ~KBD_MODE_DISABLE_KBD; 394 kbd_safe_update_irq(s); 395 break; 396 case KBD_CCMD_READ_INPORT: 397 kbd_queue(s, 0x80, 0); 398 break; 399 case KBD_CCMD_READ_OUTPORT: 400 kbd_queue(s, s->outport, 0); 401 break; 402 case KBD_CCMD_ENABLE_A20: 403 qemu_irq_raise(s->a20_out); 404 s->outport |= KBD_OUT_A20; 405 break; 406 case KBD_CCMD_DISABLE_A20: 407 qemu_irq_lower(s->a20_out); 408 s->outport &= ~KBD_OUT_A20; 409 break; 410 case KBD_CCMD_RESET: 411 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 412 break; 413 case KBD_CCMD_NO_OP: 414 /* ignore that */ 415 break; 416 default: 417 qemu_log_mask(LOG_GUEST_ERROR, 418 "unsupported keyboard cmd=0x%02" PRIx64 "\n", val); 419 break; 420 } 421 } 422 423 static uint64_t kbd_read_data(void *opaque, hwaddr addr, 424 unsigned size) 425 { 426 KBDState *s = opaque; 427 428 if (s->status & KBD_STAT_OBF) { 429 kbd_deassert_irq(s); 430 if (s->obsrc & KBD_OBSRC_KBD) { 431 if (s->throttle_timer) { 432 timer_mod(s->throttle_timer, 433 qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + 1000); 434 } 435 s->obdata = ps2_read_data(s->kbd); 436 } else if (s->obsrc & KBD_OBSRC_MOUSE) { 437 s->obdata = ps2_read_data(s->mouse); 438 } else if (s->obsrc & KBD_OBSRC_CTRL) { 439 s->obdata = kbd_dequeue(s); 440 } 441 } 442 443 trace_pckbd_kbd_read_data(s->obdata); 444 return s->obdata; 445 } 446 447 static void kbd_write_data(void *opaque, hwaddr addr, 448 uint64_t val, unsigned size) 449 { 450 KBDState *s = opaque; 451 452 trace_pckbd_kbd_write_data(val); 453 454 switch (s->write_cmd) { 455 case 0: 456 ps2_write_keyboard(s->kbd, val); 457 /* sending data to the keyboard reenables PS/2 communication */ 458 s->mode &= ~KBD_MODE_DISABLE_KBD; 459 kbd_safe_update_irq(s); 460 break; 461 case KBD_CCMD_WRITE_MODE: 462 s->mode = val; 463 ps2_keyboard_set_translation(s->kbd, (s->mode & KBD_MODE_KCC) != 0); 464 /* 465 * a write to the mode byte interrupt enable flags directly updates 466 * the irq lines 467 */ 468 kbd_update_irq_lines(s); 469 /* 470 * a write to the mode byte disable interface flags may raise 471 * an irq if there is pending data in the PS/2 queues. 472 */ 473 kbd_safe_update_irq(s); 474 break; 475 case KBD_CCMD_WRITE_OBUF: 476 kbd_queue(s, val, 0); 477 break; 478 case KBD_CCMD_WRITE_AUX_OBUF: 479 kbd_queue(s, val, 1); 480 break; 481 case KBD_CCMD_WRITE_OUTPORT: 482 outport_write(s, val); 483 break; 484 case KBD_CCMD_WRITE_MOUSE: 485 ps2_write_mouse(s->mouse, val); 486 /* sending data to the mouse reenables PS/2 communication */ 487 s->mode &= ~KBD_MODE_DISABLE_MOUSE; 488 kbd_safe_update_irq(s); 489 break; 490 default: 491 break; 492 } 493 s->write_cmd = 0; 494 } 495 496 static void kbd_reset(void *opaque) 497 { 498 KBDState *s = opaque; 499 500 s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; 501 s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; 502 s->outport = KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES; 503 s->pending = 0; 504 kbd_deassert_irq(s); 505 if (s->throttle_timer) { 506 timer_del(s->throttle_timer); 507 } 508 } 509 510 static uint8_t kbd_outport_default(KBDState *s) 511 { 512 return KBD_OUT_RESET | KBD_OUT_A20 | KBD_OUT_ONES 513 | (s->status & KBD_STAT_OBF ? KBD_OUT_OBF : 0) 514 | (s->status & KBD_STAT_MOUSE_OBF ? KBD_OUT_MOUSE_OBF : 0); 515 } 516 517 static int kbd_outport_post_load(void *opaque, int version_id) 518 { 519 KBDState *s = opaque; 520 s->outport_present = true; 521 return 0; 522 } 523 524 static bool kbd_outport_needed(void *opaque) 525 { 526 KBDState *s = opaque; 527 return s->outport != kbd_outport_default(s); 528 } 529 530 static const VMStateDescription vmstate_kbd_outport = { 531 .name = "pckbd_outport", 532 .version_id = 1, 533 .minimum_version_id = 1, 534 .post_load = kbd_outport_post_load, 535 .needed = kbd_outport_needed, 536 .fields = (VMStateField[]) { 537 VMSTATE_UINT8(outport, KBDState), 538 VMSTATE_END_OF_LIST() 539 } 540 }; 541 542 static int kbd_extended_state_pre_save(void *opaque) 543 { 544 KBDState *s = opaque; 545 546 s->migration_flags = 0; 547 if (s->throttle_timer && timer_pending(s->throttle_timer)) { 548 s->migration_flags |= KBD_MIGR_TIMER_PENDING; 549 } 550 551 return 0; 552 } 553 554 static int kbd_extended_state_post_load(void *opaque, int version_id) 555 { 556 KBDState *s = opaque; 557 558 if (s->migration_flags & KBD_MIGR_TIMER_PENDING) { 559 kbd_throttle_timeout(s); 560 } 561 s->extended_state_loaded = true; 562 563 return 0; 564 } 565 566 static bool kbd_extended_state_needed(void *opaque) 567 { 568 KBDState *s = opaque; 569 570 return s->extended_state; 571 } 572 573 static const VMStateDescription vmstate_kbd_extended_state = { 574 .name = "pckbd/extended_state", 575 .post_load = kbd_extended_state_post_load, 576 .pre_save = kbd_extended_state_pre_save, 577 .needed = kbd_extended_state_needed, 578 .fields = (VMStateField[]) { 579 VMSTATE_UINT32(migration_flags, KBDState), 580 VMSTATE_UINT32(obsrc, KBDState), 581 VMSTATE_UINT8(obdata, KBDState), 582 VMSTATE_UINT8(cbdata, KBDState), 583 VMSTATE_END_OF_LIST() 584 } 585 }; 586 587 static int kbd_pre_save(void *opaque) 588 { 589 KBDState *s = opaque; 590 591 if (s->extended_state) { 592 s->pending_tmp = s->pending; 593 } else { 594 s->pending_tmp = 0; 595 if (s->pending & KBD_PENDING_KBD) { 596 s->pending_tmp |= KBD_PENDING_KBD_COMPAT; 597 } 598 if (s->pending & KBD_PENDING_AUX) { 599 s->pending_tmp |= KBD_PENDING_AUX_COMPAT; 600 } 601 } 602 return 0; 603 } 604 605 static int kbd_pre_load(void *opaque) 606 { 607 KBDState *s = opaque; 608 609 s->outport_present = false; 610 s->extended_state_loaded = false; 611 return 0; 612 } 613 614 static int kbd_post_load(void *opaque, int version_id) 615 { 616 KBDState *s = opaque; 617 if (!s->outport_present) { 618 s->outport = kbd_outport_default(s); 619 } 620 s->pending = s->pending_tmp; 621 if (!s->extended_state_loaded) { 622 s->obsrc = s->status & KBD_STAT_OBF ? 623 (s->status & KBD_STAT_MOUSE_OBF ? KBD_OBSRC_MOUSE : KBD_OBSRC_KBD) : 624 0; 625 if (s->pending & KBD_PENDING_KBD_COMPAT) { 626 s->pending |= KBD_PENDING_KBD; 627 } 628 if (s->pending & KBD_PENDING_AUX_COMPAT) { 629 s->pending |= KBD_PENDING_AUX; 630 } 631 } 632 /* clear all unused flags */ 633 s->pending &= KBD_PENDING_CTRL_KBD | KBD_PENDING_CTRL_AUX | 634 KBD_PENDING_KBD | KBD_PENDING_AUX; 635 return 0; 636 } 637 638 static const VMStateDescription vmstate_kbd = { 639 .name = "pckbd", 640 .version_id = 3, 641 .minimum_version_id = 3, 642 .pre_load = kbd_pre_load, 643 .post_load = kbd_post_load, 644 .pre_save = kbd_pre_save, 645 .fields = (VMStateField[]) { 646 VMSTATE_UINT8(write_cmd, KBDState), 647 VMSTATE_UINT8(status, KBDState), 648 VMSTATE_UINT8(mode, KBDState), 649 VMSTATE_UINT8(pending_tmp, KBDState), 650 VMSTATE_END_OF_LIST() 651 }, 652 .subsections = (const VMStateDescription * []) { 653 &vmstate_kbd_outport, 654 &vmstate_kbd_extended_state, 655 NULL 656 } 657 }; 658 659 /* Memory mapped interface */ 660 static uint64_t kbd_mm_readfn(void *opaque, hwaddr addr, unsigned size) 661 { 662 KBDState *s = opaque; 663 664 if (addr & s->mask) { 665 return kbd_read_status(s, 0, 1) & 0xff; 666 } else { 667 return kbd_read_data(s, 0, 1) & 0xff; 668 } 669 } 670 671 static void kbd_mm_writefn(void *opaque, hwaddr addr, 672 uint64_t value, unsigned size) 673 { 674 KBDState *s = opaque; 675 676 if (addr & s->mask) { 677 kbd_write_command(s, 0, value & 0xff, 1); 678 } else { 679 kbd_write_data(s, 0, value & 0xff, 1); 680 } 681 } 682 683 684 static const MemoryRegionOps i8042_mmio_ops = { 685 .read = kbd_mm_readfn, 686 .write = kbd_mm_writefn, 687 .valid.min_access_size = 1, 688 .valid.max_access_size = 4, 689 .endianness = DEVICE_NATIVE_ENDIAN, 690 }; 691 692 void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, 693 MemoryRegion *region, ram_addr_t size, 694 hwaddr mask) 695 { 696 KBDState *s = g_new0(KBDState, 1); 697 698 s->irq_kbd = kbd_irq; 699 s->irq_mouse = mouse_irq; 700 s->mask = mask; 701 702 s->extended_state = true; 703 704 vmstate_register(NULL, 0, &vmstate_kbd, s); 705 706 memory_region_init_io(region, NULL, &i8042_mmio_ops, s, "i8042", size); 707 708 s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); 709 s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); 710 qemu_register_reset(kbd_reset, s); 711 } 712 713 struct ISAKBDState { 714 ISADevice parent_obj; 715 716 KBDState kbd; 717 bool kbd_throttle; 718 MemoryRegion io[2]; 719 uint8_t kbd_irq; 720 uint8_t mouse_irq; 721 }; 722 723 void i8042_isa_mouse_fake_event(ISAKBDState *isa) 724 { 725 KBDState *s = &isa->kbd; 726 727 ps2_mouse_fake_event(s->mouse); 728 } 729 730 void i8042_setup_a20_line(ISADevice *dev, qemu_irq a20_out) 731 { 732 qdev_connect_gpio_out_named(DEVICE(dev), I8042_A20_LINE, 0, a20_out); 733 } 734 735 static const VMStateDescription vmstate_kbd_isa = { 736 .name = "pckbd", 737 .version_id = 3, 738 .minimum_version_id = 3, 739 .fields = (VMStateField[]) { 740 VMSTATE_STRUCT(kbd, ISAKBDState, 0, vmstate_kbd, KBDState), 741 VMSTATE_END_OF_LIST() 742 } 743 }; 744 745 static const MemoryRegionOps i8042_data_ops = { 746 .read = kbd_read_data, 747 .write = kbd_write_data, 748 .impl = { 749 .min_access_size = 1, 750 .max_access_size = 1, 751 }, 752 .endianness = DEVICE_LITTLE_ENDIAN, 753 }; 754 755 static const MemoryRegionOps i8042_cmd_ops = { 756 .read = kbd_read_status, 757 .write = kbd_write_command, 758 .impl = { 759 .min_access_size = 1, 760 .max_access_size = 1, 761 }, 762 .endianness = DEVICE_LITTLE_ENDIAN, 763 }; 764 765 static void i8042_initfn(Object *obj) 766 { 767 ISAKBDState *isa_s = I8042(obj); 768 KBDState *s = &isa_s->kbd; 769 770 memory_region_init_io(isa_s->io + 0, obj, &i8042_data_ops, s, 771 "i8042-data", 1); 772 memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s, 773 "i8042-cmd", 1); 774 775 qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1); 776 } 777 778 static void i8042_realizefn(DeviceState *dev, Error **errp) 779 { 780 ISADevice *isadev = ISA_DEVICE(dev); 781 ISAKBDState *isa_s = I8042(dev); 782 KBDState *s = &isa_s->kbd; 783 784 if (isa_s->kbd_irq >= ISA_NUM_IRQS) { 785 error_setg(errp, "Maximum value for \"kbd-irq\" is: %u", 786 ISA_NUM_IRQS - 1); 787 return; 788 } 789 790 if (isa_s->mouse_irq >= ISA_NUM_IRQS) { 791 error_setg(errp, "Maximum value for \"mouse-irq\" is: %u", 792 ISA_NUM_IRQS - 1); 793 return; 794 } 795 796 s->irq_kbd = isa_get_irq(isadev, isa_s->kbd_irq); 797 s->irq_mouse = isa_get_irq(isadev, isa_s->mouse_irq); 798 799 isa_register_ioport(isadev, isa_s->io + 0, 0x60); 800 isa_register_ioport(isadev, isa_s->io + 1, 0x64); 801 802 s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); 803 s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); 804 if (isa_s->kbd_throttle && !isa_s->kbd.extended_state) { 805 warn_report(TYPE_I8042 ": can't enable kbd-throttle without" 806 " extended-state, disabling kbd-throttle"); 807 } else if (isa_s->kbd_throttle) { 808 s->throttle_timer = timer_new_us(QEMU_CLOCK_VIRTUAL, 809 kbd_throttle_timeout, s); 810 } 811 qemu_register_reset(kbd_reset, s); 812 } 813 814 static void i8042_build_aml(AcpiDevAmlIf *adev, Aml *scope) 815 { 816 ISAKBDState *isa_s = I8042(adev); 817 Aml *kbd; 818 Aml *mou; 819 Aml *crs; 820 821 crs = aml_resource_template(); 822 aml_append(crs, aml_io(AML_DECODE16, 0x0060, 0x0060, 0x01, 0x01)); 823 aml_append(crs, aml_io(AML_DECODE16, 0x0064, 0x0064, 0x01, 0x01)); 824 aml_append(crs, aml_irq_no_flags(isa_s->kbd_irq)); 825 826 kbd = aml_device("KBD"); 827 aml_append(kbd, aml_name_decl("_HID", aml_eisaid("PNP0303"))); 828 aml_append(kbd, aml_name_decl("_STA", aml_int(0xf))); 829 aml_append(kbd, aml_name_decl("_CRS", crs)); 830 831 crs = aml_resource_template(); 832 aml_append(crs, aml_irq_no_flags(isa_s->mouse_irq)); 833 834 mou = aml_device("MOU"); 835 aml_append(mou, aml_name_decl("_HID", aml_eisaid("PNP0F13"))); 836 aml_append(mou, aml_name_decl("_STA", aml_int(0xf))); 837 aml_append(mou, aml_name_decl("_CRS", crs)); 838 839 aml_append(scope, kbd); 840 aml_append(scope, mou); 841 } 842 843 static Property i8042_properties[] = { 844 DEFINE_PROP_BOOL("extended-state", ISAKBDState, kbd.extended_state, true), 845 DEFINE_PROP_BOOL("kbd-throttle", ISAKBDState, kbd_throttle, false), 846 DEFINE_PROP_UINT8("kbd-irq", ISAKBDState, kbd_irq, 1), 847 DEFINE_PROP_UINT8("mouse-irq", ISAKBDState, mouse_irq, 12), 848 DEFINE_PROP_END_OF_LIST(), 849 }; 850 851 static void i8042_class_initfn(ObjectClass *klass, void *data) 852 { 853 DeviceClass *dc = DEVICE_CLASS(klass); 854 AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); 855 856 device_class_set_props(dc, i8042_properties); 857 dc->realize = i8042_realizefn; 858 dc->vmsd = &vmstate_kbd_isa; 859 adevc->build_dev_aml = i8042_build_aml; 860 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); 861 } 862 863 static const TypeInfo i8042_info = { 864 .name = TYPE_I8042, 865 .parent = TYPE_ISA_DEVICE, 866 .instance_size = sizeof(ISAKBDState), 867 .instance_init = i8042_initfn, 868 .class_init = i8042_class_initfn, 869 .interfaces = (InterfaceInfo[]) { 870 { TYPE_ACPI_DEV_AML_IF }, 871 { }, 872 }, 873 }; 874 875 static void i8042_register_types(void) 876 { 877 type_register_static(&i8042_info); 878 } 879 880 type_init(i8042_register_types) 881