[haiku-commits] r41416 - haiku/trunk/src/system/kernel/arch/x86

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 10 May 2011 11:59:50 +0200 (CEST)

Author: mmlr
Date: 2011-05-10 11:59:50 +0200 (Tue, 10 May 2011)
New Revision: 41416
Changeset: https://dev.haiku-os.org/changeset/41416

Modified:
   haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp
   haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.cpp
   haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.h
Log:
* 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.


Modified: haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp 2011-05-10 09:29:57 UTC 
(rev 41415)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp 2011-05-10 09:59:50 UTC 
(rev 41416)
@@ -650,25 +650,26 @@
                // aren't different routings based on it this is non-fatal
        }
 
+       sLevelTriggeredInterrupts = 0;
+       sIOAPICMaxRedirectionEntry
+               = ((version >> IO_APIC_MAX_REDIRECTION_ENTRY_SHIFT)
+                       & IO_APIC_MAX_REDIRECTION_ENTRY_MASK);
+
+       TRACE(("ioapic has %lu entries\n", sIOAPICMaxRedirectionEntry + 1));
+
        IRQRoutingTable table;
-       status = read_irq_routing_table(acpiModule, &table,
+       status = prepare_irq_routing(acpiModule, table,
                sIOAPICMaxRedirectionEntry + 1);
        if (status != B_OK) {
-               dprintf("reading IRQ routing table failed, not configuring 
ioapic.\n");
+               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;
        }
 
-       sLevelTriggeredInterrupts = 0;
-       sIOAPICMaxRedirectionEntry
-               = ((version >> IO_APIC_MAX_REDIRECTION_ENTRY_SHIFT)
-                       & IO_APIC_MAX_REDIRECTION_ENTRY_MASK);
+       print_irq_routing_table(&table);
 
-       TRACE(("ioapic has %lu entries\n", sIOAPICMaxRedirectionEntry + 1));
-
-       status = enable_irq_routing(acpiModule, table,
-               sIOAPICMaxRedirectionEntry + 1);
+       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_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);

Modified: haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.cpp        
2011-05-10 09:29:57 UTC (rev 41415)
+++ haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.cpp        
2011-05-10 09:59:50 UTC (rev 41416)
@@ -163,8 +163,8 @@
 
 
 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 @@
                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;
@@ -303,6 +298,32 @@
 
 
 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 @@
        }
 
        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 @@
 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 @@
                                return B_ERROR;
                        }
 
-                       table->PushBack(irqEntry);
+                       table.PushBack(irqEntry);
                }
 
                acpiTable = (acpi_pci_routing_table*)((uint8*)acpiTable
@@ -483,8 +504,8 @@
 }
 
 
-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 @@
        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;

Modified: haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.h
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.h  2011-05-10 
09:29:57 UTC (rev 41415)
+++ haiku/trunk/src/system/kernel/arch/x86/irq_routing_table.h  2011-05-10 
09:59:50 UTC (rev 41416)
@@ -19,6 +19,7 @@
 
        acpi_handle     source;
        uint32          source_index;
+       bool            needs_configuration;
 
        // PCI bus_manager connection
        uint8           pci_bus;
@@ -71,10 +72,10 @@
 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);


Other related posts:

  • » [haiku-commits] r41416 - haiku/trunk/src/system/kernel/arch/x86 - mmlr