Read and keep around the originally assigned interrupt_line of the PCI devices.

Those can be used to white list PCI IRQs in ISA space (<= 15) as those are
basically guaranteed not to overlap with ISA devices. Those white listed entries
can then be used if we only have a 16 pin IO-APIC or if there are only legacy
IRQ resources available for configuration (i.e. ones with bitmasks of 16 bits,
limiting their range to IRQs 0-15).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41397 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2011-05-09 12:19:41 +00:00
parent de7dbd8a33
commit f65eaf15ad
2 changed files with 22 additions and 8 deletions

View File

@ -68,9 +68,9 @@ print_irq_routing_entry(const irq_routing_entry& entry)
else
dprintf(" source %p %lu;", entry.source, entry.source_index);
dprintf(" pci %u:%u pin %u; gsi %u; config 0x%02x\n", entry.pci_bus,
entry.pci_device, entry.pin + 1, entry.irq,
entry.polarity | entry.trigger_mode);
dprintf(" pci %u:%u pin %u; bios irq: %u; gsi %u; config 0x%02x\n",
entry.pci_bus, entry.pci_device, entry.pin + 1, entry.bios_irq,
entry.irq, entry.polarity | entry.trigger_mode);
}
@ -123,11 +123,23 @@ update_pci_info_for_entry(pci_module_info* pci, irq_routing_entry& entry)
// Finally match the pin with the entry, note that PCI pins are 1 based
// while ACPI ones are 0 based.
if (interruptPin == entry.pin + 1) {
if (pci->update_interrupt_line(entry.pci_bus, entry.pci_device,
function, entry.irq) == B_OK) {
updateCount++;
}
if (interruptPin != entry.pin + 1)
continue;
if (entry.bios_irq == 0) {
// Keep the originally assigned IRQ around so we can use it for
// white listing PCI IRQs in the ISA space as those are basically
// guaranteed not to overlap with ISA devices. Those white listed
// entries can then be used if we only have a 16 pin IO-APIC or if
// there are only legacy IRQ resources available for configuration
// (with bitmasks of 16 bits, limiting their range to ISA IRQs).
entry.bios_irq = pci->read_pci_config(entry.pci_bus,
entry.pci_device, function, PCI_interrupt_line, 1);
}
if (pci->update_interrupt_line(entry.pci_bus, entry.pci_device,
function, entry.irq) == B_OK) {
updateCount++;
}
}
@ -247,6 +259,7 @@ read_irq_routing_table_recursive(acpi_module_info* acpi, pci_module_info* pci,
irqEntry.source_index = acpiTable->SourceIndex;
irqEntry.pci_bus = pciAddress.bus;
irqEntry.pci_device = (uint8)(acpiTable->Address >> 16);
irqEntry.bios_irq = 0;
// resolve any link device so we get a straight GSI in all cases
if (noSource) {

View File

@ -26,6 +26,7 @@ struct irq_routing_entry {
// Distilled configuration info
uint8 irq; // Global System Interrupt (GSI)
uint8 bios_irq; // BIOS assigned original IRQ
uint8 polarity; // B_{HIGH|LOW}_ACTIVE_POLARITY
uint8 trigger_mode; // B_{LEVEL|EDGE}_TRIGGERED
};