summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2009-11-25 17:39:52 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2009-11-25 17:39:52 +0000
commit74b769daab68419f740f12dd4a4d345696354046 (patch)
tree82eec580c2361db182e94b79d90e1b65e889f722 /sys/arch
parenteddc7cb9c421d16e98e7d9f394f1eb663b8201a3 (diff)
IP30 IPI implementation.
Also few xheart modification for SMP. ok miod@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/mips64/conf/files.mips644
-rw-r--r--sys/arch/mips64/include/cpu.h11
-rw-r--r--sys/arch/mips64/mips64/cpu.c12
-rw-r--r--sys/arch/mips64/mips64/ipifuncs.c164
-rw-r--r--sys/arch/sgi/include/cpu.h9
-rw-r--r--sys/arch/sgi/include/intr.h7
-rw-r--r--sys/arch/sgi/localbus/macebus.c3
-rw-r--r--sys/arch/sgi/sgi/intr_template.c6
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c3
-rw-r--r--sys/arch/sgi/sgi/ip30_machdep.c35
-rw-r--r--sys/arch/sgi/xbow/xheart.c37
11 files changed, 265 insertions, 26 deletions
diff --git a/sys/arch/mips64/conf/files.mips64 b/sys/arch/mips64/conf/files.mips64
index 2c90943b4bb..a95e12538f3 100644
--- a/sys/arch/mips64/conf/files.mips64
+++ b/sys/arch/mips64/conf/files.mips64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.mips64,v 1.12 2009/08/06 21:11:37 miod Exp $
+# $OpenBSD: files.mips64,v 1.13 2009/11/25 17:39:51 syuu Exp $
file arch/mips64/mips64/arcbios.c arcbios
file arch/mips64/mips64/clock.c
@@ -28,5 +28,7 @@ file arch/mips64/mips64/db_disasm.c ddb
file arch/mips64/mips64/db_machdep.c ddb
file arch/mips64/mips64/lcore_ddb.S ddb|debug
+file arch/mips64/mips64/ipifuncs.c multiprocessor
+
file netinet/in_cksum.c inet
file netinet/in4_cksum.c inet
diff --git a/sys/arch/mips64/include/cpu.h b/sys/arch/mips64/include/cpu.h
index 1e63b266381..f17c7ffa028 100644
--- a/sys/arch/mips64/include/cpu.h
+++ b/sys/arch/mips64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.45 2009/11/24 22:46:59 syuu Exp $ */
+/* $OpenBSD: cpu.h,v 1.46 2009/11/25 17:39:51 syuu Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -384,6 +384,7 @@ struct cpu_info {
u_int32_t ci_pendingticks;
#ifdef MULTIPROCESSOR
u_long ci_flags; /* flags; see below */
+ struct intrhand *ci_ipiih;
#endif
};
@@ -414,6 +415,14 @@ void cpu_boot_secondary_processors(void);
vaddr_t smp_malloc(size_t);
+#define MIPS64_IPI_NOP 0x00000001
+#define MIPS64_NIPIS 1 /* must not exceed 32 */
+
+void mips64_ipi_init(void);
+void mips64_send_ipi(unsigned int, unsigned int);
+void mips64_broadcast_ipi(unsigned int);
+void mips64_multicast_ipi(unsigned int, unsigned int);
+
#include <sys/mplock.h>
#else
#define MAXCPUS 1
diff --git a/sys/arch/mips64/mips64/cpu.c b/sys/arch/mips64/mips64/cpu.c
index 8018883b62c..eb92cd951ba 100644
--- a/sys/arch/mips64/mips64/cpu.c
+++ b/sys/arch/mips64/mips64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.18 2009/11/24 22:46:59 syuu Exp $ */
+/* $OpenBSD: cpu.c,v 1.19 2009/11/25 17:39:51 syuu Exp $ */
/*
* Copyright (c) 1997-2004 Opsycon AB (www.opsycon.se)
@@ -105,6 +105,7 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
#ifdef MULTIPROCESSOR
ci->ci_flags |= CPUF_RUNNING | CPUF_PRESENT | CPUF_PRIMARY;
cpuset_add(&cpus_running, ci);
+ ci->ci_ipiih = NULL;
#endif
}
#ifdef MULTIPROCESSOR
@@ -112,6 +113,10 @@ cpuattach(struct device *parent, struct device *dev, void *aux)
ci = (struct cpu_info *)smp_malloc(sizeof(*ci));
if (ci == NULL)
panic("unable to allocate cpu_info\n");
+ ci->ci_ipiih =
+ (struct intrhand *)smp_malloc(sizeof(*ci->ci_ipiih));
+ if (ci->ci_ipiih == NULL)
+ panic("unable to allocate ipi intrhand\n");
ci->ci_next = cpu_info_list->ci_next;
cpu_info_list->ci_next = ci;
ci->ci_flags |= CPUF_PRESENT;
@@ -329,6 +334,11 @@ cpu_boot_secondary_processors(void)
continue;
cpu_boot_secondary(ci);
}
+
+ /* This must called after xheart0 has initialized, so here is
+ * the best place to do so.
+ */
+ mips64_ipi_init();
}
void
diff --git a/sys/arch/mips64/mips64/ipifuncs.c b/sys/arch/mips64/mips64/ipifuncs.c
new file mode 100644
index 00000000000..7a877545b0e
--- /dev/null
+++ b/sys/arch/mips64/mips64/ipifuncs.c
@@ -0,0 +1,164 @@
+/* $OpenBSD: ipifuncs.c,v 1.1 2009/11/25 17:39:51 syuu Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.40 2008/04/28 20:23:10 martin Exp $ */
+
+/*-
+ * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/cpu.h>
+#include <machine/intr.h>
+#include <machine/atomic.h>
+
+static int mips64_ipi_intr(void *);
+static void mips64_ipi_nop(void);
+
+static unsigned int ipi_mailbox[MAXCPUS];
+
+/*
+ * NOTE: This table must be kept in order with the bit definitions
+ * in <machine/intr.h>.
+ */
+typedef void (*ipifunc_t)(void);
+
+ipifunc_t ipifuncs[MIPS64_NIPIS] = {
+ mips64_ipi_nop,
+};
+
+/*
+ * Initialize IPI state for a CPU.
+ */
+void
+mips64_ipi_init(void)
+{
+ cpuid_t cpuid = cpu_number();
+ int error;
+
+ hw_ipi_intr_clear(cpuid);
+
+ error = hw_ipi_intr_establish(mips64_ipi_intr, cpuid);
+ if (error)
+ panic("hw_ipi_intr_establish failed:%d\n", error);
+}
+
+/*
+ * Process IPIs for a CPU.
+ */
+static int
+mips64_ipi_intr(void *arg)
+{
+ unsigned int pending_ipis, bit;
+ unsigned int cpuid = (unsigned int)(unsigned long)arg;
+ int sr;
+
+ KASSERT (cpuid == cpu_number());
+
+ sr = disableintr();
+
+ /* Load the mailbox register to figure out what we're supposed to do */
+ pending_ipis = ipi_mailbox[cpuid];
+ if (pending_ipis > 0) {
+ for (bit = 0; bit < MIPS64_NIPIS; bit++)
+ if (pending_ipis & (1UL << bit))
+ (*ipifuncs[bit])();
+
+ /* Clear the mailbox to clear the interrupt */
+ atomic_clearbits_int(&ipi_mailbox[cpuid], pending_ipis);
+ }
+ hw_ipi_intr_clear(cpuid);
+ setsr(sr);
+
+ return 1;
+}
+
+/*
+ * Send an interprocessor interrupt.
+ */
+void
+mips64_send_ipi(unsigned int cpuid, unsigned int ipimask)
+{
+#ifdef DIAGNOSTIC
+ if (cpuid >= CPU_MAXID || cpu_info[cpuid] == NULL)
+ panic("mips_send_ipi: bogus cpu_id");
+ if (!cpuset_isset(&cpus_running, cpu_info[cpuid]))
+ panic("mips_send_ipi: CPU %ld not running", cpuid);
+#endif
+
+ atomic_setbits_int(&ipi_mailbox[cpuid], ipimask);
+
+ hw_ipi_intr_set(cpuid);
+}
+
+/*
+ * Broadcast an IPI to all but ourselves.
+ */
+void
+mips64_broadcast_ipi(unsigned int ipimask)
+{
+ struct cpu_info *ci;
+ CPU_INFO_ITERATOR cii;
+
+ CPU_INFO_FOREACH(cii, ci) {
+ if (curcpu() == ci || !cpuset_isset(&cpus_running, ci))
+ continue;
+ mips64_send_ipi(ci->ci_cpuid, ipimask);
+ }
+}
+
+/*
+ * Send an IPI to all in the list but ourselves.
+ */
+void
+mips64_multicast_ipi(unsigned int cpumask, unsigned int ipimask)
+{
+ struct cpu_info *ci;
+ CPU_INFO_ITERATOR cii;
+
+ cpumask &= ~(1UL << cpu_number());
+
+ CPU_INFO_FOREACH(cii, ci) {
+ if (!(cpumask & (1UL << ci->ci_cpuid)) ||
+ !cpuset_isset(&cpus_running, ci))
+ continue;
+ mips64_send_ipi(ci->ci_cpuid, ipimask);
+ }
+}
+
+static void
+mips64_ipi_nop(void)
+{
+#ifdef DEBUG
+ printf("mips64_ipi_nop on cpu%d\n", cpu_number());
+#endif
+}
diff --git a/sys/arch/sgi/include/cpu.h b/sys/arch/sgi/include/cpu.h
index 42b85d8e549..da585d19f37 100644
--- a/sys/arch/sgi/include/cpu.h
+++ b/sys/arch/sgi/include/cpu.h
@@ -1,6 +1,7 @@
-/* $OpenBSD: cpu.h,v 1.4 2009/10/30 08:13:57 syuu Exp $ */
+/* $OpenBSD: cpu.h,v 1.5 2009/11/25 17:39:51 syuu Exp $ */
-/* Use Mips generic include file */
+#ifndef _SGI_CPU_H_
+#define _SGI_CPU_H_
#ifdef _KERNEL
#ifdef MULTIPROCESSOR
@@ -21,4 +22,8 @@
void hw_cpu_boot_secondary(struct cpu_info *);
void hw_cpu_hatch(struct cpu_info *);
void hw_cpu_spinup_trampoline(struct cpu_info *);
+int hw_ipi_intr_establish(int (*)(void *), u_long);
+void hw_ipi_intr_set(u_long);
+void hw_ipi_intr_clear(u_long);
#endif/* _KERNEL && MULTIPROCESSOR && !_LOCORE */
+#endif /* !_SGI_CPU_H_ */
diff --git a/sys/arch/sgi/include/intr.h b/sys/arch/sgi/include/intr.h
index 5532cb13d8f..62cc4e7b4d7 100644
--- a/sys/arch/sgi/include/intr.h
+++ b/sys/arch/sgi/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.36 2009/11/25 11:23:30 miod Exp $ */
+/* $OpenBSD: intr.h,v 1.37 2009/11/25 17:39:51 syuu Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -54,8 +54,9 @@
#define IPL_TTY 4 /* terminal */
#define IPL_VM 5 /* memory allocation */
#define IPL_CLOCK 6 /* clock */
-#define IPL_HIGH 7 /* everything */
-#define NIPLS 8 /* Number of levels */
+#define IPL_IPI 7 /* ipi */
+#define IPL_HIGH 8 /* everything */
+#define NIPLS 9 /* Number of levels */
/* Interrupt sharing types. */
#define IST_NONE 0 /* none */
diff --git a/sys/arch/sgi/localbus/macebus.c b/sys/arch/sgi/localbus/macebus.c
index 1bb88c4dbea..349dc3da8ee 100644
--- a/sys/arch/sgi/localbus/macebus.c
+++ b/sys/arch/sgi/localbus/macebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: macebus.c,v 1.55 2009/11/12 19:38:53 miod Exp $ */
+/* $OpenBSD: macebus.c,v 1.56 2009/11/25 17:39:51 syuu Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -559,6 +559,7 @@ macebus_splx(int newipl)
#define INTR_LOCAL_DECLS \
uint64_t mace_isr, mace_imr;
+#define MASK_LOCAL_DECLS
#define INTR_GETMASKS \
do { \
isr = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_STAT); \
diff --git a/sys/arch/sgi/sgi/intr_template.c b/sys/arch/sgi/sgi/intr_template.c
index 0be0bbc7052..9880ab66998 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.5 2009/11/12 17:13:33 miod Exp $ */
+/* $OpenBSD: intr_template.c,v 1.6 2009/11/25 17:39:51 syuu Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -28,6 +28,7 @@
* INTR_HANDLER(bit) logic to access intrhand array head for `bit'
* INTR_IMASK(ipl) logic to access imask array for `ipl'
* INTR_LOCAL_DECLS local declarations (may be empty)
+ * MASK_LOCAL_DECLS local declarations (may be empty)
* INTR_MASKPENDING logic to mask `isr'
* INTR_MASKRESTORE logic to reset `imr'
* INTR_MASKSIZE size of interrupt mask in bits
@@ -47,6 +48,8 @@ MASK_FUNCTIONNAME()
struct intrhand *q;
uint intrlevel[INTR_MASKSIZE];
+ MASK_LOCAL_DECLS
+
/* First, figure out which levels each IRQ uses. */
for (irq = 0; irq < INTR_MASKSIZE; irq++) {
uint levels = 0;
@@ -184,6 +187,7 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame)
#undef INTR_HANDLER_SKIP
#undef INTR_IMASK
#undef INTR_LOCAL_DECLS
+#undef MASK_LOCAL_DECLS
#undef INTR_MASKPENDING
#undef INTR_MASKRESTORE
#undef INTR_SPURIOUS
diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c
index 85bb7a77ce7..c5b334f4aaf 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.37 2009/11/25 11:23:30 miod Exp $ */
+/* $OpenBSD: ip27_machdep.c,v 1.38 2009/11/25 17:39:51 syuu Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -757,6 +757,7 @@ ip27_hub_splx(int newipl)
#define INTR_FUNCTIONNAME hubpi_intr0
#define MASK_FUNCTIONNAME ip27_hub_intr_makemasks0
#define INTR_LOCAL_DECLS
+#define MASK_LOCAL_DECLS
#define INTR_GETMASKS \
do { \
/* XXX this assumes we run on cpu0 */ \
diff --git a/sys/arch/sgi/sgi/ip30_machdep.c b/sys/arch/sgi/sgi/ip30_machdep.c
index e58de56008f..5f411d2ede6 100644
--- a/sys/arch/sgi/sgi/ip30_machdep.c
+++ b/sys/arch/sgi/sgi/ip30_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip30_machdep.c,v 1.23 2009/11/24 22:46:59 syuu Exp $ */
+/* $OpenBSD: ip30_machdep.c,v 1.24 2009/11/25 17:39:51 syuu Exp $ */
/*
* Copyright (c) 2008, 2009 Miodrag Vallat.
@@ -44,10 +44,22 @@
#include <dev/ic/comvar.h>
+#ifdef MULTIPROCESSOR
+#include <sgi/xbow/xheartreg.h>
+#endif
+
extern char *hw_prod;
extern int mbprint(void *, const char *);
+#ifdef MULTIPROCESSOR
+extern int xheart_intr_establish(int (*)(void *), void *, int, int,
+ const char *, struct intrhand *);
+extern void xheart_intr_set(int);
+extern void xheart_intr_clear(int);
+extern void xheart_setintrmask(int);
+#endif
+
uint32_t ip30_lights_frob(uint32_t, struct trap_frame *);
paddr_t ip30_widget_short(int16_t, u_int);
paddr_t ip30_widget_long(int16_t, u_int);
@@ -406,8 +418,12 @@ hw_cpu_hatch(struct cpu_info *ci)
cpu_startclock(ci);
+ mips64_ipi_init();
+ xheart_setintrmask(0);
+
spl0();
(void)updateimask(0);
+
#ifdef notyet
SCHED_LOCK(s);
cpu_switchto(NULL, sched_chooseproc());
@@ -416,4 +432,21 @@ hw_cpu_hatch(struct cpu_info *ci)
;
#endif
}
+
+int hw_ipi_intr_establish(int (*func)(void *), u_long cpuid)
+{
+ return xheart_intr_establish(func, (void *)cpuid, HEART_ISR_IPI(cpuid),
+ IPL_IPI, NULL, curcpu()->ci_ipiih);
+};
+
+void hw_ipi_intr_set(u_long cpuid)
+{
+ xheart_intr_set(HEART_ISR_IPI(cpuid));
+}
+
+void hw_ipi_intr_clear(u_long cpuid)
+{
+ xheart_intr_clear(HEART_ISR_IPI(cpuid));
+}
+
#endif
diff --git a/sys/arch/sgi/xbow/xheart.c b/sys/arch/sgi/xbow/xheart.c
index 547456d716b..eb2075d4866 100644
--- a/sys/arch/sgi/xbow/xheart.c
+++ b/sys/arch/sgi/xbow/xheart.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xheart.c,v 1.17 2009/11/25 11:23:30 miod Exp $ */
+/* $OpenBSD: xheart.c,v 1.18 2009/11/25 17:39:51 syuu Exp $ */
/*
* Copyright (c) 2008 Miodrag Vallat.
@@ -94,8 +94,8 @@ struct intrhand *xheart_intrhand[HEART_NINTS];
#endif
#define INTPRI_HEART_LEDS (INTPRI_HEART_0 + 1)
-uint64_t xheart_intem;
-uint64_t xheart_imask[NIPLS];
+uint64_t xheart_intem[MAXCPUS];
+uint64_t xheart_imask[MAXCPUS][NIPLS];
int
xheart_match(struct device *parent, void *match, void *aux)
@@ -145,7 +145,6 @@ xheart_attach(struct device *parent, struct device *self, void *aux)
xbow_intr_widget_intr_disestablish = xheart_intr_disestablish;
xbow_intr_widget_intr_clear = xheart_intr_clear;
xbow_intr_widget_intr_set = xheart_intr_set;
- xheart_intem = 0;
/*
* Acknowledge and disable all interrupts.
@@ -271,13 +270,14 @@ int
xheart_intr_register(int widget, int level, int *intrbit)
{
int bit;
+ u_long cpuid = cpu_number();
/*
* All interrupts will be serviced at hardware level 0,
* so the `level' argument can be ignored.
*/
for (bit = HEART_INTR_WIDGET_MAX; bit >= HEART_INTR_WIDGET_MIN; bit--)
- if ((xheart_intem & (1UL << bit)) == 0)
+ if ((xheart_intem[cpuid] & (1UL << bit)) == 0)
goto found;
return EINVAL;
@@ -296,6 +296,7 @@ xheart_intr_establish(int (*func)(void *), void *arg, int intrbit,
{
struct intrhand *ih;
int s;
+ u_long cpuid = cpu_number();
#ifdef DIAGNOSTIC
if (intrbit < 0 || intrbit >= HEART_NINTS)
@@ -332,7 +333,7 @@ xheart_intr_establish(int (*func)(void *), void *arg, int intrbit,
xheart_intrhand[intrbit] = ih;
- xheart_intem |= 1UL << intrbit;
+ xheart_intem[cpuid] |= 1UL << intrbit;
xheart_intr_makemasks();
splx(s); /* causes hw mask update */
@@ -345,6 +346,7 @@ xheart_intr_disestablish(int intrbit)
{
struct intrhand *ih;
int s;
+ u_long cpuid = cpu_number();
#ifdef DIAGNOSTIC
if (intrbit < 0 || intrbit >= HEART_NINTS)
@@ -360,7 +362,7 @@ xheart_intr_disestablish(int intrbit)
xheart_intrhand[intrbit] = NULL;
- xheart_intem &= ~(1UL << intrbit);
+ xheart_intem[cpuid] &= ~(1UL << intrbit);
xheart_intr_makemasks();
splx(s);
@@ -392,8 +394,10 @@ xheart_splx(int newipl)
__asm__ (".set noreorder\n");
ci->ci_ipl = newipl;
__asm__ ("sync\n\t.set reorder\n");
+
if (CPU_IS_PRIMARY(ci))
xheart_setintrmask(newipl);
+
/* If we still have softints pending trigger processing. */
if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
setsoftintr0();
@@ -406,11 +410,14 @@ xheart_splx(int newipl)
#define INTR_FUNCTIONNAME xheart_intr_handler
#define MASK_FUNCTIONNAME xheart_intr_makemasks
#define INTR_LOCAL_DECLS \
- paddr_t heart = PHYS_TO_XKPHYS(HEART_PIU_BASE, CCA_NC);
+ paddr_t heart = PHYS_TO_XKPHYS(HEART_PIU_BASE, CCA_NC); \
+ u_long cpuid = cpu_number();
+#define MASK_LOCAL_DECLS \
+ u_long cpuid = cpu_number();
#define INTR_GETMASKS \
do { \
isr = *(volatile uint64_t *)(heart + HEART_ISR); \
- imr = *(volatile uint64_t *)(heart + HEART_IMR(0)); \
+ imr = *(volatile uint64_t *)(heart + HEART_IMR(cpuid)); \
switch (hwpend) { \
case CR_INT_0: \
isr &= HEART_ISR_LVL0_MASK; \
@@ -437,15 +444,15 @@ do { \
} \
} while (0)
#define INTR_MASKPENDING \
- *(volatile uint64_t *)(heart + HEART_IMR(0)) &= ~isr
-#define INTR_IMASK(ipl) xheart_imask[ipl]
+ *(volatile uint64_t *)(heart + HEART_IMR(cpuid)) &= ~isr
+#define INTR_IMASK(ipl) xheart_imask[cpuid][ipl]
#define INTR_HANDLER(bit) xheart_intrhand[bit]
#define INTR_SPURIOUS(bit) \
do { \
printf("spurious xheart interrupt %d\n", bit); \
} while (0)
#define INTR_MASKRESTORE \
- *(volatile uint64_t *)(heart + HEART_IMR(0)) = imr
+ *(volatile uint64_t *)(heart + HEART_IMR(cpuid)) = imr
#define INTR_MASKSIZE HEART_NINTS
#include <sgi/sgi/intr_template.c>
@@ -454,6 +461,8 @@ void
xheart_setintrmask(int level)
{
paddr_t heart = PHYS_TO_XKPHYS(HEART_PIU_BASE, CCA_NC);
- *(volatile uint64_t *)(heart + HEART_IMR(0)) =
- xheart_intem & ~xheart_imask[level];
+ u_long cpuid = cpu_number();
+
+ *(volatile uint64_t *)(heart + HEART_IMR(cpuid)) =
+ xheart_intem[cpuid] & ~xheart_imask[cpuid][level];
}