Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150463382
D5700.id14569.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D5700.id14569.diff
View Options
Index: head/sys/arm/arm/gic.c
===================================================================
--- head/sys/arm/arm/gic.c
+++ head/sys/arm/arm/gic.c
@@ -121,6 +121,11 @@
static u_int gic_irq_cpu;
static int arm_gic_intr(void *);
static int arm_gic_bind(device_t dev, struct intr_irqsrc *isrc);
+
+#ifdef SMP
+u_int sgi_to_ipi[GIC_LAST_SGI - GIC_FIRST_SGI + 1];
+#define ISRC_IPI(isrc) sgi_to_ipi[isrc->isrc_data - GIC_FIRST_SGI]
+#endif
#endif
struct arm_gic_softc {
@@ -562,7 +567,7 @@
#ifdef SMP
/* Call EOI for all IPI before dispatch. */
gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
- intr_ipi_dispatch(isrc, tf);
+ intr_ipi_dispatch(ISRC_IPI(isrc), tf);
goto next_irq;
#else
device_printf(sc->gic_dev, "SGI %u on UP system detected\n",
@@ -918,6 +923,20 @@
gic_d_write_4(sc, GICD_SGIR(0), val | irq);
}
+
+static int
+arm_gic_ipi_setup(device_t dev, u_int ipi, struct intr_irqsrc *isrc)
+{
+ struct arm_gic_softc *sc = device_get_softc(dev);
+ u_int irq;
+ int error;
+
+ error = gic_map_nspc(sc, isrc, &irq);
+ if (error != 0)
+ return (error);
+ sgi_to_ipi[irq - GIC_FIRST_SGI] = ipi;
+ return (0);
+}
#endif
#else
static int
@@ -1146,6 +1165,7 @@
DEVMETHOD(pic_bind, arm_gic_bind),
DEVMETHOD(pic_init_secondary, arm_gic_init_secondary),
DEVMETHOD(pic_ipi_send, arm_gic_ipi_send),
+ DEVMETHOD(pic_ipi_setup, arm_gic_ipi_setup),
#endif
#endif
{ 0, 0 }
Index: head/sys/arm/arm/machdep_intr.c
===================================================================
--- head/sys/arm/arm/machdep_intr.c
+++ head/sys/arm/arm/machdep_intr.c
@@ -64,8 +64,19 @@
#include "pic_if.h"
#ifdef SMP
-static struct intr_irqsrc ipi_sources[INTR_IPI_COUNT];
-static u_int ipi_next_num;
+#define INTR_IPI_NAMELEN (MAXCOMLEN + 1)
+
+struct intr_ipi {
+ intr_ipi_handler_t * ii_handler;
+ void * ii_handler_arg;
+ intr_ipi_send_t * ii_send;
+ void * ii_send_arg;
+ char ii_name[INTR_IPI_NAMELEN];
+ u_long * ii_count;
+};
+
+static struct intr_ipi ipi_sources[INTR_IPI_COUNT];
+u_int ipi_next_num;
#endif
#endif
@@ -134,10 +145,7 @@
#ifdef ARM_INTRNG
#ifdef SMP
-/*
- * Lookup IPI source.
- */
-static struct intr_irqsrc *
+static inline struct intr_ipi *
intr_ipi_lookup(u_int ipi)
{
@@ -147,112 +155,97 @@
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)
+intr_ipi_dispatch(u_int ipi, struct trapframe *tf)
{
void *arg;
+ struct intr_ipi *ii;
- KASSERT(isrc != NULL, ("%s: no source", __func__));
+ ii = intr_ipi_lookup(ipi);
+ if (ii->ii_count == NULL)
+ panic("%s: not setup IPI %u", __func__, ipi);
- intr_ipi_increment_count(isrc->isrc_count, PCPU_GET(cpuid));
+ intr_ipi_increment_count(ii->ii_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);
+ arg = ii->ii_handler_arg != NULL ? ii->ii_handler_arg : tf;
+ ii->ii_handler(arg);
}
-/*
- * Map IPI into interrupt controller.
- *
- * Not SMP coherent.
- */
-static int
-ipi_map(struct intr_irqsrc *isrc, u_int ipi)
+void
+intr_ipi_send(cpuset_t cpus, u_int ipi)
{
- boolean_t is_percpu;
- int error;
+ struct intr_ipi *ii;
- if (ipi >= INTR_IPI_COUNT)
- panic("%s: no such IPI %u", __func__, ipi);
+ ii = intr_ipi_lookup(ipi);
+ if (ii->ii_count == NULL)
+ panic("%s: not setup IPI %u", __func__, ipi);
- KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
+ ii->ii_send(ii->ii_send_arg, cpus);
+}
- isrc->isrc_type = INTR_ISRCT_NAMESPACE;
- isrc->isrc_nspc_type = INTR_IRQ_NSPC_IPI;
- isrc->isrc_nspc_num = ipi_next_num;
+void
+intr_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand,
+ void *h_arg, intr_ipi_send_t *send, void *s_arg)
+{
+ struct intr_ipi *ii;
+
+ ii = intr_ipi_lookup(ipi);
- 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);
+ KASSERT(hand != NULL, ("%s: ipi %u no handler", __func__, ipi));
+ KASSERT(send != NULL, ("%s: ipi %u no sender", __func__, ipi));
+ KASSERT(ii->ii_count == NULL, ("%s: ipi %u reused", __func__, ipi));
+
+ ii->ii_handler = hand;
+ ii->ii_handler_arg = h_arg;
+ ii->ii_send = send;
+ ii->ii_send_arg = s_arg;
+ strlcpy(ii->ii_name, name, INTR_IPI_NAMELEN);
+ ii->ii_count = intr_ipi_setup_counters(name);
}
/*
- * 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.
+ * Send IPI thru interrupt controller.
*/
-int
-intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter,
- void *arg, u_int flags)
+static void
+pic_ipi_send(void *arg, cpuset_t cpus)
{
- 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);
+ KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
+ PIC_IPI_SEND(intr_irq_root_dev, arg, cpus);
}
/*
- * Send IPI thru interrupt controller.
+ * Setup IPI handler on interrupt controller.
+ *
+ * Not SMP coherent.
*/
-void
-pic_ipi_send(cpuset_t cpus, u_int ipi)
+int
+intr_pic_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand,
+ void *arg)
{
+ int error;
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);
+
+ isrc = intr_isrc_alloc(INTR_ISRCT_NAMESPACE, 0);
+ isrc->isrc_nspc_type = INTR_IRQ_NSPC_IPI;
+ isrc->isrc_nspc_num = ipi_next_num;
+
+ error = PIC_IPI_SETUP(intr_irq_root_dev, ipi, isrc);
+ if (error != 0)
+ return (error);
+
+ ipi_next_num++;
+
+ isrc->isrc_dev = intr_irq_root_dev;
+ isrc->isrc_handlers = 1;
+ intr_ipi_setup(ipi, name, hand, arg, pic_ipi_send, isrc);
+ return (0);
}
#endif
#endif
Index: head/sys/arm/arm/mp_machdep.c
===================================================================
--- head/sys/arm/arm/mp_machdep.c
+++ head/sys/arm/arm/mp_machdep.c
@@ -429,12 +429,11 @@
return;
#ifdef ARM_INTRNG
- intr_ipi_set_handler(IPI_RENDEZVOUS, "rendezvous", ipi_rendezvous, NULL, 0);
- intr_ipi_set_handler(IPI_AST, "ast", ipi_ast, NULL, 0);
- intr_ipi_set_handler(IPI_STOP, "stop", ipi_stop, NULL, 0);
- intr_ipi_set_handler(IPI_PREEMPT, "preempt", ipi_preempt, NULL, 0);
- intr_ipi_set_handler(IPI_HARDCLOCK, "hardclock", ipi_hardclock, NULL, 0);
-
+ intr_pic_ipi_setup(IPI_RENDEZVOUS, "rendezvous", ipi_rendezvous, NULL);
+ intr_pic_ipi_setup(IPI_AST, "ast", ipi_ast, NULL);
+ intr_pic_ipi_setup(IPI_STOP, "stop", ipi_stop, NULL);
+ intr_pic_ipi_setup(IPI_PREEMPT, "preempt", ipi_preempt, NULL);
+ intr_pic_ipi_setup(IPI_HARDCLOCK, "hardclock", ipi_hardclock, NULL);
#else
#ifdef IPI_IRQ_START
start = IPI_IRQ_START;
@@ -502,7 +501,11 @@
other_cpus = all_cpus;
CPU_CLR(PCPU_GET(cpuid), &other_cpus);
CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
+#ifdef ARM_INTRNG
+ intr_ipi_send(other_cpus, ipi);
+#else
pic_ipi_send(other_cpus, ipi);
+#endif
}
void
@@ -514,7 +517,11 @@
CPU_SET(cpu, &cpus);
CTR3(KTR_SMP, "%s: cpu: %d, ipi: %x", __func__, cpu, ipi);
+#ifdef ARM_INTRNG
+ intr_ipi_send(cpus, ipi);
+#else
pic_ipi_send(cpus, ipi);
+#endif
}
void
@@ -522,6 +529,9 @@
{
CTR2(KTR_SMP, "%s: ipi: %x", __func__, ipi);
+#ifdef ARM_INTRNG
+ intr_ipi_send(cpus, ipi);
+#else
pic_ipi_send(cpus, ipi);
+#endif
}
-
Index: head/sys/arm/include/intr.h
===================================================================
--- head/sys/arm/include/intr.h
+++ head/sys/arm/include/intr.h
@@ -52,14 +52,17 @@
#include <sys/intr.h>
#ifdef SMP
-void intr_ipi_dispatch(struct intr_irqsrc *isrc, struct trapframe *tf);
+typedef void intr_ipi_send_t(void *, cpuset_t);
+typedef void intr_ipi_handler_t(void *);
-#define AISHF_NOALLOC 0x0001
+void intr_ipi_dispatch(u_int, struct trapframe *);
+void intr_ipi_send(cpuset_t, u_int);
-int intr_ipi_set_handler(u_int ipi, const char *name, intr_ipi_filter_t *filter,
- void *arg, u_int flags);
-#endif
+void intr_ipi_setup(u_int, const char *, intr_ipi_handler_t *, void *,
+ intr_ipi_send_t *, void *);
+int intr_pic_ipi_setup(u_int, const char *, intr_ipi_handler_t *, void *);
+#endif
#else /* ARM_INTRNG */
/* XXX move to std.* files? */
Index: head/sys/arm/include/smp.h
===================================================================
--- head/sys/arm/include/smp.h
+++ head/sys/arm/include/smp.h
@@ -37,8 +37,8 @@
void ipi_selected(cpuset_t cpus, u_int ipi);
/* PIC interface */
-void pic_ipi_send(cpuset_t cpus, u_int ipi);
#ifndef ARM_INTRNG
+void pic_ipi_send(cpuset_t cpus, u_int ipi);
void pic_ipi_clear(int ipi);
int pic_ipi_read(int arg);
#endif
Index: head/sys/kern/pic_if.m
===================================================================
--- head/sys/kern/pic_if.m
+++ head/sys/kern/pic_if.m
@@ -60,6 +60,13 @@
{
return;
}
+
+ static int
+ dflt_pic_ipi_setup(device_t dev, u_int ipi, struct intr_irqsrc *isrc)
+ {
+
+ return (EOPNOTSUPP);
+ }
};
METHOD int register {
@@ -122,3 +129,9 @@
struct intr_irqsrc *isrc;
cpuset_t cpus;
} DEFAULT null_pic_ipi_send;
+
+METHOD int ipi_setup {
+ device_t dev;
+ u_int ipi;
+ struct intr_irqsrc *isrc;
+} DEFAULT dflt_pic_ipi_setup;
Index: head/sys/kern/subr_intr.c
===================================================================
--- head/sys/kern/subr_intr.c
+++ head/sys/kern/subr_intr.c
@@ -311,8 +311,8 @@
/*
* Allocate interrupt source.
*/
-static struct intr_irqsrc *
-isrc_alloc(u_int type, u_int extsize)
+struct intr_irqsrc *
+intr_isrc_alloc(u_int type, u_int extsize)
{
struct intr_irqsrc *isrc;
@@ -329,8 +329,8 @@
/*
* Free interrupt source.
*/
-static void
-isrc_free(struct intr_irqsrc *isrc)
+void
+intr_isrc_free(struct intr_irqsrc *isrc)
{
free(isrc, M_INTRNG);
@@ -462,20 +462,20 @@
struct intr_irqsrc *isrc, *new_isrc;
int error;
- new_isrc = isrc_alloc(INTR_ISRCT_NAMESPACE, 0);
+ new_isrc = intr_isrc_alloc(INTR_ISRCT_NAMESPACE, 0);
mtx_lock(&isrc_table_lock);
isrc = isrc_namespace_lookup(dev, type, num);
if (isrc != NULL) {
mtx_unlock(&isrc_table_lock);
- isrc_free(new_isrc);
+ intr_isrc_free(new_isrc);
return (isrc->isrc_irq); /* already mapped */
}
error = isrc_alloc_irq_locked(new_isrc);
if (error != 0) {
mtx_unlock(&isrc_table_lock);
- isrc_free(new_isrc);
+ intr_isrc_free(new_isrc);
return (IRQ_INVALID); /* no space left */
}
@@ -526,20 +526,20 @@
xref = (intptr_t)node; /* It's so simple for now. */
cellsize = ncells * sizeof(*cells);
- new_isrc = isrc_alloc(INTR_ISRCT_FDT, cellsize);
+ new_isrc = intr_isrc_alloc(INTR_ISRCT_FDT, cellsize);
mtx_lock(&isrc_table_lock);
isrc = isrc_fdt_lookup(xref, cells, ncells);
if (isrc != NULL) {
mtx_unlock(&isrc_table_lock);
- isrc_free(new_isrc);
+ intr_isrc_free(new_isrc);
return (isrc->isrc_irq); /* already mapped */
}
error = isrc_alloc_irq_locked(new_isrc);
if (error != 0) {
mtx_unlock(&isrc_table_lock);
- isrc_free(new_isrc);
+ intr_isrc_free(new_isrc);
return (IRQ_INVALID); /* no space left */
}
Index: head/sys/sys/intr.h
===================================================================
--- head/sys/sys/intr.h
+++ head/sys/sys/intr.h
@@ -50,8 +50,6 @@
#define INTR_ISRC_NAMELEN (MAXCOMLEN + 1)
-typedef void intr_ipi_filter_t(void *arg);
-
enum intr_isrc_type {
INTR_ISRCT_NAMESPACE,
INTR_ISRCT_FDT
@@ -81,15 +79,17 @@
struct intr_event * isrc_event;
#ifdef INTR_SOLO
intr_irq_filter_t * isrc_filter;
-#endif
- intr_ipi_filter_t * isrc_ipifilter;
void * isrc_arg;
+#endif
#ifdef FDT
u_int isrc_ncells;
pcell_t isrc_cells[]; /* leave it last */
#endif
};
+struct intr_irqsrc *intr_isrc_alloc(u_int type, u_int extsize);
+void intr_isrc_free(struct intr_irqsrc *isrc);
+
void intr_irq_set_name(struct intr_irqsrc *isrc, const char *fmt, ...)
__printflike(2, 3);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 2, 10:40 AM (22 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30719101
Default Alt Text
D5700.id14569.diff (12 KB)
Attached To
Mode
D5700: ARM intrng - generalization of IPI support
Attached
Detach File
Event Timeline
Log In to Comment