1 /* 2 * QEMU PS/2 keyboard/mouse emulation 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu/osdep.h" 26 #include "qemu/log.h" 27 #include "hw/irq.h" 28 #include "hw/sysbus.h" 29 #include "hw/input/ps2.h" 30 #include "migration/vmstate.h" 31 #include "ui/console.h" 32 #include "ui/input.h" 33 #include "sysemu/reset.h" 34 #include "sysemu/runstate.h" 35 #include "qapi/error.h" 36 37 #include "trace.h" 38 39 /* Keyboard Commands */ 40 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ 41 #define KBD_CMD_ECHO 0xEE 42 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */ 43 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */ 44 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ 45 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ 46 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */ 47 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */ 48 #define KBD_CMD_RESET 0xFF /* Reset */ 49 #define KBD_CMD_SET_MAKE_BREAK 0xFC /* Set Make and Break mode */ 50 #define KBD_CMD_SET_TYPEMATIC 0xFA /* Set Typematic Make and Break mode */ 51 52 /* Keyboard Replies */ 53 #define KBD_REPLY_POR 0xAA /* Power on reset */ 54 #define KBD_REPLY_ID 0xAB /* Keyboard ID */ 55 #define KBD_REPLY_ACK 0xFA /* Command ACK */ 56 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ 57 58 /* Mouse Commands */ 59 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ 60 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ 61 #define AUX_SET_RES 0xE8 /* Set resolution */ 62 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */ 63 #define AUX_SET_STREAM 0xEA /* Set stream mode */ 64 #define AUX_POLL 0xEB /* Poll */ 65 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */ 66 #define AUX_SET_WRAP 0xEE /* Set wrap mode */ 67 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */ 68 #define AUX_GET_TYPE 0xF2 /* Get type */ 69 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ 70 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ 71 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ 72 #define AUX_SET_DEFAULT 0xF6 73 #define AUX_RESET 0xFF /* Reset aux device */ 74 #define AUX_ACK 0xFA /* Command byte ACK. */ 75 76 #define MOUSE_STATUS_REMOTE 0x40 77 #define MOUSE_STATUS_ENABLED 0x20 78 #define MOUSE_STATUS_SCALE21 0x10 79 80 #define PS2_QUEUE_SIZE 16 /* Queue size required by PS/2 protocol */ 81 #define PS2_QUEUE_HEADROOM 8 /* Queue size for keyboard command replies */ 82 83 /* Bits for 'modifiers' field in PS2KbdState */ 84 #define MOD_CTRL_L (1 << 0) 85 #define MOD_SHIFT_L (1 << 1) 86 #define MOD_ALT_L (1 << 2) 87 #define MOD_CTRL_R (1 << 3) 88 #define MOD_SHIFT_R (1 << 4) 89 #define MOD_ALT_R (1 << 5) 90 91 static uint8_t translate_table[256] = { 92 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, 93 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, 94 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, 95 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b, 96 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, 97 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d, 98 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, 99 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f, 100 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, 101 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61, 102 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, 103 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76, 104 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, 105 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f, 106 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, 107 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54, 108 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, 109 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 110 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 111 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 112 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 113 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 114 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 115 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 116 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 117 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 118 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 119 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 120 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 121 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 122 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 123 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 124 }; 125 126 static unsigned int ps2_modifier_bit(QKeyCode key) 127 { 128 switch (key) { 129 case Q_KEY_CODE_CTRL: 130 return MOD_CTRL_L; 131 case Q_KEY_CODE_CTRL_R: 132 return MOD_CTRL_R; 133 case Q_KEY_CODE_SHIFT: 134 return MOD_SHIFT_L; 135 case Q_KEY_CODE_SHIFT_R: 136 return MOD_SHIFT_R; 137 case Q_KEY_CODE_ALT: 138 return MOD_ALT_L; 139 case Q_KEY_CODE_ALT_R: 140 return MOD_ALT_R; 141 default: 142 return 0; 143 } 144 } 145 146 static void ps2_reset_queue(PS2State *s) 147 { 148 PS2Queue *q = &s->queue; 149 150 q->rptr = 0; 151 q->wptr = 0; 152 q->cwptr = -1; 153 q->count = 0; 154 } 155 156 int ps2_queue_empty(PS2State *s) 157 { 158 return s->queue.count == 0; 159 } 160 161 void ps2_queue_noirq(PS2State *s, int b) 162 { 163 PS2Queue *q = &s->queue; 164 165 if (q->count >= PS2_QUEUE_SIZE) { 166 return; 167 } 168 169 q->data[q->wptr] = b; 170 if (++q->wptr == PS2_BUFFER_SIZE) { 171 q->wptr = 0; 172 } 173 q->count++; 174 } 175 176 static void ps2_raise_irq(PS2State *s) 177 { 178 if (qemu_irq_is_connected(s->irq)) { 179 qemu_set_irq(s->irq, 1); 180 } else { 181 s->update_irq(s->update_arg, 1); 182 } 183 } 184 185 static void ps2_lower_irq(PS2State *s) 186 { 187 if (qemu_irq_is_connected(s->irq)) { 188 qemu_set_irq(s->irq, 0); 189 } else { 190 s->update_irq(s->update_arg, 0); 191 } 192 } 193 194 void ps2_queue(PS2State *s, int b) 195 { 196 if (PS2_QUEUE_SIZE - s->queue.count < 1) { 197 return; 198 } 199 200 ps2_queue_noirq(s, b); 201 ps2_raise_irq(s); 202 } 203 204 void ps2_queue_2(PS2State *s, int b1, int b2) 205 { 206 if (PS2_QUEUE_SIZE - s->queue.count < 2) { 207 return; 208 } 209 210 ps2_queue_noirq(s, b1); 211 ps2_queue_noirq(s, b2); 212 ps2_raise_irq(s); 213 } 214 215 void ps2_queue_3(PS2State *s, int b1, int b2, int b3) 216 { 217 if (PS2_QUEUE_SIZE - s->queue.count < 3) { 218 return; 219 } 220 221 ps2_queue_noirq(s, b1); 222 ps2_queue_noirq(s, b2); 223 ps2_queue_noirq(s, b3); 224 ps2_raise_irq(s); 225 } 226 227 void ps2_queue_4(PS2State *s, int b1, int b2, int b3, int b4) 228 { 229 if (PS2_QUEUE_SIZE - s->queue.count < 4) { 230 return; 231 } 232 233 ps2_queue_noirq(s, b1); 234 ps2_queue_noirq(s, b2); 235 ps2_queue_noirq(s, b3); 236 ps2_queue_noirq(s, b4); 237 ps2_raise_irq(s); 238 } 239 240 static void ps2_cqueue_data(PS2Queue *q, int b) 241 { 242 q->data[q->cwptr] = b; 243 if (++q->cwptr >= PS2_BUFFER_SIZE) { 244 q->cwptr = 0; 245 } 246 q->count++; 247 } 248 249 static void ps2_cqueue_1(PS2State *s, int b1) 250 { 251 PS2Queue *q = &s->queue; 252 253 q->rptr = (q->rptr - 1) & (PS2_BUFFER_SIZE - 1); 254 q->cwptr = q->rptr; 255 ps2_cqueue_data(q, b1); 256 ps2_raise_irq(s); 257 } 258 259 static void ps2_cqueue_2(PS2State *s, int b1, int b2) 260 { 261 PS2Queue *q = &s->queue; 262 263 q->rptr = (q->rptr - 2) & (PS2_BUFFER_SIZE - 1); 264 q->cwptr = q->rptr; 265 ps2_cqueue_data(q, b1); 266 ps2_cqueue_data(q, b2); 267 ps2_raise_irq(s); 268 } 269 270 static void ps2_cqueue_3(PS2State *s, int b1, int b2, int b3) 271 { 272 PS2Queue *q = &s->queue; 273 274 q->rptr = (q->rptr - 3) & (PS2_BUFFER_SIZE - 1); 275 q->cwptr = q->rptr; 276 ps2_cqueue_data(q, b1); 277 ps2_cqueue_data(q, b2); 278 ps2_cqueue_data(q, b3); 279 ps2_raise_irq(s); 280 } 281 282 static void ps2_cqueue_reset(PS2State *s) 283 { 284 PS2Queue *q = &s->queue; 285 int ccount; 286 287 if (q->cwptr == -1) { 288 return; 289 } 290 291 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1); 292 q->count -= ccount; 293 q->rptr = q->cwptr; 294 q->cwptr = -1; 295 } 296 297 /* keycode is the untranslated scancode in the current scancode set. */ 298 static void ps2_put_keycode(void *opaque, int keycode) 299 { 300 PS2KbdState *s = opaque; 301 PS2State *ps = PS2_DEVICE(s); 302 303 trace_ps2_put_keycode(opaque, keycode); 304 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); 305 306 if (s->translate) { 307 if (keycode == 0xf0) { 308 s->need_high_bit = true; 309 } else if (s->need_high_bit) { 310 ps2_queue(ps, translate_table[keycode] | 0x80); 311 s->need_high_bit = false; 312 } else { 313 ps2_queue(ps, translate_table[keycode]); 314 } 315 } else { 316 ps2_queue(ps, keycode); 317 } 318 } 319 320 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, 321 InputEvent *evt) 322 { 323 PS2KbdState *s = (PS2KbdState *)dev; 324 InputKeyEvent *key = evt->u.key.data; 325 int qcode; 326 uint16_t keycode = 0; 327 int mod; 328 329 /* do not process events while disabled to prevent stream corruption */ 330 if (!s->scan_enabled) { 331 return; 332 } 333 334 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); 335 assert(evt->type == INPUT_EVENT_KIND_KEY); 336 qcode = qemu_input_key_value_to_qcode(key->key); 337 338 mod = ps2_modifier_bit(qcode); 339 trace_ps2_keyboard_event(s, qcode, key->down, mod, 340 s->modifiers, s->scancode_set, s->translate); 341 if (key->down) { 342 s->modifiers |= mod; 343 } else { 344 s->modifiers &= ~mod; 345 } 346 347 if (s->scancode_set == 1) { 348 if (qcode == Q_KEY_CODE_PAUSE) { 349 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) { 350 if (key->down) { 351 ps2_put_keycode(s, 0xe0); 352 ps2_put_keycode(s, 0x46); 353 ps2_put_keycode(s, 0xe0); 354 ps2_put_keycode(s, 0xc6); 355 } 356 } else { 357 if (key->down) { 358 ps2_put_keycode(s, 0xe1); 359 ps2_put_keycode(s, 0x1d); 360 ps2_put_keycode(s, 0x45); 361 ps2_put_keycode(s, 0xe1); 362 ps2_put_keycode(s, 0x9d); 363 ps2_put_keycode(s, 0xc5); 364 } 365 } 366 } else if (qcode == Q_KEY_CODE_PRINT) { 367 if (s->modifiers & MOD_ALT_L) { 368 if (key->down) { 369 ps2_put_keycode(s, 0xb8); 370 ps2_put_keycode(s, 0x38); 371 ps2_put_keycode(s, 0x54); 372 } else { 373 ps2_put_keycode(s, 0xd4); 374 ps2_put_keycode(s, 0xb8); 375 ps2_put_keycode(s, 0x38); 376 } 377 } else if (s->modifiers & MOD_ALT_R) { 378 if (key->down) { 379 ps2_put_keycode(s, 0xe0); 380 ps2_put_keycode(s, 0xb8); 381 ps2_put_keycode(s, 0xe0); 382 ps2_put_keycode(s, 0x38); 383 ps2_put_keycode(s, 0x54); 384 } else { 385 ps2_put_keycode(s, 0xd4); 386 ps2_put_keycode(s, 0xe0); 387 ps2_put_keycode(s, 0xb8); 388 ps2_put_keycode(s, 0xe0); 389 ps2_put_keycode(s, 0x38); 390 } 391 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L | 392 MOD_SHIFT_R | MOD_CTRL_R)) { 393 if (key->down) { 394 ps2_put_keycode(s, 0xe0); 395 ps2_put_keycode(s, 0x37); 396 } else { 397 ps2_put_keycode(s, 0xe0); 398 ps2_put_keycode(s, 0xb7); 399 } 400 } else { 401 if (key->down) { 402 ps2_put_keycode(s, 0xe0); 403 ps2_put_keycode(s, 0x2a); 404 ps2_put_keycode(s, 0xe0); 405 ps2_put_keycode(s, 0x37); 406 } else { 407 ps2_put_keycode(s, 0xe0); 408 ps2_put_keycode(s, 0xb7); 409 ps2_put_keycode(s, 0xe0); 410 ps2_put_keycode(s, 0xaa); 411 } 412 } 413 } else { 414 if (qcode < qemu_input_map_qcode_to_atset1_len) { 415 keycode = qemu_input_map_qcode_to_atset1[qcode]; 416 } 417 if (keycode) { 418 if (keycode & 0xff00) { 419 ps2_put_keycode(s, keycode >> 8); 420 } 421 if (!key->down) { 422 keycode |= 0x80; 423 } 424 ps2_put_keycode(s, keycode & 0xff); 425 } else { 426 qemu_log_mask(LOG_UNIMP, 427 "ps2: ignoring key with qcode %d\n", qcode); 428 } 429 } 430 } else if (s->scancode_set == 2) { 431 if (qcode == Q_KEY_CODE_PAUSE) { 432 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) { 433 if (key->down) { 434 ps2_put_keycode(s, 0xe0); 435 ps2_put_keycode(s, 0x7e); 436 ps2_put_keycode(s, 0xe0); 437 ps2_put_keycode(s, 0xf0); 438 ps2_put_keycode(s, 0x7e); 439 } 440 } else { 441 if (key->down) { 442 ps2_put_keycode(s, 0xe1); 443 ps2_put_keycode(s, 0x14); 444 ps2_put_keycode(s, 0x77); 445 ps2_put_keycode(s, 0xe1); 446 ps2_put_keycode(s, 0xf0); 447 ps2_put_keycode(s, 0x14); 448 ps2_put_keycode(s, 0xf0); 449 ps2_put_keycode(s, 0x77); 450 } 451 } 452 } else if (qcode == Q_KEY_CODE_PRINT) { 453 if (s->modifiers & MOD_ALT_L) { 454 if (key->down) { 455 ps2_put_keycode(s, 0xf0); 456 ps2_put_keycode(s, 0x11); 457 ps2_put_keycode(s, 0x11); 458 ps2_put_keycode(s, 0x84); 459 } else { 460 ps2_put_keycode(s, 0xf0); 461 ps2_put_keycode(s, 0x84); 462 ps2_put_keycode(s, 0xf0); 463 ps2_put_keycode(s, 0x11); 464 ps2_put_keycode(s, 0x11); 465 } 466 } else if (s->modifiers & MOD_ALT_R) { 467 if (key->down) { 468 ps2_put_keycode(s, 0xe0); 469 ps2_put_keycode(s, 0xf0); 470 ps2_put_keycode(s, 0x11); 471 ps2_put_keycode(s, 0xe0); 472 ps2_put_keycode(s, 0x11); 473 ps2_put_keycode(s, 0x84); 474 } else { 475 ps2_put_keycode(s, 0xf0); 476 ps2_put_keycode(s, 0x84); 477 ps2_put_keycode(s, 0xe0); 478 ps2_put_keycode(s, 0xf0); 479 ps2_put_keycode(s, 0x11); 480 ps2_put_keycode(s, 0xe0); 481 ps2_put_keycode(s, 0x11); 482 } 483 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L | 484 MOD_SHIFT_R | MOD_CTRL_R)) { 485 if (key->down) { 486 ps2_put_keycode(s, 0xe0); 487 ps2_put_keycode(s, 0x7c); 488 } else { 489 ps2_put_keycode(s, 0xe0); 490 ps2_put_keycode(s, 0xf0); 491 ps2_put_keycode(s, 0x7c); 492 } 493 } else { 494 if (key->down) { 495 ps2_put_keycode(s, 0xe0); 496 ps2_put_keycode(s, 0x12); 497 ps2_put_keycode(s, 0xe0); 498 ps2_put_keycode(s, 0x7c); 499 } else { 500 ps2_put_keycode(s, 0xe0); 501 ps2_put_keycode(s, 0xf0); 502 ps2_put_keycode(s, 0x7c); 503 ps2_put_keycode(s, 0xe0); 504 ps2_put_keycode(s, 0xf0); 505 ps2_put_keycode(s, 0x12); 506 } 507 } 508 } else { 509 if (qcode < qemu_input_map_qcode_to_atset2_len) { 510 keycode = qemu_input_map_qcode_to_atset2[qcode]; 511 } 512 if (keycode) { 513 if (keycode & 0xff00) { 514 ps2_put_keycode(s, keycode >> 8); 515 } 516 if (!key->down) { 517 ps2_put_keycode(s, 0xf0); 518 } 519 ps2_put_keycode(s, keycode & 0xff); 520 } else { 521 qemu_log_mask(LOG_UNIMP, 522 "ps2: ignoring key with qcode %d\n", qcode); 523 } 524 } 525 } else if (s->scancode_set == 3) { 526 if (qcode < qemu_input_map_qcode_to_atset3_len) { 527 keycode = qemu_input_map_qcode_to_atset3[qcode]; 528 } 529 if (keycode) { 530 /* FIXME: break code should be configured on a key by key basis */ 531 if (!key->down) { 532 ps2_put_keycode(s, 0xf0); 533 } 534 ps2_put_keycode(s, keycode); 535 } else { 536 qemu_log_mask(LOG_UNIMP, 537 "ps2: ignoring key with qcode %d\n", qcode); 538 } 539 } 540 } 541 542 uint32_t ps2_read_data(PS2State *s) 543 { 544 PS2Queue *q; 545 int val, index; 546 547 trace_ps2_read_data(s); 548 q = &s->queue; 549 if (q->count == 0) { 550 /* 551 * NOTE: if no data left, we return the last keyboard one 552 * (needed for EMM386) 553 */ 554 /* XXX: need a timer to do things correctly */ 555 index = q->rptr - 1; 556 if (index < 0) { 557 index = PS2_BUFFER_SIZE - 1; 558 } 559 val = q->data[index]; 560 } else { 561 val = q->data[q->rptr]; 562 if (++q->rptr == PS2_BUFFER_SIZE) { 563 q->rptr = 0; 564 } 565 q->count--; 566 if (q->rptr == q->cwptr) { 567 /* command reply queue is empty */ 568 q->cwptr = -1; 569 } 570 /* reading deasserts IRQ */ 571 ps2_lower_irq(s); 572 /* reassert IRQs if data left */ 573 if (q->count) { 574 ps2_raise_irq(s); 575 } 576 } 577 return val; 578 } 579 580 static void ps2_set_ledstate(PS2KbdState *s, int ledstate) 581 { 582 trace_ps2_set_ledstate(s, ledstate); 583 s->ledstate = ledstate; 584 kbd_put_ledstate(ledstate); 585 } 586 587 static void ps2_reset_keyboard(PS2KbdState *s) 588 { 589 PS2State *ps2 = PS2_DEVICE(s); 590 591 trace_ps2_reset_keyboard(s); 592 s->scan_enabled = 1; 593 s->scancode_set = 2; 594 ps2_reset_queue(ps2); 595 ps2_set_ledstate(s, 0); 596 } 597 598 void ps2_write_keyboard(PS2KbdState *s, int val) 599 { 600 PS2State *ps2 = PS2_DEVICE(s); 601 602 trace_ps2_write_keyboard(s, val); 603 ps2_cqueue_reset(ps2); 604 switch (ps2->write_cmd) { 605 default: 606 case -1: 607 switch (val) { 608 case 0x00: 609 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 610 break; 611 case 0x05: 612 ps2_cqueue_1(ps2, KBD_REPLY_RESEND); 613 break; 614 case KBD_CMD_GET_ID: 615 /* We emulate a MF2 AT keyboard here */ 616 ps2_cqueue_3(ps2, KBD_REPLY_ACK, KBD_REPLY_ID, 617 s->translate ? 0x41 : 0x83); 618 break; 619 case KBD_CMD_ECHO: 620 ps2_cqueue_1(ps2, KBD_CMD_ECHO); 621 break; 622 case KBD_CMD_ENABLE: 623 s->scan_enabled = 1; 624 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 625 break; 626 case KBD_CMD_SCANCODE: 627 case KBD_CMD_SET_LEDS: 628 case KBD_CMD_SET_RATE: 629 case KBD_CMD_SET_MAKE_BREAK: 630 ps2->write_cmd = val; 631 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 632 break; 633 case KBD_CMD_RESET_DISABLE: 634 ps2_reset_keyboard(s); 635 s->scan_enabled = 0; 636 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 637 break; 638 case KBD_CMD_RESET_ENABLE: 639 ps2_reset_keyboard(s); 640 s->scan_enabled = 1; 641 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 642 break; 643 case KBD_CMD_RESET: 644 ps2_reset_keyboard(s); 645 ps2_cqueue_2(ps2, 646 KBD_REPLY_ACK, 647 KBD_REPLY_POR); 648 break; 649 case KBD_CMD_SET_TYPEMATIC: 650 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 651 break; 652 default: 653 ps2_cqueue_1(ps2, KBD_REPLY_RESEND); 654 break; 655 } 656 break; 657 case KBD_CMD_SET_MAKE_BREAK: 658 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 659 ps2->write_cmd = -1; 660 break; 661 case KBD_CMD_SCANCODE: 662 if (val == 0) { 663 ps2_cqueue_2(ps2, KBD_REPLY_ACK, s->translate ? 664 translate_table[s->scancode_set] : s->scancode_set); 665 } else if (val >= 1 && val <= 3) { 666 s->scancode_set = val; 667 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 668 } else { 669 ps2_cqueue_1(ps2, KBD_REPLY_RESEND); 670 } 671 ps2->write_cmd = -1; 672 break; 673 case KBD_CMD_SET_LEDS: 674 ps2_set_ledstate(s, val); 675 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 676 ps2->write_cmd = -1; 677 break; 678 case KBD_CMD_SET_RATE: 679 ps2_cqueue_1(ps2, KBD_REPLY_ACK); 680 ps2->write_cmd = -1; 681 break; 682 } 683 } 684 685 /* 686 * Set the scancode translation mode. 687 * 0 = raw scancodes. 688 * 1 = translated scancodes (used by qemu internally). 689 */ 690 691 void ps2_keyboard_set_translation(PS2KbdState *s, int mode) 692 { 693 trace_ps2_keyboard_set_translation(s, mode); 694 s->translate = mode; 695 } 696 697 static int ps2_mouse_send_packet(PS2MouseState *s) 698 { 699 PS2State *ps2 = PS2_DEVICE(s); 700 /* IMPS/2 and IMEX send 4 bytes, PS2 sends 3 bytes */ 701 const int needed = s->mouse_type ? 4 : 3; 702 unsigned int b; 703 int dx1, dy1, dz1, dw1; 704 705 if (PS2_QUEUE_SIZE - ps2->queue.count < needed) { 706 return 0; 707 } 708 709 dx1 = s->mouse_dx; 710 dy1 = s->mouse_dy; 711 dz1 = s->mouse_dz; 712 dw1 = s->mouse_dw; 713 /* XXX: increase range to 8 bits ? */ 714 if (dx1 > 127) { 715 dx1 = 127; 716 } else if (dx1 < -127) { 717 dx1 = -127; 718 } 719 if (dy1 > 127) { 720 dy1 = 127; 721 } else if (dy1 < -127) { 722 dy1 = -127; 723 } 724 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); 725 ps2_queue_noirq(ps2, b); 726 ps2_queue_noirq(ps2, dx1 & 0xff); 727 ps2_queue_noirq(ps2, dy1 & 0xff); 728 /* extra byte for IMPS/2 or IMEX */ 729 switch (s->mouse_type) { 730 default: 731 /* Just ignore the wheels if not supported */ 732 s->mouse_dz = 0; 733 s->mouse_dw = 0; 734 break; 735 case 3: 736 if (dz1 > 127) { 737 dz1 = 127; 738 } else if (dz1 < -127) { 739 dz1 = -127; 740 } 741 ps2_queue_noirq(ps2, dz1 & 0xff); 742 s->mouse_dz -= dz1; 743 s->mouse_dw = 0; 744 break; 745 case 4: 746 /* 747 * This matches what the Linux kernel expects for exps/2 in 748 * drivers/input/mouse/psmouse-base.c. Note, if you happen to 749 * press/release the 4th or 5th buttons at the same moment as a 750 * horizontal wheel scroll, those button presses will get lost. I'm not 751 * sure what to do about that, since by this point we don't know 752 * whether those buttons actually changed state. 753 */ 754 if (dw1 != 0) { 755 if (dw1 > 31) { 756 dw1 = 31; 757 } else if (dw1 < -31) { 758 dw1 = -31; 759 } 760 761 /* 762 * linux kernel expects first 6 bits to represent the value 763 * for horizontal scroll 764 */ 765 b = (dw1 & 0x3f) | 0x40; 766 s->mouse_dw -= dw1; 767 } else { 768 if (dz1 > 7) { 769 dz1 = 7; 770 } else if (dz1 < -7) { 771 dz1 = -7; 772 } 773 774 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); 775 s->mouse_dz -= dz1; 776 } 777 ps2_queue_noirq(ps2, b); 778 break; 779 } 780 781 ps2_raise_irq(ps2); 782 783 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b); 784 /* update deltas */ 785 s->mouse_dx -= dx1; 786 s->mouse_dy -= dy1; 787 788 return 1; 789 } 790 791 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, 792 InputEvent *evt) 793 { 794 static const int bmap[INPUT_BUTTON__MAX] = { 795 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT, 796 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE, 797 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT, 798 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE, 799 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA, 800 }; 801 PS2MouseState *s = (PS2MouseState *)dev; 802 InputMoveEvent *move; 803 InputBtnEvent *btn; 804 805 /* check if deltas are recorded when disabled */ 806 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) { 807 return; 808 } 809 810 switch (evt->type) { 811 case INPUT_EVENT_KIND_REL: 812 move = evt->u.rel.data; 813 if (move->axis == INPUT_AXIS_X) { 814 s->mouse_dx += move->value; 815 } else if (move->axis == INPUT_AXIS_Y) { 816 s->mouse_dy -= move->value; 817 } 818 break; 819 820 case INPUT_EVENT_KIND_BTN: 821 btn = evt->u.btn.data; 822 if (btn->down) { 823 s->mouse_buttons |= bmap[btn->button]; 824 if (btn->button == INPUT_BUTTON_WHEEL_UP) { 825 s->mouse_dz--; 826 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { 827 s->mouse_dz++; 828 } 829 830 if (btn->button == INPUT_BUTTON_WHEEL_RIGHT) { 831 s->mouse_dw--; 832 } else if (btn->button == INPUT_BUTTON_WHEEL_LEFT) { 833 s->mouse_dw++; 834 } 835 } else { 836 s->mouse_buttons &= ~bmap[btn->button]; 837 } 838 break; 839 840 default: 841 /* keep gcc happy */ 842 break; 843 } 844 } 845 846 static void ps2_mouse_sync(DeviceState *dev) 847 { 848 PS2MouseState *s = (PS2MouseState *)dev; 849 850 /* do not sync while disabled to prevent stream corruption */ 851 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) { 852 return; 853 } 854 855 if (s->mouse_buttons) { 856 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, NULL); 857 } 858 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) { 859 /* 860 * if not remote, send event. Multiple events are sent if 861 * too big deltas 862 */ 863 while (ps2_mouse_send_packet(s)) { 864 if (s->mouse_dx == 0 && s->mouse_dy == 0 865 && s->mouse_dz == 0 && s->mouse_dw == 0) { 866 break; 867 } 868 } 869 } 870 } 871 872 void ps2_mouse_fake_event(PS2MouseState *s) 873 { 874 trace_ps2_mouse_fake_event(s); 875 s->mouse_dx++; 876 ps2_mouse_sync(DEVICE(s)); 877 } 878 879 void ps2_write_mouse(PS2MouseState *s, int val) 880 { 881 PS2State *ps2 = PS2_DEVICE(s); 882 883 trace_ps2_write_mouse(s, val); 884 switch (ps2->write_cmd) { 885 default: 886 case -1: 887 /* mouse command */ 888 if (s->mouse_wrap) { 889 if (val == AUX_RESET_WRAP) { 890 s->mouse_wrap = 0; 891 ps2_queue(ps2, AUX_ACK); 892 return; 893 } else if (val != AUX_RESET) { 894 ps2_queue(ps2, val); 895 return; 896 } 897 } 898 switch (val) { 899 case AUX_SET_SCALE11: 900 s->mouse_status &= ~MOUSE_STATUS_SCALE21; 901 ps2_queue(ps2, AUX_ACK); 902 break; 903 case AUX_SET_SCALE21: 904 s->mouse_status |= MOUSE_STATUS_SCALE21; 905 ps2_queue(ps2, AUX_ACK); 906 break; 907 case AUX_SET_STREAM: 908 s->mouse_status &= ~MOUSE_STATUS_REMOTE; 909 ps2_queue(ps2, AUX_ACK); 910 break; 911 case AUX_SET_WRAP: 912 s->mouse_wrap = 1; 913 ps2_queue(ps2, AUX_ACK); 914 break; 915 case AUX_SET_REMOTE: 916 s->mouse_status |= MOUSE_STATUS_REMOTE; 917 ps2_queue(ps2, AUX_ACK); 918 break; 919 case AUX_GET_TYPE: 920 ps2_queue_2(ps2, 921 AUX_ACK, 922 s->mouse_type); 923 break; 924 case AUX_SET_RES: 925 case AUX_SET_SAMPLE: 926 ps2->write_cmd = val; 927 ps2_queue(ps2, AUX_ACK); 928 break; 929 case AUX_GET_SCALE: 930 ps2_queue_4(ps2, 931 AUX_ACK, 932 s->mouse_status, 933 s->mouse_resolution, 934 s->mouse_sample_rate); 935 break; 936 case AUX_POLL: 937 ps2_queue(ps2, AUX_ACK); 938 ps2_mouse_send_packet(s); 939 break; 940 case AUX_ENABLE_DEV: 941 s->mouse_status |= MOUSE_STATUS_ENABLED; 942 ps2_queue(ps2, AUX_ACK); 943 break; 944 case AUX_DISABLE_DEV: 945 s->mouse_status &= ~MOUSE_STATUS_ENABLED; 946 ps2_queue(ps2, AUX_ACK); 947 break; 948 case AUX_SET_DEFAULT: 949 s->mouse_sample_rate = 100; 950 s->mouse_resolution = 2; 951 s->mouse_status = 0; 952 ps2_queue(ps2, AUX_ACK); 953 break; 954 case AUX_RESET: 955 s->mouse_sample_rate = 100; 956 s->mouse_resolution = 2; 957 s->mouse_status = 0; 958 s->mouse_type = 0; 959 ps2_reset_queue(ps2); 960 ps2_queue_3(ps2, 961 AUX_ACK, 962 0xaa, 963 s->mouse_type); 964 break; 965 default: 966 break; 967 } 968 break; 969 case AUX_SET_SAMPLE: 970 s->mouse_sample_rate = val; 971 /* detect IMPS/2 or IMEX */ 972 switch (s->mouse_detect_state) { 973 default: 974 case 0: 975 if (val == 200) { 976 s->mouse_detect_state = 1; 977 } 978 break; 979 case 1: 980 if (val == 100) { 981 s->mouse_detect_state = 2; 982 } else if (val == 200) { 983 s->mouse_detect_state = 3; 984 } else { 985 s->mouse_detect_state = 0; 986 } 987 break; 988 case 2: 989 if (val == 80) { 990 s->mouse_type = 3; /* IMPS/2 */ 991 } 992 s->mouse_detect_state = 0; 993 break; 994 case 3: 995 if (val == 80) { 996 s->mouse_type = 4; /* IMEX */ 997 } 998 s->mouse_detect_state = 0; 999 break; 1000 } 1001 ps2_queue(ps2, AUX_ACK); 1002 ps2->write_cmd = -1; 1003 break; 1004 case AUX_SET_RES: 1005 s->mouse_resolution = val; 1006 ps2_queue(ps2, AUX_ACK); 1007 ps2->write_cmd = -1; 1008 break; 1009 } 1010 } 1011 1012 static void ps2_reset(DeviceState *dev) 1013 { 1014 PS2State *s = PS2_DEVICE(dev); 1015 1016 s->write_cmd = -1; 1017 ps2_reset_queue(s); 1018 ps2_lower_irq(s); 1019 } 1020 1021 static void ps2_common_post_load(PS2State *s) 1022 { 1023 PS2Queue *q = &s->queue; 1024 int ccount = 0; 1025 1026 /* limit the number of queued command replies to PS2_QUEUE_HEADROOM */ 1027 if (q->cwptr != -1) { 1028 ccount = (q->cwptr - q->rptr) & (PS2_BUFFER_SIZE - 1); 1029 if (ccount > PS2_QUEUE_HEADROOM) { 1030 ccount = PS2_QUEUE_HEADROOM; 1031 } 1032 } 1033 1034 /* limit the scancode queue size to PS2_QUEUE_SIZE */ 1035 if (q->count < ccount) { 1036 q->count = ccount; 1037 } else if (q->count > ccount + PS2_QUEUE_SIZE) { 1038 q->count = ccount + PS2_QUEUE_SIZE; 1039 } 1040 1041 /* sanitize rptr and recalculate wptr and cwptr */ 1042 q->rptr = q->rptr & (PS2_BUFFER_SIZE - 1); 1043 q->wptr = (q->rptr + q->count) & (PS2_BUFFER_SIZE - 1); 1044 q->cwptr = ccount ? (q->rptr + ccount) & (PS2_BUFFER_SIZE - 1) : -1; 1045 } 1046 1047 static void ps2_kbd_reset(DeviceState *dev) 1048 { 1049 PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(dev); 1050 PS2KbdState *s = PS2_KBD_DEVICE(dev); 1051 1052 trace_ps2_kbd_reset(s); 1053 ps2dc->parent_reset(dev); 1054 1055 s->scan_enabled = 1; 1056 s->translate = 0; 1057 s->scancode_set = 2; 1058 s->modifiers = 0; 1059 } 1060 1061 static void ps2_mouse_reset(DeviceState *dev) 1062 { 1063 PS2DeviceClass *ps2dc = PS2_DEVICE_GET_CLASS(dev); 1064 PS2MouseState *s = PS2_MOUSE_DEVICE(dev); 1065 1066 trace_ps2_mouse_reset(s); 1067 ps2dc->parent_reset(dev); 1068 1069 s->mouse_status = 0; 1070 s->mouse_resolution = 0; 1071 s->mouse_sample_rate = 0; 1072 s->mouse_wrap = 0; 1073 s->mouse_type = 0; 1074 s->mouse_detect_state = 0; 1075 s->mouse_dx = 0; 1076 s->mouse_dy = 0; 1077 s->mouse_dz = 0; 1078 s->mouse_dw = 0; 1079 s->mouse_buttons = 0; 1080 } 1081 1082 static const VMStateDescription vmstate_ps2_common = { 1083 .name = "PS2 Common State", 1084 .version_id = 3, 1085 .minimum_version_id = 2, 1086 .fields = (VMStateField[]) { 1087 VMSTATE_INT32(write_cmd, PS2State), 1088 VMSTATE_INT32(queue.rptr, PS2State), 1089 VMSTATE_INT32(queue.wptr, PS2State), 1090 VMSTATE_INT32(queue.count, PS2State), 1091 VMSTATE_BUFFER(queue.data, PS2State), 1092 VMSTATE_END_OF_LIST() 1093 } 1094 }; 1095 1096 static bool ps2_keyboard_ledstate_needed(void *opaque) 1097 { 1098 PS2KbdState *s = opaque; 1099 1100 return s->ledstate != 0; /* 0 is default state */ 1101 } 1102 1103 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id) 1104 { 1105 PS2KbdState *s = opaque; 1106 1107 kbd_put_ledstate(s->ledstate); 1108 return 0; 1109 } 1110 1111 static const VMStateDescription vmstate_ps2_keyboard_ledstate = { 1112 .name = "ps2kbd/ledstate", 1113 .version_id = 3, 1114 .minimum_version_id = 2, 1115 .post_load = ps2_kbd_ledstate_post_load, 1116 .needed = ps2_keyboard_ledstate_needed, 1117 .fields = (VMStateField[]) { 1118 VMSTATE_INT32(ledstate, PS2KbdState), 1119 VMSTATE_END_OF_LIST() 1120 } 1121 }; 1122 1123 static bool ps2_keyboard_need_high_bit_needed(void *opaque) 1124 { 1125 PS2KbdState *s = opaque; 1126 return s->need_high_bit != 0; /* 0 is the usual state */ 1127 } 1128 1129 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = { 1130 .name = "ps2kbd/need_high_bit", 1131 .version_id = 1, 1132 .minimum_version_id = 1, 1133 .needed = ps2_keyboard_need_high_bit_needed, 1134 .fields = (VMStateField[]) { 1135 VMSTATE_BOOL(need_high_bit, PS2KbdState), 1136 VMSTATE_END_OF_LIST() 1137 } 1138 }; 1139 1140 static bool ps2_keyboard_cqueue_needed(void *opaque) 1141 { 1142 PS2KbdState *s = opaque; 1143 PS2State *ps2 = PS2_DEVICE(s); 1144 1145 return ps2->queue.cwptr != -1; /* the queue is mostly empty */ 1146 } 1147 1148 static const VMStateDescription vmstate_ps2_keyboard_cqueue = { 1149 .name = "ps2kbd/command_reply_queue", 1150 .needed = ps2_keyboard_cqueue_needed, 1151 .fields = (VMStateField[]) { 1152 VMSTATE_INT32(parent_obj.queue.cwptr, PS2KbdState), 1153 VMSTATE_END_OF_LIST() 1154 } 1155 }; 1156 1157 static int ps2_kbd_post_load(void *opaque, int version_id) 1158 { 1159 PS2KbdState *s = (PS2KbdState *)opaque; 1160 PS2State *ps2 = PS2_DEVICE(s); 1161 1162 if (version_id == 2) { 1163 s->scancode_set = 2; 1164 } 1165 1166 ps2_common_post_load(ps2); 1167 1168 return 0; 1169 } 1170 1171 static const VMStateDescription vmstate_ps2_keyboard = { 1172 .name = "ps2kbd", 1173 .version_id = 3, 1174 .minimum_version_id = 2, 1175 .post_load = ps2_kbd_post_load, 1176 .fields = (VMStateField[]) { 1177 VMSTATE_STRUCT(parent_obj, PS2KbdState, 0, vmstate_ps2_common, 1178 PS2State), 1179 VMSTATE_INT32(scan_enabled, PS2KbdState), 1180 VMSTATE_INT32(translate, PS2KbdState), 1181 VMSTATE_INT32_V(scancode_set, PS2KbdState, 3), 1182 VMSTATE_END_OF_LIST() 1183 }, 1184 .subsections = (const VMStateDescription * []) { 1185 &vmstate_ps2_keyboard_ledstate, 1186 &vmstate_ps2_keyboard_need_high_bit, 1187 &vmstate_ps2_keyboard_cqueue, 1188 NULL 1189 } 1190 }; 1191 1192 static int ps2_mouse_post_load(void *opaque, int version_id) 1193 { 1194 PS2MouseState *s = (PS2MouseState *)opaque; 1195 PS2State *ps2 = PS2_DEVICE(s); 1196 1197 ps2_common_post_load(ps2); 1198 1199 return 0; 1200 } 1201 1202 static const VMStateDescription vmstate_ps2_mouse = { 1203 .name = "ps2mouse", 1204 .version_id = 2, 1205 .minimum_version_id = 2, 1206 .post_load = ps2_mouse_post_load, 1207 .fields = (VMStateField[]) { 1208 VMSTATE_STRUCT(parent_obj, PS2MouseState, 0, vmstate_ps2_common, 1209 PS2State), 1210 VMSTATE_UINT8(mouse_status, PS2MouseState), 1211 VMSTATE_UINT8(mouse_resolution, PS2MouseState), 1212 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState), 1213 VMSTATE_UINT8(mouse_wrap, PS2MouseState), 1214 VMSTATE_UINT8(mouse_type, PS2MouseState), 1215 VMSTATE_UINT8(mouse_detect_state, PS2MouseState), 1216 VMSTATE_INT32(mouse_dx, PS2MouseState), 1217 VMSTATE_INT32(mouse_dy, PS2MouseState), 1218 VMSTATE_INT32(mouse_dz, PS2MouseState), 1219 VMSTATE_UINT8(mouse_buttons, PS2MouseState), 1220 VMSTATE_END_OF_LIST() 1221 } 1222 }; 1223 1224 static QemuInputHandler ps2_keyboard_handler = { 1225 .name = "QEMU PS/2 Keyboard", 1226 .mask = INPUT_EVENT_MASK_KEY, 1227 .event = ps2_keyboard_event, 1228 }; 1229 1230 static void ps2_kbd_realize(DeviceState *dev, Error **errp) 1231 { 1232 qemu_input_handler_register(dev, &ps2_keyboard_handler); 1233 } 1234 1235 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) 1236 { 1237 DeviceState *dev; 1238 PS2KbdState *s; 1239 PS2State *ps2; 1240 1241 dev = qdev_new(TYPE_PS2_KBD_DEVICE); 1242 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1243 s = PS2_KBD_DEVICE(dev); 1244 ps2 = PS2_DEVICE(s); 1245 1246 trace_ps2_kbd_init(s); 1247 ps2->update_irq = update_irq; 1248 ps2->update_arg = update_arg; 1249 1250 return s; 1251 } 1252 1253 static QemuInputHandler ps2_mouse_handler = { 1254 .name = "QEMU PS/2 Mouse", 1255 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL, 1256 .event = ps2_mouse_event, 1257 .sync = ps2_mouse_sync, 1258 }; 1259 1260 static void ps2_mouse_realize(DeviceState *dev, Error **errp) 1261 { 1262 qemu_input_handler_register(dev, &ps2_mouse_handler); 1263 } 1264 1265 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) 1266 { 1267 DeviceState *dev; 1268 PS2MouseState *s; 1269 PS2State *ps2; 1270 1271 dev = qdev_new(TYPE_PS2_MOUSE_DEVICE); 1272 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1273 s = PS2_MOUSE_DEVICE(dev); 1274 ps2 = PS2_DEVICE(s); 1275 1276 trace_ps2_mouse_init(s); 1277 ps2->update_irq = update_irq; 1278 ps2->update_arg = update_arg; 1279 return s; 1280 } 1281 1282 static void ps2_kbd_class_init(ObjectClass *klass, void *data) 1283 { 1284 DeviceClass *dc = DEVICE_CLASS(klass); 1285 PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass); 1286 1287 dc->realize = ps2_kbd_realize; 1288 device_class_set_parent_reset(dc, ps2_kbd_reset, &ps2dc->parent_reset); 1289 dc->vmsd = &vmstate_ps2_keyboard; 1290 } 1291 1292 static const TypeInfo ps2_kbd_info = { 1293 .name = TYPE_PS2_KBD_DEVICE, 1294 .parent = TYPE_PS2_DEVICE, 1295 .instance_size = sizeof(PS2KbdState), 1296 .class_init = ps2_kbd_class_init 1297 }; 1298 1299 static void ps2_mouse_class_init(ObjectClass *klass, void *data) 1300 { 1301 DeviceClass *dc = DEVICE_CLASS(klass); 1302 PS2DeviceClass *ps2dc = PS2_DEVICE_CLASS(klass); 1303 1304 dc->realize = ps2_mouse_realize; 1305 device_class_set_parent_reset(dc, ps2_mouse_reset, 1306 &ps2dc->parent_reset); 1307 dc->vmsd = &vmstate_ps2_mouse; 1308 } 1309 1310 static const TypeInfo ps2_mouse_info = { 1311 .name = TYPE_PS2_MOUSE_DEVICE, 1312 .parent = TYPE_PS2_DEVICE, 1313 .instance_size = sizeof(PS2MouseState), 1314 .class_init = ps2_mouse_class_init 1315 }; 1316 1317 static void ps2_init(Object *obj) 1318 { 1319 PS2State *s = PS2_DEVICE(obj); 1320 1321 qdev_init_gpio_out(DEVICE(obj), &s->irq, 1); 1322 } 1323 1324 static void ps2_class_init(ObjectClass *klass, void *data) 1325 { 1326 DeviceClass *dc = DEVICE_CLASS(klass); 1327 1328 dc->reset = ps2_reset; 1329 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); 1330 } 1331 1332 static const TypeInfo ps2_info = { 1333 .name = TYPE_PS2_DEVICE, 1334 .parent = TYPE_SYS_BUS_DEVICE, 1335 .instance_init = ps2_init, 1336 .instance_size = sizeof(PS2State), 1337 .class_init = ps2_class_init, 1338 .class_size = sizeof(PS2DeviceClass), 1339 .abstract = true 1340 }; 1341 1342 static void ps2_register_types(void) 1343 { 1344 type_register_static(&ps2_info); 1345 type_register_static(&ps2_kbd_info); 1346 type_register_static(&ps2_mouse_info); 1347 } 1348 1349 type_init(ps2_register_types) 1350