* When initializing MSI support, don't assume a single 24 entry IO-APIC. Instead
mark the ISA interrupts as unusable and then use ioapic_is_interrupt_available to determine if that vector is possibly taken by an IO-APIC. If IO-APICs are not used, this will simply always return false, leaving all vectors free for MSI use. * The msi_init() now has to be done after a potential IO-APIC init, so it is now done after ioapic_init() instead of inside apic_init(). * Add apic_disable_local_ints() to clear the local ints on the local APIC once we are in APIC mode (i.e. the IO-APIC is set up and we don't need the external routing anymore). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41445 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
dfd1e5889e
commit
a56cbb2afb
@ -115,6 +115,8 @@ void apic_write(uint32 offset, uint32 data);
|
|||||||
uint32 apic_local_id();
|
uint32 apic_local_id();
|
||||||
void apic_end_of_interrupt();
|
void apic_end_of_interrupt();
|
||||||
|
|
||||||
|
void apic_disable_local_ints();
|
||||||
|
|
||||||
status_t apic_init(kernel_args *args);
|
status_t apic_init(kernel_args *args);
|
||||||
status_t apic_per_cpu_init(kernel_args *args, int32 cpu);
|
status_t apic_per_cpu_init(kernel_args *args, int32 cpu);
|
||||||
|
|
||||||
|
@ -5,8 +5,12 @@
|
|||||||
#ifndef _KERNEL_ARCH_x86_IOAPIC_H
|
#ifndef _KERNEL_ARCH_x86_IOAPIC_H
|
||||||
#define _KERNEL_ARCH_x86_IOAPIC_H
|
#define _KERNEL_ARCH_x86_IOAPIC_H
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
struct kernel_args;
|
struct kernel_args;
|
||||||
|
|
||||||
|
bool ioapic_is_interrupt_available(int32 gsi);
|
||||||
|
|
||||||
void ioapic_map(kernel_args* args);
|
void ioapic_map(kernel_args* args);
|
||||||
void ioapic_init(kernel_args* args);
|
void ioapic_init(kernel_args* args);
|
||||||
|
|
||||||
|
@ -56,6 +56,15 @@ apic_end_of_interrupt()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
apic_disable_local_ints()
|
||||||
|
{
|
||||||
|
// just clear them out completely
|
||||||
|
apic_write(APIC_LVT_LINT0, APIC_LVT_MASKED);
|
||||||
|
apic_write(APIC_LVT_LINT1, APIC_LVT_MASKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
apic_init(kernel_args *args)
|
apic_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
@ -72,7 +81,6 @@ apic_init(kernel_args *args)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
msi_init();
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <arch/x86/apic.h>
|
#include <arch/x86/apic.h>
|
||||||
#include <arch/x86/descriptors.h>
|
#include <arch/x86/descriptors.h>
|
||||||
|
#include <arch/x86/msi.h>
|
||||||
#include <arch/x86/vm86.h>
|
#include <arch/x86/vm86.h>
|
||||||
|
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
@ -866,6 +867,7 @@ status_t
|
|||||||
arch_int_init_io(kernel_args* args)
|
arch_int_init_io(kernel_args* args)
|
||||||
{
|
{
|
||||||
ioapic_init(args);
|
ioapic_init(args);
|
||||||
|
msi_init();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,13 +170,6 @@ ioapic_write_64(struct ioapic& ioapic, uint8 registerSelect, uint64 value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
|
||||||
ioapic_is_interrupt_available(int32 gsi)
|
|
||||||
{
|
|
||||||
return find_ioapic(gsi) != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ioapic_is_spurious_interrupt(int32 gsi)
|
ioapic_is_spurious_interrupt(int32 gsi)
|
||||||
{
|
{
|
||||||
@ -456,6 +449,13 @@ acpi_set_interrupt_model(acpi_module_info* acpiModule, uint32 interruptModel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ioapic_is_interrupt_available(int32 gsi)
|
||||||
|
{
|
||||||
|
return find_ioapic(gsi) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ioapic_map(kernel_args* args)
|
ioapic_map(kernel_args* args)
|
||||||
{
|
{
|
||||||
@ -577,6 +577,14 @@ ioapic_init(kernel_args* args)
|
|||||||
entry.polarity | entry.trigger_mode);
|
entry.polarity | entry.trigger_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// kill the local ints on the local APIC
|
||||||
|
apic_disable_local_ints();
|
||||||
|
// TODO: This uses the assumption that our init is running on the
|
||||||
|
// boot CPU and only the boot CPU has the local ints configured
|
||||||
|
// because it was running in legacy PIC mode. Possibly the other
|
||||||
|
// local APICs of the other CPUs have them configured as well. It
|
||||||
|
// shouldn't really harm, but should eventually be corrected.
|
||||||
|
|
||||||
// disable the legacy PIC
|
// disable the legacy PIC
|
||||||
pic_disable();
|
pic_disable();
|
||||||
|
|
||||||
|
@ -5,14 +5,17 @@
|
|||||||
|
|
||||||
#include <arch/x86/apic.h>
|
#include <arch/x86/apic.h>
|
||||||
#include <arch/x86/arch_int.h>
|
#include <arch/x86/arch_int.h>
|
||||||
|
#include <arch/x86/ioapic.h>
|
||||||
#include <arch/x86/msi.h>
|
#include <arch/x86/msi.h>
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
|
|
||||||
|
|
||||||
static bool sMSISupported = false;
|
|
||||||
static const uint32 kVectorCount = 256 - ARCH_INTERRUPT_BASE;
|
static const uint32 kVectorCount = 256 - ARCH_INTERRUPT_BASE;
|
||||||
|
static const uint8 kNumISAVectors = 16;
|
||||||
|
|
||||||
|
static bool sMSISupported = false;
|
||||||
static bool sAllocatedVectors[kVectorCount];
|
static bool sAllocatedVectors[kVectorCount];
|
||||||
static mutex sMSIAllocationLock = MUTEX_INITIALIZER("msi_allocation");
|
static mutex sMSIAllocationLock = MUTEX_INITIALIZER("msi_allocation");
|
||||||
|
|
||||||
@ -25,13 +28,19 @@ msi_init()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint16 i = 0; i < kVectorCount; i++)
|
// TODO: less hardcoding!
|
||||||
sAllocatedVectors[i] = false;
|
|
||||||
|
|
||||||
// the first 24 vectors are addressable with a single ioapic config
|
// the first 16 vectors are legacy ISA in all cases
|
||||||
for (uint16 i = 0; i < 24; i++)
|
for (uint16 i = 0; i < kNumISAVectors; i++)
|
||||||
sAllocatedVectors[i] = true;
|
sAllocatedVectors[i] = true;
|
||||||
|
|
||||||
|
for (uint16 i = kNumISAVectors; i < kVectorCount; i++) {
|
||||||
|
// if ioapics aren't in use this will always return false, leaving
|
||||||
|
// the vectors free for us; otherwise we'll avoid any vector that
|
||||||
|
// can be addressed by an IO-APIC
|
||||||
|
sAllocatedVectors[i] = ioapic_is_interrupt_available(i);
|
||||||
|
}
|
||||||
|
|
||||||
// performance testing and syscall interrupts
|
// performance testing and syscall interrupts
|
||||||
sAllocatedVectors[98 - ARCH_INTERRUPT_BASE] = true;
|
sAllocatedVectors[98 - ARCH_INTERRUPT_BASE] = true;
|
||||||
sAllocatedVectors[99 - ARCH_INTERRUPT_BASE] = true;
|
sAllocatedVectors[99 - ARCH_INTERRUPT_BASE] = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user