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