Commit 6f51f6b593e0a0065f83bcebb6f9e4aa05a4c8b3
1 parent
0294ffb9
keyboard irq generation fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@778 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
18 additions
and
21 deletions
hw/pckbd.c
| @@ -111,12 +111,13 @@ | @@ -111,12 +111,13 @@ | ||
| 111 | #define KBD_QUEUE_SIZE 256 | 111 | #define KBD_QUEUE_SIZE 256 |
| 112 | 112 | ||
| 113 | typedef struct { | 113 | typedef struct { |
| 114 | + uint8_t aux[KBD_QUEUE_SIZE]; | ||
| 114 | uint8_t data[KBD_QUEUE_SIZE]; | 115 | uint8_t data[KBD_QUEUE_SIZE]; |
| 115 | int rptr, wptr, count; | 116 | int rptr, wptr, count; |
| 116 | } KBDQueue; | 117 | } KBDQueue; |
| 117 | 118 | ||
| 118 | typedef struct KBDState { | 119 | typedef struct KBDState { |
| 119 | - KBDQueue queues[2]; | 120 | + KBDQueue queue; |
| 120 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ | 121 | uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ |
| 121 | uint8_t status; | 122 | uint8_t status; |
| 122 | uint8_t mode; | 123 | uint8_t mode; |
| @@ -145,15 +146,15 @@ int reset_requested; | @@ -145,15 +146,15 @@ int reset_requested; | ||
| 145 | incorrect, but it avoids having to simulate exact delays */ | 146 | incorrect, but it avoids having to simulate exact delays */ |
| 146 | static void kbd_update_irq(KBDState *s) | 147 | static void kbd_update_irq(KBDState *s) |
| 147 | { | 148 | { |
| 149 | + KBDQueue *q = &s->queue; | ||
| 148 | int irq12_level, irq1_level; | 150 | int irq12_level, irq1_level; |
| 149 | 151 | ||
| 150 | irq1_level = 0; | 152 | irq1_level = 0; |
| 151 | irq12_level = 0; | 153 | irq12_level = 0; |
| 152 | s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); | 154 | s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF); |
| 153 | - if (s->queues[0].count != 0 || | ||
| 154 | - s->queues[1].count != 0) { | 155 | + if (q->count != 0) { |
| 155 | s->status |= KBD_STAT_OBF; | 156 | s->status |= KBD_STAT_OBF; |
| 156 | - if (s->queues[1].count != 0) { | 157 | + if (q->aux[q->rptr]) { |
| 157 | s->status |= KBD_STAT_MOUSE_OBF; | 158 | s->status |= KBD_STAT_MOUSE_OBF; |
| 158 | if (s->mode & KBD_MODE_MOUSE_INT) | 159 | if (s->mode & KBD_MODE_MOUSE_INT) |
| 159 | irq12_level = 1; | 160 | irq12_level = 1; |
| @@ -169,7 +170,7 @@ static void kbd_update_irq(KBDState *s) | @@ -169,7 +170,7 @@ static void kbd_update_irq(KBDState *s) | ||
| 169 | 170 | ||
| 170 | static void kbd_queue(KBDState *s, int b, int aux) | 171 | static void kbd_queue(KBDState *s, int b, int aux) |
| 171 | { | 172 | { |
| 172 | - KBDQueue *q = &s->queues[aux]; | 173 | + KBDQueue *q = &s->queue; |
| 173 | 174 | ||
| 174 | #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) | 175 | #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) |
| 175 | if (aux) | 176 | if (aux) |
| @@ -181,6 +182,7 @@ static void kbd_queue(KBDState *s, int b, int aux) | @@ -181,6 +182,7 @@ static void kbd_queue(KBDState *s, int b, int aux) | ||
| 181 | #endif | 182 | #endif |
| 182 | if (q->count >= KBD_QUEUE_SIZE) | 183 | if (q->count >= KBD_QUEUE_SIZE) |
| 183 | return; | 184 | return; |
| 185 | + q->aux[q->wptr] = aux; | ||
| 184 | q->data[q->wptr] = b; | 186 | q->data[q->wptr] = b; |
| 185 | if (++q->wptr == KBD_QUEUE_SIZE) | 187 | if (++q->wptr == KBD_QUEUE_SIZE) |
| 186 | q->wptr = 0; | 188 | q->wptr = 0; |
| @@ -288,30 +290,28 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr) | @@ -288,30 +290,28 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr) | ||
| 288 | { | 290 | { |
| 289 | KBDState *s = opaque; | 291 | KBDState *s = opaque; |
| 290 | KBDQueue *q; | 292 | KBDQueue *q; |
| 291 | - int val, index; | 293 | + int val, index, aux; |
| 292 | 294 | ||
| 293 | - q = &s->queues[1]; /* first check AUX data */ | ||
| 294 | - if (q->count == 0) | ||
| 295 | - q = &s->queues[0]; /* then check KBD data */ | 295 | + q = &s->queue; |
| 296 | if (q->count == 0) { | 296 | if (q->count == 0) { |
| 297 | /* NOTE: if no data left, we return the last keyboard one | 297 | /* NOTE: if no data left, we return the last keyboard one |
| 298 | (needed for EMM386) */ | 298 | (needed for EMM386) */ |
| 299 | /* XXX: need a timer to do things correctly */ | 299 | /* XXX: need a timer to do things correctly */ |
| 300 | - q = &s->queues[0]; | ||
| 301 | index = q->rptr - 1; | 300 | index = q->rptr - 1; |
| 302 | if (index < 0) | 301 | if (index < 0) |
| 303 | index = KBD_QUEUE_SIZE - 1; | 302 | index = KBD_QUEUE_SIZE - 1; |
| 304 | val = q->data[index]; | 303 | val = q->data[index]; |
| 305 | } else { | 304 | } else { |
| 305 | + aux = q->aux[q->rptr]; | ||
| 306 | val = q->data[q->rptr]; | 306 | val = q->data[q->rptr]; |
| 307 | if (++q->rptr == KBD_QUEUE_SIZE) | 307 | if (++q->rptr == KBD_QUEUE_SIZE) |
| 308 | q->rptr = 0; | 308 | q->rptr = 0; |
| 309 | q->count--; | 309 | q->count--; |
| 310 | /* reading deasserts IRQ */ | 310 | /* reading deasserts IRQ */ |
| 311 | - if (q == &s->queues[0]) | ||
| 312 | - pic_set_irq(1, 0); | ||
| 313 | - else | 311 | + if (aux) |
| 314 | pic_set_irq(12, 0); | 312 | pic_set_irq(12, 0); |
| 313 | + else | ||
| 314 | + pic_set_irq(1, 0); | ||
| 315 | } | 315 | } |
| 316 | /* reassert IRQs if data left */ | 316 | /* reassert IRQs if data left */ |
| 317 | kbd_update_irq(s); | 317 | kbd_update_irq(s); |
| @@ -452,7 +452,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) | @@ -452,7 +452,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) | ||
| 452 | s->mouse_buttons = buttons_state; | 452 | s->mouse_buttons = buttons_state; |
| 453 | 453 | ||
| 454 | if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && | 454 | if (!(s->mouse_status & MOUSE_STATUS_REMOTE) && |
| 455 | - (s->queues[1].count < (KBD_QUEUE_SIZE - 16))) { | 455 | + (s->queue.count < (KBD_QUEUE_SIZE - 16))) { |
| 456 | for(;;) { | 456 | for(;;) { |
| 457 | /* if not remote, send event. Multiple events are sent if | 457 | /* if not remote, send event. Multiple events are sent if |
| 458 | too big deltas */ | 458 | too big deltas */ |
| @@ -632,18 +632,15 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | @@ -632,18 +632,15 @@ void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | ||
| 632 | void kbd_reset(KBDState *s) | 632 | void kbd_reset(KBDState *s) |
| 633 | { | 633 | { |
| 634 | KBDQueue *q; | 634 | KBDQueue *q; |
| 635 | - int i; | ||
| 636 | 635 | ||
| 637 | s->kbd_write_cmd = -1; | 636 | s->kbd_write_cmd = -1; |
| 638 | s->mouse_write_cmd = -1; | 637 | s->mouse_write_cmd = -1; |
| 639 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; | 638 | s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; |
| 640 | s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; | 639 | s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED; |
| 641 | - for(i = 0; i < 2; i++) { | ||
| 642 | - q = &s->queues[i]; | ||
| 643 | - q->rptr = 0; | ||
| 644 | - q->wptr = 0; | ||
| 645 | - q->count = 0; | ||
| 646 | - } | 640 | + q = &s->queue; |
| 641 | + q->rptr = 0; | ||
| 642 | + q->wptr = 0; | ||
| 643 | + q->count = 0; | ||
| 647 | } | 644 | } |
| 648 | 645 | ||
| 649 | void kbd_init(void) | 646 | void kbd_init(void) |