summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-03-06 17:16:47 +0000
committerjhb <jhb@FreeBSD.org>2007-03-06 17:16:47 +0000
commit432a1d8db500d646851a9158c0bf0e7df4ca5855 (patch)
tree7d449fe1c2cd369c1d96d20251aea25b4116a366 /sys/i386
parentb67850e4380a4cfabfe3e85e61cc3e3b0376683c (diff)
downloadFreeBSD-src-432a1d8db500d646851a9158c0bf0e7df4ca5855.zip
FreeBSD-src-432a1d8db500d646851a9158c0bf0e7df4ca5855.tar.gz
Change the x86 interrupt code to use FreeBSD CPU IDs (i.e. PCPU_GET(cpuid))
rather than local APIC IDs to keep track of CPUs which can handle interrupts.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/intr_machdep.c30
-rw-r--r--sys/i386/i386/local_apic.c1
-rw-r--r--sys/i386/i386/mp_machdep.c11
-rw-r--r--sys/i386/include/intr_machdep.h4
-rw-r--r--sys/i386/include/smp.h1
5 files changed, 26 insertions, 21 deletions
diff --git a/sys/i386/i386/intr_machdep.c b/sys/i386/i386/intr_machdep.c
index c505984..ee34570 100644
--- a/sys/i386/i386/intr_machdep.c
+++ b/sys/i386/i386/intr_machdep.c
@@ -51,6 +51,7 @@
#include <sys/systm.h>
#include <machine/clock.h>
#include <machine/intr_machdep.h>
+#include <machine/smp.h>
#ifdef DDB
#include <ddb/ddb.h>
#endif
@@ -395,8 +396,9 @@ DB_SHOW_COMMAND(irqs, db_show_irqs)
* allocate CPUs round-robin.
*/
-static u_int cpu_apic_ids[MAXCPU];
-static int current_cpu, num_cpus;
+/* The BSP is always a valid target. */
+static cpumask_t intr_cpus = (1 << 0);
+static int current_cpu, num_cpus = 1;
static void
intr_assign_next_cpu(struct intsrc *isrc)
@@ -409,25 +411,29 @@ intr_assign_next_cpu(struct intsrc *isrc)
*/
pic = isrc->is_pic;
apic_id = cpu_apic_ids[current_cpu];
- current_cpu++;
- if (current_cpu >= num_cpus)
- current_cpu = 0;
pic->pic_assign_cpu(isrc, apic_id);
+ do {
+ current_cpu++;
+ if (current_cpu >= num_cpus)
+ current_cpu = 0;
+ } while (!(intr_cpus & (1 << current_cpu)));
}
/*
- * Add a local APIC ID to our list of valid local APIC IDs that can
- * be destinations of interrupts.
+ * Add a CPU to our mask of valid CPUs that can be destinations of
+ * interrupts.
*/
void
-intr_add_cpu(u_int apic_id)
+intr_add_cpu(u_int cpu)
{
+ if (cpu >= MAXCPU)
+ panic("%s: Invalid CPU ID", __func__);
if (bootverbose)
- printf("INTR: Adding local APIC %d as a target\n", apic_id);
- if (num_cpus >= MAXCPU)
- panic("WARNING: Local APIC IDs exhausted!");
- cpu_apic_ids[num_cpus] = apic_id;
+ printf("INTR: Adding local APIC %d as a target\n",
+ cpu_apic_ids[cpu]);
+
+ intr_cpus |= (1 << cpu);
num_cpus++;
}
diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
index ea27aa2..6b6d561 100644
--- a/sys/i386/i386/local_apic.c
+++ b/sys/i386/i386/local_apic.c
@@ -221,7 +221,6 @@ lapic_init(vm_paddr_t addr)
/* Set BSP's per-CPU local APIC ID. */
PCPU_SET(apic_id, lapic_id());
- intr_add_cpu(PCPU_GET(apic_id));
/* Local APIC timer interrupt. */
setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_SYS386IGT, SEL_KPL,
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 3ca9bcf..7fa9458 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -209,7 +209,7 @@ struct cpu_info {
int cpu_bsp:1;
int cpu_disabled:1;
} static cpu_info[MAXCPU];
-static int cpu_apic_ids[MAXCPU];
+int cpu_apic_ids[MAXCPU];
/* Holds pending bitmap based IPIs per CPU */
static volatile u_int cpu_ipi_pending[MAXCPU];
@@ -668,10 +668,11 @@ init_secondary(void)
static void
set_interrupt_apic_ids(void)
{
- u_int apic_id;
+ u_int i, apic_id;
- for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
- if (!cpu_info[apic_id].cpu_present)
+ for (i = 0; i < MAXCPU; i++) {
+ apic_id = cpu_apic_ids[i];
+ if (apic_id == -1)
continue;
if (cpu_info[apic_id].cpu_bsp)
continue;
@@ -683,7 +684,7 @@ set_interrupt_apic_ids(void)
apic_id % hyperthreading_cpus != 0)
continue;
- intr_add_cpu(apic_id);
+ intr_add_cpu(i);
}
}
diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h
index 253027e..8d36436 100644
--- a/sys/i386/include/intr_machdep.h
+++ b/sys/i386/include/intr_machdep.h
@@ -128,9 +128,7 @@ enum intr_trigger elcr_read_trigger(u_int irq);
void elcr_resume(void);
void elcr_write_trigger(u_int irq, enum intr_trigger trigger);
#ifdef SMP
-void intr_add_cpu(u_int apic_id);
-#else
-#define intr_add_cpu(apic_id)
+void intr_add_cpu(u_int cpu);
#endif
int intr_add_handler(const char *name, int vector, driver_filter_t filter,
driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep);
diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h
index 6451a5c..7116b43 100644
--- a/sys/i386/include/smp.h
+++ b/sys/i386/include/smp.h
@@ -35,6 +35,7 @@ extern int mp_naps;
extern int boot_cpu_id;
extern struct pcb stoppcbs[];
extern struct mtx smp_tlb_mtx;
+extern int cpu_apic_ids[];
#ifdef COUNT_IPIS
extern u_long *ipi_invltlb_counts[MAXCPU];
extern u_long *ipi_invlrng_counts[MAXCPU];
OpenPOWER on IntegriCloud