summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Reindl <martin@cvs.openbsd.org>2007-04-13 08:31:51 +0000
committerMartin Reindl <martin@cvs.openbsd.org>2007-04-13 08:31:51 +0000
commit4561238b1707d998fc3e95eb3e45ada00ffe2487 (patch)
treefaea9c5797ba2a3761817731a9d33c30796213c3
parentfe27c6b5fb1a85687c673879f19a5c8cc187ea3d (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.cf3
-rw-r--r--sys/arch/alpha/alpha/ipifuncs.c181
-rw-r--r--sys/arch/alpha/alpha/machdep.c7
-rw-r--r--sys/arch/alpha/alpha/pmap.c6
-rw-r--r--sys/arch/alpha/conf/files.alpha3
-rw-r--r--sys/arch/alpha/include/cpu.h13
-rw-r--r--sys/arch/alpha/include/intr.h6
-rw-r--r--sys/arch/alpha/include/lock.h161
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_ */