* 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:
Michael Lotz 2011-05-11 18:05:05 +00:00
parent dfd1e5889e
commit a56cbb2afb
6 changed files with 46 additions and 13 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

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

View File

@ -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;