diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2010-05-21 15:24:30 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2010-05-21 15:24:30 +0000 |
commit | 3f2a999731840f759db74c30afbc7991920e94cd (patch) | |
tree | 4de5237e6f74e62cdfe5fbd142633c72bb0a716f /sys/arch | |
parent | bfd547210325a1e414767cc9ef7a9b15d51b8878 (diff) |
Add support for IPIs on hppa.
ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hppa/conf/files.hppa | 3 | ||||
-rw-r--r-- | sys/arch/hppa/dev/cpu.c | 13 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/intr.c | 18 | ||||
-rw-r--r-- | sys/arch/hppa/hppa/ipi.c | 90 | ||||
-rw-r--r-- | sys/arch/hppa/include/cpu.h | 7 | ||||
-rw-r--r-- | sys/arch/hppa/include/intr.h | 19 |
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_ */ |