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