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