498 |
return (irq_num + slot_addend) & 3; |
return (irq_num + slot_addend) & 3; |
499 |
} |
} |
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 |
|
|
522 |
static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level) |
static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level) |
523 |
{ |
{ |
524 |
int irq_index, shift, pic_irq, pic_level; |
int irq_index, shift, pic_irq, pic_level; |
531 |
*p = (*p & ~(1 << shift)) | (level << shift); |
*p = (*p & ~(1 << shift)) | (level << shift); |
532 |
|
|
533 |
/* now we change the pic irq level according to the piix irq mappings */ |
/* now we change the pic irq level according to the piix irq mappings */ |
534 |
|
/* XXX: optimize */ |
535 |
pic_irq = piix3_state->dev.config[0x60 + irq_num]; |
pic_irq = piix3_state->dev.config[0x60 + irq_num]; |
536 |
if (pic_irq < 16) { |
if (pic_irq < 16) { |
537 |
/* the pic level is the logical OR of all the PCI irqs mapped |
/* the pic level is the logical OR of all the PCI irqs mapped |
538 |
to it */ |
to it */ |
539 |
pic_level = 0; |
pic_level = 0; |
540 |
#if (PCI_IRQ_WORDS == 2) |
if (pic_irq == piix3_state->dev.config[0x60]) |
541 |
pic_level = ((pci_irq_levels[irq_num][0] | |
pic_level |= get_pci_irq_level(0); |
542 |
pci_irq_levels[irq_num][1]) != 0); |
if (pic_irq == piix3_state->dev.config[0x61]) |
543 |
#else |
pic_level |= get_pci_irq_level(1); |
544 |
{ |
if (pic_irq == piix3_state->dev.config[0x62]) |
545 |
int i; |
pic_level |= get_pci_irq_level(2); |
546 |
pic_level = 0; |
if (pic_irq == piix3_state->dev.config[0x63]) |
547 |
for(i = 0; i < PCI_IRQ_WORDS; i++) { |
pic_level |= get_pci_irq_level(3); |
|
if (pci_irq_levels[irq_num][i]) { |
|
|
pic_level = 1; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
#endif |
|
548 |
pic_set_irq(pic_irq, pic_level); |
pic_set_irq(pic_irq, pic_level); |
549 |
} |
} |
550 |
} |
} |