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,13 +298,13 @@ VL_OBJS+= usb.o usb-uhci.o usb-linux.o usb-hid.o | ||
| 298 | 298 | ||
| 299 | ifeq ($(TARGET_BASE_ARCH), i386) | 299 | ifeq ($(TARGET_BASE_ARCH), i386) |
| 300 | # Hardware support | 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 | VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o | 302 | VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o |
| 303 | VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o | 303 | VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o |
| 304 | DEFINES += -DHAS_AUDIO | 304 | DEFINES += -DHAS_AUDIO |
| 305 | endif | 305 | endif |
| 306 | ifeq ($(TARGET_BASE_ARCH), ppc) | 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 | VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o | 308 | VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o |
| 309 | VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o | 309 | VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o |
| 310 | DEFINES += -DHAS_AUDIO | 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,7 +315,7 @@ VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8254.o i8259.o | ||
| 315 | endif | 315 | endif |
| 316 | ifeq ($(TARGET_BASE_ARCH), sparc) | 316 | ifeq ($(TARGET_BASE_ARCH), sparc) |
| 317 | ifeq ($(TARGET_ARCH), sparc64) | 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 | VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o | 319 | VL_OBJS+= fdc.o mc146818rtc.o serial.o m48t59.o |
| 320 | VL_OBJS+= cirrus_vga.o parallel.o | 320 | VL_OBJS+= cirrus_vga.o parallel.o |
| 321 | VL_OBJS+= magic-load.o | 321 | VL_OBJS+= magic-load.o |
hw/pckbd.c
| @@ -110,32 +110,17 @@ | @@ -110,32 +110,17 @@ | ||
| 110 | 110 | ||
| 111 | #define KBD_QUEUE_SIZE 256 | 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 | typedef struct KBDState { | 116 | typedef struct KBDState { |
| 120 | - KBDQueue queue; | ||
| 121 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ | 117 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ |
| 122 | uint8_t status; | 118 | uint8_t status; |
| 123 | uint8_t mode; | 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 | } KBDState; | 124 | } KBDState; |
| 140 | 125 | ||
| 141 | KBDState kbd_state; | 126 | KBDState kbd_state; |
| @@ -145,15 +130,15 @@ KBDState kbd_state; | @@ -145,15 +130,15 @@ KBDState kbd_state; | ||
| 145 | incorrect, but it avoids having to simulate exact delays */ | 130 | incorrect, but it avoids having to simulate exact delays */ |
| 146 | static void kbd_update_irq(KBDState *s) | 131 | static void kbd_update_irq(KBDState *s) |
| 147 | { | 132 | { |
| 148 | - KBDQueue *q = &s->queue; | ||
| 149 | int irq12_level, irq1_level; | 133 | int irq12_level, irq1_level; |
| 150 | 134 | ||
| 151 | irq1_level = 0; | 135 | irq1_level = 0; |
| 152 | irq12_level = 0; | 136 | irq12_level = 0; |
| 153 | s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); | 137 | s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); |
| 154 | - if (q->count != 0) { | 138 | + if (s->pending) { |
| 155 | s->status |= KBD_STAT_OBF; | 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 | s->status |= KBD_STAT_MOUSE_OBF; | 142 | s->status |= KBD_STAT_MOUSE_OBF; |
| 158 | if (s->mode & KBD_MODE_MOUSE_INT) | 143 | if (s->mode & KBD_MODE_MOUSE_INT) |
| 159 | irq12_level = 1; | 144 | irq12_level = 1; |
| @@ -167,32 +152,26 @@ static void kbd_update_irq(KBDState *s) | @@ -167,32 +152,26 @@ static void kbd_update_irq(KBDState *s) | ||
| 167 | pic_set_irq(12, irq12_level); | 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 | else | 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 | kbd_update_irq(s); | 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 | static uint32_t kbd_read_status(void *opaque, uint32_t addr) | 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,6 +185,14 @@ static uint32_t kbd_read_status(void *opaque, uint32_t addr) | ||
| 206 | return val; | 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 | static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) | 196 | static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) |
| 210 | { | 197 | { |
| 211 | KBDState *s = opaque; | 198 | KBDState *s = opaque; |
| @@ -287,304 +274,11 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) | @@ -287,304 +274,11 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) | ||
| 287 | static uint32_t kbd_read_data(void *opaque, uint32_t addr) | 274 | static uint32_t kbd_read_data(void *opaque, uint32_t addr) |
| 288 | { | 275 | { |
| 289 | KBDState *s = opaque; | 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 | void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | 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,10 +291,11 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | ||
| 597 | 291 | ||
| 598 | switch(s->write_cmd) { | 292 | switch(s->write_cmd) { |
| 599 | case 0: | 293 | case 0: |
| 600 | - kbd_write_keyboard(s, val); | 294 | + ps2_write_keyboard(s->kbd, val); |
| 601 | break; | 295 | break; |
| 602 | case KBD_CCMD_WRITE_MODE: | 296 | case KBD_CCMD_WRITE_MODE: |
| 603 | s->mode = val; | 297 | s->mode = val; |
| 298 | + /* ??? */ | ||
| 604 | kbd_update_irq(s); | 299 | kbd_update_irq(s); |
| 605 | break; | 300 | break; |
| 606 | case KBD_CCMD_WRITE_OBUF: | 301 | case KBD_CCMD_WRITE_OBUF: |
| @@ -618,7 +313,7 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | @@ -618,7 +313,7 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | ||
| 618 | } | 313 | } |
| 619 | break; | 314 | break; |
| 620 | case KBD_CCMD_WRITE_MOUSE: | 315 | case KBD_CCMD_WRITE_MOUSE: |
| 621 | - kbd_write_mouse(s, val); | 316 | + ps2_write_mouse(s->mouse, val); |
| 622 | break; | 317 | break; |
| 623 | default: | 318 | default: |
| 624 | break; | 319 | break; |
| @@ -629,16 +324,9 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | @@ -629,16 +324,9 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | ||
| 629 | static void kbd_reset(void *opaque) | 324 | static void kbd_reset(void *opaque) |
| 630 | { | 325 | { |
| 631 | KBDState *s = opaque; | 326 | KBDState *s = opaque; |
| 632 | - KBDQueue *q; | ||
| 633 | 327 | ||
| 634 | - s->kbd_write_cmd = -1; | ||
| 635 | - s->mouse_write_cmd = -1; | ||
| 636 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; | 328 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; |
| 637 | s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; | 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 | static void kbd_save(QEMUFile* f, void* opaque) | 332 | static void kbd_save(QEMUFile* f, void* opaque) |
| @@ -648,43 +336,17 @@ static void kbd_save(QEMUFile* f, void* opaque) | @@ -648,43 +336,17 @@ static void kbd_save(QEMUFile* f, void* opaque) | ||
| 648 | qemu_put_8s(f, &s->write_cmd); | 336 | qemu_put_8s(f, &s->write_cmd); |
| 649 | qemu_put_8s(f, &s->status); | 337 | qemu_put_8s(f, &s->status); |
| 650 | qemu_put_8s(f, &s->mode); | 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 | static int kbd_load(QEMUFile* f, void* opaque, int version_id) | 341 | static int kbd_load(QEMUFile* f, void* opaque, int version_id) |
| 667 | { | 342 | { |
| 668 | KBDState *s = (KBDState*)opaque; | 343 | KBDState *s = (KBDState*)opaque; |
| 669 | 344 | ||
| 670 | - if (version_id != 1) | 345 | + if (version_id != 2) |
| 671 | return -EINVAL; | 346 | return -EINVAL; |
| 672 | qemu_get_8s(f, &s->write_cmd); | 347 | qemu_get_8s(f, &s->write_cmd); |
| 673 | qemu_get_8s(f, &s->status); | 348 | qemu_get_8s(f, &s->status); |
| 674 | qemu_get_8s(f, &s->mode); | 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 | return 0; | 350 | return 0; |
| 689 | } | 351 | } |
| 690 | 352 | ||
| @@ -693,13 +355,13 @@ void kbd_init(void) | @@ -693,13 +355,13 @@ void kbd_init(void) | ||
| 693 | KBDState *s = &kbd_state; | 355 | KBDState *s = &kbd_state; |
| 694 | 356 | ||
| 695 | kbd_reset(s); | 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 | register_ioport_read(0x60, 1, 1, kbd_read_data, s); | 359 | register_ioport_read(0x60, 1, 1, kbd_read_data, s); |
| 698 | register_ioport_write(0x60, 1, 1, kbd_write_data, s); | 360 | register_ioport_write(0x60, 1, 1, kbd_write_data, s); |
| 699 | register_ioport_read(0x64, 1, 1, kbd_read_status, s); | 361 | register_ioport_read(0x64, 1, 1, kbd_read_status, s); |
| 700 | register_ioport_write(0x64, 1, 1, kbd_write_command, s); | 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 | qemu_register_reset(kbd_reset, s); | 366 | qemu_register_reset(kbd_reset, s); |
| 705 | } | 367 | } |
vl.h
| @@ -928,6 +928,14 @@ void do_usb_add(const char *devname); | @@ -928,6 +928,14 @@ void do_usb_add(const char *devname); | ||
| 928 | void do_usb_del(const char *devname); | 928 | void do_usb_del(const char *devname); |
| 929 | void usb_info(void); | 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 | #endif /* defined(QEMU_TOOL) */ | 939 | #endif /* defined(QEMU_TOOL) */ |
| 932 | 940 | ||
| 933 | /* monitor.c */ | 941 | /* monitor.c */ |