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