* Choose the desired configuration of the link devices at preparation time
already. This allows to detect invalid settings before starting to enable IRQ routing and therefore allows to gracefully fall back to PIC mode on error. * Actually read the number of IO-APIC entries before using that number in routing preparation. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41416 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ad1757252e
commit
9173e3843e
@ -650,16 +650,6 @@ ioapic_init(kernel_args* args)
|
||||
// aren't different routings based on it this is non-fatal
|
||||
}
|
||||
|
||||
IRQRoutingTable table;
|
||||
status = read_irq_routing_table(acpiModule, &table,
|
||||
sIOAPICMaxRedirectionEntry + 1);
|
||||
if (status != B_OK) {
|
||||
dprintf("reading IRQ routing table failed, not configuring ioapic.\n");
|
||||
acpi_set_interrupt_model(acpiModule, ACPI_INTERRUPT_MODEL_PIC);
|
||||
// revert to PIC interrupt model just in case
|
||||
return;
|
||||
}
|
||||
|
||||
sLevelTriggeredInterrupts = 0;
|
||||
sIOAPICMaxRedirectionEntry
|
||||
= ((version >> IO_APIC_MAX_REDIRECTION_ENTRY_SHIFT)
|
||||
@ -667,8 +657,19 @@ ioapic_init(kernel_args* args)
|
||||
|
||||
TRACE(("ioapic has %lu entries\n", sIOAPICMaxRedirectionEntry + 1));
|
||||
|
||||
status = enable_irq_routing(acpiModule, table,
|
||||
IRQRoutingTable table;
|
||||
status = prepare_irq_routing(acpiModule, table,
|
||||
sIOAPICMaxRedirectionEntry + 1);
|
||||
if (status != B_OK) {
|
||||
dprintf("IRQ routing preparation failed, not configuring ioapic.\n");
|
||||
acpi_set_interrupt_model(acpiModule, ACPI_INTERRUPT_MODEL_PIC);
|
||||
// revert to PIC interrupt model just in case
|
||||
return;
|
||||
}
|
||||
|
||||
print_irq_routing_table(&table);
|
||||
|
||||
status = enable_irq_routing(acpiModule, table);
|
||||
if (status != B_OK) {
|
||||
panic("failed to enable IRQ routing");
|
||||
// if it failed early on it might still work in PIC mode
|
||||
@ -709,8 +710,6 @@ ioapic_init(kernel_args* args)
|
||||
ioapic_write_64(IO_APIC_REDIRECTION_TABLE + 2 * i, entry);
|
||||
}
|
||||
|
||||
print_irq_routing_table(&table);
|
||||
|
||||
// configure io apic interrupts from PCI routing table
|
||||
for (int i = 0; i < table.Count(); i++) {
|
||||
irq_routing_entry& entry = table.ElementAt(i);
|
||||
|
@ -163,8 +163,8 @@ fill_pci_info_for_entry(pci_module_info* pci, irq_routing_entry& entry)
|
||||
|
||||
|
||||
static status_t
|
||||
configure_link_devices(acpi_module_info* acpi, IRQRoutingTable& routingTable,
|
||||
uint32 maxIRQCount)
|
||||
choose_link_device_configurations(acpi_module_info* acpi,
|
||||
IRQRoutingTable& routingTable, uint32 maxIRQCount)
|
||||
{
|
||||
/*
|
||||
Before configuring the link devices we have to take a few things into
|
||||
@ -275,21 +275,16 @@ configure_link_devices(acpi_module_info* acpi, IRQRoutingTable& routingTable,
|
||||
irq_descriptor& chosenDescriptor
|
||||
= link->possible_irqs.ElementAt(bestIRQIndex);
|
||||
if (chosenDescriptor.irq >= maxIRQCount) {
|
||||
panic("chosen irq %u is not addressable (max %lu)",
|
||||
dprintf("chosen irq %u is not addressable (max %lu)\n",
|
||||
chosenDescriptor.irq, maxIRQCount);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
irqUsage[chosenDescriptor.irq] += link->used_by.Count();
|
||||
|
||||
status_t status = set_current_irq(acpi, link->handle, chosenDescriptor);
|
||||
if (status != B_OK) {
|
||||
panic("failed to set irq on link device");
|
||||
return status;
|
||||
}
|
||||
|
||||
for (int j = 0; j < link->used_by.Count(); j++) {
|
||||
irq_routing_entry* irqEntry = link->used_by.ElementAt(j);
|
||||
irqEntry->needs_configuration = j == 0; // only configure once
|
||||
irqEntry->irq = chosenDescriptor.irq;
|
||||
irqEntry->polarity = chosenDescriptor.polarity;
|
||||
irqEntry->trigger_mode = chosenDescriptor.trigger_mode;
|
||||
@ -302,6 +297,32 @@ configure_link_devices(acpi_module_info* acpi, IRQRoutingTable& routingTable,
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
configure_link_devices(acpi_module_info* acpi, IRQRoutingTable& routingTable)
|
||||
{
|
||||
for (int i = 0; i < routingTable.Count(); i++) {
|
||||
irq_routing_entry& irqEntry = routingTable.ElementAt(i);
|
||||
if (!irqEntry.needs_configuration)
|
||||
continue;
|
||||
|
||||
irq_descriptor configuration;
|
||||
configuration.irq = irqEntry.irq;
|
||||
configuration.polarity = irqEntry.polarity;
|
||||
configuration.trigger_mode = irqEntry.trigger_mode;
|
||||
|
||||
status_t status = set_current_irq(acpi, irqEntry.source, configuration);
|
||||
if (status != B_OK) {
|
||||
panic("failed to set irq on link device");
|
||||
return status;
|
||||
}
|
||||
|
||||
irqEntry.needs_configuration = false;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
evaluate_integer(acpi_module_info* acpi, acpi_handle handle,
|
||||
const char* method, uint64& value)
|
||||
@ -368,8 +389,8 @@ handle_routing_table_entry(acpi_module_info* acpi, pci_module_info* pci,
|
||||
}
|
||||
|
||||
if (noSource) {
|
||||
// fill in the GSI and config; link based entries will be resolved at
|
||||
// link configuration time
|
||||
// fill in the GSI and config
|
||||
irqEntry.needs_configuration = false;
|
||||
irqEntry.irq = irqEntry.source_index;
|
||||
irqEntry.polarity = B_LOW_ACTIVE_POLARITY;
|
||||
irqEntry.trigger_mode = B_LEVEL_TRIGGERED;
|
||||
@ -382,7 +403,7 @@ handle_routing_table_entry(acpi_module_info* acpi, pci_module_info* pci,
|
||||
static status_t
|
||||
read_irq_routing_table_recursive(acpi_module_info* acpi, pci_module_info* pci,
|
||||
acpi_handle device, const pci_address& parentAddress,
|
||||
IRQRoutingTable* table, bool rootBridge, uint32 maxIRQCount)
|
||||
IRQRoutingTable& table, bool rootBridge, uint32 maxIRQCount)
|
||||
{
|
||||
acpi_data buffer;
|
||||
buffer.pointer = NULL;
|
||||
@ -440,7 +461,7 @@ read_irq_routing_table_recursive(acpi_module_info* acpi, pci_module_info* pci,
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
table->PushBack(irqEntry);
|
||||
table.PushBack(irqEntry);
|
||||
}
|
||||
|
||||
acpiTable = (acpi_pci_routing_table*)((uint8*)acpiTable
|
||||
@ -483,8 +504,8 @@ read_irq_routing_table_recursive(acpi_module_info* acpi, pci_module_info* pci,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
read_irq_routing_table(acpi_module_info* acpi, IRQRoutingTable* table,
|
||||
static status_t
|
||||
read_irq_routing_table(acpi_module_info* acpi, IRQRoutingTable& table,
|
||||
uint32 maxIRQCount)
|
||||
{
|
||||
char rootPciName[255];
|
||||
@ -526,16 +547,28 @@ read_irq_routing_table(acpi_module_info* acpi, IRQRoutingTable* table,
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
return table->Count() > 0 ? B_OK : B_ERROR;
|
||||
return table.Count() > 0 ? B_OK : B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
enable_irq_routing(acpi_module_info* acpi, IRQRoutingTable& routingTable,
|
||||
prepare_irq_routing(acpi_module_info* acpi, IRQRoutingTable& routingTable,
|
||||
uint32 maxIRQCount)
|
||||
{
|
||||
status_t status = read_irq_routing_table(acpi, routingTable, maxIRQCount);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// resolve desired configuration of link devices
|
||||
return choose_link_device_configurations(acpi, routingTable, maxIRQCount);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
enable_irq_routing(acpi_module_info* acpi, IRQRoutingTable& routingTable)
|
||||
{
|
||||
// configure the link devices; also resolves GSIs for link based entries
|
||||
status_t status = configure_link_devices(acpi, routingTable, maxIRQCount);
|
||||
status_t status = configure_link_devices(acpi, routingTable);
|
||||
if (status != B_OK) {
|
||||
panic("failed to configure link devices");
|
||||
return status;
|
||||
|
@ -19,6 +19,7 @@ struct irq_routing_entry {
|
||||
|
||||
acpi_handle source;
|
||||
uint32 source_index;
|
||||
bool needs_configuration;
|
||||
|
||||
// PCI bus_manager connection
|
||||
uint8 pci_bus;
|
||||
@ -71,10 +72,10 @@ void print_irq_descriptor(irq_descriptor* descriptor);
|
||||
void print_irq_routing_table(IRQRoutingTable* table);
|
||||
|
||||
|
||||
status_t read_irq_routing_table(acpi_module_info* acpi, IRQRoutingTable* table,
|
||||
status_t prepare_irq_routing(acpi_module_info* acpi, IRQRoutingTable& table,
|
||||
uint32 maxIRQCount);
|
||||
status_t enable_irq_routing(acpi_module_info* acpi,
|
||||
IRQRoutingTable& routingTable, uint32 maxIRQCount);
|
||||
IRQRoutingTable& routingTable);
|
||||
|
||||
status_t read_current_irq(acpi_module_info* acpi, acpi_handle device,
|
||||
irq_descriptor& descriptor);
|
||||
|
Loading…
Reference in New Issue
Block a user