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 (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) { 645 if (key->down) { 646 ps2_put_keycode(s, 0xe0); 647 ps2_put_keycode(s, 0x46); 648 ps2_put_keycode(s, 0xe0); 649 ps2_put_keycode(s, 0xc6); 650 } 651 } else { 652 if (key->down) { 653 ps2_put_keycode(s, 0xe1); 654 ps2_put_keycode(s, 0x1d); 655 ps2_put_keycode(s, 0x45); 656 ps2_put_keycode(s, 0xe1); 657 ps2_put_keycode(s, 0x9d); 658 ps2_put_keycode(s, 0xc5); 659 } 660 } 661 } else if (qcode == Q_KEY_CODE_PRINT) { 662 if (s->modifiers & MOD_ALT_L) { 663 if (key->down) { 664 ps2_put_keycode(s, 0xb8); 665 ps2_put_keycode(s, 0x38); 666 ps2_put_keycode(s, 0x54); 667 } else { 668 ps2_put_keycode(s, 0xd4); 669 ps2_put_keycode(s, 0xb8); 670 ps2_put_keycode(s, 0x38); 671 } 672 } else if (s->modifiers & MOD_ALT_R) { 673 if (key->down) { 674 ps2_put_keycode(s, 0xe0); 675 ps2_put_keycode(s, 0xb8); 676 ps2_put_keycode(s, 0xe0); 677 ps2_put_keycode(s, 0x38); 678 ps2_put_keycode(s, 0x54); 679 } else { 680 ps2_put_keycode(s, 0xd4); 681 ps2_put_keycode(s, 0xe0); 682 ps2_put_keycode(s, 0xb8); 683 ps2_put_keycode(s, 0xe0); 684 ps2_put_keycode(s, 0x38); 685 } 686 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L | 687 MOD_SHIFT_R | MOD_CTRL_R)) { 688 if (key->down) { 689 ps2_put_keycode(s, 0xe0); 690 ps2_put_keycode(s, 0x37); 691 } else { 692 ps2_put_keycode(s, 0xe0); 693 ps2_put_keycode(s, 0xb7); 694 } 695 } else { 696 if (key->down) { 697 ps2_put_keycode(s, 0xe0); 698 ps2_put_keycode(s, 0x2a); 699 ps2_put_keycode(s, 0xe0); 700 ps2_put_keycode(s, 0x37); 701 } else { 702 ps2_put_keycode(s, 0xe0); 703 ps2_put_keycode(s, 0xb7); 704 ps2_put_keycode(s, 0xe0); 705 ps2_put_keycode(s, 0xaa); 706 } 707 } 708 } else { 709 keycode = qcode_to_keycode_set1[qcode]; 710 if (keycode) { 711 if (keycode & 0xff00) { 712 ps2_put_keycode(s, keycode >> 8); 713 } 714 if (!key->down) { 715 keycode |= 0x80; 716 } 717 ps2_put_keycode(s, keycode & 0xff); 718 } else { 719 qemu_log_mask(LOG_UNIMP, 720 "ps2: ignoring key with qcode %d\n", qcode); 721 } 722 } 723 } else if (s->scancode_set == 2) { 724 if (qcode == Q_KEY_CODE_PAUSE) { 725 if (s->modifiers & (MOD_CTRL_L | MOD_CTRL_R)) { 726 if (key->down) { 727 ps2_put_keycode(s, 0xe0); 728 ps2_put_keycode(s, 0x7e); 729 ps2_put_keycode(s, 0xe0); 730 ps2_put_keycode(s, 0xf0); 731 ps2_put_keycode(s, 0x7e); 732 } 733 } else { 734 if (key->down) { 735 ps2_put_keycode(s, 0xe1); 736 ps2_put_keycode(s, 0x14); 737 ps2_put_keycode(s, 0x77); 738 ps2_put_keycode(s, 0xe1); 739 ps2_put_keycode(s, 0xf0); 740 ps2_put_keycode(s, 0x14); 741 ps2_put_keycode(s, 0xf0); 742 ps2_put_keycode(s, 0x77); 743 } 744 } 745 } else if (qcode == Q_KEY_CODE_PRINT) { 746 if (s->modifiers & MOD_ALT_L) { 747 if (key->down) { 748 ps2_put_keycode(s, 0xf0); 749 ps2_put_keycode(s, 0x11); 750 ps2_put_keycode(s, 0x11); 751 ps2_put_keycode(s, 0x84); 752 } else { 753 ps2_put_keycode(s, 0xf0); 754 ps2_put_keycode(s, 0x84); 755 ps2_put_keycode(s, 0xf0); 756 ps2_put_keycode(s, 0x11); 757 ps2_put_keycode(s, 0x11); 758 } 759 } else if (s->modifiers & MOD_ALT_R) { 760 if (key->down) { 761 ps2_put_keycode(s, 0xe0); 762 ps2_put_keycode(s, 0xf0); 763 ps2_put_keycode(s, 0x11); 764 ps2_put_keycode(s, 0xe0); 765 ps2_put_keycode(s, 0x11); 766 ps2_put_keycode(s, 0x84); 767 } else { 768 ps2_put_keycode(s, 0xf0); 769 ps2_put_keycode(s, 0x84); 770 ps2_put_keycode(s, 0xe0); 771 ps2_put_keycode(s, 0xf0); 772 ps2_put_keycode(s, 0x11); 773 ps2_put_keycode(s, 0xe0); 774 ps2_put_keycode(s, 0x11); 775 } 776 } else if (s->modifiers & (MOD_SHIFT_L | MOD_CTRL_L | 777 MOD_SHIFT_R | MOD_CTRL_R)) { 778 if (key->down) { 779 ps2_put_keycode(s, 0xe0); 780 ps2_put_keycode(s, 0x7c); 781 } else { 782 ps2_put_keycode(s, 0xe0); 783 ps2_put_keycode(s, 0xf0); 784 ps2_put_keycode(s, 0x7c); 785 } 786 } else { 787 if (key->down) { 788 ps2_put_keycode(s, 0xe0); 789 ps2_put_keycode(s, 0x12); 790 ps2_put_keycode(s, 0xe0); 791 ps2_put_keycode(s, 0x7c); 792 } else { 793 ps2_put_keycode(s, 0xe0); 794 ps2_put_keycode(s, 0xf0); 795 ps2_put_keycode(s, 0x7c); 796 ps2_put_keycode(s, 0xe0); 797 ps2_put_keycode(s, 0xf0); 798 ps2_put_keycode(s, 0x12); 799 } 800 } 801 } else { 802 keycode = qcode_to_keycode_set2[qcode]; 803 if (keycode) { 804 if (keycode & 0xff00) { 805 ps2_put_keycode(s, keycode >> 8); 806 } 807 if (!key->down) { 808 ps2_put_keycode(s, 0xf0); 809 } 810 ps2_put_keycode(s, keycode & 0xff); 811 } else { 812 qemu_log_mask(LOG_UNIMP, 813 "ps2: ignoring key with qcode %d\n", qcode); 814 } 815 } 816 } else if (s->scancode_set == 3) { 817 keycode = qcode_to_keycode_set3[qcode]; 818 if (keycode) { 819 /* FIXME: break code should be configured on a key by key basis */ 820 if (!key->down) { 821 ps2_put_keycode(s, 0xf0); 822 } 823 ps2_put_keycode(s, keycode); 824 } else { 825 qemu_log_mask(LOG_UNIMP, 826 "ps2: ignoring key with qcode %d\n", qcode); 827 } 828 } 829 } 830 831 uint32_t ps2_read_data(PS2State *s) 832 { 833 PS2Queue *q; 834 int val, index; 835 836 trace_ps2_read_data(s); 837 q = &s->queue; 838 if (q->count == 0) { 839 /* NOTE: if no data left, we return the last keyboard one 840 (needed for EMM386) */ 841 /* XXX: need a timer to do things correctly */ 842 index = q->rptr - 1; 843 if (index < 0) 844 index = PS2_QUEUE_SIZE - 1; 845 val = q->data[index]; 846 } else { 847 val = q->data[q->rptr]; 848 if (++q->rptr == PS2_QUEUE_SIZE) 849 q->rptr = 0; 850 q->count--; 851 /* reading deasserts IRQ */ 852 s->update_irq(s->update_arg, 0); 853 /* reassert IRQs if data left */ 854 s->update_irq(s->update_arg, q->count != 0); 855 } 856 return val; 857 } 858 859 static void ps2_set_ledstate(PS2KbdState *s, int ledstate) 860 { 861 trace_ps2_set_ledstate(s, ledstate); 862 s->ledstate = ledstate; 863 kbd_put_ledstate(ledstate); 864 } 865 866 static void ps2_reset_keyboard(PS2KbdState *s) 867 { 868 trace_ps2_reset_keyboard(s); 869 s->scan_enabled = 1; 870 s->scancode_set = 2; 871 ps2_reset_queue(&s->common); 872 ps2_set_ledstate(s, 0); 873 } 874 875 void ps2_write_keyboard(void *opaque, int val) 876 { 877 PS2KbdState *s = (PS2KbdState *)opaque; 878 879 trace_ps2_write_keyboard(opaque, val); 880 switch(s->common.write_cmd) { 881 default: 882 case -1: 883 switch(val) { 884 case 0x00: 885 ps2_queue(&s->common, KBD_REPLY_ACK); 886 break; 887 case 0x05: 888 ps2_queue(&s->common, KBD_REPLY_RESEND); 889 break; 890 case KBD_CMD_GET_ID: 891 ps2_queue(&s->common, KBD_REPLY_ACK); 892 /* We emulate a MF2 AT keyboard here */ 893 ps2_queue(&s->common, KBD_REPLY_ID); 894 if (s->translate) 895 ps2_queue(&s->common, 0x41); 896 else 897 ps2_queue(&s->common, 0x83); 898 break; 899 case KBD_CMD_ECHO: 900 ps2_queue(&s->common, KBD_CMD_ECHO); 901 break; 902 case KBD_CMD_ENABLE: 903 s->scan_enabled = 1; 904 ps2_queue(&s->common, KBD_REPLY_ACK); 905 break; 906 case KBD_CMD_SCANCODE: 907 case KBD_CMD_SET_LEDS: 908 case KBD_CMD_SET_RATE: 909 s->common.write_cmd = val; 910 ps2_queue(&s->common, KBD_REPLY_ACK); 911 break; 912 case KBD_CMD_RESET_DISABLE: 913 ps2_reset_keyboard(s); 914 s->scan_enabled = 0; 915 ps2_queue(&s->common, KBD_REPLY_ACK); 916 break; 917 case KBD_CMD_RESET_ENABLE: 918 ps2_reset_keyboard(s); 919 s->scan_enabled = 1; 920 ps2_queue(&s->common, KBD_REPLY_ACK); 921 break; 922 case KBD_CMD_RESET: 923 ps2_reset_keyboard(s); 924 ps2_queue(&s->common, KBD_REPLY_ACK); 925 ps2_queue(&s->common, KBD_REPLY_POR); 926 break; 927 default: 928 ps2_queue(&s->common, KBD_REPLY_RESEND); 929 break; 930 } 931 break; 932 case KBD_CMD_SCANCODE: 933 if (val == 0) { 934 ps2_queue(&s->common, KBD_REPLY_ACK); 935 ps2_put_keycode(s, s->scancode_set); 936 } else if (val >= 1 && val <= 3) { 937 s->scancode_set = val; 938 ps2_queue(&s->common, KBD_REPLY_ACK); 939 } else { 940 ps2_queue(&s->common, KBD_REPLY_RESEND); 941 } 942 s->common.write_cmd = -1; 943 break; 944 case KBD_CMD_SET_LEDS: 945 ps2_set_ledstate(s, val); 946 ps2_queue(&s->common, KBD_REPLY_ACK); 947 s->common.write_cmd = -1; 948 break; 949 case KBD_CMD_SET_RATE: 950 ps2_queue(&s->common, KBD_REPLY_ACK); 951 s->common.write_cmd = -1; 952 break; 953 } 954 } 955 956 /* Set the scancode translation mode. 957 0 = raw scancodes. 958 1 = translated scancodes (used by qemu internally). */ 959 960 void ps2_keyboard_set_translation(void *opaque, int mode) 961 { 962 PS2KbdState *s = (PS2KbdState *)opaque; 963 trace_ps2_keyboard_set_translation(opaque, mode); 964 s->translate = mode; 965 } 966 967 static void ps2_mouse_send_packet(PS2MouseState *s) 968 { 969 unsigned int b; 970 int dx1, dy1, dz1; 971 972 dx1 = s->mouse_dx; 973 dy1 = s->mouse_dy; 974 dz1 = s->mouse_dz; 975 /* XXX: increase range to 8 bits ? */ 976 if (dx1 > 127) 977 dx1 = 127; 978 else if (dx1 < -127) 979 dx1 = -127; 980 if (dy1 > 127) 981 dy1 = 127; 982 else if (dy1 < -127) 983 dy1 = -127; 984 b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); 985 ps2_queue(&s->common, b); 986 ps2_queue(&s->common, dx1 & 0xff); 987 ps2_queue(&s->common, dy1 & 0xff); 988 /* extra byte for IMPS/2 or IMEX */ 989 switch(s->mouse_type) { 990 default: 991 break; 992 case 3: 993 if (dz1 > 127) 994 dz1 = 127; 995 else if (dz1 < -127) 996 dz1 = -127; 997 ps2_queue(&s->common, dz1 & 0xff); 998 break; 999 case 4: 1000 if (dz1 > 7) 1001 dz1 = 7; 1002 else if (dz1 < -7) 1003 dz1 = -7; 1004 b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); 1005 ps2_queue(&s->common, b); 1006 break; 1007 } 1008 1009 trace_ps2_mouse_send_packet(s, dx1, dy1, dz1, b); 1010 /* update deltas */ 1011 s->mouse_dx -= dx1; 1012 s->mouse_dy -= dy1; 1013 s->mouse_dz -= dz1; 1014 } 1015 1016 static void ps2_mouse_event(DeviceState *dev, QemuConsole *src, 1017 InputEvent *evt) 1018 { 1019 static const int bmap[INPUT_BUTTON__MAX] = { 1020 [INPUT_BUTTON_LEFT] = PS2_MOUSE_BUTTON_LEFT, 1021 [INPUT_BUTTON_MIDDLE] = PS2_MOUSE_BUTTON_MIDDLE, 1022 [INPUT_BUTTON_RIGHT] = PS2_MOUSE_BUTTON_RIGHT, 1023 [INPUT_BUTTON_SIDE] = PS2_MOUSE_BUTTON_SIDE, 1024 [INPUT_BUTTON_EXTRA] = PS2_MOUSE_BUTTON_EXTRA, 1025 }; 1026 PS2MouseState *s = (PS2MouseState *)dev; 1027 InputMoveEvent *move; 1028 InputBtnEvent *btn; 1029 1030 /* check if deltas are recorded when disabled */ 1031 if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) 1032 return; 1033 1034 switch (evt->type) { 1035 case INPUT_EVENT_KIND_REL: 1036 move = evt->u.rel.data; 1037 if (move->axis == INPUT_AXIS_X) { 1038 s->mouse_dx += move->value; 1039 } else if (move->axis == INPUT_AXIS_Y) { 1040 s->mouse_dy -= move->value; 1041 } 1042 break; 1043 1044 case INPUT_EVENT_KIND_BTN: 1045 btn = evt->u.btn.data; 1046 if (btn->down) { 1047 s->mouse_buttons |= bmap[btn->button]; 1048 if (btn->button == INPUT_BUTTON_WHEEL_UP) { 1049 s->mouse_dz--; 1050 } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) { 1051 s->mouse_dz++; 1052 } 1053 } else { 1054 s->mouse_buttons &= ~bmap[btn->button]; 1055 } 1056 break; 1057 1058 default: 1059 /* keep gcc happy */ 1060 break; 1061 } 1062 } 1063 1064 static void ps2_mouse_sync(DeviceState *dev) 1065 { 1066 PS2MouseState *s = (PS2MouseState *)dev; 1067 1068 if (s->mouse_buttons) { 1069 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); 1070 } 1071 if (!(s->mouse_status & MOUSE_STATUS_REMOTE)) { 1072 while (s->common.queue.count < PS2_QUEUE_SIZE - 4) { 1073 /* if not remote, send event. Multiple events are sent if 1074 too big deltas */ 1075 ps2_mouse_send_packet(s); 1076 if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0) 1077 break; 1078 } 1079 } 1080 } 1081 1082 void ps2_mouse_fake_event(void *opaque) 1083 { 1084 PS2MouseState *s = opaque; 1085 trace_ps2_mouse_fake_event(opaque); 1086 s->mouse_dx++; 1087 ps2_mouse_sync(opaque); 1088 } 1089 1090 void ps2_write_mouse(void *opaque, int val) 1091 { 1092 PS2MouseState *s = (PS2MouseState *)opaque; 1093 1094 trace_ps2_write_mouse(opaque, val); 1095 #ifdef DEBUG_MOUSE 1096 printf("kbd: write mouse 0x%02x\n", val); 1097 #endif 1098 switch(s->common.write_cmd) { 1099 default: 1100 case -1: 1101 /* mouse command */ 1102 if (s->mouse_wrap) { 1103 if (val == AUX_RESET_WRAP) { 1104 s->mouse_wrap = 0; 1105 ps2_queue(&s->common, AUX_ACK); 1106 return; 1107 } else if (val != AUX_RESET) { 1108 ps2_queue(&s->common, val); 1109 return; 1110 } 1111 } 1112 switch(val) { 1113 case AUX_SET_SCALE11: 1114 s->mouse_status &= ~MOUSE_STATUS_SCALE21; 1115 ps2_queue(&s->common, AUX_ACK); 1116 break; 1117 case AUX_SET_SCALE21: 1118 s->mouse_status |= MOUSE_STATUS_SCALE21; 1119 ps2_queue(&s->common, AUX_ACK); 1120 break; 1121 case AUX_SET_STREAM: 1122 s->mouse_status &= ~MOUSE_STATUS_REMOTE; 1123 ps2_queue(&s->common, AUX_ACK); 1124 break; 1125 case AUX_SET_WRAP: 1126 s->mouse_wrap = 1; 1127 ps2_queue(&s->common, AUX_ACK); 1128 break; 1129 case AUX_SET_REMOTE: 1130 s->mouse_status |= MOUSE_STATUS_REMOTE; 1131 ps2_queue(&s->common, AUX_ACK); 1132 break; 1133 case AUX_GET_TYPE: 1134 ps2_queue(&s->common, AUX_ACK); 1135 ps2_queue(&s->common, s->mouse_type); 1136 break; 1137 case AUX_SET_RES: 1138 case AUX_SET_SAMPLE: 1139 s->common.write_cmd = val; 1140 ps2_queue(&s->common, AUX_ACK); 1141 break; 1142 case AUX_GET_SCALE: 1143 ps2_queue(&s->common, AUX_ACK); 1144 ps2_queue(&s->common, s->mouse_status); 1145 ps2_queue(&s->common, s->mouse_resolution); 1146 ps2_queue(&s->common, s->mouse_sample_rate); 1147 break; 1148 case AUX_POLL: 1149 ps2_queue(&s->common, AUX_ACK); 1150 ps2_mouse_send_packet(s); 1151 break; 1152 case AUX_ENABLE_DEV: 1153 s->mouse_status |= MOUSE_STATUS_ENABLED; 1154 ps2_queue(&s->common, AUX_ACK); 1155 break; 1156 case AUX_DISABLE_DEV: 1157 s->mouse_status &= ~MOUSE_STATUS_ENABLED; 1158 ps2_queue(&s->common, AUX_ACK); 1159 break; 1160 case AUX_SET_DEFAULT: 1161 s->mouse_sample_rate = 100; 1162 s->mouse_resolution = 2; 1163 s->mouse_status = 0; 1164 ps2_queue(&s->common, AUX_ACK); 1165 break; 1166 case AUX_RESET: 1167 s->mouse_sample_rate = 100; 1168 s->mouse_resolution = 2; 1169 s->mouse_status = 0; 1170 s->mouse_type = 0; 1171 ps2_queue(&s->common, AUX_ACK); 1172 ps2_queue(&s->common, 0xaa); 1173 ps2_queue(&s->common, s->mouse_type); 1174 break; 1175 default: 1176 break; 1177 } 1178 break; 1179 case AUX_SET_SAMPLE: 1180 s->mouse_sample_rate = val; 1181 /* detect IMPS/2 or IMEX */ 1182 switch(s->mouse_detect_state) { 1183 default: 1184 case 0: 1185 if (val == 200) 1186 s->mouse_detect_state = 1; 1187 break; 1188 case 1: 1189 if (val == 100) 1190 s->mouse_detect_state = 2; 1191 else if (val == 200) 1192 s->mouse_detect_state = 3; 1193 else 1194 s->mouse_detect_state = 0; 1195 break; 1196 case 2: 1197 if (val == 80) 1198 s->mouse_type = 3; /* IMPS/2 */ 1199 s->mouse_detect_state = 0; 1200 break; 1201 case 3: 1202 if (val == 80) 1203 s->mouse_type = 4; /* IMEX */ 1204 s->mouse_detect_state = 0; 1205 break; 1206 } 1207 ps2_queue(&s->common, AUX_ACK); 1208 s->common.write_cmd = -1; 1209 break; 1210 case AUX_SET_RES: 1211 s->mouse_resolution = val; 1212 ps2_queue(&s->common, AUX_ACK); 1213 s->common.write_cmd = -1; 1214 break; 1215 } 1216 } 1217 1218 static void ps2_common_reset(PS2State *s) 1219 { 1220 s->write_cmd = -1; 1221 ps2_reset_queue(s); 1222 s->update_irq(s->update_arg, 0); 1223 } 1224 1225 static void ps2_common_post_load(PS2State *s) 1226 { 1227 PS2Queue *q = &s->queue; 1228 int size; 1229 int i; 1230 int tmp_data[PS2_QUEUE_SIZE]; 1231 1232 /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */ 1233 size = q->count > PS2_QUEUE_SIZE ? 0 : q->count; 1234 1235 /* move the queue elements to the start of data array */ 1236 if (size > 0) { 1237 for (i = 0; i < size; i++) { 1238 /* move the queue elements to the temporary buffer */ 1239 tmp_data[i] = q->data[q->rptr]; 1240 if (++q->rptr == 256) { 1241 q->rptr = 0; 1242 } 1243 } 1244 memcpy(q->data, tmp_data, size); 1245 } 1246 /* reset rptr/wptr/count */ 1247 q->rptr = 0; 1248 q->wptr = size; 1249 q->count = size; 1250 s->update_irq(s->update_arg, q->count != 0); 1251 } 1252 1253 static void ps2_kbd_reset(void *opaque) 1254 { 1255 PS2KbdState *s = (PS2KbdState *) opaque; 1256 1257 trace_ps2_kbd_reset(opaque); 1258 ps2_common_reset(&s->common); 1259 s->scan_enabled = 0; 1260 s->translate = 0; 1261 s->scancode_set = 2; 1262 s->modifiers = 0; 1263 } 1264 1265 static void ps2_mouse_reset(void *opaque) 1266 { 1267 PS2MouseState *s = (PS2MouseState *) opaque; 1268 1269 trace_ps2_mouse_reset(opaque); 1270 ps2_common_reset(&s->common); 1271 s->mouse_status = 0; 1272 s->mouse_resolution = 0; 1273 s->mouse_sample_rate = 0; 1274 s->mouse_wrap = 0; 1275 s->mouse_type = 0; 1276 s->mouse_detect_state = 0; 1277 s->mouse_dx = 0; 1278 s->mouse_dy = 0; 1279 s->mouse_dz = 0; 1280 s->mouse_buttons = 0; 1281 } 1282 1283 static const VMStateDescription vmstate_ps2_common = { 1284 .name = "PS2 Common State", 1285 .version_id = 3, 1286 .minimum_version_id = 2, 1287 .fields = (VMStateField[]) { 1288 VMSTATE_INT32(write_cmd, PS2State), 1289 VMSTATE_INT32(queue.rptr, PS2State), 1290 VMSTATE_INT32(queue.wptr, PS2State), 1291 VMSTATE_INT32(queue.count, PS2State), 1292 VMSTATE_BUFFER(queue.data, PS2State), 1293 VMSTATE_END_OF_LIST() 1294 } 1295 }; 1296 1297 static bool ps2_keyboard_ledstate_needed(void *opaque) 1298 { 1299 PS2KbdState *s = opaque; 1300 1301 return s->ledstate != 0; /* 0 is default state */ 1302 } 1303 1304 static int ps2_kbd_ledstate_post_load(void *opaque, int version_id) 1305 { 1306 PS2KbdState *s = opaque; 1307 1308 kbd_put_ledstate(s->ledstate); 1309 return 0; 1310 } 1311 1312 static const VMStateDescription vmstate_ps2_keyboard_ledstate = { 1313 .name = "ps2kbd/ledstate", 1314 .version_id = 3, 1315 .minimum_version_id = 2, 1316 .post_load = ps2_kbd_ledstate_post_load, 1317 .needed = ps2_keyboard_ledstate_needed, 1318 .fields = (VMStateField[]) { 1319 VMSTATE_INT32(ledstate, PS2KbdState), 1320 VMSTATE_END_OF_LIST() 1321 } 1322 }; 1323 1324 static bool ps2_keyboard_need_high_bit_needed(void *opaque) 1325 { 1326 PS2KbdState *s = opaque; 1327 return s->need_high_bit != 0; /* 0 is the usual state */ 1328 } 1329 1330 static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = { 1331 .name = "ps2kbd/need_high_bit", 1332 .version_id = 1, 1333 .minimum_version_id = 1, 1334 .needed = ps2_keyboard_need_high_bit_needed, 1335 .fields = (VMStateField[]) { 1336 VMSTATE_BOOL(need_high_bit, PS2KbdState), 1337 VMSTATE_END_OF_LIST() 1338 } 1339 }; 1340 1341 static int ps2_kbd_post_load(void* opaque, int version_id) 1342 { 1343 PS2KbdState *s = (PS2KbdState*)opaque; 1344 PS2State *ps2 = &s->common; 1345 1346 if (version_id == 2) 1347 s->scancode_set=2; 1348 1349 ps2_common_post_load(ps2); 1350 1351 return 0; 1352 } 1353 1354 static int ps2_kbd_pre_save(void *opaque) 1355 { 1356 PS2KbdState *s = (PS2KbdState *)opaque; 1357 PS2State *ps2 = &s->common; 1358 1359 ps2_common_post_load(ps2); 1360 1361 return 0; 1362 } 1363 1364 static const VMStateDescription vmstate_ps2_keyboard = { 1365 .name = "ps2kbd", 1366 .version_id = 3, 1367 .minimum_version_id = 2, 1368 .post_load = ps2_kbd_post_load, 1369 .pre_save = ps2_kbd_pre_save, 1370 .fields = (VMStateField[]) { 1371 VMSTATE_STRUCT(common, PS2KbdState, 0, vmstate_ps2_common, PS2State), 1372 VMSTATE_INT32(scan_enabled, PS2KbdState), 1373 VMSTATE_INT32(translate, PS2KbdState), 1374 VMSTATE_INT32_V(scancode_set, PS2KbdState,3), 1375 VMSTATE_END_OF_LIST() 1376 }, 1377 .subsections = (const VMStateDescription*[]) { 1378 &vmstate_ps2_keyboard_ledstate, 1379 &vmstate_ps2_keyboard_need_high_bit, 1380 NULL 1381 } 1382 }; 1383 1384 static int ps2_mouse_post_load(void *opaque, int version_id) 1385 { 1386 PS2MouseState *s = (PS2MouseState *)opaque; 1387 PS2State *ps2 = &s->common; 1388 1389 ps2_common_post_load(ps2); 1390 1391 return 0; 1392 } 1393 1394 static int ps2_mouse_pre_save(void *opaque) 1395 { 1396 PS2MouseState *s = (PS2MouseState *)opaque; 1397 PS2State *ps2 = &s->common; 1398 1399 ps2_common_post_load(ps2); 1400 1401 return 0; 1402 } 1403 1404 static const VMStateDescription vmstate_ps2_mouse = { 1405 .name = "ps2mouse", 1406 .version_id = 2, 1407 .minimum_version_id = 2, 1408 .post_load = ps2_mouse_post_load, 1409 .pre_save = ps2_mouse_pre_save, 1410 .fields = (VMStateField[]) { 1411 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State), 1412 VMSTATE_UINT8(mouse_status, PS2MouseState), 1413 VMSTATE_UINT8(mouse_resolution, PS2MouseState), 1414 VMSTATE_UINT8(mouse_sample_rate, PS2MouseState), 1415 VMSTATE_UINT8(mouse_wrap, PS2MouseState), 1416 VMSTATE_UINT8(mouse_type, PS2MouseState), 1417 VMSTATE_UINT8(mouse_detect_state, PS2MouseState), 1418 VMSTATE_INT32(mouse_dx, PS2MouseState), 1419 VMSTATE_INT32(mouse_dy, PS2MouseState), 1420 VMSTATE_INT32(mouse_dz, PS2MouseState), 1421 VMSTATE_UINT8(mouse_buttons, PS2MouseState), 1422 VMSTATE_END_OF_LIST() 1423 } 1424 }; 1425 1426 static QemuInputHandler ps2_keyboard_handler = { 1427 .name = "QEMU PS/2 Keyboard", 1428 .mask = INPUT_EVENT_MASK_KEY, 1429 .event = ps2_keyboard_event, 1430 }; 1431 1432 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg) 1433 { 1434 PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState)); 1435 1436 trace_ps2_kbd_init(s); 1437 s->common.update_irq = update_irq; 1438 s->common.update_arg = update_arg; 1439 s->scancode_set = 2; 1440 vmstate_register(NULL, 0, &vmstate_ps2_keyboard, s); 1441 qemu_input_handler_register((DeviceState *)s, 1442 &ps2_keyboard_handler); 1443 qemu_register_reset(ps2_kbd_reset, s); 1444 return s; 1445 } 1446 1447 static QemuInputHandler ps2_mouse_handler = { 1448 .name = "QEMU PS/2 Mouse", 1449 .mask = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL, 1450 .event = ps2_mouse_event, 1451 .sync = ps2_mouse_sync, 1452 }; 1453 1454 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg) 1455 { 1456 PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState)); 1457 1458 trace_ps2_mouse_init(s); 1459 s->common.update_irq = update_irq; 1460 s->common.update_arg = update_arg; 1461 vmstate_register(NULL, 0, &vmstate_ps2_mouse, s); 1462 qemu_input_handler_register((DeviceState *)s, 1463 &ps2_mouse_handler); 1464 qemu_register_reset(ps2_mouse_reset, s); 1465 return s; 1466 } 1467