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