[haiku-commits] r36221 - in haiku/trunk: headers/private/kernel/arch/x86 src/system/kernel/arch/x86 src/system/kernel/arch/x86/timers

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 13 Apr 2010 16:46:09 +0200 (CEST)

Author: mmlr
Date: 2010-04-13 16:46:09 +0200 (Tue, 13 Apr 2010)
New Revision: 36221
Changeset: http://dev.haiku-os.org/changeset/36221/haiku

Added:
   haiku/trunk/headers/private/kernel/arch/x86/msi.h
   haiku/trunk/src/system/kernel/arch/x86/msi.cpp
Modified:
   haiku/trunk/src/system/kernel/arch/x86/Jamfile
   haiku/trunk/src/system/kernel/arch/x86/apic.cpp
   haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp
   haiku/trunk/src/system/kernel/arch/x86/arch_interrupts.S
   haiku/trunk/src/system/kernel/arch/x86/arch_smp.cpp
   haiku/trunk/src/system/kernel/arch/x86/interrupts.h
   haiku/trunk/src/system/kernel/arch/x86/timers/x86_apic.cpp
Log:
* Add code to allocate and free interrupt vectors for message signaled
  interrupts (MSI).
* Add the remaining IDT entries and redirection functions in the interrupt code.
* Make the PIC end_of_interrupt() return a result to indicate whether the vector
  was handled by this PIC. If it isn't we now issue a apic_end_of_interrupt()
  in the assumption of apic local interrupt, MSI or IPI. This also removes
  the need for the gUsingIOAPIC global and doing manual apic_end_of_interrupt()
  calls in the SMP and timer code.


Added: haiku/trunk/headers/private/kernel/arch/x86/msi.h
===================================================================
--- haiku/trunk/headers/private/kernel/arch/x86/msi.h                           
(rev 0)
+++ haiku/trunk/headers/private/kernel/arch/x86/msi.h   2010-04-13 14:46:09 UTC 
(rev 36221)
@@ -0,0 +1,33 @@
+#ifndef _KERNEL_ARCH_x86_MSI_H
+#define _KERNEL_ARCH_x86_MSI_H
+
+#include <SupportDefs.h>
+
+// address register
+#define MSI_ADDRESS_BASE                               0xfee00000
+#define MSI_DESTINATION_ID_SHIFT               12
+#define MSI_REDIRECTION                                        0x00000008
+#define MSI_NO_REDIRECTION                             0x00000000
+#define MSI_DESTINATION_MODE_LOGICAL   0x00000004
+#define MSI_DESTINATION_MODE_PHYSICAL  0x00000000
+
+// data register
+#define MSI_TRIGGER_MODE_EDGE                  0x00000000
+#define MSI_TRIGGER_MODE_LEVEL                 0x00008000
+#define MSI_LEVEL_DEASSERT                             0x00000000
+#define MSI_LEVEL_ASSERT                               0x00004000
+#define MSI_DELIVERY_MODE_FIXED                        0x00000000
+#define MSI_DELIVERY_MODE_LOWEST_PRIO  0x00000100
+#define MSI_DELIVERY_MODE_SMI                  0x00000200
+#define MSI_DELIVERY_MODE_NMI                  0x00000400
+#define MSI_DELIVERY_MODE_INIT                 0x00000500
+#define MSI_DELIVERY_MODE_EXT_INT              0x00000700
+
+
+void           msi_init();
+bool           msi_supported();
+status_t       msi_allocate_vectors(uint8 count, uint8 *startVector,
+                               uint64 *address, uint16 *data);
+void           msi_free_vectors(uint8 count, uint8 startVector);
+
+#endif // _KERNEL_ARCH_x86_MSI_H

Modified: haiku/trunk/src/system/kernel/arch/x86/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/Jamfile      2010-04-13 14:34:06 UTC 
(rev 36220)
+++ haiku/trunk/src/system/kernel/arch/x86/Jamfile      2010-04-13 14:46:09 UTC 
(rev 36221)
@@ -34,6 +34,7 @@
        bios.cpp
        cpuid.S
        irq_routing_table.cpp
+       msi.cpp
        syscall.S
        vm86.cpp
        x86_physical_page_mapper.cpp

Modified: haiku/trunk/src/system/kernel/arch/x86/apic.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/apic.cpp     2010-04-13 14:34:06 UTC 
(rev 36220)
+++ haiku/trunk/src/system/kernel/arch/x86/apic.cpp     2010-04-13 14:46:09 UTC 
(rev 36221)
@@ -10,6 +10,7 @@
  */
 
 #include <arch/x86/apic.h>
+#include <arch/x86/msi.h>
 
 #include <debug.h>
 #include <vm/vm.h>
@@ -71,6 +72,7 @@
                return B_ERROR;
        }
 
+       msi_init();
        return B_OK;
 }
 

Modified: haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp 2010-04-13 14:34:06 UTC 
(rev 36220)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_int.cpp 2010-04-13 14:46:09 UTC 
(rev 36221)
@@ -136,15 +136,13 @@
 
 static uint32 sIRQToIOAPICPin[256];
 
-bool gUsingIOAPIC = false;
-
 typedef struct interrupt_controller_s {
        const char *name;
        void    (*enable_io_interrupt)(int32 num);
        void    (*disable_io_interrupt)(int32 num);
        void    (*configure_io_interrupt)(int32 num, uint32 config);
        bool    (*is_spurious_interrupt)(int32 num);
-       void    (*end_of_interrupt)(int32 num);
+       bool    (*end_of_interrupt)(int32 num);
 } interrupt_controller;
 
 static const interrupt_controller *sCurrentPIC = NULL;
