* 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:
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user