Commit 72cc6cfeef616f443761365c294a86057950f9bd
1 parent
bc380d17
handle the case where several PCI irqs share the same PIC irq
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1433 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
30 additions
and
15 deletions
hw/pci.c
| @@ -498,6 +498,27 @@ static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) | @@ -498,6 +498,27 @@ static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) | ||
| 498 | return (irq_num + slot_addend) & 3; | 498 | return (irq_num + slot_addend) & 3; |
| 499 | } | 499 | } |
| 500 | 500 | ||
| 501 | +static inline int get_pci_irq_level(int irq_num) | ||
| 502 | +{ | ||
| 503 | + int pic_level; | ||
| 504 | +#if (PCI_IRQ_WORDS == 2) | ||
| 505 | + pic_level = ((pci_irq_levels[irq_num][0] | | ||
| 506 | + pci_irq_levels[irq_num][1]) != 0); | ||
| 507 | +#else | ||
| 508 | + { | ||
| 509 | + int i; | ||
| 510 | + pic_level = 0; | ||
| 511 | + for(i = 0; i < PCI_IRQ_WORDS; i++) { | ||
| 512 | + if (pci_irq_levels[irq_num][i]) { | ||
| 513 | + pic_level = 1; | ||
| 514 | + break; | ||
| 515 | + } | ||
| 516 | + } | ||
| 517 | + } | ||
| 518 | +#endif | ||
| 519 | + return pic_level; | ||
| 520 | +} | ||
| 521 | + | ||
| 501 | static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level) | 522 | static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level) |
| 502 | { | 523 | { |
| 503 | int irq_index, shift, pic_irq, pic_level; | 524 | int irq_index, shift, pic_irq, pic_level; |
| @@ -510,26 +531,20 @@ static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level) | @@ -510,26 +531,20 @@ static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level) | ||
| 510 | *p = (*p & ~(1 << shift)) | (level << shift); | 531 | *p = (*p & ~(1 << shift)) | (level << shift); |
| 511 | 532 | ||
| 512 | /* now we change the pic irq level according to the piix irq mappings */ | 533 | /* now we change the pic irq level according to the piix irq mappings */ |
| 534 | + /* XXX: optimize */ | ||
| 513 | pic_irq = piix3_state->dev.config[0x60 + irq_num]; | 535 | pic_irq = piix3_state->dev.config[0x60 + irq_num]; |
| 514 | if (pic_irq < 16) { | 536 | if (pic_irq < 16) { |
| 515 | /* the pic level is the logical OR of all the PCI irqs mapped | 537 | /* the pic level is the logical OR of all the PCI irqs mapped |
| 516 | to it */ | 538 | to it */ |
| 517 | pic_level = 0; | 539 | pic_level = 0; |
| 518 | -#if (PCI_IRQ_WORDS == 2) | ||
| 519 | - pic_level = ((pci_irq_levels[irq_num][0] | | ||
| 520 | - pci_irq_levels[irq_num][1]) != 0); | ||
| 521 | -#else | ||
| 522 | - { | ||
| 523 | - int i; | ||
| 524 | - pic_level = 0; | ||
| 525 | - for(i = 0; i < PCI_IRQ_WORDS; i++) { | ||
| 526 | - if (pci_irq_levels[irq_num][i]) { | ||
| 527 | - pic_level = 1; | ||
| 528 | - break; | ||
| 529 | - } | ||
| 530 | - } | ||
| 531 | - } | ||
| 532 | -#endif | 540 | + if (pic_irq == piix3_state->dev.config[0x60]) |
| 541 | + pic_level |= get_pci_irq_level(0); | ||
| 542 | + if (pic_irq == piix3_state->dev.config[0x61]) | ||
| 543 | + pic_level |= get_pci_irq_level(1); | ||
| 544 | + if (pic_irq == piix3_state->dev.config[0x62]) | ||
| 545 | + pic_level |= get_pci_irq_level(2); | ||
| 546 | + if (pic_irq == piix3_state->dev.config[0x63]) | ||
| 547 | + pic_level |= get_pci_irq_level(3); | ||
| 533 | pic_set_irq(pic_irq, pic_level); | 548 | pic_set_irq(pic_irq, pic_level); |
| 534 | } | 549 | } |
| 535 | } | 550 | } |