@@ -282,11 +280,11 @@
        question (or both of them).
        This clears the PIC interrupt in-service bit.
 */
-static void
+static bool
 pic_end_of_interrupt(int32 num)
 {
        if (num < 0 || num > PIC_NUM_INTS)
-               return;
+               return false;
 
        // PIC 8259 controlled interrupt
        if (num >= PIC_SLAVE_INT_BASE)
@@ -294,6 +292,7 @@
 
        // we always need to acknowledge the master PIC
        out8(PIC_NON_SPECIFIC_EOI, PIC_MASTER_CONTROL);
+       return true;
 }
 
 
@@ -413,7 +412,6 @@
 
        // make the pic controller the current one
        sCurrentPIC = &picController;
-       gUsingIOAPIC = false;
 }
 
 
@@ -466,10 +464,11 @@
 }
 
 
-static void
+static bool
 ioapic_end_of_interrupt(int32 num)
 {
        apic_end_of_interrupt();
+       return true;
 }
 
 
@@ -673,7 +672,6 @@
        // prefer the ioapic over the normal pic
        dprintf("using ioapic for interrupt routing\n");
        sCurrentPIC = &ioapicController;
-       gUsingIOAPIC = true;
 }
 
 
@@ -1011,13 +1009,19 @@
        if (vector < 32)
                levelTriggered = (sLevelTriggeredInterrupts & (1 << vector)) != 
0;
 
-       if (!levelTriggered)
-               sCurrentPIC->end_of_interrupt(vector);
+       if (!levelTriggered) {
+               // if it's not handled by the current pic then it's an apic 
generated
+               // interrupt like local interrupts, msi or ipi.
+               if (!sCurrentPIC->end_of_interrupt(vector))
+                       apic_end_of_interrupt();
+       }
 
        int_io_interrupt_handler(vector, levelTriggered);
 
