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 #include "qemu/osdep.h" 25 #include "qemu/log.h" 26 #include "hw/hw.h" 27 #include "hw/input/ps2.h" 28 #include "ui/console.h" 29 #include "ui/input.h" 30 #include "sysemu/sysemu.h" 31 32 #include "trace.h" 33 34 /* debug PC keyboard */ 35 //#define DEBUG_KBD 36 37 /* debug PC keyboard : only mouse */ 38 //#define DEBUG_MOUSE 39 40 /* Keyboard Commands */ 41 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ 42 #define KBD_CMD_ECHO 0xEE 43 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */ 44 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */ 45 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ 46 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ 47 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */ 48 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */ 49 #define KBD_CMD_RESET 0xFF /* Reset */ 50 51 /* Keyboard Replies */ 52 #define KBD_REPLY_POR 0xAA /* Power on reset */ 53 #define KBD_REPLY_ID 0xAB /* Keyboard ID */ 54 #define KBD_REPLY_ACK 0xFA /* Command ACK */ 55 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ 56 57 /* Mouse Commands */ 58 #define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */ 59 #define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */ 60 #define AUX_SET_RES 0xE8 /* Set resolution */ 61 #define AUX_GET_SCALE 0xE9 /* Get scaling factor */ 62 #define AUX_SET_STREAM 0xEA /* Set stream mode */ 63 #define AUX_POLL 0xEB /* Poll */ 64 #define AUX_RESET_WRAP 0xEC /* Reset wrap mode */ 65 #define AUX_SET_WRAP 0xEE /* Set wrap mode */ 66 #define AUX_SET_REMOTE 0xF0 /* Set remote mode */ 67 #define AUX_GET_TYPE 0xF2 /* Get type */ 68 #define AUX_SET_SAMPLE 0xF3 /* Set sample rate */ 69 #define AUX_ENABLE_DEV 0xF4 /* Enable aux device */ 70 #define AUX_DISABLE_DEV 0xF5 /* Disable aux device */ 71 #define AUX_SET_DEFAULT 0xF6 72 #define AUX_RESET 0xFF /* Reset aux device */ 73 #define AUX_ACK 0xFA /* Command byte ACK. */ 74 75 #define MOUSE_STATUS_REMOTE 0x40 76 #define MOUSE_STATUS_ENABLED 0x20 77 #define MOUSE_STATUS_SCALE21 0x10 78 79 #define PS2_QUEUE_SIZE 16 /* Buffer size required by PS/2 protocol */ 80 81 /* Bits for 'modifiers' field in PS2KbdState */ 82 #define MOD_CTRL_L (1 << 0) 83 #define MOD_SHIFT_L (1 << 1) 84 #define MOD_ALT_L (1 << 2) 85 #define MOD_CTRL_R (1 << 3) 86 #define MOD_SHIFT_R (1 << 4) 87 #define MOD_ALT_R (1 << 5) 88 89 typedef struct { 90 /* Keep the data array 256 bytes long, which compatibility 91 with older qemu versions. */ 92 uint8_t data[256]; 93 int rptr, wptr, count; 94 } PS2Queue; 95 96 struct PS2State { 97 PS2Queue queue; 98 int32_t write_cmd; 99 void (*update_irq)(void *, int); 100 void *update_arg; 101 }; 102 103 typedef struct { 104 PS2State common; 105 int scan_enabled; 106 int translate; 107 int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */ 108 int ledstate; 109 bool need_high_bit; 110 unsigned int modifiers; /* bitmask of MOD_* constants above */ 111 } PS2KbdState; 112 113 typedef struct { 114 PS2State common; 115 uint8_t mouse_status; 116 uint8_t mouse_resolution; 117 uint8_t mouse_sample_rate; 118 uint8_t mouse_wrap; 119 uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */ 120 uint8_t mouse_detect_state; 121 int mouse_dx; /* current values, needed for 'poll' mode */ 122 int mouse_dy; 123 int mouse_dz; 124 uint8_t mouse_buttons; 125 } PS2MouseState; 126 127 /* Table to convert from QEMU codes to scancodes. */ 128 static const uint16_t qcode_to_keycode_set1[Q_KEY_CODE__MAX] = { 129 [0 ... Q_KEY_CODE__MAX - 1] = 0, 130 131 [Q_KEY_CODE_A] = 0x1e, 132 [Q_KEY_CODE_B] = 0x30, 133 [Q_KEY_CODE_C] = 0x2e, 134 [Q_KEY_CODE_D] = 0x20, 135 [Q_KEY_CODE_E] = 0x12, 136 [Q_KEY_CODE_F] = 0x21, 137 [Q_KEY_CODE_G] = 0x22, 138 [Q_KEY_CODE_H] = 0x23, 139 [Q_KEY_CODE_I] = 0x17, 140 [Q_KEY_CODE_J] = 0x24, 141 [Q_KEY_CODE_K] = 0x25, 142 [Q_KEY_CODE_L] = 0x26, 143 [Q_KEY_CODE_M] = 0x32, 144 [Q_KEY_CODE_N] = 0x31, 145 [Q_KEY_CODE_O] = 0x18, 146 [Q_KEY_CODE_P] = 0x19, 147 [Q_KEY_CODE_Q] = 0x10, 148 [Q_KEY_CODE_R] = 0x13, 149 [Q_KEY_CODE_S] = 0x1f, 150 [Q_KEY_CODE_T] = 0x14, 151 [Q_KEY_CODE_U] = 0x16, 152 [Q_KEY_CODE_V] = 0x2f, 153 [Q_KEY_CODE_W] = 0x11, 154 [Q_KEY_CODE_X] = 0x2d, 155 [Q_KEY_CODE_Y] = 0x15, 156 [Q_KEY_CODE_Z] = 0x2c, 157 [Q_KEY_CODE_0] = 0x0b, 158 [Q_KEY_CODE_1] = 0x02, 159 [Q_KEY_CODE_2] = 0x03, 160 [Q_KEY_CODE_3] = 0x04, 161 [Q_KEY_CODE_4] = 0x05, 162 [Q_KEY_CODE_5] = 0x06, 163 [Q_KEY_CODE_6] = 0x07, 164 [Q_KEY_CODE_7] = 0x08, 165 [Q_KEY_CODE_8] = 0x09, 166 [Q_KEY_CODE_9] = 0x0a, 167 [Q_KEY_CODE_GRAVE_ACCENT] = 0x29, 168 [Q_KEY_CODE_MINUS] = 0x0c, 169 [Q_KEY_CODE_EQUAL] = 0x0d, 170 [Q_KEY_CODE_BACKSLASH] = 0x2b, 171 [Q_KEY_CODE_BACKSPACE] = 0x0e, 172 [Q_KEY_CODE_SPC] = 0x39, 173 [Q_KEY_CODE_TAB] = 0x0f, 174 [Q_KEY_CODE_CAPS_LOCK] = 0x3a, 175 [Q_KEY_CODE_SHIFT] = 0x2a, 176 [Q_KEY_CODE_CTRL] = 0x1d, 177 [Q_KEY_CODE_META_L] = 0xe05b, 178 [Q_KEY_CODE_ALT] = 0x38, 179 [Q_KEY_CODE_SHIFT_R] = 0x36, 180 [Q_KEY_CODE_CTRL_R] = 0xe01d, 181 [Q_KEY_CODE_META_R] = 0xe05c, 182 [Q_KEY_CODE_ALT_R] = 0xe038, 183 [Q_KEY_CODE_MENU] = 0xe05d, 184 [Q_KEY_CODE_RET] = 0x1c, 185 [Q_KEY_CODE_ESC] = 0x01, 186 [Q_KEY_CODE_F1] = 0x3b, 187 [Q_KEY_CODE_F2] = 0x3c, 188 [Q_KEY_CODE_F3] = 0x3d, 189 [Q_KEY_CODE_F4] = 0x3e, 190 [Q_KEY_CODE_F5] = 0x3f, 191 [Q_KEY_CODE_F6] = 0x40, 192 [Q_KEY_CODE_F7] = 0x41, 193 [Q_KEY_CODE_F8] = 0x42, 194 [Q_KEY_CODE_F9] = 0x43, 195 [Q_KEY_CODE_F10] = 0x44, 196 [Q_KEY_CODE_F11] = 0x57, 197 [Q_KEY_CODE_F12] = 0x58, 198 /* special handling for Q_KEY_CODE_PRINT */ 199 [Q_KEY_CODE_SCROLL_LOCK] = 0x46, 200 /* special handling for Q_KEY_CODE_PAUSE */ 201 [Q_KEY_CODE_BRACKET_LEFT] = 0x1a, 202 [Q_KEY_CODE_INSERT] = 0xe052, 203 [Q_KEY_CODE_HOME] = 0xe047, 204 [Q_KEY_CODE_PGUP] = 0xe049, 205 [Q_KEY_CODE_DELETE] = 0xe053, 206 [Q_KEY_CODE_END] = 0xe04f, 207 [Q_KEY_CODE_PGDN] = 0xe051, 208 [Q_KEY_CODE_UP] = 0xe048, 209 [Q_KEY_CODE_LEFT] = 0xe04b, 210 [Q_KEY_CODE_DOWN] = 0xe050, 211 [Q_KEY_CODE_RIGHT] = 0xe04d, 212 [Q_KEY_CODE_NUM_LOCK] = 0x45, 213 [Q_KEY_CODE_KP_DIVIDE] = 0xe035, 214 [Q_KEY_CODE_KP_MULTIPLY] = 0x37, 215 [Q_KEY_CODE_KP_SUBTRACT] = 0x4a, 216 [Q_KEY_CODE_KP_ADD] = 0x4e, 217 [Q_KEY_CODE_KP_ENTER] = 0xe01c, 218 [Q_KEY_CODE_KP_DECIMAL] = 0x53, 219 [Q_KEY_CODE_KP_0] = 0x52, 220 [Q_KEY_CODE_KP_1] = 0x4f, 221 [Q_KEY_CODE_KP_2] = 0x50, 222 [Q_KEY_CODE_KP_3] = 0x51, 223 [Q_KEY_CODE_KP_4] = 0x4b, 224 [Q_KEY_CODE_KP_5] = 0x4c, 225 [Q_KEY_CODE_KP_6] = 0x4d, 226 [Q_KEY_CODE_KP_7] = 0x47, 227 [Q_KEY_CODE_KP_8] = 0x48, 228 [Q_KEY_CODE_KP_9] = 0x49, 229 [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b, 230 [Q_KEY_CODE_SEMICOLON] = 0x27, 231 [Q_KEY_CODE_APOSTROPHE] = 0x28, 232 [Q_KEY_CODE_COMMA] = 0x33, 233 [Q_KEY_CODE_DOT] = 0x34, 234 [Q_KEY_CODE_SLASH] = 0x35, 235 236 [Q_KEY_CODE_POWER] = 0x0e5e, 237 [Q_KEY_CODE_SLEEP] = 0x0e5f, 238 [Q_KEY_CODE_WAKE] = 0x0e63, 239 240 [Q_KEY_CODE_AUDIONEXT] = 0xe019, 241 [Q_KEY_CODE_AUDIOPREV] = 0xe010, 242 [Q_KEY_CODE_AUDIOSTOP] = 0xe024, 243 [Q_KEY_CODE_AUDIOPLAY] = 0xe022, 244 [Q_KEY_CODE_AUDIOMUTE] = 0xe020, 245 [Q_KEY_CODE_VOLUMEUP] = 0xe030, 246 [Q_KEY_CODE_VOLUMEDOWN] = 0xe02e, 247 [Q_KEY_CODE_MEDIASELECT] = 0xe06d, 248 [Q_KEY_CODE_MAIL] = 0xe06c, 249 [Q_KEY_CODE_CALCULATOR] = 0xe021, 250 [Q_KEY_CODE_COMPUTER] = 0xe06b, 251 [Q_KEY_CODE_FIND] = 0xe065, 252 [Q_KEY_CODE_AC_HOME] = 0xe032, 253 [Q_KEY_CODE_AC_BACK] = 0xe06a, 254 [Q_KEY_CODE_AC_FORWARD] = 0xe069, 255 [Q_KEY_CODE_STOP] = 0xe068, 256 [Q_KEY_CODE_AC_REFRESH] = 0xe067, 257 [Q_KEY_CODE_AC_BOOKMARKS] = 0xe066, 258 259 [Q_KEY_CODE_ASTERISK] = 0x37, 260 [Q_KEY_CODE_LESS] = 0x56, 261 [Q_KEY_CODE_RO] = 0x73, 262 [Q_KEY_CODE_HIRAGANA] = 0x70, 263 [Q_KEY_CODE_HENKAN] = 0x79, 264 [Q_KEY_CODE_YEN] = 0x7d, 265 [Q_KEY_CODE_KP_COMMA] = 0x7e, 266 }; 267 268 static const uint16_t qcode_to_keycode_set2[Q_KEY_CODE__MAX] = { 269 [0 ... Q_KEY_CODE__MAX - 1] = 0, 270 271 [Q_KEY_CODE_A] = 0x1c, 272 [Q_KEY_CODE_B] = 0x32, 273 [Q_KEY_CODE_C] = 0x21, 274 [Q_KEY_CODE_D] = 0x23, 275 [Q_KEY_CODE_E] = 0x24, 276 [Q_KEY_CODE_F] = 0x2b, 277 [Q_KEY_CODE_G] = 0x34, 278 [Q_KEY_CODE_H] = 0x33, 279 [Q_KEY_CODE_I] = 0x43, 280 [Q_KEY_CODE_J] = 0x3b, 281 [Q_KEY_CODE_K] = 0x42, 282 [Q_KEY_CODE_L] = 0x4b, 283 [Q_KEY_CODE_M] = 0x3a, 284 [Q_KEY_CODE_N] = 0x31, 285 [Q_KEY_CODE_O] = 0x44, 286 [Q_KEY_CODE_P] = 0x4d, 287 [Q_KEY_CODE_Q] = 0x15, 288 [Q_KEY_CODE_R] = 0x2d, 289 [Q_KEY_CODE_S] = 0x1b, 290 [Q_KEY_CODE_T] = 0x2c, 291 [Q_KEY_CODE_U] = 0x3c, 292 [Q_KEY_CODE_V] = 0x2a, 293 [Q_KEY_CODE_W] = 0x1d, 294 [Q_KEY_CODE_X] = 0x22, 295 [Q_KEY_CODE_Y] = 0x35, 296 [Q_KEY_CODE_Z] = 0x1a, 297 [Q_KEY_CODE_0] = 0x45, 298 [Q_KEY_CODE_1] = 0x16, 299 [Q_KEY_CODE_2] = 0x1e, 300 [Q_KEY_CODE_3] = 0x26, 301 [Q_KEY_CODE_4] = 0x25, 302 [Q_KEY_CODE_5] = 0x2e, 303 [Q_KEY_CODE_6] = 0x36, 304 [Q_KEY_CODE_7] = 0x3d, 305 [Q_KEY_CODE_8] = 0x3e, 306 [Q_KEY_CODE_9] = 0x46, 307 [Q_KEY_CODE_GRAVE_ACCENT] = 0x0e, 308 [Q_KEY_CODE_MINUS] = 0x4e, 309 [Q_KEY_CODE_EQUAL] = 0x55, 310 [Q_KEY_CODE_BACKSLASH] = 0x5d, 311 [Q_KEY_CODE_BACKSPACE] = 0x66, 312 [Q_KEY_CODE_SPC] = 0x29, 313 [Q_KEY_CODE_TAB] = 0x0d, 314 [Q_KEY_CODE_CAPS_LOCK] = 0x58, 315 [Q_KEY_CODE_SHIFT] = 0x12, 316 [Q_KEY_CODE_CTRL] = 0x14, 317 [Q_KEY_CODE_META_L] = 0xe01f, 318 [Q_KEY_CODE_ALT] = 0x11, 319 [Q_KEY_CODE_SHIFT_R] = 0x59, 320 [Q_KEY_CODE_CTRL_R] = 0xe014, 321 [Q_KEY_CODE_META_R] = 0xe027, 322 [Q_KEY_CODE_ALT_R] = 0xe011, 323 [Q_KEY_CODE_MENU] = 0xe02f, 324 [Q_KEY_CODE_RET] = 0x5a, 325 [Q_KEY_CODE_ESC] = 0x76, 326 [Q_KEY_CODE_F1] = 0x05, 327 [Q_KEY_CODE_F2] = 0x06, 328 [Q_KEY_CODE_F3] = 0x04, 329 [Q_KEY_CODE_F4] = 0x0c, 330 [Q_KEY_CODE_F5] = 0x03, 331 [Q_KEY_CODE_F6] = 0x0b, 332 [Q_KEY_CODE_F7] = 0x83, 333 [Q_KEY_CODE_F8] = 0x0a, 334 [Q_KEY_CODE_F9] = 0x01, 335 [Q_KEY_CODE_F10] = 0x09, 336 [Q_KEY_CODE_F11] = 0x78, 337 [Q_KEY_CODE_F12] = 0x07, 338 /* special handling for Q_KEY_CODE_PRINT */ 339 [Q_KEY_CODE_SCROLL_LOCK] = 0x7e, 340 /* special handling for Q_KEY_CODE_PAUSE */ 341 [Q_KEY_CODE_BRACKET_LEFT] = 0x54, 342 [Q_KEY_CODE_INSERT] = 0xe070, 343 [Q_KEY_CODE_HOME] = 0xe06c, 344 [Q_KEY_CODE_PGUP] = 0xe07d, 345 [Q_KEY_CODE_DELETE] = 0xe071, 346 [Q_KEY_CODE_END] = 0xe069, 347 [Q_KEY_CODE_PGDN] = 0xe07a, 348 [Q_KEY_CODE_UP] = 0xe075, 349 [Q_KEY_CODE_LEFT] = 0xe06b, 350 [Q_KEY_CODE_DOWN] = 0xe072, 351 [Q_KEY_CODE_RIGHT] = 0xe074, 352 [Q_KEY_CODE_NUM_LOCK] = 0x77, 353 [Q_KEY_CODE_KP_DIVIDE] = 0xe04a, 354 [Q_KEY_CODE_KP_MULTIPLY] = 0x7c, 355 [Q_KEY_CODE_KP_SUBTRACT] = 0x7b, 356 [Q_KEY_CODE_KP_ADD] = 0x79, 357 [Q_KEY_CODE_KP_ENTER] = 0xe05a, 358 [Q_KEY_CODE_KP_DECIMAL] = 0x71, 359 [Q_KEY_CODE_KP_0] = 0x70, 360 [Q_KEY_CODE_KP_1] = 0x69, 361 [Q_KEY_CODE_KP_2] = 0x72, 362 [Q_KEY_CODE_KP_3] = 0x7a, 363 [Q_KEY_CODE_KP_4] = 0x6b, 364 [Q_KEY_CODE_KP_5] = 0x73, 365 [Q_KEY_CODE_KP_6] = 0x74, 366 [Q_KEY_CODE_KP_7] = 0x6c, 367 [Q_KEY_CODE_KP_8] = 0x75, 368 [Q_KEY_CODE_KP_9] = 0x7d, 369 [Q_KEY_CODE_BRACKET_RIGHT] = 0x5b, 370 [Q_KEY_CODE_SEMICOLON] = 0x4c, 371 [Q_KEY_CODE_APOSTROPHE] = 0x52, 372 [Q_KEY_CODE_COMMA] = 0x41, 373 [Q_KEY_CODE_DOT] = 0x49, 374 [Q_KEY_CODE_SLASH] = 0x4a, 375 376 [Q_KEY_CODE_POWER] = 0x0e37, 377 [Q_KEY_CODE_SLEEP] = 0x0e3f, 378 [Q_KEY_CODE_WAKE] = 0x0e5e, 379 380 [Q_KEY_CODE_AUDIONEXT] = 0xe04d, 381 [Q_KEY_CODE_AUDIOPREV] = 0xe015, 382 [Q_KEY_CODE_AUDIOSTOP] = 0xe03b, 383 [Q_KEY_CODE_AUDIOPLAY] = 0xe034, 384 [Q_KEY_CODE_AUDIOMUTE] = 0xe023, 385 [Q_KEY_CODE_VOLUMEUP] = 0xe032, 386 [Q_KEY_CODE_VOLUMEDOWN] = 0xe021, 387 [Q_KEY_CODE_MEDIASELECT] = 0xe050, 388 [Q_KEY_CODE_MAIL] = 0xe048, 389 [Q_KEY_CODE_CALCULATOR] = 0xe02b, 390 [Q_KEY_CODE_COMPUTER] = 0xe040, 391 [Q_KEY_CODE_FIND] = 0xe010, 392 [Q_KEY_CODE_AC_HOME] = 0xe03a, 393 [Q_KEY_CODE_AC_BACK] = 0xe038, 394 [Q_KEY_CODE_AC_FORWARD] = 0xe030, 395 [Q_KEY_CODE_STOP] = 0xe028, 396 [Q_KEY_CODE_AC_REFRESH] = 0xe020, 397 [Q_KEY_CODE_AC_BOOKMARKS] = 0xe018, 398 399 [Q_KEY_CODE_ASTERISK] = 0x7c, 400 [Q_KEY_CODE_LESS] = 0x61, 401 [Q_KEY_CODE_SYSRQ] = 0x7f, 402 [Q_KEY_CODE_RO] = 0x51, 403 [Q_KEY_CODE_HIRAGANA] = 0x13, 404 [Q_KEY_CODE_HENKAN] = 0x64, 405 [Q_KEY_CODE_YEN] = 0x6a, 406 [Q_KEY_CODE_KP_COMMA] = 0x6d, 407 }; 408 409 static const uint16_t qcode_to_keycode_set3[Q_KEY_CODE__MAX] = { 410 [0 ... Q_KEY_CODE__MAX - 1] = 0, 411 412 [Q_KEY_CODE_A] = 0x1c, 413 [Q_KEY_CODE_B] = 0x32, 414 [Q_KEY_CODE_C] = 0x21, 415 [Q_KEY_CODE_D] = 0x23, 416 [Q_KEY_CODE_E] = 0x24, 417 [Q_KEY_CODE_F] = 0x2b, 418 [Q_KEY_CODE_G] = 0x34, 419 [Q_KEY_CODE_H] = 0x33, 420 [Q_KEY_CODE_I] = 0x43, 421 [Q_KEY_CODE_J] = 0x3b, 422 [Q_KEY_CODE_K] = 0x42, 423 [Q_KEY_CODE_L] = 0x4b, 424 [Q_KEY_CODE_M] = 0x3a, 425 [Q_KEY_CODE_N] = 0x31, 426 [Q_KEY_CODE_O] = 0x44, 427 [Q_KEY_CODE_P] = 0x4d, 428 [Q_KEY_CODE_Q] = 0x15, 429 [Q_KEY_CODE_R] = 0x2d, 430 [Q_KEY_CODE_S] = 0x1b, 431 [Q_KEY_CODE_T] = 0x2c, 432 [Q_KEY_CODE_U] = 0x3c, 433 [Q_KEY_CODE_V] = 0x2a, 434 [Q_KEY_CODE_W] = 0x1d, 435 [Q_KEY_CODE_X] = 0x22, 436 [Q_KEY_CODE_Y] = 0x35, 437 [Q_KEY_CODE_Z] = 0x1a, 438 [Q_KEY_CODE_0] = 0x45, 439 [Q_KEY_CODE_1] = 0x16, 440 [Q_KEY_CODE_2] = 0x1e, 441 [Q_KEY_CODE_3] = 0x26, 442 [Q_KEY_CODE_4] = 0x25, 443 [Q_KEY_CODE_5] = 0x2e, 444 [Q_KEY_CODE_6] = 0x36, 445 [Q_KEY_CODE_7] = 0x3d, 446 [Q_KEY_CODE_8] = 0x3e, 447 [Q_KEY_CODE_9] = 0x46, 448 [Q_KEY_CODE_GRAVE_ACCENT] = 0x0e, 449 [Q_KEY_CODE_MINUS] = 0x4e, 450 [Q_KEY_CODE_EQUAL] = 0x55, 451 [Q_KEY_CODE_BACKSLASH] = 0x5c, 452 [Q_KEY_CODE_BACKSPACE] = 0x66, 453 [Q_KEY_CODE_SPC] = 0x29, 454 [Q_KEY_CODE_TAB] = 0x0d, 455 [Q_KEY_CODE_CAPS_LOCK] = 0x14, 456 [Q_KEY_CODE_SHIFT] = 0x12, 457 [Q_KEY_CODE_CTRL] = 0x11, 458 [Q_KEY_CODE_META_L] = 0x8b, 459 [Q_KEY_CODE_ALT] = 0x19, 460 [Q_KEY_CODE_SHIFT_R] = 0x59, 461 [Q_KEY_CODE_CTRL_R] = 0x58, 462 [Q_KEY_CODE_META_R] = 0x8c, 463 [Q_KEY_CODE_ALT_R] = 0x39, 464 [Q_KEY_CODE_MENU] = 0x8d, 465 [Q_KEY_CODE_RET] = 0x5a, 466 [Q_KEY_CODE_ESC] = 0x08, 467 [Q_KEY_CODE_F1] = 0x07, 468 [Q_KEY_CODE_F2] = 0x0f, 469 [Q_KEY_CODE_F3] = 0x17, 470 [Q_KEY_CODE_F4] = 0x1f, 471 [Q_KEY_CODE_F5] = 0x27, 472 [Q_KEY_CODE_F6] = 0x2f, 473 [Q_KEY_CODE_F7] = 0x37, 474 [Q_KEY_CODE_F8] = 0x3f, 475 [Q_KEY_CODE_F9] = 0x47, 476 [Q_KEY_CODE_F10] = 0x4f, 477 [Q_KEY_CODE_F11] = 0x56, 478 [Q_KEY_CODE_F12] = 0x5e, 479 [Q_KEY_CODE_PRINT] = 0x57, 480 [Q_KEY_CODE_SCROLL_LOCK] = 0x5f, 481 [Q_KEY_CODE_PAUSE] = 0x62, 482 [Q_KEY_CODE_BRACKET_LEFT] = 0x54, 483 [Q_KEY_CODE_INSERT] = 0x67, 484 [Q_KEY_CODE_HOME] = 0x6e, 485 [Q_KEY_CODE_PGUP] = 0x6f, 486 [Q_KEY_CODE_DELETE] = 0x64, 487 [Q_KEY_CODE_END] = 0x65, 488 [Q_KEY_CODE_PGDN] = 0x6d, 489 [Q_KEY_CODE_UP] = 0x63, 490 [Q_KEY_CODE_LEFT] = 0x61, 491 [Q_KEY_CODE_DOWN] = 0x60, 492 [Q_KEY_CODE_RIGHT] = 0x6a, 493 [Q_KEY_CODE_NUM_LOCK] = 0x76, 494 [Q_KEY_CODE_KP_DIVIDE] = 0x4a, 495 [Q_KEY_CODE_KP_MULTIPLY] = 0x7e, 496 [Q_KEY_CODE_KP_SUBTRACT] = 0x4e, 497 [Q_KEY_CODE_KP_ADD] = 0x7c, 498 [Q_KEY_CODE_KP_ENTER] = 0x79, 499 [Q_KEY_CODE_KP_DECIMAL] = 0x71, 500 [Q_KEY_CODE_KP_0] = 0x70, 501 [Q_KEY_CODE_KP_1] = 0x69, 502 [Q_KEY_CODE_KP_2] = 0x72, 503 [Q_KEY_CODE_KP_3] = 0x7a, 504 [Q_KEY_CODE_KP_4] = 0x6b, 505 [Q_KEY_CODE_KP_5] = 0x73, 506 [Q_KEY_CODE_KP_6] = 0x74, 507 [Q_KEY_CODE_KP_7] = 0x6c, 508 [Q_KEY_CODE_KP_8] = 0x75, 509 [Q_KEY_CODE_KP_9] = 0x7d, 510 [Q_KEY_CODE_BRACKET_RIGHT] = 0x5b, 511 [Q_KEY_CODE_SEMICOLON] = 0x4c, 512 [Q_KEY_CODE_APOSTROPHE] = 0x52, 513 [Q_KEY_CODE_COMMA] = 0x41, 514 [Q_KEY_CODE_DOT] = 0x49, 515 [Q_KEY_CODE_SLASH] = 0x4a, 516 517 [Q_KEY_CODE_HIRAGANA] = 0x87, 518 [Q_KEY_CODE_HENKAN] = 0x86, 519 [Q_KEY_CODE_YEN] = 0x5d, 520 }; 521 522 static uint8_t translate_table[256] = { 523 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, 524 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, 525 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, 526 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b, 527 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, 528 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d, 529 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, 530 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f, 531 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, 532 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61, 533 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, 534 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76, 535 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, 536 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f, 537 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, 538 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54, 539 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, 540 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 541 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 542 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 543 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 544 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 545 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 546 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 547 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 548 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 549 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 550 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 551 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 552 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 553 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 554 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, 555 }; 556 557 static unsigned int ps2_modifier_bit(QKeyCode key) 558 { 559 switch (key) { 560 case Q_KEY_CODE_CTRL: 561 return MOD_CTRL_L; 562 case Q_KEY_CODE_CTRL_R: 563 return MOD_CTRL_R; 564 case Q_KEY_CODE_SHIFT: 565 return MOD_SHIFT_L; 566 case Q_KEY_CODE_SHIFT_R: 567 return MOD_SHIFT_R; 568 case Q_KEY_CODE_ALT: 569 return MOD_ALT_L; 570 case Q_KEY_CODE_ALT_R: 571 return MOD_ALT_R; 572 default: 573 return 0; 574 } 575 } 576 577 static void ps2_reset_queue(PS2State *s) 578 { 579 PS2Queue *q = &s->queue; 580 581 q->rptr = 0; 582 q->wptr = 0; 583 q->count = 0; 584 } 585 586 void ps2_queue(PS2State *s, int b) 587 { 588 PS2Queue *q = &s->queue; 589 590 if (q->count >= PS2_QUEUE_SIZE - 1) 591 return; 592 q->data[q->wptr] = b; 593 if (++q->wptr == PS2_QUEUE_SIZE) 594 q->wptr = 0; 595 q->count++; 596 s->update_irq(s->update_arg, 1); 597 } 598 599 /* keycode is the untranslated scancode in the current scancode set. */ 600 static void ps2_put_keycode(void *opaque, int keycode) 601 { 602 PS2KbdState *s = opaque; 603 604 trace_ps2_put_keycode(opaque, keycode); 605 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); 606 607 if (s->translate) { 608 if (keycode == 0xf0) { 609 s->need_high_bit = true; 610 } else if (s->need_high_bit) { 611 ps2_queue(&s->common, translate_table[keycode] | 0x80); 612 s->need_high_bit = false; 613 } else { 614 ps2_queue(&s->common, translate_table[keycode]); 615 } 616 } else { 617 ps2_queue(&s->common, keycode); 618 } 619 } 620 621 static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src, 622 InputEvent *evt) 623 { 624 PS2KbdState *s = (PS2KbdState *)dev; 625 InputKeyEvent *key = evt->u.key.data; 626 int qcode; 627 uint16_t keycode; 628 int mod; 629 630 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); 631 assert(evt->type == INPUT_EVENT_KIND_KEY); 632 qcode = qemu_input_key_value_to_qcode(key->key); 633 634 mod = ps2_modifier_bit(qcode); 635 trace_ps2_keyboard_event(s, qcode, key->down, mod, s->modifiers); 636 if (key->down) { 637 s->modifiers |= mod; 638 } else { 639 s->modifiers &= ~mod; 640 } 641 642 if (s->scancode_set == 1) { 643 if (qcode == Q_KEY_CODE_PAUSE) { 644 if (key->down) { 645 ps2_put_keycode(s, 0xe1); 646 ps2_put_keycode(s, 0x1d); 647 ps2_put_keycode(s, 0x45); 648 ps2_put_keycode(s, 0xe1); 649 ps2_put_keycode(s, 0x9d); 650 ps2_put_keycode(s, 0xc5); 651 } 652 } else if (qcode == Q_KEY_CODE_PRINT) { 653 if (s->modifiers & MOD_ALT_L) { 654 if (key->down) { 655 ps2_put_keycode(s, 0xb8); 656 ps2_put_keycode(s, 0x38); 657 ps2_put_keycode(s, 0x54); 658 } else { 659 ps2_put_keycode(s, 0xd4); 660 ps2_put_keycode(s, 0xb8); 661 ps2_put_keycode(s, 0x38); 662 } 663 } else if (s->modifiers & MOD_ALT_R) { 664 if (key->down) { 665 ps2_put_keycode(s, 0xe0); 666 ps2_put_keycode(s, 0xb8); 667 ps2_put_keycode(s, 0xe0); 668 ps2_put_keycode(s, 0x38); 669 ps2_put_keycode(s, 0x54); 670 } else { 671 ps2_put_keycode(s, 0xd4); 672 ps2_put_keycode(s, 0xe0); 673 ps2_put_keycode(s, 0xb8); 674 ps2_put_keycode(s, 0xe0); 675 ps2_put_keycode(s, 0x38); 676 } 677 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L | 678 MOD_SHIFT_R | MOD_CTRL_R)) { 679 if (key->down) { 680 ps2_put_keycode(s, 0xe0); 681 ps2_put_keycode(s, 0x37); 682 } else { 683 ps2_put_keycode(s, 0xe0); 684 ps2_put_keycode(s, 0xb7); 685 } 686 } else { 687 if (key->down) { 688 ps2_put_keycode(s, 0xe0); 689 ps2_put_keycode(s, 0x2a); 690 ps2_put_keycode(s, 0xe0); 691 ps2_put_keycode(s, 0x37); 692 } else { 693 ps2_put_keycode(s, 0xe0); 694 ps2_put_keycode(s, 0xb7); 695 ps2_put_keycode(s, 0xe0); 696 ps2_put_keycode(s, 0xaa); 697 } 698 } 699 } else { 700 keycode = qcode_to_keycode_set1[qcode]; 701 if (keycode) { 702 if (keycode & 0xff00) { 703 ps2_put_keycode(s, keycode >> 8); 704 } 705 if (!key->down) { 706 keycode |= 0x80; 707 } 708 ps2_put_keycode(s, keycode & 0xff); 709 } else { 710 qemu_log_mask(LOG_UNIMP, 711 "ps2: ignoring key with qcode %d\n", qcode); 712 } 713 } 714 } else if (s->scancode_set == 2) { 715 if (qcode == Q_KEY_CODE_PAUSE) { 716 if (key->down) { 717 ps2_put_keycode(s, 0xe1); 718 ps2_put_keycode(s, 0x14); 719 ps2_put_keycode(s, 0x77); 720 ps2_put_keycode(s, 0xe1); 721 ps2_put_keycode(s, 0xf0); 722 ps2_put_keycode(s, 0x14); 723 ps2_put_keycode(s, 0xf0); 724 ps2_put_keycode(s, 0x77); 725 } 726 } else if (qcode == Q_KEY_CODE_PRINT) { 727 if (s->modifiers & MOD_ALT_L) { 728 if (key->down) { 729 ps2_put_keycode(s, 0xf0); 730 ps2_put_keycode(s, 0x11); 731 ps2_put_keycode(s, 0x11); 732 ps2_put_keycode(s, 0x84); 733 } else { 734 ps2_put_keycode(s, 0xf0); 735 ps2_put_keycode(s, 0x84); 736 ps2_put_keycode(s, 0xf0); 737 ps2_put_keycode(s, 0x11); 738 ps2_put_keycode(s, 0x11); 739 } 740 } else if (s->modifiers & MOD_ALT_R) { 741 if (key->down) { 742 ps2_put_keycode(s, 0xe0); 743 ps2_put_keycode(s, 0xf0); 744 ps2_put_keycode(s, 0x11); 745 ps2_put_keycode(s, 0xe0); 746 ps2_put_keycode(s, 0x11); 747 ps2_put_keycode(s, 0x84); 748 } else { 749 ps2_put_keycode(s, 0xf0); 750 ps2_put_keycode(s, 0x84); 751 ps2_put_keycode(s, 0xe0); 752 ps2_put_keycode(s, 0xf0); 753 ps2_put_keycode(s, 0x11); 754 ps2_put_keycode(s, 0xe0); 755 ps2_put_keycode(s, 0x11); 756 } 757 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L | 758 MOD_SHIFT_R | MOD_CTRL_R)) { 759 if (key->down) { 760 ps2_put_keycode(s, 0xe0); 761 ps2_put_keycode(s, 0x7c); 762 } else { 763 ps2_put_keycode(s, 0xe0); 764 ps2_put_keycode(s, 0xf0); 765 ps2_put_keycode(s, 0x7c); 766 } 767 } else { 768 if (key->down) { 769 ps2_put_keycode(s, 0xe0); 770 ps2_put_keycode(s, 0x12); 771 ps2_put_keycode(s, 0xe0); 772 ps2_put_keycode(s, 0x7c); 773 } else { 774 ps2_put_keycode(s, 0xe0); 775 ps2_put_keycode(s, 0xf0); 776 ps2_put_keycode(s, 0x7c); 777 ps2_put_keycode(s, 0xe0); 778 ps2_put_keycode(s, 0xf0); 779 ps2_put_keycode(s, 0x12); 780 } 781 } 782 } else { 783 keycode = qcode_to_keycode_set2[qcode]; 784 if (keycode) { 785 if (keycode & 0xff00) { 786 ps2_put_keycode(s, keycode >> 8); 787 } 788 if (!key->down) { 789 ps2_put_keycode(s, 0xf0); 790 } 791 ps2_put_keycode(s, keycode & 0xff); 792 } else { 793 qemu_log_mask(LOG_UNIMP, 794 "ps2: ignoring key with qcode %d\n", qcode); 795 } 796 } 797 } else if (s->scancode_set == 3) { 798 keycode = qcode_to_keycode_set3[qcode]; 799 if (keycode) { 800 /* FIXME: break code should be configured on a key by key basis */ 801 if (!key->down) { 802 ps2_put_keycode(s, 0xf0); 803 } 804 ps2_put_keycode(s, keycode); 805 } else { 806 qemu_log_mask(LOG_UNIMP, 807 "ps2: ignoring key with qcode %d\n", qcode); 808 } 809 } 810 } 811 812 uint32_t ps2_read_data(PS2State *s) 813 { 814 PS2Queue *q; 815 int val, index; 816 817 trace_ps2_read_data(s); 818 q = &s->queue; 819 if (q->count == 0) { 820 /* NOTE: if no data left, we return the last keyboard one 821 (needed for EMM386) */ 822 /* XXX: need a timer to do things correctly */ 823 index = q->rptr - 1; 824 if (index < 0) 825 index = PS2_QUEUE_SIZE - 1; 826 val = q->data[index]; 827 } else { 828 val = q->data[q->rptr]; 829 if (++q->rptr == PS2_QUEUE_SIZE) 830 q->rptr = 0; 831 q->count--; 832 /* reading deasserts IRQ */ 833 s->update_irq(s->update_arg, 0); 834 /* reassert IRQs if data left */ 835 s->update_irq(s->update_arg, q->count != 0); 836 } 837 return val; 838 } 839 840 static void ps2_set_ledstate(PS2KbdState *s, int ledstate) 841 { 842 trace_ps2_set_ledstate(s, ledstate); 843 s->ledstate = ledstate; 844 kbd_put_ledstate(ledstate); 845 } 846 847 static void ps2_reset_keyboard(PS2KbdState *s) 848 { 849 trace_ps2_reset_keyboard(s); 850 s->scan_enabled = 1; 851 s->scancode_set = 2; 852 ps2_reset_queue(&s->common); 853 ps2_set_ledstate(s, 0); 854 } 855 856 void ps2_write_keyboard(void *opaque, int val) 857 { 858 PS2KbdState *s = (PS2KbdState *)opaque; 859 860 trace_ps2_write_keyboard(opaque, val); 861 switch(s->common.write_cmd) { 862 default: 863 case -1: 864 switch(val) { 865 case 0x00: 866 ps2_queue(&s->common, KBD_REPLY_ACK); 867 break; 868 case 0x05: 869 ps2_queue(&s->common, KBD_REPLY_RESEND); 870 break; 871 case KBD_CMD_GET_ID: 872 ps2_queue(&s->common, KBD_REPLY_ACK); 873 /* We emulate a MF2 AT keyboard here */ 874 ps2_queue(&s->common, KBD_REPLY_ID); 875 if (s->translate) 876 ps2_queue(&s->common, 0x41); 877 else 878 ps2_queue(&s->common, 0x83); 879 break; 880 case KBD_CMD_ECHO: 881 ps2_queue(&s->common, KBD_CMD_ECHO); 882 break; 883 case KBD_CMD_ENABLE: 884 s->scan_enabled = 1; 885 ps2_queue(&s->common, KBD_REPLY_ACK); 886 break; 887 case KBD_CMD_SCANCODE: 888 case KBD_CMD_SET_LEDS: 889 case KBD_CMD_SET_RATE: 890 s->common.write_cmd = val; 891 ps2_queue(&s->common, KBD_REPLY_ACK); 892 break; 893 case KBD_CMD_RESET_DISABLE: 894 ps2_reset_keyboard(s); 895 s->scan_enabled = 0; 896 ps2_queue(&s->common, KBD_REPLY_ACK); 897 break; 898 case KBD_CMD_RESET_ENABLE: 899 ps2_reset_keyboard(s); 900 s->scan_enabled = 1; 901 ps2_queue(&s->common, KBD_REPLY_ACK); 902 break; 903 case KBD_CMD_RESET: 904 ps2_reset_keyboard(s); 905 ps2_queue(&s->common, KBD_REPLY_ACK); 906 ps2_queue(&s->common, KBD_REPLY_POR); 907 break; 908 default: 909 ps2_queue(&s->common, KBD_REPLY_RESEND); 910 break; 911 } 912 break; 913 case KBD_CMD_SCANCODE: 914 if (val == 0) { 915 ps2_queue(&s->common, KBD_REPLY_ACK); 916 ps2_put_keycode(s, s->scancode_set); 917 } else if (val >= 1 && val <= 3) { 918 s->scancode_set = val; 919 ps2_queue(&s->common, KBD_REPLY_ACK); 920 } else { 921 ps2_queue(&s->common, KBD_REPLY_RESEND); 922 } 923 s->common.write_cmd = -1; 924 break; 925 case KBD_CMD_SET_LEDS: 926 ps2_set_ledstate(s, val); 927 ps2_queue(&s->common, KBD_REPLY_ACK); 928 s->common.write_cmd = -1; 929 break; 930 case KBD_CMD_SET_RATE: 931 ps2_queue(&s->common, KBD_REPLY_ACK); 932 s->common.write_cmd = -1; 933 break; 934 } 935 } 936 937 /* Set the scancode translation mode. 938 0 = raw scancodes. 939 1 = translated scancodes (used by qemu internally). */ 940 941 void ps2_keyboard_set_translation(void *opaque, int mode) 942 { 943 PS2KbdState *s = (PS2KbdState *)opaque; 944 trace_ps2_keyboard_set_translation(opaque, mode); 945 s->translate = mode; 946 } 947 948 static void ps2_mouse_send_packet(PS2MouseState *s) 949 { 950 unsigned int b; 951 int dx1, dy1, dz1; 952 953 dx1 = s->mouse_dx; 954 dy1 = s->mouse_dy; 955 dz1 = s->mouse_dz; 956 /* XXX: increase range to 8 bits ? */ 957 if (dx1 > 127) 958 dx1 = 127; 959 else if (dx1 < -127) 960 dx1 = -127; 961 if (dy1 > 127) 962 dy1 = 127; 963 else if (dy1 < -127) 964 dy1 = -127; 965 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); 966 ps2_queue(&s->common, b); 967 ps2_queue(&s->common, dx1 & 0xff); 968 ps2_queue(&s->common, dy1 & 0xff); 969 /* extra byte for IMPS/2 or IMEX */ 970 switch(s->mouse_type) { 971 default: 972 break; 973 case 3: 974 if (dz1 > 127) 975 dz1 = 127; 976 else if (dz1 < -127) 977 dz1 = -127; 978 ps2_queue(&s->common, dz1 & 0xff); 979 break; 980 case 4: 981 if (dz1 > 7) 982 dz1 = 7; 983 else if (dz1 < -7) 984 dz1 = -7; 985 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); 986 ps2_queue(&s->common, b); 987 break; 988 } 989 990 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b); 991 /* update deltas */ 992 s->mouse_dx -= dx1; 993 s->mouse_dy -= dy1; 994 s->mouse_dz -= dz1; 995 } 996 997 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, 998 InputEvent *evt) 999 { 1000 static const int bmap[INPUT_BUTTON__MAX] = { 1001 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT, 1002 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE, 1003 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT, 1004 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE, 1005 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA, 1006 }; 1007 PS2MouseState *s = (PS2MouseState *)dev; 1008 InputMoveEvent *move; 1009 InputBtnEvent *btn; 1010 1011 /* check if deltas are recorded when disabled */ 1012 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) 1013 return; 1014 1015 switch (evt->type) { 1016 case INPUT_EVENT_KIND_REL: 1017 move = evt->u.rel.data; 1018 if (move->axis == INPUT_AXIS_X) { 1019 s->mouse_dx += move->value; 1020 } else if (move->axis == INPUT_AXIS_Y) { 1021 s->mouse_dy -= move->value; 1022 } 1023 break; 1024 1025 case INPUT_EVENT_KIND_BTN: 1026 btn = evt->u.btn.data; 1027 if (btn->down) { 1028 s->mouse_buttons |= bmap[btn->button]; 1029 if (btn->button == INPUT_BUTTON_WHEEL_UP) { 1030 s->mouse_dz--; 1031 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { 1032 s->mouse_dz++; 1033 } 1034 } else { 1035 s->mouse_buttons &= ~bmap[btn->button]; 1036 } 1037 break; 1038 1039 default: 1040 /* keep gcc happy */ 1041 break; 1042 } 1043 } 1044 1045 static void ps2_mouse_sync(DeviceState *dev) 1046 { 1047 PS2MouseState *s = (PS2MouseState *)dev; 1048 1049 if (s->mouse_buttons) { 1050 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); 1051 } 1052 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) { 1053 while (s->common.queue.count < PS2_QUEUE_SIZE - 4) { 1054 /* if not remote, send event. Multiple events are sent if 1055 too big deltas */ 1056 ps2_mouse_send_packet(s); 1057 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0) 1058 break; 1059 } 1060 } 1061 } 1062 1063 void ps2_mouse_fake_event(void *opaque) 1064 { 1065 PS2MouseState *s = opaque; 1066 trace_ps2_mouse_fake_event(opaque); 1067 s->mouse_dx++; 1068 ps2_mouse_sync(opaque); 1069 } 1070 1071 void ps2_write_mouse(void *opaque, int val) 1072 { 1073 PS2MouseState *s = (PS2MouseState *)opaque; 1074 1075 trace_ps2_write_mouse(opaque, val); 1076 #ifdef DEBUG_MOUSE 1077 printf("kbd: write mouse 0x%02x\n", val); 1078 #endif 1079 switch(s->common.write_cmd) { 1080 default: 1081 case -1: 1082 /* mouse command */ 1083 if (s->mouse_wrap) { 1084 if (val == AUX_RESET_WRAP) { 1085 s->mouse_wrap = 0; 1086 ps2_queue(&s->common, AUX_ACK); 1087 return; 1088 } else if (val != AUX_RESET) { 1089 ps2_queue(&s->common, val); 1090 return; 1091 } 1092 } 1093 switch(val) { 1094 case AUX_SET_SCALE11: 1095 s->mouse_status &= ~MOUSE_STATUS_SCALE21; 1096 ps2_queue(&s->common, AUX_ACK); 1097 break; 1098 case AUX_SET_SCALE21: 1099 s->mouse_status |= MOUSE_STATUS_SCALE21; 1100 ps2_queue(&s->common, AUX_ACK); 1101 break; 1102 case AUX_SET_STREAM: 1103 s->mouse_status &= ~MOUSE_STATUS_REMOTE; 1104 ps2_queue(&s->common, AUX_ACK); 1105 break; 1106 case AUX_SET_WRAP: 1107 s->mouse_wrap = 1; 1108 ps2_queue(&s->common, AUX_ACK); 1109 break; 1110 case AUX_SET_REMOTE: 1111 s->mouse_status |= MOUSE_STATUS_REMOTE; 1112 ps2_queue(&s->common, AUX_ACK); 1113 break; 1114 case AUX_GET_TYPE: 1115 ps2_queue(&s->common, AUX_ACK); 1116 ps2_queue(&s->common, s->mouse_type); 1117 break; 1118 case AUX_SET_RES: 1119 case AUX_SET_SAMPLE: 1120 s->common.write_cmd = val; 1121 ps2_queue(&s->common, AUX_ACK); 1122 break; 1123 case AUX_GET_SCALE: 1124 ps2_queue(&s->common, AUX_ACK); 1125 ps2_queue(&s->common, s->mouse_status); 1126 ps2_queue(&s->common, s->mouse_resolution); 1127 ps2_queue(&s->common, s->mouse_sample_rate); 1128 break; 1129 case AUX_POLL: 1130 ps2_queue(&s->common, AUX_ACK); 1131 ps2_mouse_send_packet(s); 1132 break; 1133 case AUX_ENABLE_DEV: 1134 s->mouse_status |= MOUSE_STATUS_ENABLED; 1135 ps2_queue(&s->common, AUX_ACK); 1136 break; 1137 case AUX_DISABLE_DEV: 1138 s->mouse_status &= ~MOUSE_STATUS_ENABLED; 1139 ps2_queue(&s->common, AUX_ACK); 1140 break; 1141 case AUX_SET_DEFAULT: 1142 s->mouse_sample_rate = 100; 1143 s->mouse_resolution = 2; 1144 s->mouse_status = 0; 1145 ps2_queue(&s->common, AUX_ACK); 1146 break; 1147 case AUX_RESET: 1148 s->mouse_sample_rate = 100; 1149 s->mouse_resolution = 2; 1150 s->mouse_status = 0; 1151 s->mouse_type = 0; 1152 ps2_queue(&s->common, AUX_ACK); 1153 ps2_queue(&s->common, 0xaa); 1154 ps2_queue(&s->common, s->mouse_type); 1155 break; 1156 default: 1157 break; 1158 } 1159 break; 1160 case AUX_SET_SAMPLE: 1161 s->mouse_sample_rate = val; 1162 /* detect IMPS/2 or IMEX */ 1163 switch(s->mouse_detect_state) { 1164 default: 1165 case 0: 1166 if (val == 200) 1167 s->mouse_detect_state = 1; 1168 break; 1169 case 1: 1170 if (val == 100) 1171 s->mouse_detect_state = 2; 1172 else if (val == 200) 1173 s->mouse_detect_state = 3; 1174 else 1175 s->mouse_detect_state = 0; 1176 break; 1177 case 2: 1178 if (val == 80) 1179 s->mouse_type = 3; /* IMPS/2 */ 1180 s->mouse_detect_state = 0; 1181 break; 1182 case 3: 1183 if (val == 80) 1184 s->mouse_type = 4; /* IMEX */ 1185 s->mouse_detect_state = 0; 1186 break; 1187 } 1188 ps2_queue(&s->common, AUX_ACK); 1189 s->common.write_cmd = -1; 1190 break; 1191 case AUX_SET_RES: 1192 s->mouse_resolution = val; 1193 ps2_queue(&s->common, AUX_ACK); 1194 s->common.write_cmd = -1; 1195 break; 1196 } 1197 } 1198 1199 static void ps2_common_reset(PS2State *s) 1200 { 1201 s->write_cmd = -1; 1202 ps2_reset_queue(s); 1203 s->update_irq(s->update_arg, 0); 1204 } 1205 1206 static void ps2_common_post_load(PS2State *s) 1207 { 1208 PS2Queue *q = &s->queue; 1209 int size; 1210 int i; 1211 int tmp_data[PS2_QUEUE_SIZE]; 1212 1213 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */ 1214 size = q->count > PS2_QUEUE_SIZE ? 0 : q->count; 1215 1216 /* move the queue elements to the start of data array */ 1217 if (size > 0) { 1218 for (i = 0; i < size; i++) { 1219 /* move the queue elements to the temporary buffer */ 1220 tmp_data[i] = q->data[q->rptr]; 1221 if (++q->rptr == 256) { 1222 q->rptr = 0; 1223 } 1224 } 1225 memcpy(q->data, tmp_data, size); 1226 } 1227 /* reset rptr/wptr/count */ 1228 q->rptr = 0; 1229 q->wptr = size; 1230 q->count = size; 1231 s->update_irq(s->update_arg, q->count != 0); 1232 } 1233 1234 static void ps2_kbd_reset(void *opaque) 1235 { 1236 PS2KbdState *s = (PS2KbdState *) opaque; 1237 1238 trace_ps2_kbd_reset(opaque); 1239 ps2_common_reset(&s->common); 1240 s->scan_enabled = 0; 1241 s->translate = 0; 1242 s->scancode_set = 2; 1243 s->modifiers = 0; 1244 } 1245 1246 static void ps2_mouse_reset(void *opaque) 1247 { 1248 PS2MouseState *s = (PS2MouseState *) opaque; 1249 1250 trace_ps2_mouse_reset(opaque); 1251 ps2_common_reset(&s->common); 1252 s->mouse_status = 0; 1253 s->mouse_resolution = 0; 1254 s->mouse_sample_rate = 0; 1255 s->mouse_wrap = 0; 1256 s->mouse_type = 0; 1257 s->mouse_detect_state = 0; 1258 s->mouse_dx = 0; 1259 s->mouse_dy = 0; 1260 s->mouse_dz = 0; 1261 s->mouse_buttons = 0; 1262 } 1263 1264 static const VMStateDescription vmstate_ps2_common = { 1265 .name = "PS2 Common State", 1266 .version_id = 3, 1267 .minimum_version_id = 2, 1268 .fields = (VMStateField[]) { 1269 VMSTATE_INT32(write_cmd, PS2State), 1270 VMSTATE_INT32(queue.rptr, PS2State), 1271 VMSTATE_INT32(queue.wptr, PS2State), 1272 VMSTATE_INT32(queue.count, PS2State), 1273 VMSTATE_BUFFER(queue.data, PS2State), 1274 VMSTATE_END_OF_LIST() 1275 } 1276 }; 1277 1278 static bool ps2_keyboard_ledstate_needed(void *opaque) 1279 { 1280 PS2KbdState *s = opaque; 1281 1282 return s->ledstate != 0; /* 0 is default state */ 1283 } 1284 1285 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id) 1286 { 1287 PS2KbdState *s = opaque; 1288 1289 kbd_put_ledstate(s->ledstate); 1290 return 0; 1291 } 1292 1293 static const VMStateDescription vmstate_ps2_keyboard_ledstate = { 1294 .name = "ps2kbd/ledstate", 1295 .version_id = 3, 1296 .minimum_version_id = 2, 1297 .post_load = ps2_kbd_ledstate_post_load, 1298 .needed = ps2_keyboard_ledstate_needed, 1299 .fields = (VMStateField[]) { 1300 VMSTATE_INT32(ledstate, PS2KbdState), 1301 VMSTATE_END_OF_LIST() 1302 } 1303 }; 1304 1305 static bool ps2_keyboard_need_high_bit_needed(void *opaque) 1306 { 1307 PS2KbdState *s = opaque; 1308 return s->need_high_bit != 0; /* 0 is the usual state */ 1309 } 1310 1311 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = { 1312 .name = "ps2kbd/need_high_bit", 1313 .version_id = 1, 1314 .minimum_version_id = 1, 1315 .needed = ps2_keyboard_need_high_bit_needed, 1316 .fields = (VMStateField[]) { 1317 VMSTATE_BOOL(need_high_bit, PS2KbdState), 1318 VMSTATE_END_OF_LIST() 1319 } 1320 }; 1321 1322 static int ps2_kbd_post_load(void* opaque, int version_id) 1323 { 1324 PS2KbdState *s = (PS2KbdState*)opaque; 1325 PS2State *ps2 = &s->common; 1326 1327 if (version_id == 2) 1328 s->scancode_set=2; 1329 1330 ps2_common_post_load(ps2); 1331 1332 return 0; 1333 } 1334 1335 static int ps2_kbd_pre_save(void *opaque) 1336 { 1337 PS2KbdState *s = (PS2KbdState *)opaque; 1338 PS2State *ps2 = &s->common; 1339 1340 ps2_common_post_load(ps2); 1341 1342 return 0; 1343 } 1344 1345 static const VMStateDescription vmstate_ps2_keyboard = { 1346 .name = "ps2kbd", 1347 .version_id = 3, 1348 .minimum_version_id = 2, 1349 .post_load = ps2_kbd_post_load, 1350 .pre_save = ps2_kbd_pre_save, 1351 .fields = (VMStateField[]) { 1352 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State), 1353 VMSTATE_INT32(scan_enabled, PS2KbdState), 1354 VMSTATE_INT32(translate, PS2KbdState), 1355 VMSTATE_INT32_V(scancode_set, PS2KbdState,3), 1356 VMSTATE_END_OF_LIST() 1357 }, 1358 .subsections = (const VMStateDescription*[]) { 1359 &vmstate_ps2_keyboard_ledstate, 1360 &vmstate_ps2_keyboard_need_high_bit, 1361 NULL 1362 } 1363 }; 1364 1365 static int ps2_mouse_post_load(void *opaque, int version_id) 1366 { 1367 PS2MouseState *s = (PS2MouseState *)opaque; 1368 PS2State *ps2 = &s->common; 1369 1370 ps2_common_post_load(ps2); 1371 1372 return 0; 1373 } 1374 1375 static int ps2_mouse_pre_save(void *opaque) 1376 { 1377 PS2MouseState *s = (PS2MouseState *)opaque; 1378 PS2State *ps2 = &s->common; 1379 1380 ps2_common_post_load(ps2); 1381 1382 return 0; 1383 } 1384 1385 static const VMStateDescription vmstate_ps2_mouse = { 1386 .name = "ps2mouse", 1387 .version_id = 2, 1388 .minimum_version_id = 2, 1389 .post_load = ps2_mouse_post_load, 1390 .pre_save = ps2_mouse_pre_save, 1391 .fields = (VMStateField[]) { 1392 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State), 1393 VMSTATE_UINT8(mouse_status, PS2MouseState), 1394 VMSTATE_UINT8(mouse_resolution, PS2MouseState), 1395 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState), 1396 VMSTATE_UINT8(mouse_wrap, PS2MouseState), 1397 VMSTATE_UINT8(mouse_type, PS2MouseState), 1398 VMSTATE_UINT8(mouse_detect_state, PS2MouseState), 1399 VMSTATE_INT32(mouse_dx, PS2MouseState), 1400 VMSTATE_INT32(mouse_dy, PS2MouseState), 1401 VMSTATE_INT32(mouse_dz, PS2MouseState), 1402 VMSTATE_UINT8(mouse_buttons, PS2MouseState), 1403 VMSTATE_END_OF_LIST() 1404 } 1405 }; 1406 1407 static QemuInputHandler ps2_keyboard_handler = { 1408 .name = "QEMU PS/2 Keyboard", 1409 .mask = INPUT_EVENT_MASK_KEY, 1410 .event = ps2_keyboard_event, 1411 }; 1412 1413 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) 1414 { 1415 PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState)); 1416 1417 trace_ps2_kbd_init(s); 1418 s->common.update_irq = update_irq; 1419 s->common.update_arg = update_arg; 1420 s->scancode_set = 2; 1421 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); 1422 qemu_input_handler_register((DeviceState *)s, 1423 &ps2_keyboard_handler); 1424 qemu_register_reset(ps2_kbd_reset, s); 1425 return s; 1426 } 1427 1428 static QemuInputHandler ps2_mouse_handler = { 1429 .name = "QEMU PS/2 Mouse", 1430 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL, 1431 .event = ps2_mouse_event, 1432 .sync = ps2_mouse_sync, 1433 }; 1434 1435 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) 1436 { 1437 PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState)); 1438 1439 trace_ps2_mouse_init(s); 1440 s->common.update_irq = update_irq; 1441 s->common.update_arg = update_arg; 1442 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s); 1443 qemu_input_handler_register((DeviceState *)s, 1444 &ps2_mouse_handler); 1445 qemu_register_reset(ps2_mouse_reset, s); 1446 return s; 1447 } 1448