Page MenuHomeFreeBSD

D5459.diff
No OneTemporary

D5459.diff

Index: head/sys/arm/arm/machdep_intr.c
===================================================================
--- head/sys/arm/arm/machdep_intr.c
+++ head/sys/arm/arm/machdep_intr.c
@@ -52,11 +52,22 @@
#include <sys/conf.h>
#include <sys/pmc.h>
#include <sys/pmckern.h>
+#include <sys/smp.h>
#include <machine/atomic.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/cpu.h>
+#include <machine/smp.h>
+
+#ifdef ARM_INTRNG
+#include "pic_if.h"
+
+#ifdef SMP
+static struct intr_irqsrc ipi_sources[INTR_IPI_COUNT];
+static u_int ipi_next_num;
+#endif
+#endif
/*
* arm_irq_memory_barrier()
@@ -121,3 +132,127 @@
cpu_l2cache_drain_writebuf();
}
+#ifdef ARM_INTRNG
+#ifdef SMP
+/*
+ * Lookup IPI source.
+ */
+static struct intr_irqsrc *
+intr_ipi_lookup(u_int ipi)
+{
+
+ if (ipi >= INTR_IPI_COUNT)
+ panic("%s: no such IPI %u", __func__, ipi);
+
+ return (&ipi_sources[ipi]);
+}
+
+/*
+ * interrupt controller dispatch function for IPIs. It should
+ * be called straight from the interrupt controller, when associated
+ * interrupt source is learned. Or from anybody who has an interrupt
+ * source mapped.
+ */
+void
+intr_ipi_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf)
+{
+ void *arg;
+
+ KASSERT(isrc != NULL, ("%s: no source", __func__));
+
+ intr_ipi_increment_count(isrc->isrc_count, PCPU_GET(cpuid));
+
+ /*
+ * Supply ipi filter with trapframe argument
+ * if none is registered.
+ */
+ arg = isrc->isrc_arg != NULL ? isrc->isrc_arg : tf;
+ isrc->isrc_ipifilter(arg);
+}
+
+/*
+ * Map IPI into interrupt controller.
+ *
+ * Not SMP coherent.
+ */
+static int
+ipi_map(struct intr_irqsrc *isrc, u_int ipi)
+{
+ boolean_t is_percpu;
+ int error;
+
+ if (ipi >= INTR_IPI_COUNT)
+ panic("%s: no such IPI %u", __func__, ipi);
+
+ KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
+
+ isrc->isrc_type = INTR_ISRCT_NAMESPACE;
+ isrc->isrc_nspc_type = INTR_IRQ_NSPC_IPI;
+ isrc->isrc_nspc_num = ipi_next_num;
+
+ error = PIC_REGISTER(intr_irq_root_dev, isrc, &is_percpu);
+ if (error == 0) {
+ isrc->isrc_dev = intr_irq_root_dev;
+ ipi_next_num++;
+ }
+ return (error);
+}
+
+/*
+ * Setup IPI handler to interrupt source.
+ *
+ * Note that there could be more ways how to send and receive IPIs
+ * on a platform like fast interrupts for example. In that case,
+ * one can call this function with ASIF_NOALLOC flag set and then
+ * call intr_ipi_dispatch() when appropriate.
+ *
+ * Not SMP coherent.
+ */
+int
+intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter,
+ void *arg, u_int flags)
+{
+ struct intr_irqsrc *isrc;
+ int error;
+
+ if (filter == NULL)
+ return(EINVAL);
+
+ isrc = intr_ipi_lookup(ipi);
+ if (isrc->isrc_ipifilter != NULL)
+ return (EEXIST);
+
+ if ((flags & AISHF_NOALLOC) == 0) {
+ error = ipi_map(isrc, ipi);
+ if (error != 0)
+ return (error);
+ }
+
+ isrc->isrc_ipifilter = filter;
+ isrc->isrc_arg = arg;
+ isrc->isrc_handlers = 1;
+ isrc->isrc_count = intr_ipi_setup_counters(name);
+ isrc->isrc_index = 0; /* it should not be used in IPI case */
+
+ if (isrc->isrc_dev != NULL) {
+ PIC_ENABLE_INTR(isrc->isrc_dev, isrc);
+ PIC_ENABLE_SOURCE(isrc->isrc_dev, isrc);
+ }
+ return (0);
+}
+
+/*
+ * Send IPI thru interrupt controller.
+ */
+void
+pic_ipi_send(cpuset_t cpus, u_int ipi)
+{
+ struct intr_irqsrc *isrc;
+
+ isrc = intr_ipi_lookup(ipi);
+
+ KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
+ PIC_IPI_SEND(intr_irq_root_dev, isrc, cpus);
+}
+#endif
+#endif
Index: head/sys/arm/include/intr.h
===================================================================
--- head/sys/arm/include/intr.h
+++ head/sys/arm/include/intr.h
@@ -51,6 +51,15 @@
#include <sys/intr.h>
+#ifdef SMP
+void intr_ipi_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf);
+
+#define AISHF_NOALLOC 0x0001
+
+int intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter,
+ void *arg, u_int flags);
+#endif
+
#else /* ARM_INTRNG */
/* XXX move to std.* files? */
Index: head/sys/kern/subr_intr.c
===================================================================
--- head/sys/kern/subr_intr.c
+++ head/sys/kern/subr_intr.c
@@ -89,7 +89,7 @@
/* Root interrupt controller stuff. */
static struct intr_irqsrc *irq_root_isrc;
-static device_t irq_root_dev;
+device_t intr_irq_root_dev;
static intr_irq_filter_t *irq_root_filter;
static void *irq_root_arg;
static u_int irq_root_ipicount;
@@ -115,9 +115,6 @@
#ifdef SMP
static boolean_t irq_assign_cpu = FALSE;
-
-static struct intr_irqsrc ipi_sources[INTR_IPI_COUNT];
-static u_int ipi_next_num;
#endif
/*
@@ -239,36 +236,20 @@
#ifdef SMP
/*
- * Virtualization for interrupt source IPI counter increment.
- */
-static inline void
-isrc_increment_ipi_count(struct intr_irqsrc *isrc, u_int cpu)
-{
-
- isrc->isrc_count[cpu]++;
-}
-
-/*
* Virtualization for interrupt source IPI counters setup.
*/
-static void
-isrc_setup_ipi_counters(struct intr_irqsrc *isrc, const char *name)
+u_long *
+intr_ipi_setup_counters(const char *name)
{
u_int index, i;
char str[INTRNAME_LEN];
index = atomic_fetchadd_int(&intrcnt_index, MAXCPU);
- isrc->isrc_index = index;
- isrc->isrc_count = &intrcnt[index];
-
for (i = 0; i < MAXCPU; i++) {
- /*
- * We do not expect any race in IPI case here,
- * so locking is not needed.
- */
snprintf(str, INTRNAME_LEN, "cpu%d:%s", i, name);
intrcnt_setname(str, index + i);
}
+ return (&intrcnt[index]);
}
#endif
@@ -679,7 +660,7 @@
struct intr_irqsrc *isrc = arg;
int error;
- if (isrc->isrc_dev != irq_root_dev)
+ if (isrc->isrc_dev != intr_irq_root_dev)
return (EINVAL);
mtx_lock(&isrc_table_lock);
@@ -926,7 +907,7 @@
* Note that we further suppose that there is not threaded interrupt
* routine (handler) on the root. See intr_irq_handler().
*/
- if (irq_root_dev != NULL) {
+ if (intr_irq_root_dev != NULL) {
device_printf(dev, "another root already set\n");
return (EBUSY);
}
@@ -949,7 +930,7 @@
device_printf(dev, "failed to install root pic handler\n");
return (error);
}
- irq_root_dev = dev;
+ intr_irq_root_dev = dev;
irq_root_filter = filter;
irq_root_arg = arg;
irq_root_ipicount = ipicount;
@@ -1211,132 +1192,6 @@
#ifdef SMP
/*
- * Lookup IPI source.
- */
-static struct intr_irqsrc *
-intr_ipi_lookup(u_int ipi)
-{
-
- if (ipi >= INTR_IPI_COUNT)
- panic("%s: no such IPI %u", __func__, ipi);
-
- return (&ipi_sources[ipi]);
-}
-
-/*
- * interrupt controller dispatch function for IPIs. It should
- * be called straight from the interrupt controller, when associated
- * interrupt source is learned. Or from anybody who has an interrupt
- * source mapped.
- */
-void
-intr_ipi_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf)
-{
- void *arg;
-
- KASSERT(isrc != NULL, ("%s: no source", __func__));
-
- isrc_increment_ipi_count(isrc, PCPU_GET(cpuid));
-
- /*
- * Supply ipi filter with trapframe argument
- * if none is registered.
- */
- arg = isrc->isrc_arg != NULL ? isrc->isrc_arg : tf;
- isrc->isrc_ipifilter(arg);
-}
-
-/*
- * Map IPI into interrupt controller.
- *
- * Not SMP coherent.
- */
-static int
-ipi_map(struct intr_irqsrc *isrc, u_int ipi)
-{
- boolean_t is_percpu;
- int error;
-
- if (ipi >= INTR_IPI_COUNT)
- panic("%s: no such IPI %u", __func__, ipi);
-
- KASSERT(irq_root_dev != NULL, ("%s: no root attached", __func__));
-
- isrc->isrc_type = INTR_ISRCT_NAMESPACE;
- isrc->isrc_nspc_type = INTR_IRQ_NSPC_IPI;
- isrc->isrc_nspc_num = ipi_next_num;
-
- error = PIC_REGISTER(irq_root_dev, isrc, &is_percpu);
-
- debugf("ipi %u mapped to %u on %s - error %d\n", ipi, ipi_next_num,
- device_get_nameunit(irq_root_dev), error);
-
- if (error == 0) {
- isrc->isrc_dev = irq_root_dev;
- ipi_next_num++;
- }
- return (error);
-}
-
-/*
- * Setup IPI handler to interrupt source.
- *
- * Note that there could be more ways how to send and receive IPIs
- * on a platform like fast interrupts for example. In that case,
- * one can call this function with ASIF_NOALLOC flag set and then
- * call intr_ipi_dispatch() when appropriate.
- *
- * Not SMP coherent.
- */
-int
-intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter,
- void *arg, u_int flags)
-{
- struct intr_irqsrc *isrc;
- int error;
-
- if (filter == NULL)
- return(EINVAL);
-
- isrc = intr_ipi_lookup(ipi);
- if (isrc->isrc_ipifilter != NULL)
- return (EEXIST);
-
- if ((flags & AISHF_NOALLOC) == 0) {
- error = ipi_map(isrc, ipi);
- if (error != 0)
- return (error);
- }
-
- isrc->isrc_ipifilter = filter;
- isrc->isrc_arg = arg;
- isrc->isrc_handlers = 1;
- isrc_setup_ipi_counters(isrc, name);
-
- if (isrc->isrc_dev != NULL) {
- mtx_lock(&isrc_table_lock);
- PIC_ENABLE_INTR(isrc->isrc_dev, isrc);
- PIC_ENABLE_SOURCE(isrc->isrc_dev, isrc);
- mtx_unlock(&isrc_table_lock);
- }
- return (0);
-}
-
-/*
- * Send IPI thru interrupt controller.
- */
-void
-pic_ipi_send(cpuset_t cpus, u_int ipi)
-{
- struct intr_irqsrc *isrc;
-
- isrc = intr_ipi_lookup(ipi);
-
- KASSERT(irq_root_dev != NULL, ("%s: no root attached", __func__));
- PIC_IPI_SEND(irq_root_dev, isrc, cpus);
-}
-
-/*
* Init interrupt controller on another CPU.
*/
void
@@ -1346,10 +1201,10 @@
/*
* QQQ: Only root PIC is aware of other CPUs ???
*/
- KASSERT(irq_root_dev != NULL, ("%s: no root attached", __func__));
+ KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
//mtx_lock(&isrc_table_lock);
- PIC_INIT_SECONDARY(irq_root_dev);
+ PIC_INIT_SECONDARY(intr_irq_root_dev);
//mtx_unlock(&isrc_table_lock);
}
#endif
@@ -1360,25 +1215,6 @@
u_int i, irqsum;
struct intr_irqsrc *isrc;
-#ifdef SMP
- for (i = 0; i <= mp_maxid; i++) {
- struct pcpu *pc;
- u_int ipi, ipisum;
-
- pc = pcpu_find(i);
- if (pc != NULL) {
- for (ipisum = 0, ipi = 0; ipi < INTR_IPI_COUNT; ipi++) {
- isrc = intr_ipi_lookup(ipi);
- if (isrc->isrc_count != NULL)
- ipisum += isrc->isrc_count[i];
- }
- printf ("cpu%u: total %u ipis %u\n", i,
- pc->pc_cnt.v_intr, ipisum);
- }
- }
- db_printf("\n");
-#endif
-
for (irqsum = 0, i = 0; i < NIRQ; i++) {
isrc = irq_sources[i];
if (isrc == NULL)
Index: head/sys/sys/intr.h
===================================================================
--- head/sys/sys/intr.h
+++ head/sys/sys/intr.h
@@ -39,6 +39,8 @@
#ifndef _SYS_INTR_H_
#define _SYS_INTR_H_
+#include <sys/systm.h>
+
#ifdef notyet
#define INTR_SOLO INTR_MD1
typedef int intr_irq_filter_t(void *arg, struct trapframe *tf);
@@ -101,6 +103,8 @@
u_int intr_fdt_map_irq(phandle_t, pcell_t *, u_int);
#endif
+extern device_t intr_irq_root_dev;
+
int intr_pic_register(device_t dev, intptr_t xref);
int intr_pic_unregister(device_t dev, intptr_t xref);
int intr_pic_claim_root(device_t dev, intptr_t xref, intr_irq_filter_t *filter,
@@ -117,14 +121,19 @@
#ifdef SMP
int intr_irq_bind(u_int, int);
-void intr_ipi_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf);
-
-#define AISHF_NOALLOC 0x0001
+void intr_pic_init_secondary(void);
-int intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter,
- void *arg, u_int flags);
+/* Virtualization for interrupt source IPI counter increment. */
+static inline void
+intr_ipi_increment_count(u_long *counter, u_int cpu)
+{
+
+ KASSERT(cpu < MAXCPU, ("%s: too big cpu %u", __func__, cpu));
+ counter[cpu]++;
+}
-void intr_pic_init_secondary(void);
+/* Virtualization for interrupt source IPI counters setup. */
+u_long * intr_ipi_setup_counters(const char *name);
#endif
#endif /* _SYS_INTR_H */

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 12, 2:59 AM (18 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31325023
Default Alt Text
D5459.diff (11 KB)

Event Timeline