diff options
author | Martin Reindl <martin@cvs.openbsd.org> | 2007-04-13 08:31:51 +0000 |
---|---|---|
committer | Martin Reindl <martin@cvs.openbsd.org> | 2007-04-13 08:31:51 +0000 |
commit | 4561238b1707d998fc3e95eb3e45ada00ffe2487 (patch) | |
tree | faea9c5797ba2a3761817731a9d33c30796213c3 | |
parent | fe27c6b5fb1a85687c673879f19a5c8cc187ea3d (diff) |
get alpha SMP into a state where it at least compiles:
- add machine-dependent spinlock operations
- add basic interprocessor interrupt sending and receiving code
from NetBSD; ok miod@
-rw-r--r-- | sys/arch/alpha/alpha/genassym.cf | 3 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/ipifuncs.c | 181 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/alpha/alpha/pmap.c | 6 | ||||
-rw-r--r-- | sys/arch/alpha/conf/files.alpha | 3 | ||||
-rw-r--r-- | sys/arch/alpha/include/cpu.h | 13 | ||||
-rw-r--r-- | sys/arch/alpha/include/intr.h | 6 | ||||
-rw-r--r-- | sys/arch/alpha/include/lock.h | 161 |
8 files changed, 366 insertions, 14 deletions
diff --git a/sys/arch/alpha/alpha/genassym.cf b/sys/arch/alpha/alpha/genassym.cf index cbdf29151c4..8045b0d8a33 100644 --- a/sys/arch/alpha/alpha/genassym.cf +++ b/sys/arch/alpha/alpha/genassym.cf @@ -1,4 +1,4 @@ -# $OpenBSD: genassym.cf,v 1.8 2006/04/13 14:41:08 brad Exp $ +# $OpenBSD: genassym.cf,v 1.9 2007/04/13 08:31:50 martin Exp $ # Copyright (c) 1994, 1995 Gordon W. Ross # Copyright (c) 1993 Adam Glass @@ -114,6 +114,7 @@ member p_vmspace member p_stat member P_MD_FLAGS p_md.md_flags member P_MD_PCBPADDR p_md.md_pcbpaddr +member p_cpu struct prochd member ph_link member ph_rlink diff --git a/sys/arch/alpha/alpha/ipifuncs.c b/sys/arch/alpha/alpha/ipifuncs.c new file mode 100644 index 00000000000..c705fe4a9e3 --- /dev/null +++ b/sys/arch/alpha/alpha/ipifuncs.c @@ -0,0 +1,181 @@ +/* $OpenBSD: ipifuncs.c,v 1.1 2007/04/13 08:31:50 martin Exp $ */ +/* $NetBSD: ipifuncs.c,v 1.9 1999/12/02 01:09:11 thorpej Exp $ */ + +/*- + * Copyright (c) 1998, 1999 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ + +/* + * Interprocessor interrupt handlers. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/systm.h> + +#include <uvm/uvm_extern.h> + +#include <machine/atomic.h> +#include <machine/alpha_cpu.h> +#include <machine/cpu.h> +#include <machine/intr.h> +#include <machine/rpb.h> + +void alpha_ipi_halt(void); +void alpha_ipi_tbia(void); +void alpha_ipi_tbiap(void); +void alpha_ipi_imb(void); +void alpha_ipi_ast(void); + +/* + * NOTE: This table must be kept in order with the bit definitions + * in <machine/intr.h>. + */ +ipifunc_t ipifuncs[ALPHA_NIPIS] = { + alpha_ipi_halt, + alpha_ipi_tbia, + alpha_ipi_tbiap, + alpha_ipi_imb, + alpha_ipi_ast, +}; + +/* + * Send an interprocessor interrupt. + */ +void +alpha_send_ipi(cpu_id, ipimask) + u_long cpu_id, ipimask; +{ + +#ifdef DIAGNOSTIC + if (cpu_id >= hwrpb->rpb_pcs_cnt || + cpu_info[cpu_id].ci_dev == NULL) + panic("alpha_sched_ipi: bogus cpu_id"); +#endif + + atomic_setbits_ulong(&cpu_info[cpu_id].ci_ipis, ipimask); + alpha_pal_wripir(cpu_id); +} + +/* + * Broadcast an IPI to all but ourselves. + */ +void +alpha_broadcast_ipi(ipimask) + u_long ipimask; +{ + u_long i; + + for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { + if (cpu_info[i].ci_dev == NULL) + continue; + alpha_send_ipi(i, ipimask); + } +} + +/* + * Send an IPI to all in the list but ourselves. + */ +void +alpha_multicast_ipi(cpumask, ipimask) + u_long cpumask, ipimask; +{ + u_long i; + + cpumask &= cpus_running; + cpumask &= ~(1UL << cpu_number()); + if (cpumask == 0) + return; + + for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { + if ((cpumask & (1UL << i)) == 0) + continue; + alpha_send_ipi(i, ipimask); + } +} + +void +alpha_ipi_halt() +{ + u_long cpu_id = alpha_pal_whami(); + struct pcs *pcsp = LOCATE_PCS(hwrpb, cpu_id); + + /* Disable interrupts. */ + (void) splhigh(); + + printf("%s: shutting down...\n", cpu_info[cpu_id].ci_dev->dv_xname); + atomic_clearbits_ulong(&cpus_running, (1UL << cpu_id)); + + pcsp->pcs_flags &= ~(PCS_RC | PCS_HALT_REQ); + pcsp->pcs_flags |= PCS_HALT_STAY_HALTED; + alpha_pal_halt(); + /* NOTREACHED */ +} + +void +alpha_ipi_tbia() +{ + u_long cpu_id = alpha_pal_whami(); + + /* If we're doing a TBIA, we don't need to do a TBIAP or a SHOOTDOWN. */ + atomic_clearbits_ulong(&cpu_info[cpu_id].ci_ipis, + ALPHA_IPI_TBIAP|ALPHA_IPI_SHOOTDOWN); + + ALPHA_TBIA(); +} + +void +alpha_ipi_tbiap() +{ + + /* Can't clear SHOOTDOWN here; might have PG_ASM mappings. */ + + ALPHA_TBIAP(); +} + +void +alpha_ipi_imb() +{ + + alpha_pal_imb(); +} + +void +alpha_ipi_ast() +{ + + aston(curcpu()); +} diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index 15b6b0a8ff5..3e66b0af869 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.104 2007/02/26 21:30:16 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.105 2007/04/13 08:31:50 martin Exp $ */ /* $NetBSD: machdep.c,v 1.210 2000/06/01 17:12:38 thorpej Exp $ */ /*- @@ -1855,9 +1855,6 @@ void fpusave_cpu(struct cpu_info *ci, int save) { struct proc *p; -#if defined(MULTIPROCESSOR) - int s; -#endif KDASSERT(ci == curcpu()); @@ -1896,7 +1893,7 @@ fpusave_proc(struct proc *p, int save) struct cpu_info *oci; #if defined(MULTIPROCESSOR) u_long ipi = save ? ALPHA_IPI_SYNCH_FPU : ALPHA_IPI_DISCARD_FPU; - int s, spincount; + int spincount; #endif KDASSERT(p->p_addr != NULL); diff --git a/sys/arch/alpha/alpha/pmap.c b/sys/arch/alpha/alpha/pmap.c index dc9ac1e59c1..71d122e0321 100644 --- a/sys/arch/alpha/alpha/pmap.c +++ b/sys/arch/alpha/alpha/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.49 2007/02/03 16:48:21 miod Exp $ */ +/* $OpenBSD: pmap.c,v 1.50 2007/04/13 08:31:50 martin Exp $ */ /* $NetBSD: pmap.c,v 1.154 2000/12/07 22:18:55 thorpej Exp $ */ /*- @@ -4108,9 +4108,9 @@ pmap_tlb_shootdown(pmap_t pmap, vaddr_t va, pt_entry_t pte) * TBIA[P]. */ if (pq->pq_pte & PG_ASM) - ipinum = ALPHA_IPI_TBIA; + ipinum = ALPHA_IPI_SHOOTDOWN; else - ipinum = ALPHA_IPI_TBIAP; + ipinum = ALPHA_IPI_IMB; alpha_send_ipi(i, ipinum); } else { pj->pj_pmap = pmap; diff --git a/sys/arch/alpha/conf/files.alpha b/sys/arch/alpha/conf/files.alpha index e4cbf718643..a56f1413fcd 100644 --- a/sys/arch/alpha/conf/files.alpha +++ b/sys/arch/alpha/conf/files.alpha @@ -1,4 +1,4 @@ -# $OpenBSD: files.alpha,v 1.78 2007/03/16 21:22:27 robert Exp $ +# $OpenBSD: files.alpha,v 1.79 2007/04/13 08:31:50 martin Exp $ # $NetBSD: files.alpha,v 1.32 1996/11/25 04:03:21 cgd Exp $ # # alpha-specific configuration info @@ -292,6 +292,7 @@ file arch/alpha/alpha/db_disasm.c ddb file arch/alpha/alpha/db_interface.c ddb file arch/alpha/alpha/db_trace.c ddb file arch/alpha/alpha/interrupt.c +file arch/alpha/alpha/ipifuncs.c multiprocessor file arch/alpha/alpha/machdep.c file arch/alpha/alpha/mainbus.c file arch/alpha/alpha/mem.c diff --git a/sys/arch/alpha/include/cpu.h b/sys/arch/alpha/include/cpu.h index 4911e1e6cd5..5034699376c 100644 --- a/sys/arch/alpha/include/cpu.h +++ b/sys/arch/alpha/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.28 2007/04/12 14:38:36 martin Exp $ */ +/* $OpenBSD: cpu.h,v 1.29 2007/04/13 08:31:50 martin Exp $ */ /* $NetBSD: cpu.h,v 1.45 2000/08/21 02:03:12 thorpej Exp $ */ /*- @@ -101,10 +101,12 @@ typedef union alpha_t_float { #include <machine/alpha_cpu.h> #include <machine/frame.h> +#include <machine/param.h> #ifdef _KERNEL #include <machine/bus.h> +#include <machine/intr.h> #include <sys/device.h> #include <sys/sched.h> @@ -205,6 +207,7 @@ struct cpu_info { u_long ci_want_resched; /* preempt current process */ u_long ci_astpending; /* AST is pending */ u_long ci_intrdepth; /* interrupt trap depth */ + struct trapframe *ci_db_regs; /* registers for debuggers */ #if defined(MULTIPROCESSOR) u_long ci_flags; /* flags; see below */ u_long ci_ipis; /* interprocessor interrupts pending */ @@ -230,8 +233,8 @@ extern __volatile u_long cpus_running; extern __volatile u_long cpus_paused; extern struct cpu_info cpu_info[]; -#define curcpu() ((struct cpu_info *)alpha_pal_rdval()) -#define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY) +#define curcpu() ((struct cpu_info *)alpha_pal_rdval()) +#define CPU_IS_PRIMARY(ci) ((ci)->ci_flags & CPUF_PRIMARY) void cpu_boot_secondary_processors(void); @@ -406,5 +409,9 @@ int alpha_fp_complete(u_long, u_long, struct proc *, u_int64_t *); void alpha_enable_fp(struct proc *, int); +#ifdef MULTIPROCESSOR +#include <sys/mplock.h> +#endif + #endif /* _KERNEL */ #endif /* _ALPHA_CPU_H_ */ diff --git a/sys/arch/alpha/include/intr.h b/sys/arch/alpha/include/intr.h index 6391372a4c8..ea6c5b7e708 100644 --- a/sys/arch/alpha/include/intr.h +++ b/sys/arch/alpha/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.24 2007/04/12 14:38:36 martin Exp $ */ +/* $OpenBSD: intr.h,v 1.25 2007/04/13 08:31:50 martin Exp $ */ /* $NetBSD: intr.h,v 1.26 2000/06/03 20:47:41 thorpej Exp $ */ /*- @@ -162,6 +162,7 @@ int _splraise(int); #define splhigh() _splraise(ALPHA_PSL_IPL_HIGH) #define spllpt() spltty() +#define spllock() splhigh() #define splsched() splhigh() /* @@ -173,6 +174,9 @@ int _splraise(int); #define ALPHA_IPI_SHOOTDOWN 0x0000000000000008UL #define ALPHA_IPI_IMB 0x0000000000000010UL #define ALPHA_IPI_AST 0x0000000000000020UL +#define ALPHA_IPI_SYNCH_FPU 0x0000000000000040UL +#define ALPHA_IPI_DISCARD_FPU 0x0000000000000080UL +#define ALPHA_IPI_PAUSE 0x0000000000000100UL #define ALPHA_NIPIS 6 /* must not exceed 64 */ diff --git a/sys/arch/alpha/include/lock.h b/sys/arch/alpha/include/lock.h new file mode 100644 index 00000000000..11ac737db4f --- /dev/null +++ b/sys/arch/alpha/include/lock.h @@ -0,0 +1,161 @@ +/* $OpenBSD: lock.h,v 1.1 2007/04/13 08:31:50 martin Exp $ */ +/* $NetBSD: lock.h,v 1.16 2001/12/17 23:34:57 thorpej Exp $ */ + +/*- + * Copyright (c) 1998, 1999, 2000 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ + +/* + * Machine-dependent spin lock operations. + */ + +#ifndef _ALPHA_LOCK_H_ +#define _ALPHA_LOCK_H_ + +typedef __volatile int __cpu_simple_lock_t; + +#define __SIMPLELOCK_LOCKED 1 +#define __SIMPLELOCK_UNLOCKED 0 + +static __inline void +__cpu_simple_lock_init(__cpu_simple_lock_t *alp) +{ + + __asm __volatile( + "# BEGIN __cpu_simple_lock_init\n" + " stl $31, %0 \n" + " mb \n" + " # END __cpu_simple_lock_init" + : "=m" (*alp)); +} + +static __inline void +__cpu_simple_lock(__cpu_simple_lock_t *alp) +{ + unsigned long t0; + + /* + * Note, if we detect that the lock is held when + * we do the initial load-locked, we spin using + * a non-locked load to save the coherency logic + * some work. + */ + + __asm __volatile( + "# BEGIN __cpu_simple_lock\n" + "1: ldl_l %0, %3 \n" + " bne %0, 2f \n" + " bis $31, %2, %0 \n" + " stl_c %0, %1 \n" + " beq %0, 3f \n" + " mb \n" + " br 4f \n" + "2: ldl %0, %3 \n" + " beq %0, 1b \n" + " br 2b \n" + "3: br 1b \n" + "4: \n" + " # END __cpu_simple_lock\n" + : "=&r" (t0), "=m" (*alp) + : "i" (__SIMPLELOCK_LOCKED), "m" (*alp) + : "memory"); +} + +static __inline int +__cpu_simple_lock_try(__cpu_simple_lock_t *alp) +{ + unsigned long t0, v0; + + __asm __volatile( + "# BEGIN __cpu_simple_lock_try\n" + "1: ldl_l %0, %4 \n" + " bne %0, 2f \n" + " bis $31, %3, %0 \n" + " stl_c %0, %2 \n" + " beq %0, 3f \n" + " mb \n" + " bis $31, 1, %1 \n" + " br 4f \n" + "2: bis $31, $31, %1 \n" + " br 4f \n" + "3: br 1b \n" + "4: \n" + " # END __cpu_simple_lock_try" + : "=&r" (t0), "=r" (v0), "=m" (*alp) + : "i" (__SIMPLELOCK_LOCKED), "m" (*alp) + : "memory"); + + return (v0 != 0); +} + +static __inline void +__cpu_simple_unlock(__cpu_simple_lock_t *alp) +{ + + __asm __volatile( + "# BEGIN __cpu_simple_unlock\n" + " mb \n" + " stl $31, %0 \n" + " # END __cpu_simple_unlock" + : "=m" (*alp)); +} + +#if defined(MULTIPROCESSOR) +/* + * On the Alpha, interprocessor interrupts come in at device priority + * level. This can cause some problems while waiting for r/w spinlocks + * from a high'ish priority level: IPIs that come in will not be processed. + * This can lead to deadlock. + * + * This hook allows IPIs to be processed while a spinlock's interlock + * is released. + */ +#define SPINLOCK_SPIN_HOOK \ +do { \ + struct cpu_info *__ci = curcpu(); \ + int __s; \ + \ + if (__ci->ci_ipis != 0) { \ + /* printf("CPU %lu has IPIs pending\n", \ + __ci->ci_cpuid); */ \ + __s = splipi(); \ + alpha_ipi_process(__ci, NULL); \ + splx(__s); \ + } \ +} while (0) +#endif /* MULTIPROCESSOR */ + +#endif /* _ALPHA_LOCK_H_ */ |