diff options
author | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-11-25 17:39:52 +0000 |
---|---|---|
committer | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-11-25 17:39:52 +0000 |
commit | 74b769daab68419f740f12dd4a4d345696354046 (patch) | |
tree | 82eec580c2361db182e94b79d90e1b65e889f722 /sys/arch | |
parent | eddc7cb9c421d16e98e7d9f394f1eb663b8201a3 (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.mips64 | 4 | ||||
-rw-r--r-- | sys/arch/mips64/include/cpu.h | 11 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/cpu.c | 12 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/ipifuncs.c | 164 | ||||
-rw-r--r-- | sys/arch/sgi/include/cpu.h | 9 | ||||
-rw-r--r-- | sys/arch/sgi/include/intr.h | 7 | ||||
-rw-r--r-- | sys/arch/sgi/localbus/macebus.c | 3 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/intr_template.c | 6 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27_machdep.c | 3 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip30_machdep.c | 35 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/xheart.c | 37 |
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]; } |