Commit 15aeac38055aadc788b85eb1e66385723942ba8a
1 parent
28ab0e2e
PIC spurious irq support (aka Solaris install bug)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@838 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
29 additions
and
23 deletions
Changelog
| @@ -14,6 +14,7 @@ version 0.5.6: | @@ -14,6 +14,7 @@ version 0.5.6: | ||
| 14 | - dummy VGA PCI support | 14 | - dummy VGA PCI support |
| 15 | - VGA font selection fix (Daniel Serpell) | 15 | - VGA font selection fix (Daniel Serpell) |
| 16 | - PIC reset fix (Hidemi KAWAI) | 16 | - PIC reset fix (Hidemi KAWAI) |
| 17 | + - PIC spurious irq support (aka Solaris install bug) | ||
| 17 | 18 | ||
| 18 | version 0.5.5: | 19 | version 0.5.5: |
| 19 | 20 |
hw/i8259.c
| @@ -49,7 +49,6 @@ typedef struct PicState { | @@ -49,7 +49,6 @@ typedef struct PicState { | ||
| 49 | 49 | ||
| 50 | /* 0 is master pic, 1 is slave pic */ | 50 | /* 0 is master pic, 1 is slave pic */ |
| 51 | static PicState pics[2]; | 51 | static PicState pics[2]; |
| 52 | -static int pic_irq_requested; | ||
| 53 | 52 | ||
| 54 | /* set irq level. If an edge is detected, then the IRR is set to 1 */ | 53 | /* set irq level. If an edge is detected, then the IRR is set to 1 */ |
| 55 | static inline void pic_set_irq1(PicState *s, int irq, int level) | 54 | static inline void pic_set_irq1(PicState *s, int irq, int level) |
| @@ -130,13 +129,6 @@ static void pic_update_irq(void) | @@ -130,13 +129,6 @@ static void pic_update_irq(void) | ||
| 130 | /* look at requested irq */ | 129 | /* look at requested irq */ |
| 131 | irq = pic_get_irq(&pics[0]); | 130 | irq = pic_get_irq(&pics[0]); |
| 132 | if (irq >= 0) { | 131 | if (irq >= 0) { |
| 133 | - if (irq == 2) { | ||
| 134 | - /* from slave pic */ | ||
| 135 | - pic_irq_requested = 8 + irq2; | ||
| 136 | - } else { | ||
| 137 | - /* from master pic */ | ||
| 138 | - pic_irq_requested = irq; | ||
| 139 | - } | ||
| 140 | #if defined(DEBUG_PIC) | 132 | #if defined(DEBUG_PIC) |
| 141 | { | 133 | { |
| 142 | int i; | 134 | int i; |
| @@ -192,8 +184,31 @@ int cpu_get_pic_interrupt(CPUState *env) | @@ -192,8 +184,31 @@ int cpu_get_pic_interrupt(CPUState *env) | ||
| 192 | { | 184 | { |
| 193 | int irq, irq2, intno; | 185 | int irq, irq2, intno; |
| 194 | 186 | ||
| 195 | - /* signal the pic that the irq was acked by the CPU */ | ||
| 196 | - irq = pic_irq_requested; | 187 | + /* read the irq from the PIC */ |
| 188 | + | ||
| 189 | + irq = pic_get_irq(&pics[0]); | ||
| 190 | + if (irq >= 0) { | ||
| 191 | + pic_intack(&pics[0], irq); | ||
| 192 | + if (irq == 2) { | ||
| 193 | + irq2 = pic_get_irq(&pics[1]); | ||
| 194 | + if (irq2 >= 0) { | ||
| 195 | + pic_intack(&pics[1], irq2); | ||
| 196 | + } else { | ||
| 197 | + /* spurious IRQ on slave controller */ | ||
| 198 | + irq2 = 7; | ||
| 199 | + } | ||
| 200 | + intno = pics[1].irq_base + irq2; | ||
| 201 | + irq = irq2 + 8; | ||
| 202 | + } else { | ||
| 203 | + intno = pics[0].irq_base + irq; | ||
| 204 | + } | ||
| 205 | + } else { | ||
| 206 | + /* spurious IRQ on host controller */ | ||
| 207 | + irq = 7; | ||
| 208 | + intno = pics[0].irq_base + irq; | ||
| 209 | + } | ||
| 210 | + pic_update_irq(); | ||
| 211 | + | ||
| 197 | #ifdef DEBUG_IRQ_LATENCY | 212 | #ifdef DEBUG_IRQ_LATENCY |
| 198 | printf("IRQ%d latency=%0.3fus\n", | 213 | printf("IRQ%d latency=%0.3fus\n", |
| 199 | irq, | 214 | irq, |
| @@ -202,17 +217,6 @@ int cpu_get_pic_interrupt(CPUState *env) | @@ -202,17 +217,6 @@ int cpu_get_pic_interrupt(CPUState *env) | ||
| 202 | #if defined(DEBUG_PIC) | 217 | #if defined(DEBUG_PIC) |
| 203 | printf("pic_interrupt: irq=%d\n", irq); | 218 | printf("pic_interrupt: irq=%d\n", irq); |
| 204 | #endif | 219 | #endif |
| 205 | - | ||
| 206 | - if (irq >= 8) { | ||
| 207 | - irq2 = irq & 7; | ||
| 208 | - pic_intack(&pics[1], irq2); | ||
| 209 | - irq = 2; | ||
| 210 | - intno = pics[1].irq_base + irq2; | ||
| 211 | - } else { | ||
| 212 | - intno = pics[0].irq_base + irq; | ||
| 213 | - } | ||
| 214 | - pic_intack(&pics[0], irq); | ||
| 215 | - pic_update_irq(); | ||
| 216 | return intno; | 220 | return intno; |
| 217 | } | 221 | } |
| 218 | 222 | ||
| @@ -452,9 +456,10 @@ void pic_info(void) | @@ -452,9 +456,10 @@ void pic_info(void) | ||
| 452 | 456 | ||
| 453 | for(i=0;i<2;i++) { | 457 | for(i=0;i<2;i++) { |
| 454 | s = &pics[i]; | 458 | s = &pics[i]; |
| 455 | - term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x\n", | 459 | + term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n", |
| 456 | i, s->irr, s->imr, s->isr, s->priority_add, | 460 | i, s->irr, s->imr, s->isr, s->priority_add, |
| 457 | - s->irq_base, s->read_reg_select, s->elcr); | 461 | + s->irq_base, s->read_reg_select, s->elcr, |
| 462 | + s->special_fully_nested_mode); | ||
| 458 | } | 463 | } |
| 459 | } | 464 | } |
| 460 | 465 |