Commit daa579632da11bd3108326ed04de1c096fc5f849
1 parent
e80e1cc4
PS2 mouse and keyboard separation (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1658 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
51 additions
and
381 deletions
Makefile.target
| ... | ... | @@ -298,13 +298,13 @@ VL_OBJS+= usb.o usb-uhci.o usb-linux.o usb-hid.o |
| 298 | 298 | |
| 299 | 299 | ifeq ($(TARGET_BASE_ARCH), i386) |
| 300 | 300 | # Hardware support |
| 301 | -VL_OBJS+= ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) | |
| 301 | +VL_OBJS+= ide.o ne2000.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) | |
| 302 | 302 | VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o |
| 303 | 303 | VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o |
| 304 | 304 | DEFINES += -DHAS_AUDIO |
| 305 | 305 | endif |
| 306 | 306 | ifeq ($(TARGET_BASE_ARCH), ppc) |
| 307 | -VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) | |
| 307 | +VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) | |
| 308 | 308 | VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o |
| 309 | 309 | VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o |
| 310 | 310 | DEFINES += -DHAS_AUDIO |
| ... | ... | @@ -315,7 +315,7 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8254.o i8259.o |
| 315 | 315 | endif |
| 316 | 316 | ifeq ($(TARGET_BASE_ARCH), sparc) |
| 317 | 317 | ifeq ($(TARGET_ARCH), sparc64) |
| 318 | -VL_OBJS+= sun4u.o ide.o ne2000.o pckbd.o vga.o | |
| 318 | +VL_OBJS+= sun4u.o ide.o ne2000.o pckbd.o ps2.o vga.o | |
| 319 | 319 | VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o |
| 320 | 320 | VL_OBJS+= cirrus_vga.o parallel.o |
| 321 | 321 | VL_OBJS+= magic-load.o | ... | ... |
hw/pckbd.c
| ... | ... | @@ -110,32 +110,17 @@ |
| 110 | 110 | |
| 111 | 111 | #define KBD_QUEUE_SIZE 256 |
| 112 | 112 | |
| 113 | -typedef struct { | |
| 114 | - uint8_t aux[KBD_QUEUE_SIZE]; | |
| 115 | - uint8_t data[KBD_QUEUE_SIZE]; | |
| 116 | - int rptr, wptr, count; | |
| 117 | -} KBDQueue; | |
| 113 | +#define KBD_PENDING_KBD 1 | |
| 114 | +#define KBD_PENDING_AUX 2 | |
| 118 | 115 | |
| 119 | 116 | typedef struct KBDState { |
| 120 | - KBDQueue queue; | |
| 121 | 117 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ |
| 122 | 118 | uint8_t status; |
| 123 | 119 | uint8_t mode; |
| 124 | - /* keyboard state */ | |
| 125 | - int kbd_write_cmd; | |
| 126 | - int scan_enabled; | |
| 127 | - /* mouse state */ | |
| 128 | - int mouse_write_cmd; | |
| 129 | - uint8_t mouse_status; | |
| 130 | - uint8_t mouse_resolution; | |
| 131 | - uint8_t mouse_sample_rate; | |
| 132 | - uint8_t mouse_wrap; | |
| 133 | - uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */ | |
| 134 | - uint8_t mouse_detect_state; | |
| 135 | - int mouse_dx; /* current values, needed for 'poll' mode */ | |
| 136 | - int mouse_dy; | |
| 137 | - int mouse_dz; | |
| 138 | - uint8_t mouse_buttons; | |
| 120 | + /* Bitmask of devices with data available. */ | |
| 121 | + int pending; | |
| 122 | + void *kbd; | |
| 123 | + void *mouse; | |
| 139 | 124 | } KBDState; |
| 140 | 125 | |
| 141 | 126 | KBDState kbd_state; |
| ... | ... | @@ -145,15 +130,15 @@ KBDState kbd_state; |
| 145 | 130 | incorrect, but it avoids having to simulate exact delays */ |
| 146 | 131 | static void kbd_update_irq(KBDState *s) |
| 147 | 132 | { |
| 148 | - KBDQueue *q = &s->queue; | |
| 149 | 133 | int irq12_level, irq1_level; |
| 150 | 134 | |
| 151 | 135 | irq1_level = 0; |
| 152 | 136 | irq12_level = 0; |
| 153 | 137 | s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); |
| 154 | - if (q->count != 0) { | |
| 138 | + if (s->pending) { | |
| 155 | 139 | s->status |= KBD_STAT_OBF; |
| 156 | - if (q->aux[q->rptr]) { | |
| 140 | + /* kdb data takes priority over aux data. */ | |
| 141 | + if (s->pending == KBD_PENDING_AUX) { | |
| 157 | 142 | s->status |= KBD_STAT_MOUSE_OBF; |
| 158 | 143 | if (s->mode & KBD_MODE_MOUSE_INT) |
| 159 | 144 | irq12_level = 1; |
| ... | ... | @@ -167,32 +152,26 @@ static void kbd_update_irq(KBDState *s) |
| 167 | 152 | pic_set_irq(12, irq12_level); |
| 168 | 153 | } |
| 169 | 154 | |
| 170 | -static void kbd_queue(KBDState *s, int b, int aux) | |
| 155 | +static void kbd_update_kbd_irq(void *opaque, int level) | |
| 171 | 156 | { |
| 172 | - KBDQueue *q = &s->queue; | |
| 157 | + KBDState *s = (KBDState *)opaque; | |
| 173 | 158 | |
| 174 | -#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) | |
| 175 | - if (aux) | |
| 176 | - printf("mouse event: 0x%02x\n", b); | |
| 177 | -#ifdef DEBUG_KBD | |
| 159 | + if (level) | |
| 160 | + s->pending |= KBD_PENDING_KBD; | |
| 178 | 161 | else |
| 179 | - printf("kbd event: 0x%02x\n", b); | |
| 180 | -#endif | |
| 181 | -#endif | |
| 182 | - if (q->count >= KBD_QUEUE_SIZE) | |
| 183 | - return; | |
| 184 | - q->aux[q->wptr] = aux; | |
| 185 | - q->data[q->wptr] = b; | |
| 186 | - if (++q->wptr == KBD_QUEUE_SIZE) | |
| 187 | - q->wptr = 0; | |
| 188 | - q->count++; | |
| 162 | + s->pending &= ~KBD_PENDING_KBD; | |
| 189 | 163 | kbd_update_irq(s); |
| 190 | 164 | } |
| 191 | 165 | |
| 192 | -static void pc_kbd_put_keycode(void *opaque, int keycode) | |
| 166 | +static void kbd_update_aux_irq(void *opaque, int level) | |
| 193 | 167 | { |
| 194 | - KBDState *s = opaque; | |
| 195 | - kbd_queue(s, keycode, 0); | |
| 168 | + KBDState *s = (KBDState *)opaque; | |
| 169 | + | |
| 170 | + if (level) | |
| 171 | + s->pending |= KBD_PENDING_AUX; | |
| 172 | + else | |
| 173 | + s->pending &= ~KBD_PENDING_AUX; | |
| 174 | + kbd_update_irq(s); | |
| 196 | 175 | } |
| 197 | 176 | |
| 198 | 177 | static uint32_t kbd_read_status(void *opaque, uint32_t addr) |
| ... | ... | @@ -206,6 +185,14 @@ static uint32_t kbd_read_status(void *opaque, uint32_t addr) |
| 206 | 185 | return val; |
| 207 | 186 | } |
| 208 | 187 | |
| 188 | +static void kbd_queue(KBDState *s, int b, int aux) | |
| 189 | +{ | |
| 190 | + if (aux) | |
| 191 | + ps2_queue(s->mouse, b); | |
| 192 | + else | |
| 193 | + ps2_queue(s->kbd, b); | |
| 194 | +} | |
| 195 | + | |
| 209 | 196 | static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) |
| 210 | 197 | { |
| 211 | 198 | KBDState *s = opaque; |
| ... | ... | @@ -287,304 +274,11 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) |
| 287 | 274 | static uint32_t kbd_read_data(void *opaque, uint32_t addr) |
| 288 | 275 | { |
| 289 | 276 | KBDState *s = opaque; |
| 290 | - KBDQueue *q; | |
| 291 | - int val, index, aux; | |
| 292 | - | |
| 293 | - q = &s->queue; | |
| 294 | - if (q->count == 0) { | |
| 295 | - /* NOTE: if no data left, we return the last keyboard one | |
| 296 | - (needed for EMM386) */ | |
| 297 | - /* XXX: need a timer to do things correctly */ | |
| 298 | - index = q->rptr - 1; | |
| 299 | - if (index < 0) | |
| 300 | - index = KBD_QUEUE_SIZE - 1; | |
| 301 | - val = q->data[index]; | |
| 302 | - } else { | |
| 303 | - aux = q->aux[q->rptr]; | |
| 304 | - val = q->data[q->rptr]; | |
| 305 | - if (++q->rptr == KBD_QUEUE_SIZE) | |
| 306 | - q->rptr = 0; | |
| 307 | - q->count--; | |
| 308 | - /* reading deasserts IRQ */ | |
| 309 | - if (aux) | |
| 310 | - pic_set_irq(12, 0); | |
| 311 | - else | |
| 312 | - pic_set_irq(1, 0); | |
| 313 | - } | |
| 314 | - /* reassert IRQs if data left */ | |
| 315 | - kbd_update_irq(s); | |
| 316 | -#ifdef DEBUG_KBD | |
| 317 | - printf("kbd: read data=0x%02x\n", val); | |
| 318 | -#endif | |
| 319 | - return val; | |
| 320 | -} | |
| 321 | - | |
| 322 | -static void kbd_reset_keyboard(KBDState *s) | |
| 323 | -{ | |
| 324 | - s->scan_enabled = 1; | |
| 325 | -} | |
| 326 | - | |
| 327 | -static void kbd_write_keyboard(KBDState *s, int val) | |
| 328 | -{ | |
| 329 | - switch(s->kbd_write_cmd) { | |
| 330 | - default: | |
| 331 | - case -1: | |
| 332 | - switch(val) { | |
| 333 | - case 0x00: | |
| 334 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 335 | - break; | |
| 336 | - case 0x05: | |
| 337 | - kbd_queue(s, KBD_REPLY_RESEND, 0); | |
| 338 | - break; | |
| 339 | - case KBD_CMD_GET_ID: | |
| 340 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 341 | - kbd_queue(s, 0xab, 0); | |
| 342 | - kbd_queue(s, 0x83, 0); | |
| 343 | - break; | |
| 344 | - case KBD_CMD_ECHO: | |
| 345 | - kbd_queue(s, KBD_CMD_ECHO, 0); | |
| 346 | - break; | |
| 347 | - case KBD_CMD_ENABLE: | |
| 348 | - s->scan_enabled = 1; | |
| 349 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 350 | - break; | |
| 351 | - case KBD_CMD_SET_LEDS: | |
| 352 | - case KBD_CMD_SET_RATE: | |
| 353 | - s->kbd_write_cmd = val; | |
| 354 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 355 | - break; | |
| 356 | - case KBD_CMD_RESET_DISABLE: | |
| 357 | - kbd_reset_keyboard(s); | |
| 358 | - s->scan_enabled = 0; | |
| 359 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 360 | - break; | |
| 361 | - case KBD_CMD_RESET_ENABLE: | |
| 362 | - kbd_reset_keyboard(s); | |
| 363 | - s->scan_enabled = 1; | |
| 364 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 365 | - break; | |
| 366 | - case KBD_CMD_RESET: | |
| 367 | - kbd_reset_keyboard(s); | |
| 368 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 369 | - kbd_queue(s, KBD_REPLY_POR, 0); | |
| 370 | - break; | |
| 371 | - default: | |
| 372 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 373 | - break; | |
| 374 | - } | |
| 375 | - break; | |
| 376 | - case KBD_CMD_SET_LEDS: | |
| 377 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 378 | - s->kbd_write_cmd = -1; | |
| 379 | - break; | |
| 380 | - case KBD_CMD_SET_RATE: | |
| 381 | - kbd_queue(s, KBD_REPLY_ACK, 0); | |
| 382 | - s->kbd_write_cmd = -1; | |
| 383 | - break; | |
| 384 | - } | |
| 385 | -} | |
| 386 | - | |
| 387 | -static void kbd_mouse_send_packet(KBDState *s) | |
| 388 | -{ | |
| 389 | - unsigned int b; | |
| 390 | - int dx1, dy1, dz1; | |
| 391 | - | |
| 392 | - dx1 = s->mouse_dx; | |
| 393 | - dy1 = s->mouse_dy; | |
| 394 | - dz1 = s->mouse_dz; | |
| 395 | - /* XXX: increase range to 8 bits ? */ | |
| 396 | - if (dx1 > 127) | |
| 397 | - dx1 = 127; | |
| 398 | - else if (dx1 < -127) | |
| 399 | - dx1 = -127; | |
| 400 | - if (dy1 > 127) | |
| 401 | - dy1 = 127; | |
| 402 | - else if (dy1 < -127) | |
| 403 | - dy1 = -127; | |
| 404 | - b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07); | |
| 405 | - kbd_queue(s, b, 1); | |
| 406 | - kbd_queue(s, dx1 & 0xff, 1); | |
| 407 | - kbd_queue(s, dy1 & 0xff, 1); | |
| 408 | - /* extra byte for IMPS/2 or IMEX */ | |
| 409 | - switch(s->mouse_type) { | |
| 410 | - default: | |
| 411 | - break; | |
| 412 | - case 3: | |
| 413 | - if (dz1 > 127) | |
| 414 | - dz1 = 127; | |
| 415 | - else if (dz1 < -127) | |
| 416 | - dz1 = -127; | |
| 417 | - kbd_queue(s, dz1 & 0xff, 1); | |
| 418 | - break; | |
| 419 | - case 4: | |
| 420 | - if (dz1 > 7) | |
| 421 | - dz1 = 7; | |
| 422 | - else if (dz1 < -7) | |
| 423 | - dz1 = -7; | |
| 424 | - b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1); | |
| 425 | - kbd_queue(s, b, 1); | |
| 426 | - break; | |
| 427 | - } | |
| 428 | - | |
| 429 | - /* update deltas */ | |
| 430 | - s->mouse_dx -= dx1; | |
| 431 | - s->mouse_dy -= dy1; | |
| 432 | - s->mouse_dz -= dz1; | |
| 433 | -} | |
| 434 | - | |
| 435 | -static void pc_kbd_mouse_event(void *opaque, | |
| 436 | - int dx, int dy, int dz, int buttons_state) | |
| 437 | -{ | |
| 438 | - KBDState *s = opaque; | |
| 439 | 277 | |
| 440 | - /* check if deltas are recorded when disabled */ | |
| 441 | - if (!(s->mouse_status & MOUSE_STATUS_ENABLED)) | |
| 442 | - return; | |
| 443 | - | |
| 444 | - s->mouse_dx += dx; | |
| 445 | - s->mouse_dy -= dy; | |
| 446 | - s->mouse_dz += dz; | |
| 447 | - /* XXX: SDL sometimes generates nul events: we delete them */ | |
| 448 | - if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 && | |
| 449 | - s->mouse_buttons == buttons_state) | |
| 450 | - return; | |
| 451 | - s->mouse_buttons = buttons_state; | |
| 452 | - | |
| 453 | - if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && | |
| 454 | - (s->queue.count < (KBD_QUEUE_SIZE - 16))) { | |
| 455 | - for(;;) { | |
| 456 | - /* if not remote, send event. Multiple events are sent if | |
| 457 | - too big deltas */ | |
| 458 | - kbd_mouse_send_packet(s); | |
| 459 | - if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0) | |
| 460 | - break; | |
| 461 | - } | |
| 462 | - } | |
| 463 | -} | |
| 278 | + if (s->pending == KBD_PENDING_AUX) | |
| 279 | + return ps2_read_data(s->mouse); | |
| 464 | 280 | |
| 465 | -static void kbd_write_mouse(KBDState *s, int val) | |
| 466 | -{ | |
| 467 | -#ifdef DEBUG_MOUSE | |
| 468 | - printf("kbd: write mouse 0x%02x\n", val); | |
| 469 | -#endif | |
| 470 | - switch(s->mouse_write_cmd) { | |
| 471 | - default: | |
| 472 | - case -1: | |
| 473 | - /* mouse command */ | |
| 474 | - if (s->mouse_wrap) { | |
| 475 | - if (val == AUX_RESET_WRAP) { | |
| 476 | - s->mouse_wrap = 0; | |
| 477 | - kbd_queue(s, AUX_ACK, 1); | |
| 478 | - return; | |
| 479 | - } else if (val != AUX_RESET) { | |
| 480 | - kbd_queue(s, val, 1); | |
| 481 | - return; | |
| 482 | - } | |
| 483 | - } | |
| 484 | - switch(val) { | |
| 485 | - case AUX_SET_SCALE11: | |
| 486 | - s->mouse_status &= ~MOUSE_STATUS_SCALE21; | |
| 487 | - kbd_queue(s, AUX_ACK, 1); | |
| 488 | - break; | |
| 489 | - case AUX_SET_SCALE21: | |
| 490 | - s->mouse_status |= MOUSE_STATUS_SCALE21; | |
| 491 | - kbd_queue(s, AUX_ACK, 1); | |
| 492 | - break; | |
| 493 | - case AUX_SET_STREAM: | |
| 494 | - s->mouse_status &= ~MOUSE_STATUS_REMOTE; | |
| 495 | - kbd_queue(s, AUX_ACK, 1); | |
| 496 | - break; | |
| 497 | - case AUX_SET_WRAP: | |
| 498 | - s->mouse_wrap = 1; | |
| 499 | - kbd_queue(s, AUX_ACK, 1); | |
| 500 | - break; | |
| 501 | - case AUX_SET_REMOTE: | |
| 502 | - s->mouse_status |= MOUSE_STATUS_REMOTE; | |
| 503 | - kbd_queue(s, AUX_ACK, 1); | |
| 504 | - break; | |
| 505 | - case AUX_GET_TYPE: | |
| 506 | - kbd_queue(s, AUX_ACK, 1); | |
| 507 | - kbd_queue(s, s->mouse_type, 1); | |
| 508 | - break; | |
| 509 | - case AUX_SET_RES: | |
| 510 | - case AUX_SET_SAMPLE: | |
| 511 | - s->mouse_write_cmd = val; | |
| 512 | - kbd_queue(s, AUX_ACK, 1); | |
| 513 | - break; | |
| 514 | - case AUX_GET_SCALE: | |
| 515 | - kbd_queue(s, AUX_ACK, 1); | |
| 516 | - kbd_queue(s, s->mouse_status, 1); | |
| 517 | - kbd_queue(s, s->mouse_resolution, 1); | |
| 518 | - kbd_queue(s, s->mouse_sample_rate, 1); | |
| 519 | - break; | |
| 520 | - case AUX_POLL: | |
| 521 | - kbd_queue(s, AUX_ACK, 1); | |
| 522 | - kbd_mouse_send_packet(s); | |
| 523 | - break; | |
| 524 | - case AUX_ENABLE_DEV: | |
| 525 | - s->mouse_status |= MOUSE_STATUS_ENABLED; | |
| 526 | - kbd_queue(s, AUX_ACK, 1); | |
| 527 | - break; | |
| 528 | - case AUX_DISABLE_DEV: | |
| 529 | - s->mouse_status &= ~MOUSE_STATUS_ENABLED; | |
| 530 | - kbd_queue(s, AUX_ACK, 1); | |
| 531 | - break; | |
| 532 | - case AUX_SET_DEFAULT: | |
| 533 | - s->mouse_sample_rate = 100; | |
| 534 | - s->mouse_resolution = 2; | |
| 535 | - s->mouse_status = 0; | |
| 536 | - kbd_queue(s, AUX_ACK, 1); | |
| 537 | - break; | |
| 538 | - case AUX_RESET: | |
| 539 | - s->mouse_sample_rate = 100; | |
| 540 | - s->mouse_resolution = 2; | |
| 541 | - s->mouse_status = 0; | |
| 542 | - s->mouse_type = 0; | |
| 543 | - kbd_queue(s, AUX_ACK, 1); | |
| 544 | - kbd_queue(s, 0xaa, 1); | |
| 545 | - kbd_queue(s, s->mouse_type, 1); | |
| 546 | - break; | |
| 547 | - default: | |
| 548 | - break; | |
| 549 | - } | |
| 550 | - break; | |
| 551 | - case AUX_SET_SAMPLE: | |
| 552 | - s->mouse_sample_rate = val; | |
| 553 | - /* detect IMPS/2 or IMEX */ | |
| 554 | - switch(s->mouse_detect_state) { | |
| 555 | - default: | |
| 556 | - case 0: | |
| 557 | - if (val == 200) | |
| 558 | - s->mouse_detect_state = 1; | |
| 559 | - break; | |
| 560 | - case 1: | |
| 561 | - if (val == 100) | |
| 562 | - s->mouse_detect_state = 2; | |
| 563 | - else if (val == 200) | |
| 564 | - s->mouse_detect_state = 3; | |
| 565 | - else | |
| 566 | - s->mouse_detect_state = 0; | |
| 567 | - break; | |
| 568 | - case 2: | |
| 569 | - if (val == 80) | |
| 570 | - s->mouse_type = 3; /* IMPS/2 */ | |
| 571 | - s->mouse_detect_state = 0; | |
| 572 | - break; | |
| 573 | - case 3: | |
| 574 | - if (val == 80) | |
| 575 | - s->mouse_type = 4; /* IMEX */ | |
| 576 | - s->mouse_detect_state = 0; | |
| 577 | - break; | |
| 578 | - } | |
| 579 | - kbd_queue(s, AUX_ACK, 1); | |
| 580 | - s->mouse_write_cmd = -1; | |
| 581 | - break; | |
| 582 | - case AUX_SET_RES: | |
| 583 | - s->mouse_resolution = val; | |
| 584 | - kbd_queue(s, AUX_ACK, 1); | |
| 585 | - s->mouse_write_cmd = -1; | |
| 586 | - break; | |
| 587 | - } | |
| 281 | + return ps2_read_data(s->kbd); | |
| 588 | 282 | } |
| 589 | 283 | |
| 590 | 284 | void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) |
| ... | ... | @@ -597,10 +291,11 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) |
| 597 | 291 | |
| 598 | 292 | switch(s->write_cmd) { |
| 599 | 293 | case 0: |
| 600 | - kbd_write_keyboard(s, val); | |
| 294 | + ps2_write_keyboard(s->kbd, val); | |
| 601 | 295 | break; |
| 602 | 296 | case KBD_CCMD_WRITE_MODE: |
| 603 | 297 | s->mode = val; |
| 298 | + /* ??? */ | |
| 604 | 299 | kbd_update_irq(s); |
| 605 | 300 | break; |
| 606 | 301 | case KBD_CCMD_WRITE_OBUF: |
| ... | ... | @@ -618,7 +313,7 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) |
| 618 | 313 | } |
| 619 | 314 | break; |
| 620 | 315 | case KBD_CCMD_WRITE_MOUSE: |
| 621 | - kbd_write_mouse(s, val); | |
| 316 | + ps2_write_mouse(s->mouse, val); | |
| 622 | 317 | break; |
| 623 | 318 | default: |
| 624 | 319 | break; |
| ... | ... | @@ -629,16 +324,9 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) |
| 629 | 324 | static void kbd_reset(void *opaque) |
| 630 | 325 | { |
| 631 | 326 | KBDState *s = opaque; |
| 632 | - KBDQueue *q; | |
| 633 | 327 | |
| 634 | - s->kbd_write_cmd = -1; | |
| 635 | - s->mouse_write_cmd = -1; | |
| 636 | 328 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; |
| 637 | 329 | s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; |
| 638 | - q = &s->queue; | |
| 639 | - q->rptr = 0; | |
| 640 | - q->wptr = 0; | |
| 641 | - q->count = 0; | |
| 642 | 330 | } |
| 643 | 331 | |
| 644 | 332 | static void kbd_save(QEMUFile* f, void* opaque) |
| ... | ... | @@ -648,43 +336,17 @@ static void kbd_save(QEMUFile* f, void* opaque) |
| 648 | 336 | qemu_put_8s(f, &s->write_cmd); |
| 649 | 337 | qemu_put_8s(f, &s->status); |
| 650 | 338 | qemu_put_8s(f, &s->mode); |
| 651 | - qemu_put_be32s(f, &s->kbd_write_cmd); | |
| 652 | - qemu_put_be32s(f, &s->scan_enabled); | |
| 653 | - qemu_put_be32s(f, &s->mouse_write_cmd); | |
| 654 | - qemu_put_8s(f, &s->mouse_status); | |
| 655 | - qemu_put_8s(f, &s->mouse_resolution); | |
| 656 | - qemu_put_8s(f, &s->mouse_sample_rate); | |
| 657 | - qemu_put_8s(f, &s->mouse_wrap); | |
| 658 | - qemu_put_8s(f, &s->mouse_type); | |
| 659 | - qemu_put_8s(f, &s->mouse_detect_state); | |
| 660 | - qemu_put_be32s(f, &s->mouse_dx); | |
| 661 | - qemu_put_be32s(f, &s->mouse_dy); | |
| 662 | - qemu_put_be32s(f, &s->mouse_dz); | |
| 663 | - qemu_put_8s(f, &s->mouse_buttons); | |
| 664 | 339 | } |
| 665 | 340 | |
| 666 | 341 | static int kbd_load(QEMUFile* f, void* opaque, int version_id) |
| 667 | 342 | { |
| 668 | 343 | KBDState *s = (KBDState*)opaque; |
| 669 | 344 | |
| 670 | - if (version_id != 1) | |
| 345 | + if (version_id != 2) | |
| 671 | 346 | return -EINVAL; |
| 672 | 347 | qemu_get_8s(f, &s->write_cmd); |
| 673 | 348 | qemu_get_8s(f, &s->status); |
| 674 | 349 | qemu_get_8s(f, &s->mode); |
| 675 | - qemu_get_be32s(f, &s->kbd_write_cmd); | |
| 676 | - qemu_get_be32s(f, &s->scan_enabled); | |
| 677 | - qemu_get_be32s(f, &s->mouse_write_cmd); | |
| 678 | - qemu_get_8s(f, &s->mouse_status); | |
| 679 | - qemu_get_8s(f, &s->mouse_resolution); | |
| 680 | - qemu_get_8s(f, &s->mouse_sample_rate); | |
| 681 | - qemu_get_8s(f, &s->mouse_wrap); | |
| 682 | - qemu_get_8s(f, &s->mouse_type); | |
| 683 | - qemu_get_8s(f, &s->mouse_detect_state); | |
| 684 | - qemu_get_be32s(f, &s->mouse_dx); | |
| 685 | - qemu_get_be32s(f, &s->mouse_dy); | |
| 686 | - qemu_get_be32s(f, &s->mouse_dz); | |
| 687 | - qemu_get_8s(f, &s->mouse_buttons); | |
| 688 | 350 | return 0; |
| 689 | 351 | } |
| 690 | 352 | |
| ... | ... | @@ -693,13 +355,13 @@ void kbd_init(void) |
| 693 | 355 | KBDState *s = &kbd_state; |
| 694 | 356 | |
| 695 | 357 | kbd_reset(s); |
| 696 | - register_savevm("pckbd", 0, 1, kbd_save, kbd_load, s); | |
| 358 | + register_savevm("pckbd", 0, 2, kbd_save, kbd_load, s); | |
| 697 | 359 | register_ioport_read(0x60, 1, 1, kbd_read_data, s); |
| 698 | 360 | register_ioport_write(0x60, 1, 1, kbd_write_data, s); |
| 699 | 361 | register_ioport_read(0x64, 1, 1, kbd_read_status, s); |
| 700 | 362 | register_ioport_write(0x64, 1, 1, kbd_write_command, s); |
| 701 | 363 | |
| 702 | - qemu_add_kbd_event_handler(pc_kbd_put_keycode, s); | |
| 703 | - qemu_add_mouse_event_handler(pc_kbd_mouse_event, s); | |
| 364 | + s->kbd = ps2_kbd_init(kbd_update_kbd_irq, s); | |
| 365 | + s->mouse = ps2_mouse_init(kbd_update_aux_irq, s); | |
| 704 | 366 | qemu_register_reset(kbd_reset, s); |
| 705 | 367 | } | ... | ... |
vl.h
| ... | ... | @@ -928,6 +928,14 @@ void do_usb_add(const char *devname); |
| 928 | 928 | void do_usb_del(const char *devname); |
| 929 | 929 | void usb_info(void); |
| 930 | 930 | |
| 931 | +/* ps2.c */ | |
| 932 | +void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg); | |
| 933 | +void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg); | |
| 934 | +void ps2_write_mouse(void *, int val); | |
| 935 | +void ps2_write_keyboard(void *, int val); | |
| 936 | +uint32_t ps2_read_data(void *); | |
| 937 | +void ps2_queue(void *, int b); | |
| 938 | + | |
| 931 | 939 | #endif /* defined(QEMU_TOOL) */ |
| 932 | 940 | |
| 933 | 941 | /* monitor.c */ | ... | ... |