summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2010-05-21 15:24:30 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2010-05-21 15:24:30 +0000
commit3f2a999731840f759db74c30afbc7991920e94cd (patch)
tree4de5237e6f74e62cdfe5fbd142633c72bb0a716f /sys/arch
parentbfd547210325a1e414767cc9ef7a9b15d51b8878 (diff)
Add support for IPIs on hppa.
ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/hppa/conf/files.hppa3
-rw-r--r--sys/arch/hppa/dev/cpu.c13
-rw-r--r--sys/arch/hppa/hppa/intr.c18
-rw-r--r--sys/arch/hppa/hppa/ipi.c90
-rw-r--r--sys/arch/hppa/include/cpu.h7
-rw-r--r--sys/arch/hppa/include/intr.h19
6 files changed, 141 insertions, 9 deletions
diff --git a/sys/arch/hppa/conf/files.hppa b/sys/arch/hppa/conf/files.hppa
index dfbb5dc7609..e1e35c1d3d8 100644
--- a/sys/arch/hppa/conf/files.hppa
+++ b/sys/arch/hppa/conf/files.hppa
@@ -1,4 +1,4 @@
-# $OpenBSD: files.hppa,v 1.81 2010/03/25 14:26:21 jsing Exp $
+# $OpenBSD: files.hppa,v 1.82 2010/05/21 15:24:29 jsing Exp $
#
# hppa-specific configuration info
@@ -307,6 +307,7 @@ file arch/hppa/hppa/conf.c
file arch/hppa/hppa/db_interface.c ddb
file arch/hppa/hppa/db_disasm.c ddb
file arch/hppa/hppa/disksubr.c disk
+file arch/hppa/hppa/ipi.c multiprocessor
file arch/hppa/hppa/lock_machdep.c multiprocessor
file arch/hppa/hppa/machdep.c
file arch/hppa/hppa/mutex.c
diff --git a/sys/arch/hppa/dev/cpu.c b/sys/arch/hppa/dev/cpu.c
index 262b8a989b1..f1b787cfccf 100644
--- a/sys/arch/hppa/dev/cpu.c
+++ b/sys/arch/hppa/dev/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.34 2010/05/19 13:10:24 jsing Exp $ */
+/* $OpenBSD: cpu.c,v 1.35 2010/05/21 15:24:29 jsing Exp $ */
/*
* Copyright (c) 1998-2003 Michael Shalayeff
@@ -89,6 +89,8 @@ cpuattach(struct device *parent, struct device *self, void *aux)
extern u_int fpu_enable;
/* clock.c */
extern int cpu_hardclock(void *);
+ /* ipi.c */
+ extern int hppa_ipi_intr(void *);
struct confargs *ca = (struct confargs *)aux;
struct cpu_info *ci;
@@ -157,7 +159,10 @@ cpuattach(struct device *parent, struct device *self, void *aux)
pdc_btlb.finfo.num_i, pdc_btlb.finfo.num_d);
cpu_intr_establish(IPL_CLOCK, 31, cpu_hardclock, NULL, "clock");
-
+#ifdef MULTIPROCESSOR
+ cpu_intr_establish(IPL_IPI, 30, hppa_ipi_intr, NULL, "ipi");
+#endif
+
printf("\n");
}
@@ -174,6 +179,7 @@ cpu_boot_secondary_processors(void)
/* Initialise primary CPU. */
ci = curcpu();
ci->ci_flags |= CPUF_RUNNING;
+ hppa_ipi_init(ci);
for (i = 0; i < HPPA_MAXCPUS; i++) {
@@ -239,6 +245,9 @@ cpu_hatch(void)
extern u_long cpu_hzticks;
u_long itmr;
+ /* Initialise IPIs. */
+ hppa_ipi_init(ci);
+
/* Initialise clock. */
mtctl((1 << 31), CR_EIRR);
mfctl(CR_ITMR, itmr);
diff --git a/sys/arch/hppa/hppa/intr.c b/sys/arch/hppa/hppa/intr.c
index 6a18273a472..47df804c9ed 100644
--- a/sys/arch/hppa/hppa/intr.c
+++ b/sys/arch/hppa/hppa/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.31 2010/04/29 13:14:44 jsing Exp $ */
+/* $OpenBSD: intr.c,v 1.32 2010/05/21 15:24:29 jsing Exp $ */
/*
* Copyright (c) 2002-2004 Michael Shalayeff
@@ -292,6 +292,9 @@ cpu_intr(void *v)
struct cpu_info *ci = curcpu();
struct trapframe *frame = v;
u_long mask;
+#ifdef MULTIPROCESSOR
+ int pri;
+#endif
int s;
mtctl(0, CR_EIEM);
@@ -314,6 +317,13 @@ cpu_intr(void *v)
ci->ci_cpl = iv->pri;
mtctl(frame->tf_eiem, CR_EIEM);
+
+#ifdef MULTIPROCESSOR
+ pri = iv->pri;
+ if (pri < IPL_IPI && s < IPL_SCHED)
+ __mp_lock(&kernel_lock);
+#endif
+
for (r = iv->flags & HPPA_IV_SOFT;
iv && iv->handler; iv = iv->next)
/* no arg means pass the frame */
@@ -328,6 +338,11 @@ cpu_intr(void *v)
printf("stray interrupt %d\n", bit);
}
#endif
+
+#ifdef MULTIPROCESSOR
+ if (pri < IPL_IPI && s < IPL_SCHED)
+ __mp_unlock(&kernel_lock);
+#endif
mtctl(0, CR_EIEM);
}
ci->ci_in_intr--;
@@ -336,7 +351,6 @@ cpu_intr(void *v)
mtctl(frame->tf_eiem, CR_EIEM);
}
-
void *
softintr_establish(int pri, void (*handler)(void *), void *arg)
{
diff --git a/sys/arch/hppa/hppa/ipi.c b/sys/arch/hppa/hppa/ipi.c
new file mode 100644
index 00000000000..f3f0aec7500
--- /dev/null
+++ b/sys/arch/hppa/hppa/ipi.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 Joel Sing <jsing@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/mutex.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/iomod.h>
+#include <machine/intr.h>
+#include <machine/mutex.h>
+#include <machine/reg.h>
+
+void hppa_ipi_nop(void);
+
+void (*ipifunc[HPPA_NIPI])(void) =
+{
+ hppa_ipi_nop
+};
+
+void
+hppa_ipi_init(struct cpu_info *ci)
+{
+ /* Initialise IPIs for given CPU. */
+ mtx_init(&ci->ci_ipi_mtx, IPL_IPI);
+ ci->ci_mask |= (1 << 30);
+}
+
+int
+hppa_ipi_intr(void *arg)
+{
+ struct cpu_info *ci = curcpu();
+ u_long ipi_pending;
+ int bit = 0;
+
+ /* Handle an IPI. */
+ mtx_enter(&ci->ci_ipi_mtx);
+ ipi_pending = ci->ci_ipi;
+ ci->ci_ipi = 0;
+ mtx_leave(&ci->ci_ipi_mtx);
+
+ while (ipi_pending) {
+ if (ipi_pending & (1L << bit))
+ (*ipifunc[bit])();
+ ipi_pending &= ~(1L << bit);
+ bit++;
+ }
+
+ return 1;
+}
+
+int
+hppa_ipi_send(struct cpu_info *ci, u_long ipi)
+{
+ struct iomod *cpu;
+
+ if (!(ci->ci_flags & CPUF_RUNNING))
+ return -1;
+
+ mtx_enter(&ci->ci_ipi_mtx);
+ ci->ci_ipi |= (1L << ipi);
+ asm volatile ("sync" ::: "memory");
+ mtx_leave(&ci->ci_ipi_mtx);
+
+ /* Send an IPI to the specified CPU by triggering EIR{1} (irq 30). */
+ cpu = (struct iomod *)(ci->ci_hpa);
+ cpu->io_eir = 1;
+ asm volatile ("sync" ::: "memory");
+
+ return 0;
+}
+
+void
+hppa_ipi_nop(void)
+{
+}
diff --git a/sys/arch/hppa/include/cpu.h b/sys/arch/hppa/include/cpu.h
index c404b0bf859..315478cc5b2 100644
--- a/sys/arch/hppa/include/cpu.h
+++ b/sys/arch/hppa/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.71 2010/05/19 13:10:24 jsing Exp $ */
+/* $OpenBSD: cpu.h,v 1.72 2010/05/21 15:24:29 jsing Exp $ */
/*
* Copyright (c) 2000-2004 Michael Shalayeff
@@ -68,6 +68,8 @@
#include <sys/queue.h>
#include <sys/sched.h>
+#include <machine/mutex.h>
+
/*
* Note that the alignment of ci_trap_save is important since we want to keep
* it within a single cache line. As a result, it must be kept as the first
@@ -92,6 +94,9 @@ struct cpu_info {
int ci_want_resched;
u_long ci_itmr;
+ volatile u_long ci_ipi; /* IPIs pending. */
+ struct mutex ci_ipi_mtx;
+
struct schedstate_percpu ci_schedstate;
u_int32_t ci_randseed;
} __attribute__((__aligned__(64)));
diff --git a/sys/arch/hppa/include/intr.h b/sys/arch/hppa/include/intr.h
index 97efc5faecb..4459180bbaa 100644
--- a/sys/arch/hppa/include/intr.h
+++ b/sys/arch/hppa/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.30 2010/04/23 03:50:22 miod Exp $ */
+/* $OpenBSD: intr.h,v 1.31 2010/05/21 15:24:29 jsing Exp $ */
/*
* Copyright (c) 2002-2004 Michael Shalayeff
@@ -32,7 +32,7 @@
#include <machine/psl.h>
#define CPU_NINTS 32
-#define NIPL 16
+#define NIPL 17
#define IPL_NONE 0
#define IPL_SOFTCLOCK 1
@@ -47,13 +47,20 @@
#define IPL_STATCLOCK 10
#define IPL_SCHED 10
#define IPL_HIGH 10
-#define IPL_NESTED 11 /* pseudo-level for sub-tables */
+#define IPL_IPI 11
+#define IPL_NESTED 12 /* pseudo-level for sub-tables */
#define IST_NONE 0
#define IST_PULSE 1
#define IST_EDGE 2
#define IST_LEVEL 3
+#ifdef MULTIPROCESSOR
+#define HPPA_IPI_NOP 0
+
+#define HPPA_NIPI 1
+#endif
+
#if !defined(_LOCORE) && defined(_KERNEL)
#include <machine/atomic.h>
@@ -136,6 +143,7 @@ hppa_intr_enable(register_t eiem)
#define splsched() splraise(IPL_SCHED)
#define splstatclock() splraise(IPL_STATCLOCK)
#define splhigh() splraise(IPL_HIGH)
+#define splipi() splraise(IPL_IPI)
#define spl0() spllower(IPL_NONE)
#define softintr(mask) atomic_setbits_long(&curcpu()->ci_ipending, mask)
@@ -150,5 +158,10 @@ void *softintr_establish(int, void (*)(void *), void *);
void softintr_disestablish(void *);
void softintr_schedule(void *);
+#ifdef MULTIPROCESSOR
+void hppa_ipi_init(struct cpu_info *);
+int hppa_ipi_send(struct cpu_info *, u_long);
+#endif
+
#endif /* !_LOCORE && _KERNEL */
#endif /* _MACHINE_INTR_H_ */