* 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.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36221 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2010-04-13 14:46:09 +00:00
parent aeae7bf4dc
commit 33fbe25496
9 changed files with 678 additions and 82 deletions
+33
View File
@@ -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
+1
View File
@@ -34,6 +34,7 @@ KernelMergeObject kernel_arch_x86.o :
bios.cpp
cpuid.S
irq_routing_table.cpp
msi.cpp
syscall.S
vm86.cpp
x86_physical_page_mapper.cpp
+2
View File
@@ -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 @@ apic_init(kernel_args *args)
return B_ERROR;
}
msi_init();
return B_OK;
}
+261 -56
View File
@@ -136,15 +136,13 @@ static uint32 sIOAPICMaxRedirectionEntry = 23;
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 @@ pic_is_spurious_interrupt(int32 num)
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 @@ pic_end_of_interrupt(int32 num)
// we always need to acknowledge the master PIC
out8(PIC_NON_SPECIFIC_EOI, PIC_MASTER_CONTROL);
return true;
}
@@ -413,7 +412,6 @@ pic_init(void)
// make the pic controller the current one
sCurrentPIC = &picController;
gUsingIOAPIC = false;
}
@@ -466,10 +464,11 @@ ioapic_is_spurious_interrupt(int32 num)
}
static void
static bool
ioapic_end_of_interrupt(int32 num)
{
apic_end_of_interrupt();
return true;
}
@@ -673,7 +672,6 @@ ioapic_init(kernel_args *args)
// prefer the ioapic over the normal pic
dprintf("using ioapic for interrupt routing\n");
sCurrentPIC = &ioapicController;
gUsingIOAPIC = true;
}
@@ -1011,13 +1009,19 @@ hardware_interrupt(struct iframe* frame)
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 @@ arch_int_init(struct kernel_args *args)
// 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);
@@ -226,6 +226,7 @@ TRAP_ERRC(trap17, 17)
TRAP(trap18, 18)
TRAP(trap19, 19)
// legacy or ioapic interrupts
TRAP(trap32, 32)
TRAP(trap33, 33)
TRAP(trap34, 34)
@@ -242,6 +243,8 @@ TRAP(trap44, 44)
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(trap53, 53)
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)
-13
View File
@@ -37,7 +37,6 @@ static uint32 sCPUAPICIds[B_MAX_CPU_COUNT];
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 @@ i386_ici_interrupt(void *data)
// 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 @@ i386_smp_error_interrupt(void *data)
{
// 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;
}
+49 -6
View File
@@ -15,12 +15,23 @@ extern "C" {
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();
@@ -28,6 +39,38 @@ 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
+131
View File
@@ -0,0 +1,131 @@
/*
* Copyright 20010, Michael Lotz, mmlr@mlotz.ch. 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);
}
@@ -27,8 +27,6 @@ static status_t apic_timer_init(struct kernel_args *args);
static uint32 sApicTicsPerSec = 0;
extern bool gUsingIOAPIC;
struct timer_info gAPICTimer = {
"APIC",
&apic_timer_get_priority,
@@ -48,11 +46,6 @@ apic_timer_get_priority()
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();
}