* 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();
|
||||
void apic_end_of_interrupt();
|
||||
|
||||
void apic_disable_local_ints();
|
||||
|
||||
status_t apic_init(kernel_args *args);
|
||||
status_t apic_per_cpu_init(kernel_args *args, int32 cpu);
|
||||
|
||||
|
@ -5,8 +5,12 @@
|
||||
#ifndef _KERNEL_ARCH_x86_IOAPIC_H
|
||||
#define _KERNEL_ARCH_x86_IOAPIC_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
struct kernel_args;
|
||||
|
||||
bool ioapic_is_interrupt_available(int32 gsi);
|
||||
|
||||
void ioapic_map(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
|
||||
apic_init(kernel_args *args)
|
||||
{
|
||||
@ -72,7 +81,6 @@ apic_init(kernel_args *args)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
msi_init();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <arch/x86/apic.h>
|
||||
#include <arch/x86/descriptors.h>
|
||||
#include <arch/x86/msi.h>
|
||||
#include <arch/x86/vm86.h>
|
||||
|
||||
#include "interrupts.h"
|
||||
@ -866,6 +867,7 @@ status_t
|
||||
arch_int_init_io(kernel_args* args)
|
||||
{
|
||||
ioapic_init(args);
|
||||
msi_init();
|
||||
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
|
||||
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
|
||||
ioapic_map(kernel_args* args)
|
||||
{
|
||||
@ -577,6 +577,14 @@ ioapic_init(kernel_args* args)
|
||||
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
|
||||
pic_disable();
|
||||
|
||||
|
@ -5,14 +5,17 @@
|
||||
|
||||
#include <arch/x86/apic.h>
|
||||
#include <arch/x86/arch_int.h>
|
||||
#include <arch/x86/ioapic.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 const uint8 kNumISAVectors = 16;
|
||||
|
||||
static bool sMSISupported = false;
|
||||
static bool sAllocatedVectors[kVectorCount];
|
||||
static mutex sMSIAllocationLock = MUTEX_INITIALIZER("msi_allocation");
|
||||
|
||||
@ -25,13 +28,19 @@ msi_init()
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint16 i = 0; i < kVectorCount; i++)
|
||||
sAllocatedVectors[i] = false;
|
||||
// TODO: less hardcoding!
|
||||
|
||||
// the first 24 vectors are addressable with a single ioapic config
|
||||
for (uint16 i = 0; i < 24; i++)
|
||||
// the first 16 vectors are legacy ISA in all cases
|
||||
for (uint16 i = 0; i < kNumISAVectors; i++)
|
||||
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
|
||||
sAllocatedVectors[98 - ARCH_INTERRUPT_BASE] = true;
|
||||
sAllocatedVectors[99 - ARCH_INTERRUPT_BASE] = true;
|
||||
|
Loading…
Reference in New Issue
Block a user