-       if (levelTriggered)
-               sCurrentPIC->end_of_interrupt(vector);
+       if (levelTriggered) {
+               if (!sCurrentPIC->end_of_interrupt(vector))
+                       apic_end_of_interrupt();
+       }
 
        cpu_status state = disable_interrupts();
        if (thread->cpu->invoke_scheduler) {
@@ -1050,55 +1054,256 @@
        // setup the standard programmable interrupt controller
        pic_init();
 
-       set_interrupt_gate(0, 0,  &trap0);
-       set_interrupt_gate(0, 1,  &trap1);
-       set_interrupt_gate(0, 2,  &trap2);
-       set_trap_gate(0, 3,  &trap3);
-       set_interrupt_gate(0, 4,  &trap4);
-       set_interrupt_gate(0, 5,  &trap5);
-       set_interrupt_gate(0, 6,  &trap6);
-       set_interrupt_gate(0, 7,  &trap7);
+       set_interrupt_gate(0, 0, &trap0);
+       set_interrupt_gate(0, 1, &trap1);
+       set_interrupt_gate(0, 2, &trap2);
+       set_trap_gate(0, 3, &trap3);
+       set_interrupt_gate(0, 4, &trap4);
+       set_interrupt_gate(0, 5, &trap5);
+       set_interrupt_gate(0, 6, &trap6);
+       set_interrupt_gate(0, 7, &trap7);
        // trap8 (double fault) is set in arch_cpu.c
-       set_interrupt_gate(0, 9,  &trap9);
-       set_interrupt_gate(0, 10,  &trap10);
-       set_interrupt_gate(0, 11,  &trap11);
-       set_interrupt_gate(0, 12,  &trap12);
-       set_interrupt_gate(0, 13,  &trap13);
-       set_interrupt_gate(0, 14,  &trap14);
-//     set_interrupt_gate(0, 15,  &trap15);
-       set_interrupt_gate(0, 16,  &trap16);
-       set_interrupt_gate(0, 17,  &trap17);
-       set_interrupt_gate(0, 18,  &trap18);
-       set_interrupt_gate(0, 19,  &trap19);
+       set_interrupt_gate(0, 9, &trap9);
+       set_interrupt_gate(0, 10, &trap10);
+       set_interrupt_gate(0, 11, &trap11);
+       set_interrupt_gate(0, 12, &trap12);
+       set_interrupt_gate(0, 13, &trap13);
+       set_interrupt_gate(0, 14, &trap14);
+//     set_interrupt_gate(0, 15, &trap15);
+       set_interrupt_gate(0, 16, &trap16);
+       set_interrupt_gate(0, 17, &trap17);
+       set_interrupt_gate(0, 18, &trap18);
+       set_interrupt_gate(0, 19, &trap19);
 
-       set_interrupt_gate(0, 32,  &trap32);
-       set_interrupt_gate(0, 33,  &trap33);
-       set_interrupt_gate(0, 34,  &trap34);
-       set_interrupt_gate(0, 35,  &trap35);
-       set_interrupt_gate(0, 36,  &trap36);
-       set_interrupt_gate(0, 37,  &trap37);
-       set_interrupt_gate(0, 38,  &trap38);
-       set_interrupt_gate(0, 39,  &trap39);
-       set_interrupt_gate(0, 40,  &trap40);
-       set_interrupt_gate(0, 41,  &trap41);
-       set_interrupt_gate(0, 42,  &trap42);
-       set_interrupt_gate(0, 43,  &trap43);
-       set_interrupt_gate(0, 44,  &trap44);
-       set_interrupt_gate(0, 45,  &trap45);
-       set_interrupt_gate(0, 46,  &trap46);
-       set_interrupt_gate(0, 47,  &trap47);
-       set_interrupt_gate(0, 48,  &trap48);
-       set_interrupt_gate(0, 49,  &trap49);
-       set_interrupt_gate(0, 50,  &trap50);
-       set_interrupt_gate(0, 51,  &trap51);
-       set_interrupt_gate(0, 52,  &trap52);
-       set_interrupt_gate(0, 53,  &trap53);
-       set_interrupt_gate(0, 54,  &trap54);
-       set_interrupt_gate(0, 55,  &trap55);
+       // legacy or ioapic interrupts
+       set_interrupt_gate(0, 32, &trap32);
+       set_interrupt_gate(0, 33, &trap33);
+       set_interrupt_gate(0, 34, &trap34);
+       set_interrupt_gate(0, 35, &trap35);
+       set_interrupt_gate(0, 36, &trap36);
+       set_interrupt_gate(0, 37, &trap37);
+       set_interrupt_gate(0, 38, &trap38);
+       set_interrupt_gate(0, 39, &trap39);
+       set_interrupt_gate(0, 40, &trap40);
+       set_interrupt_gate(0, 41, &trap41);
+       set_interrupt_gate(0, 42, &trap42);
+       set_interrupt_gate(0, 43, &trap43);
+       set_interrupt_gate(0, 44, &trap44);
+       set_interrupt_gate(0, 45, &trap45);
+       set_interrupt_gate(0, 46, &trap46);
+       set_interrupt_gate(0, 47, &trap47);
 
+       // additional ioapic interrupts
+       set_interrupt_gate(0, 48, &trap48);
+       set_interrupt_gate(0, 49, &trap49);
+       set_interrupt_gate(0, 50, &trap50);
+       set_interrupt_gate(0, 51, &trap51);
+       set_interrupt_gate(0, 52, &trap52);
+       set_interrupt_gate(0, 53, &trap53);
+       set_interrupt_gate(0, 54, &trap54);
+       set_interrupt_gate(0, 55, &trap55);
+
+       // configurable msi or msi-x interrupts
+       set_interrupt_gate(0, 56, &trap56);
+       set_interrupt_gate(0, 57, &trap57);
+       set_interrupt_gate(0, 58, &trap58);
+       set_interrupt_gate(0, 59, &trap59);
+       set_interrupt_gate(0, 60, &trap60);
+       set_interrupt_gate(0, 61, &trap61);
+       set_interrupt_gate(0, 62, &trap62);
+       set_interrupt_gate(0, 63, &trap63);
+       set_interrupt_gate(0, 64, &trap64);
+       set_interrupt_gate(0, 65, &trap65);
+       set_interrupt_gate(0, 66, &trap66);
+       set_interrupt_gate(0, 67, &trap67);
+       set_interrupt_gate(0, 68, &trap68);
+       set_interrupt_gate(0, 69, &trap69);
+       set_interrupt_gate(0, 70, &trap70);
+       set_interrupt_gate(0, 71, &trap71);
+       set_interrupt_gate(0, 72, &trap72);
+       set_interrupt_gate(0, 73, &trap73);
+       set_interrupt_gate(0, 74, &trap74);
+       set_interrupt_gate(0, 75, &trap75);
+       set_interrupt_gate(0, 76, &trap76);
+       set_interrupt_gate(0, 77, &trap77);
+       set_interrupt_gate(0, 78, &trap78);
+       set_interrupt_gate(0, 79, &trap79);
+       set_interrupt_gate(0, 80, &trap80);
+       set_interrupt_gate(0, 81, &trap81);
+       set_interrupt_gate(0, 82, &trap82);
+       set_interrupt_gate(0, 83, &trap83);
+       set_interrupt_gate(0, 84, &trap84);
+       set_interrupt_gate(0, 85, &trap85);
+       set_interrupt_gate(0, 86, &trap86);
+       set_interrupt_gate(0, 87, &trap87);
+       set_interrupt_gate(0, 88, &trap88);
+       set_interrupt_gate(0, 89, &trap89);
+       set_interrupt_gate(0, 90, &trap90);
+       set_interrupt_gate(0, 91, &trap91);
+       set_interrupt_gate(0, 92, &trap92);
+       set_interrupt_gate(0, 93, &trap93);
+       set_interrupt_gate(0, 94, &trap94);
+       set_interrupt_gate(0, 95, &trap95);
+       set_interrupt_gate(0, 96, &trap96);
+       set_interrupt_gate(0, 97, &trap97);
+
        set_trap_gate(0, 98, &trap98);  // for performance testing only
-       set_trap_gate(0, 99, &trap99);
+       set_trap_gate(0, 99, &trap99);  // syscall interrupt
 
+       // configurable msi or msi-x interrupts
+       set_interrupt_gate(0, 100, &trap100);
+       set_interrupt_gate(0, 101, &trap101);
+       set_interrupt_gate(0, 102, &trap102);
+       set_interrupt_gate(0, 103, &trap103);
+       set_interrupt_gate(0, 104, &trap104);
+       set_interrupt_gate(0, 105, &trap105);
+       set_interrupt_gate(0, 106, &trap106);
+       set_interrupt_gate(0, 107, &trap107);
+       set_interrupt_gate(0, 108, &trap108);
+       set_interrupt_gate(0, 109, &trap109);
+       set_interrupt_gate(0, 110, &trap110);
+       set_interrupt_gate(0, 111, &trap111);
+       set_interrupt_gate(0, 112, &trap112);
+       set_interrupt_gate(0, 113, &trap113);
+       set_interrupt_gate(0, 114, &trap114);
+       set_interrupt_gate(0, 115, &trap115);
+       set_interrupt_gate(0, 116, &trap116);
+       set_interrupt_gate(0, 117, &trap117);
+       set_interrupt_gate(0, 118, &trap118);
+       set_interrupt_gate(0, 119, &trap119);
+       set_interrupt_gate(0, 120, &trap120);
+       set_interrupt_gate(0, 121, &trap121);
+       set_interrupt_gate(0, 122, &trap122);
+       set_interrupt_gate(0, 123, &trap123);
+       set_interrupt_gate(0, 124, &trap124);
+       set_interrupt_gate(0, 125, &trap125);
+       set_interrupt_gate(0, 126, &trap126);
+       set_interrupt_gate(0, 127, &trap127);
+       set_interrupt_gate(0, 128, &trap128);
+       set_interrupt_gate(0, 129, &trap129);
+       set_interrupt_gate(0, 130, &trap130);
+       set_interrupt_gate(0, 131, &trap131);
+       set_interrupt_gate(0, 132, &trap132);
+       set_interrupt_gate(0, 133, &trap133);
+       set_interrupt_gate(0, 134, &trap134);
+       set_interrupt_gate(0, 135, &trap135);
+       set_interrupt_gate(0, 136, &trap136);
+       set_interrupt_gate(0, 137, &trap137);
+       set_interrupt_gate(0, 138, &trap138);
+       set_interrupt_gate(0, 139, &trap139);
+       set_interrupt_gate(0, 140, &trap140);
+       set_interrupt_gate(0, 141, &trap141);
+       set_interrupt_gate(0, 142, &trap142);
+       set_interrupt_gate(0, 143, &trap143);
+       set_interrupt_gate(0, 144, &trap144);
+       set_interrupt_gate(0, 145, &trap145);
+       set_interrupt_gate(0, 146, &trap146);
+       set_interrupt_gate(0, 147, &trap147);
+       set_interrupt_gate(0, 148, &trap148);
+       set_interrupt_gate(0, 149, &trap149);
+       set_interrupt_gate(0, 150, &trap150);
+       set_interrupt_gate(0, 151, &trap151);
+       set_interrupt_gate(0, 152, &trap152);
+       set_interrupt_gate(0, 153, &trap153);
+       set_interrupt_gate(0, 154, &trap154);
+       set_interrupt_gate(0, 155, &trap155);
+       set_interrupt_gate(0, 156, &trap156);
+       set_interrupt_gate(0, 157, &trap157);
+       set_interrupt_gate(0, 158, &trap158);
+       set_interrupt_gate(0, 159, &trap159);
+       set_interrupt_gate(0, 160, &trap160);
+       set_interrupt_gate(0, 161, &trap161);
+       set_interrupt_gate(0, 162, &trap162);
+       set_interrupt_gate(0, 163, &trap163);
+       set_interrupt_gate(0, 164, &trap164);
+       set_interrupt_gate(0, 165, &trap165);
+       set_interrupt_gate(0, 166, &trap166);
+       set_interrupt_gate(0, 167, &trap167);
+       set_interrupt_gate(0, 168, &trap168);
+       set_interrupt_gate(0, 169, &trap169);
+       set_interrupt_gate(0, 170, &trap170);
+       set_interrupt_gate(0, 171, &trap171);
+       set_interrupt_gate(0, 172, &trap172);
+       set_interrupt_gate(0, 173, &trap173);
+       set_interrupt_gate(0, 174, &trap174);
+       set_interrupt_gate(0, 175, &trap175);
+       set_interrupt_gate(0, 176, &trap176);
+       set_interrupt_gate(0, 177, &trap177);
+       set_interrupt_gate(0, 178, &trap178);
+       set_interrupt_gate(0, 179, &trap179);
+       set_interrupt_gate(0, 180, &trap180);
+       set_interrupt_gate(0, 181, &trap181);
+       set_interrupt_gate(0, 182, &trap182);
+       set_interrupt_gate(0, 183, &trap183);
+       set_interrupt_gate(0, 184, &trap184);
+       set_interrupt_gate(0, 185, &trap185);
+       set_interrupt_gate(0, 186, &trap186);
+       set_interrupt_gate(0, 187, &trap187);
+       set_interrupt_gate(0, 188, &trap188);
+       set_interrupt_gate(0, 189, &trap189);
+       set_interrupt_gate(0, 190, &trap190);
+       set_interrupt_gate(0, 191, &trap191);
+       set_interrupt_gate(0, 192, &trap192);
+       set_interrupt_gate(0, 193, &trap193);
+       set_interrupt_gate(0, 194, &trap194);
+       set_interrupt_gate(0, 195, &trap195);
+       set_interrupt_gate(0, 196, &trap196);
+       set_interrupt_gate(0, 197, &trap197);
+       set_interrupt_gate(0, 198, &trap198);
+       set_interrupt_gate(0, 199, &trap199);
+       set_interrupt_gate(0, 200, &trap200);
+       set_interrupt_gate(0, 201, &trap201);
+       set_interrupt_gate(0, 202, &trap202);
+       set_interrupt_gate(0, 203, &trap203);
+       set_interrupt_gate(0, 204, &trap204);
+       set_interrupt_gate(0, 205, &trap205);
+       set_interrupt_gate(0, 206, &trap206);
+       set_interrupt_gate(0, 207, &trap207);
+       set_interrupt_gate(0, 208, &trap208);
+       set_interrupt_gate(0, 209, &trap209);
+       set_interrupt_gate(0, 210, &trap210);
+       set_interrupt_gate(0, 211, &trap211);
+       set_interrupt_gate(0, 212, &trap212);
+       set_interrupt_gate(0, 213, &trap213);
+       set_interrupt_gate(0, 214, &trap214);
+       set_interrupt_gate(0, 215, &trap215);
+       set_interrupt_gate(0, 216, &trap216);
+       set_interrupt_gate(0, 217, &trap217);
+       set_interrupt_gate(0, 218, &trap218);
+       set_interrupt_gate(0, 219, &trap219);
+       set_interrupt_gate(0, 220, &trap220);
+       set_interrupt_gate(0, 221, &trap221);
+       set_interrupt_gate(0, 222, &trap222);
+       set_interrupt_gate(0, 223, &trap223);
+       set_interrupt_gate(0, 224, &trap224);
+       set_interrupt_gate(0, 225, &trap225);
+       set_interrupt_gate(0, 226, &trap226);
+       set_interrupt_gate(0, 227, &trap227);
+       set_interrupt_gate(0, 228, &trap228);
+       set_interrupt_gate(0, 229, &trap229);
+       set_interrupt_gate(0, 230, &trap230);
+       set_interrupt_gate(0, 231, &trap231);
+       set_interrupt_gate(0, 232, &trap232);
+       set_interrupt_gate(0, 233, &trap233);
+       set_interrupt_gate(0, 234, &trap234);
+       set_interrupt_gate(0, 235, &trap235);
+       set_interrupt_gate(0, 236, &trap236);
+       set_interrupt_gate(0, 237, &trap237);
+       set_interrupt_gate(0, 238, &trap238);
+       set_interrupt_gate(0, 239, &trap239);
+       set_interrupt_gate(0, 240, &trap240);
+       set_interrupt_gate(0, 241, &trap241);
+       set_interrupt_gate(0, 242, &trap242);
+       set_interrupt_gate(0, 243, &trap243);
+       set_interrupt_gate(0, 244, &trap244);
+       set_interrupt_gate(0, 245, &trap245);
+       set_interrupt_gate(0, 246, &trap246);
+       set_interrupt_gate(0, 247, &trap247);
+       set_interrupt_gate(0, 248, &trap248);
+       set_interrupt_gate(0, 249, &trap249);
+       set_interrupt_gate(0, 250, &trap250);
+
+       // smp / apic local interrupts
        set_interrupt_gate(0, 251, &trap251);
        set_interrupt_gate(0, 252, &trap252);
        set_interrupt_gate(0, 253, &trap253);

Modified: haiku/trunk/src/system/kernel/arch/x86/arch_interrupts.S
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_interrupts.S    2010-04-13 
14:34:06 UTC (rev 36220)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_interrupts.S    2010-04-13 
14:46:09 UTC (rev 36221)
@@ -226,6 +226,7 @@
 TRAP(trap18, 18)
 TRAP(trap19, 19)
 
+// legacy or ioapic interrupts
 TRAP(trap32, 32)
 TRAP(trap33, 33)
 TRAP(trap34, 34)
@@ -242,6 +243,8 @@
 TRAP(trap45, 45)
 TRAP(trap46, 46)
 TRAP(trap47, 47)
+
+// additional ioapic interrupts
 TRAP(trap48, 48)
 TRAP(trap49, 49)
 TRAP(trap50, 50)
@@ -251,6 +254,204 @@
 TRAP(trap54, 54)
 TRAP(trap55, 55)
 
+// configurable msi or msi-x interrupts
+TRAP(trap56, 56)
+TRAP(trap57, 57)
+TRAP(trap58, 58)
+TRAP(trap59, 59)
+TRAP(trap60, 60)
+TRAP(trap61, 61)
+TRAP(trap62, 62)
+TRAP(trap63, 63)
+TRAP(trap64, 64)
+TRAP(trap65, 65)
+TRAP(trap66, 66)
+TRAP(trap67, 67)
+TRAP(trap68, 68)
+TRAP(trap69, 69)
+TRAP(trap70, 70)
+TRAP(trap71, 71)
+TRAP(trap72, 72)
+TRAP(trap73, 73)
+TRAP(trap74, 74)
+TRAP(trap75, 75)
+TRAP(trap76, 76)
+TRAP(trap77, 77)
+TRAP(trap78, 78)
+TRAP(trap79, 79)
+TRAP(trap80, 80)
+TRAP(trap81, 81)
+TRAP(trap82, 82)
+TRAP(trap83, 83)
+TRAP(trap84, 84)
+TRAP(trap85, 85)
+TRAP(trap86, 86)
+TRAP(trap87, 87)
+TRAP(trap88, 88)
+TRAP(trap89, 89)
+TRAP(trap90, 90)
+TRAP(trap91, 91)
+TRAP(trap92, 92)
+TRAP(trap93, 93)
+TRAP(trap94, 94)
+TRAP(trap95, 95)
+TRAP(trap96, 96)
+TRAP(trap97, 97)
+//TRAP(trap98, 98) // performance testing interrupt
+//TRAP(trap99, 99) // syscall interrupt
+TRAP(trap100, 100)
+TRAP(trap101, 101)
+TRAP(trap102, 102)
+TRAP(trap103, 103)
+TRAP(trap104, 104)
+TRAP(trap105, 105)
+TRAP(trap106, 106)
+TRAP(trap107, 107)
+TRAP(trap108, 108)
+TRAP(trap109, 109)
+TRAP(trap110, 110)
+TRAP(trap111, 111)
+TRAP(trap112, 112)
+TRAP(trap113, 113)
+TRAP(trap114, 114)
+TRAP(trap115, 115)
+TRAP(trap116, 116)
+TRAP(trap117, 117)
+TRAP(trap118, 118)
+TRAP(trap119, 119)
+TRAP(trap120, 120)
+TRAP(trap121, 121)
+TRAP(trap122, 122)
+TRAP(trap123, 123)
+TRAP(trap124, 124)
+TRAP(trap125, 125)
+TRAP(trap126, 126)
+TRAP(trap127, 127)
+TRAP(trap128, 128)
+TRAP(trap129, 129)
+TRAP(trap130, 130)
+TRAP(trap131, 131)
+TRAP(trap132, 132)
+TRAP(trap133, 133)
+TRAP(trap134, 134)
+TRAP(trap135, 135)
+TRAP(trap136, 136)
+TRAP(trap137, 137)
+TRAP(trap138, 138)
+TRAP(trap139, 139)
+TRAP(trap140, 140)
+TRAP(trap141, 141)
+TRAP(trap142, 142)
+TRAP(trap143, 143)
+TRAP(trap144, 144)
+TRAP(trap145, 145)
+TRAP(trap146, 146)
+TRAP(trap147, 147)
+TRAP(trap148, 148)
+TRAP(trap149, 149)
+TRAP(trap150, 150)
+TRAP(trap151, 151)
+TRAP(trap152, 152)
+TRAP(trap153, 153)
+TRAP(trap154, 154)
+TRAP(trap155, 155)
+TRAP(trap156, 156)
+TRAP(trap157, 157)
+TRAP(trap158, 158)
+TRAP(trap159, 159)
+TRAP(trap160, 160)
+TRAP(trap161, 161)
+TRAP(trap162, 162)
+TRAP(trap163, 163)
+TRAP(trap164, 164)
+TRAP(trap165, 165)
+TRAP(trap166, 166)
+TRAP(trap167, 167)
+TRAP(trap168, 168)
+TRAP(trap169, 169)
+TRAP(trap170, 170)
+TRAP(trap171, 171)
+TRAP(trap172, 172)
+TRAP(trap173, 173)
+TRAP(trap174, 174)
+TRAP(trap175, 175)
+TRAP(trap176, 176)
+TRAP(trap177, 177)
+TRAP(trap178, 178)
+TRAP(trap179, 179)
+TRAP(trap180, 180)
+TRAP(trap181, 181)
+TRAP(trap182, 182)
+TRAP(trap183, 183)
+TRAP(trap184, 184)
+TRAP(trap185, 185)
+TRAP(trap186, 186)
+TRAP(trap187, 187)
+TRAP(trap188, 188)
+TRAP(trap189, 189)
+TRAP(trap190, 190)
+TRAP(trap191, 191)
+TRAP(trap192, 192)
+TRAP(trap193, 193)
+TRAP(trap194, 194)
+TRAP(trap195, 195)
+TRAP(trap196, 196)
+TRAP(trap197, 197)
+TRAP(trap198, 198)
+TRAP(trap199, 199)
+TRAP(trap200, 200)
+TRAP(trap201, 201)
+TRAP(trap202, 202)
+TRAP(trap203, 203)
+TRAP(trap204, 204)
+TRAP(trap205, 205)
+TRAP(trap206, 206)
+TRAP(trap207, 207)
+TRAP(trap208, 208)
+TRAP(trap209, 209)
+TRAP(trap210, 210)
+TRAP(trap211, 211)
+TRAP(trap212, 212)
+TRAP(trap213, 213)
+TRAP(trap214, 214)
+TRAP(trap215, 215)
+TRAP(trap216, 216)
+TRAP(trap217, 217)
+TRAP(trap218, 218)
+TRAP(trap219, 219)
+TRAP(trap220, 220)
+TRAP(trap221, 221)
+TRAP(trap222, 222)
+TRAP(trap223, 223)
+TRAP(trap224, 224)
+TRAP(trap225, 225)
+TRAP(trap226, 226)
+TRAP(trap227, 227)
+TRAP(trap228, 228)
+TRAP(trap229, 229)
+TRAP(trap230, 230)
+TRAP(trap231, 231)
+TRAP(trap232, 232)
+TRAP(trap233, 233)
+TRAP(trap234, 234)
+TRAP(trap235, 235)
+TRAP(trap236, 236)
+TRAP(trap237, 237)
+TRAP(trap238, 238)
+TRAP(trap239, 239)
+TRAP(trap240, 240)
+TRAP(trap241, 241)
+TRAP(trap242, 242)
+TRAP(trap243, 243)
+TRAP(trap244, 244)
+TRAP(trap245, 245)
+TRAP(trap246, 246)
+TRAP(trap247, 247)
+TRAP(trap248, 248)
+TRAP(trap249, 249)
+TRAP(trap250, 250)
+
+// smp / apic local interrupts
 TRAP(trap251, 251)
 TRAP(trap252, 252)
 TRAP(trap253, 253)

Modified: haiku/trunk/src/system/kernel/arch/x86/arch_smp.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_smp.cpp 2010-04-13 14:34:06 UTC 
(rev 36220)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_smp.cpp 2010-04-13 14:46:09 UTC 
(rev 36221)
@@ -37,7 +37,6 @@
 static uint32 sCPUOSIds[B_MAX_CPU_COUNT];
 static uint32 sAPICVersions[B_MAX_CPU_COUNT];
 
-extern bool gUsingIOAPIC;
 extern "C" void init_sse(void);
 
 
@@ -47,12 +46,6 @@
        // genuine inter-cpu interrupt
        int cpu = smp_get_current_cpu();
        TRACE(("inter-cpu interrupt on cpu %d\n", cpu));
-
-       // if we are not using the IO APIC we need to acknowledge the
-       // interrupt ourselfs
-       if (!gUsingIOAPIC)
-               apic_end_of_interrupt();
-
        return smp_intercpu_int_handler(cpu);
 }
 
