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 */ |