summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2015-12-25 09:22:01 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2015-12-25 09:22:01 +0000
commit6929ccd0b8fb97c64b0b58c8c9d3a339ac958979 (patch)
tree74b79ef53065e5292e6e67dde6bbced9056e44c5 /sys
parent5430870495c1eaf9405739d118a4cd5945e74b1f (diff)
Add IPI logic. Assign two additional interrupts for inter-processor
signalling as a workaround to a limitation in the hub interrupt code, to allow four CPUs per node. At the moment, multi-node setups are not supported.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sgi/include/intr.h4
-rw-r--r--sys/arch/sgi/sgi/intr_template.c8
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c52
-rw-r--r--sys/arch/sgi/xbow/hub.h8
4 files changed, 66 insertions, 6 deletions
diff --git a/sys/arch/sgi/include/intr.h b/sys/arch/sgi/include/intr.h
index 8b1a5e14fa7..8f88c358f6c 100644
--- a/sys/arch/sgi/include/intr.h
+++ b/sys/arch/sgi/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.45 2015/09/13 20:38:45 kettenis Exp $ */
+/* $OpenBSD: intr.h,v 1.46 2015/12/25 09:22:00 visa Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -192,6 +192,8 @@ void dosoftint(void);
#ifdef MULTIPROCESSOR
#if defined (TGT_OCTANE)
#define ENABLEIPI() updateimask(~CR_INT_2) /* enable IPI interrupt level */
+#elif defined (TGT_ORIGIN)
+#define ENABLEIPI() updateimask(~CR_INT_0) /* enable IPI interrupt level */
#else
#error MULTIPROCESSOR kernel not supported on this configuration
#endif
diff --git a/sys/arch/sgi/sgi/intr_template.c b/sys/arch/sgi/sgi/intr_template.c
index 8fea687f635..3091fdab2b0 100644
--- a/sys/arch/sgi/sgi/intr_template.c
+++ b/sys/arch/sgi/sgi/intr_template.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr_template.c,v 1.15 2015/05/01 11:17:22 miod Exp $ */
+/* $OpenBSD: intr_template.c,v 1.16 2015/12/25 09:22:00 visa Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -36,6 +36,7 @@
*
* The following macros are optional:
* INTR_HANDLER_SKIP(ih) nonzero to skip intrhand invocation
+ * INTR_IPI_HOOK(ipl) special case logic for IPIs
*/
/*
@@ -112,6 +113,10 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame)
if (isr == 0)
return 0; /* not for us */
+#ifdef INTR_IPI_HOOK
+ INTR_IPI_HOOK(frame->ipl);
+#endif
+
/*
* Mask all pending interrupts.
*/
@@ -216,3 +221,4 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame)
#undef INTR_MASKPENDING
#undef INTR_MASKRESTORE
#undef INTR_SPURIOUS
+#undef INTR_IPI_HOOK
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index 7ee64dbc594..73a87e52a1e 100644
--- a/sys/arch/sgi/sgi/ip27_machdep.c
+++ b/sys/arch/sgi/sgi/ip27_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip27_machdep.c,v 1.69 2015/12/25 09:02:57 visa Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.70 2015/12/25 09:22:00 visa Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -94,6 +94,8 @@ void ip27_nmi(void *);
#ifdef MULTIPROCESSOR
+#define IP27_SLICE_IPI(slice) ((slice) + HUBPI_ISR0_IPI_A)
+
unsigned int ip27_ncpus;
int ip27_kl_launch_cpu(klinfo_t *, void *);
@@ -914,6 +916,19 @@ do { \
(void)IP27_LHUB_L(HUBPI_IR0); \
} while (0)
#define INTR_IMASK(ipl) hubpi_imask[ci->ci_cpuid][ipl].hw[0]
+#ifdef MULTIPROCESSOR
+#define INTR_IPI_HOOK(ipl) \
+do { \
+ unsigned long ipibit = IP27_SLICE_IPI(ci->ci_slice); \
+ unsigned long ipimask = 1 << ipibit; \
+ if ((isr & ipimask) && \
+ !(hubpi_imask[ci->ci_cpuid][ipl].hw[0] & ipimask)) { \
+ struct intrhand *ih = hubpi_intrhand0[ipibit]; \
+ ih->ih_fun(ih->ih_arg); \
+ isr &= ~ipimask; \
+ } \
+} while (0)
+#endif /* MULTIPROCESSOR */
#define INTR_HANDLER(bit) hubpi_intrhand0[bit]
#define INTR_SPURIOUS(bit) \
do { \
@@ -1115,6 +1130,41 @@ ip27_hub_get_timecount(struct timecounter *tc)
}
void
+hw_ipi_intr_set(u_long cpuid)
+{
+ struct cpu_info *ci = get_cpu_info(cpuid);
+ int intr;
+
+ intr = IP27_SLICE_IPI(ci->ci_slice);
+ IP27_RHUB_PI_S(ci->ci_nasid, IP27_SLICE_SUBNODE(ci->ci_slice),
+ HUBPI_IR_CHANGE, PI_IR_SET | intr);
+}
+
+void
+hw_ipi_intr_clear(u_long cpuid)
+{
+ struct cpu_info *ci = get_cpu_info(cpuid);
+ int intr;
+
+ intr = IP27_SLICE_IPI(ci->ci_slice);
+ IP27_RHUB_PI_S(ci->ci_nasid, IP27_SLICE_SUBNODE(ci->ci_slice),
+ HUBPI_IR_CHANGE, PI_IR_CLR | intr);
+ (void)IP27_RHUB_PI_L(ci->ci_nasid, IP27_SLICE_SUBNODE(ci->ci_slice),
+ HUBPI_IR0);
+}
+
+int
+hw_ipi_intr_establish(int (*func)(void *), u_long cpuid)
+{
+ struct cpu_info *ci = get_cpu_info(cpuid);
+ int intr;
+
+ intr = IP27_SLICE_IPI(ci->ci_slice);
+ return ip27_hub_intr_establish(func, (void *)cpuid, intr, IPL_IPI,
+ NULL, &ci->ci_ipiih);
+}
+
+void
hw_cpu_hatch(struct cpu_info *ci)
{
int s;
diff --git a/sys/arch/sgi/xbow/hub.h b/sys/arch/sgi/xbow/hub.h
index 2d26c7c6c95..8c36d562380 100644
--- a/sys/arch/sgi/xbow/hub.h
+++ b/sys/arch/sgi/xbow/hub.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hub.h,v 1.9 2015/12/25 06:18:50 visa Exp $ */
+/* $OpenBSD: hub.h,v 1.10 2015/12/25 09:22:00 visa Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -147,8 +147,10 @@
/* 35-0 available */
/** Level 0 interrupt */
-/* 63-9 available */
+/* 63-11 available */
/* IPI interrupts */
+#define HUBPI_ISR0_IPI_D 10
+#define HUBPI_ISR0_IPI_C 9
#define HUBPI_ISR0_IPI_B 8
#define HUBPI_ISR0_IPI_A 7
/* ? */
@@ -166,7 +168,7 @@
#define HUBPI_INTR1_WIDGET_MAX 35
#define HUBPI_INTR1_WIDGET_MIN 0
#define HUBPI_INTR0_WIDGET_MAX 63
-#define HUBPI_INTR0_WIDGET_MIN 9
+#define HUBPI_INTR0_WIDGET_MIN 11
#define HUBPI_NINTS 64 /* per register */