@@ -75,12 +68,6 @@
 {
        // smp error interrupt
        TRACE(("smp error interrupt on cpu %ld\n", smp_get_current_cpu()));
-
-       // if we are not using the IO APIC we need to acknowledge the
-       // interrupt ourselfs
-       if (!gUsingIOAPIC)
-               apic_end_of_interrupt();
-
        return B_HANDLED_INTERRUPT;
 }
 

Modified: haiku/trunk/src/system/kernel/arch/x86/interrupts.h
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/interrupts.h 2010-04-13 14:34:06 UTC 
(rev 36220)
+++ haiku/trunk/src/system/kernel/arch/x86/interrupts.h 2010-04-13 14:46:09 UTC 
(rev 36221)
@@ -15,19 +15,62 @@
 
 void trap0();void trap1();void trap2();void trap3();void trap4();void trap5();
 void trap6();void trap7();void trap9();void trap10();void trap11();
-void trap12();void trap13();void trap14();void trap16();void trap17();void 
trap18();
-void trap19();
-void trap32();void trap33();void trap34();void trap35();void trap36();void 
trap37();
-void trap38();void trap39();void trap40();void trap41();void trap42();void 
trap43();
-void trap44();void trap45();void trap46();void trap47();void trap48();void 
trap49();
-void trap50();void trap51();void trap52();void trap53();void trap54();void 
trap55();
+void trap12();void trap13();void trap14();void trap16();void trap17();
+void trap18();void trap19();
 
+void trap32();void trap33();void trap34();void trap35();void trap36();
+void trap37();void trap38();void trap39();void trap40();void trap41();
+void trap42();void trap43();void trap44();void trap45();void trap46();
+void trap47();void trap48();void trap49();void trap50();void trap51();
+void trap52();void trap53();void trap54();void trap55();void trap56();
+void trap57();void trap58();void trap59();void trap60();void trap61();
+void trap62();void trap63();void trap64();void trap65();void trap66();
+void trap67();void trap68();void trap69();void trap70();void trap71();
+void trap72();void trap73();void trap74();void trap75();void trap76();
+void trap77();void trap78();void trap79();void trap80();void trap81();
+void trap82();void trap83();void trap84();void trap85();void trap86();
+void trap87();void trap88();void trap89();void trap90();void trap91();
+void trap92();void trap93();void trap94();void trap95();void trap96();
+void trap97();
+
 void double_fault();   // int 8
 void trap14_double_fault();
 
 void trap98();
 void trap99();
 
+void trap100();void trap101();void trap102();void trap103();void trap104();
+void trap105();void trap106();void trap107();void trap108();void trap109();
+void trap110();void trap111();void trap112();void trap113();void trap114();
+void trap115();void trap116();void trap117();void trap118();void trap119();
+void trap120();void trap121();void trap122();void trap123();void trap124();
+void trap125();void trap126();void trap127();void trap128();void trap129();
+void trap130();void trap131();void trap132();void trap133();void trap134();
+void trap135();void trap136();void trap137();void trap138();void trap139();
+void trap140();void trap141();void trap142();void trap143();void trap144();
+void trap145();void trap146();void trap147();void trap148();void trap149();
+void trap150();void trap151();void trap152();void trap153();void trap154();
+void trap155();void trap156();void trap157();void trap158();void trap159();
+void trap160();void trap161();void trap162();void trap163();void trap164();
+void trap165();void trap166();void trap167();void trap168();void trap169();
+void trap170();void trap171();void trap172();void trap173();void trap174();
+void trap175();void trap176();void trap177();void trap178();void trap179();
+void trap180();void trap181();void trap182();void trap183();void trap184();
+void trap185();void trap186();void trap187();void trap188();void trap189();
+void trap190();void trap191();void trap192();void trap193();void trap194();
+void trap195();void trap196();void trap197();void trap198();void trap199();
+void trap200();void trap201();void trap202();void trap203();void trap204();
+void trap205();void trap206();void trap207();void trap208();void trap209();
+void trap210();void trap211();void trap212();void trap213();void trap214();
+void trap215();void trap216();void trap217();void trap218();void trap219();
+void trap220();void trap221();void trap222();void trap223();void trap224();
+void trap225();void trap226();void trap227();void trap228();void trap229();
+void trap230();void trap231();void trap232();void trap233();void trap234();
+void trap235();void trap236();void trap237();void trap238();void trap239();
+void trap240();void trap241();void trap242();void trap243();void trap244();
+void trap245();void trap246();void trap247();void trap248();void trap249();
+void trap250();
+
 void trap251();void trap252();void trap253();void trap254();void trap255();
 
 #ifdef __cplusplus

Added: haiku/trunk/src/system/kernel/arch/x86/msi.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/msi.cpp                              
(rev 0)
+++ haiku/trunk/src/system/kernel/arch/x86/msi.cpp      2010-04-13 14:46:09 UTC 
(rev 36221)
@@ -0,0 +1,131 @@
+/*
+ * Copyright 20010, Michael Lotz, mmlr@xxxxxxxxx All Rights Reserved.
+ * Distributed under the terms of the MIT license.
+ */
+
+#include <arch/x86/apic.h>
+#include <arch/x86/arch_int.h>
+#include <arch/x86/msi.h>
+
+#include <debug.h>
+#include <lock.h>
+
+
+static bool sMSISupported = false;
+static const uint32 kVectorCount = 256 - ARCH_INTERRUPT_BASE;
+static bool sAllocatedVectors[kVectorCount];
+static mutex sMSIAllocationLock = MUTEX_INITIALIZER("msi_allocation");
+
+
+void
+msi_init()
+{
+       if (!apic_available()) {
+               dprintf("disabling msi due to missing apic\n");
+               return;
+       }
+
+       for (uint16 i = 0; i < kVectorCount; i++)
+               sAllocatedVectors[i] = false;
+
+       // the first 24 vectors are addressable with a single ioapic config
+       for (uint16 i = 0; i < 24; i++)
+               sAllocatedVectors[i] = true;
+
+       // performance testing and syscall interrupts
+       sAllocatedVectors[98 - ARCH_INTERRUPT_BASE] = true;
+       sAllocatedVectors[99 - ARCH_INTERRUPT_BASE] = true;
+
+       // the upper range is used by apic local (timer) and smp interrupts 
(ipi)
+       for (uint16 i = 251; i < 256; i++)
+               sAllocatedVectors[i - ARCH_INTERRUPT_BASE] = true;
+
+       dprintf("msi support enabled\n");
+       sMSISupported = true;
+}
+
+
+bool
+msi_supported()
+{
+       return sMSISupported;
+}
+
+
+status_t
+msi_allocate_vectors(uint8 count, uint8 *startVector, uint64 *address,
+       uint16 *data)
+{
+       if (!sMSISupported)
+               return B_UNSUPPORTED;
+
+       mutex_lock(&sMSIAllocationLock);
+
+       uint8 vector = 0;
+       bool runFound = true;
+       for (uint16 i = 0; i < kVectorCount - (count - 1); i++) {
+               if (!sAllocatedVectors[i]) {
+                       vector = i;
+                       runFound = true;
+                       for (uint16 j = 1; j < count; j++) {
+                               if (sAllocatedVectors[i + j]) {
+                                       runFound = false;
+                                       i += j;
+                                       break;
+                               }
+                       }
+
+                       if (runFound)
+                               break;
+               }
+       }
+
+       if (!runFound) {
+               mutex_unlock(&sMSIAllocationLock);
+               dprintf("found no free vectors to allocate %u msi messages\n", 
count);
+               return B_NO_MEMORY;
+       }
+
+       for (uint16 i = 0; i < count; i++)
+               sAllocatedVectors[i + vector] = true;
+
+       mutex_unlock(&sMSIAllocationLock);
+
+       *startVector = vector;
+       *address = MSI_ADDRESS_BASE | (0 << MSI_DESTINATION_ID_SHIFT)
+               | MSI_NO_REDIRECTION | MSI_DESTINATION_MODE_PHYSICAL;
+       *data = MSI_TRIGGER_MODE_EDGE | MSI_DELIVERY_MODE_FIXED
+               | (vector + ARCH_INTERRUPT_BASE);
+
+       dprintf("msi_allocate_vectors: allocated %u vectors starting from %u\n",
+               count, vector);
+       return B_OK;
+}
+
+
+void
+msi_free_vectors(uint8 count, uint8 startVector)
+{
+       if (!sMSISupported) {
+               panic("trying to free msi vectors but msi not supported\n");
+               return;
+       }
+
+       if ((uint32)startVector + count > kVectorCount) {
+               panic("invalid start vector %u or count %u supplied to "
+                       "msi_free_vectors\n", startVector, count);
+       }
+
+       dprintf("msi_free_vectors: freeing %u vectors starting from %u\n", 
count,
+               startVector);
+
+       mutex_lock(&sMSIAllocationLock);
+       for (uint16 i = 0; i < count; i++) {
+               if (!sAllocatedVectors[i + startVector])
+                       panic("msi vector %u was not allocated\n", i + 
startVector);
+
+               sAllocatedVectors[i + startVector] = false;
+       }
+
+       mutex_unlock(&sMSIAllocationLock);
+}

Modified: haiku/trunk/src/system/kernel/arch/x86/timers/x86_apic.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/timers/x86_apic.cpp  2010-04-13 
14:34:06 UTC (rev 36220)
+++ haiku/trunk/src/system/kernel/arch/x86/timers/x86_apic.cpp  2010-04-13 
14:46:09 UTC (rev 36221)
@@ -27,8 +27,6 @@
 
 static uint32 sApicTicsPerSec = 0;
 
-extern bool gUsingIOAPIC;
-
 struct timer_info gAPICTimer = {
        "APIC",
        &apic_timer_get_priority,
@@ -48,11 +46,6 @@
 static int32
 apic_timer_interrupt(void *data)
 {
-       // if we are not using the IO APIC we need to acknowledge the
-       // interrupt ourselfs
-       if (!gUsingIOAPIC)
-               apic_end_of_interrupt();
-
        return timer_interrupt();
 }
 


Other related posts:

  • » [haiku-commits] r36221 - in haiku/trunk: headers/private/kernel/arch/x86 src/system/kernel/arch/x86 src/system/kernel/arch/x86/timers - mmlr