summaryrefslogtreecommitdiffstats
path: root/sys/amd64/isa
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-02-28 22:24:55 +0000
committerjhb <jhb@FreeBSD.org>2006-02-28 22:24:55 +0000
commit3478c467ee4302dfd13af593c68c02bcf15cd5aa (patch)
treef5550e7925fc98745c64609db43678c325dc0243 /sys/amd64/isa
parent1ec49d602a80028377023a0fdc8f11d6281a3b18 (diff)
downloadFreeBSD-src-3478c467ee4302dfd13af593c68c02bcf15cd5aa.zip
FreeBSD-src-3478c467ee4302dfd13af593c68c02bcf15cd5aa.tar.gz
Rework how we wire up interrupt sources to CPUs:
- Throw out all of the logical APIC ID stuff. The Intel docs are somewhat ambiguous, but it seems that the "flat" cluster model we are currently using is only supported on Pentium and P6 family CPUs. The other "hierarchy" cluster model that is supported on all Intel CPUs with local APICs is severely underdocumented. For example, it's not clear if the OS needs to glean the topology of the APIC hierarchy from somewhere (neither ACPI nor MP Table include it) and setup the logical clusters based on the physical hierarchy or not. Not only that, but on certain Intel chipsets, even though there were 4 CPUs in a logical cluster, all the interrupts were only sent to one CPU anyway. - We now bind interrupts to individual CPUs using physical addressing via the local APIC IDs. This code has also moved out of the ioapic PIC driver and into the common interrupt source code so that it can be shared with MSI interrupt sources since MSI is addressed to APICs the same way that I/O APIC pins are. - Interrupt source classes grow a new method pic_assign_cpu() to bind an interrupt source to a specific local APIC ID. - The SMP code now tells the interrupt code which CPUs are avaiable to handle interrupts in a simpler and more intuitive manner. For one thing, it means we could now choose to not route interrupts to HT cores if we wanted to (this code is currently in place in fact, but under an #if 0 for now). - For now we simply do static round-robin of IRQs to CPUs when the first interrupt handler just as before, with the change that IRQs are now bound to individual CPUs rather than groups of up to 4 CPUs. - Because the IRQ to CPU mapping has now been moved up a layer, it would be easier to manage this mapping from higher levels. For example, we could allow drivers to specify a CPU affinity map for their interrupts, or we could allow a userland tool to bind IRQs to specific CPUs. The MFC is tentative, but I want to see if this fixes problems some folks had with UP APIC kernels on 6.0 on SMP machines (an SMP kernel would work fine, but a UP APIC kernel (such as GENERIC in RELENG_6) would lose interrupts). MFC after: 1 week
Diffstat (limited to 'sys/amd64/isa')
-rw-r--r--sys/amd64/isa/atpic.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/sys/amd64/isa/atpic.c b/sys/amd64/isa/atpic.c
index 906edda..1398e47 100644
--- a/sys/amd64/isa/atpic.c
+++ b/sys/amd64/isa/atpic.c
@@ -108,8 +108,8 @@ inthand_t
#define ATPIC(io, base, eoi, imenptr) \
{ { atpic_enable_source, atpic_disable_source, (eoi), \
atpic_enable_intr, atpic_vector, atpic_source_pending, NULL, \
- atpic_resume, atpic_config_intr }, (io), (base), \
- IDT_IO_INTS + (base), (imenptr) }
+ atpic_resume, atpic_config_intr, atpic_assign_cpu }, (io), \
+ (base), IDT_IO_INTS + (base), (imenptr) }
#define INTSRC(irq) \
{ { &atpics[(irq) / 8].at_pic }, IDTVEC(atpic_intr ## irq ), \
@@ -142,6 +142,7 @@ static void atpic_resume(struct intsrc *isrc);
static int atpic_source_pending(struct intsrc *isrc);
static int atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
enum intr_polarity pol);
+static void atpic_assign_cpu(struct intsrc *isrc, u_int apic_id);
static void i8259_init(struct atpic *pic, int slave);
static struct atpic atpics[] = {
@@ -353,6 +354,17 @@ atpic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
}
static void
+atpic_assign_cpu(struct intsrc *isrc, u_int apic_id)
+{
+
+ /*
+ * 8259A's are only used in UP in which case all interrupts always
+ * go to the sole CPU and this function shouldn't even be called.
+ */
+ panic("%s: bad cookie", __func__);
+}
+
+static void
i8259_init(struct atpic *pic, int slave)
{
int imr_addr;
OpenPOWER on IntegriCloud