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

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 6 May 2011 03:55:58 +0200 (CEST)

Author: mmlr
Date: 2011-05-06 03:55:58 +0200 (Fri, 06 May 2011)
New Revision: 41338
Changeset: https://dev.haiku-os.org/changeset/41338

Modified:
   haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp
Log:
We need to specify the intended interrupt model with ACPI so that we get the
correct PCI IRQ routing table for that mode. With this, we finally get the right
PIRQ <-> Global System Interrupt mapping and can therefore program the right
IO APIC entries. The only missing part now is to fix up the pci_info of the
devices with the then active GSI.


Modified: haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp 2011-05-06 00:01:40 UTC 
(rev 41337)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp 2011-05-06 01:55:58 UTC 
(rev 41338)
@@ -83,6 +83,12 @@
 #define PIC_NUM_INTS                   0x0f
 
 
+// ACPI interrupt models
+#define ACPI_INTERRUPT_MODEL_PIC       0
+#define ACPI_INTERRUPT_MODEL_APIC      1
+#define ACPI_INTERRUPT_MODEL_SAPIC     2
+
+
 // Definitions for a 82093AA IO APIC controller
 #define IO_APIC_IDENTIFICATION                         0x00
 #define IO_APIC_VERSION                                                0x01
@@ -571,6 +577,21 @@
 }
 
 
+static status_t
+acpi_set_interrupt_model(acpi_module_info* acpiModule, uint32 interruptModel)
+{
+       acpi_object_type model;
+       model.object_type = ACPI_TYPE_INTEGER;
+       model.data.integer = interruptModel;
+
+       acpi_objects parameter;
+       parameter.count = 1;
+       parameter.pointer = &model;
+
+       return acpiModule->evaluate_method(NULL, "\\_PIC", &parameter, NULL);
+}
+
+
 static void
 ioapic_init(kernel_args* args)
 {
@@ -609,13 +630,21 @@
        BPrivate::CObjectDeleter<const char, status_t>
                acpiModulePutter(B_ACPI_MODULE_NAME, put_module);
 
-       // TODO: here ACPI needs to be used to properly set up the PCI IRQ
-       // routing.
+       // switch to the APIC interrupt model before retrieving the irq routing
+       // table as it will return different settings depending on the model
+       status = acpi_set_interrupt_model(acpiModule, 
ACPI_INTERRUPT_MODEL_APIC);
+       if (status != B_OK) {
+               dprintf("failed to put ACPI into APIC interrupt model, 
ignoring\n");
+               // don't abort, as the _PIC method is optional and as long as 
there
+               // aren't different routings based on it this is non-fatal
+       }
 
        IRQRoutingTable table;
        status = read_irq_routing_table(acpiModule, &table);
        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;
        }
 
@@ -663,6 +692,10 @@
        for (uint32 i = 0; i < 256; i++)
                sIRQToIOAPICPin[i] = i;
 
+#ifdef TRACE_ARCH_INT
+       print_irq_routing_table(&table);
+#endif
+
        // configure io apic interrupts from pci routing table
        for (int i = 0; i < table.Count(); i++) {
                uint8 irq = 0;


Other related posts: