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(); }