summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2009-02-21 18:37:50 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2009-02-21 18:37:50 +0000
commite075faf7c1a9f5957b847d3d593556f95ce7264e (patch)
treed1926699111e1683de98fe5983db040b34f75583 /sys
parentfaa75621447538e222604390362935041779baf0 (diff)
Move part of the mp lock logic into per-cpu callbacks; on MVME197DP we need
to disable NMI sources in addition to interrupt sources, and we can not use a quick sequence with shadowing frozen as done for atomic ops. This lets GENERIC.MP boot multiuser on MVME197DP boards, and is so far stable enough to be able to recompile a kernel from scratch (with make -j2).
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/m88k/include/cpu.h15
-rw-r--r--sys/arch/m88k/include/m88100.h3
-rw-r--r--sys/arch/m88k/m88k/m88100_machdep.c39
-rw-r--r--sys/arch/m88k/m88k/mplock.c50
-rw-r--r--sys/arch/mvme88k/include/cpu.h3
-rw-r--r--sys/arch/mvme88k/mvme88k/locore.S15
-rw-r--r--sys/arch/mvme88k/mvme88k/m188_machdep.c5
-rw-r--r--sys/arch/mvme88k/mvme88k/m197_machdep.c42
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c10
9 files changed, 144 insertions, 38 deletions
diff --git a/sys/arch/m88k/include/cpu.h b/sys/arch/m88k/include/cpu.h
index b85a7e93dad..90dec8e0e56 100644
--- a/sys/arch/m88k/include/cpu.h
+++ b/sys/arch/m88k/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.43 2009/02/21 18:35:20 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.44 2009/02/21 18:37:47 miod Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* Copyright (c) 1992, 1993
@@ -79,6 +79,8 @@
extern u_int max_cpus;
+#include <machine/lock.h>
+
/*
* Per-CPU data structure
*/
@@ -94,6 +96,15 @@ struct cpu_info {
u_int ci_cpuid; /* cpu number */
/*
+ * Function pointers used within mplock to ensure
+ * non-interruptability.
+ */
+ uint32_t (*ci_mp_atomic_begin)
+ (__cpu_simple_lock_t *lock, uint *csr);
+ void (*ci_mp_atomic_end)
+ (uint32_t psr, __cpu_simple_lock_t *lock, uint csr);
+
+ /*
* The following fields are used differently depending on
* the processor type. Think of them as an anonymous union
* of two anonymous structs.
@@ -104,8 +115,6 @@ struct cpu_info {
u_int ci_cpudep3;
u_int ci_cpudep4;
u_int ci_cpudep5;
- u_int ci_cpudep6;
- u_int ci_cpudep7;
/* 88100 fields */
#define ci_pfsr_i0 ci_cpudep0 /* instruction... */
diff --git a/sys/arch/m88k/include/m88100.h b/sys/arch/m88k/include/m88100.h
index ded8b635150..245e2af244f 100644
--- a/sys/arch/m88k/include/m88100.h
+++ b/sys/arch/m88k/include/m88100.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: m88100.h,v 1.4 2007/11/17 05:36:23 miod Exp $ */
+/* $OpenBSD: m88100.h,v 1.5 2009/02/21 18:37:47 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1992 Carnegie Mellon University
@@ -71,6 +71,7 @@ u_int32_t do_xmem_word(vaddr_t, u_int32_t, int);
u_int8_t do_xmem_byte(vaddr_t, u_int8_t, int);
void m88100_apply_patches(void);
+void m88100_smp_setup(struct cpu_info *);
#endif
diff --git a/sys/arch/m88k/m88k/m88100_machdep.c b/sys/arch/m88k/m88k/m88100_machdep.c
index 359019d215d..e97306ca658 100644
--- a/sys/arch/m88k/m88k/m88100_machdep.c
+++ b/sys/arch/m88k/m88k/m88100_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m88100_machdep.c,v 1.6 2007/12/02 21:17:17 miod Exp $ */
+/* $OpenBSD: m88100_machdep.c,v 1.7 2009/02/21 18:37:48 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -32,6 +32,11 @@
#include <machine/asm_macro.h>
#include <m88k/m88100.h>
+#ifdef MULTIPROCESSOR
+uint32_t m88100_mp_atomic_begin(__cpu_simple_lock_t *, uint *);
+void m88100_mp_atomic_end(uint32_t, __cpu_simple_lock_t *, uint);
+#endif
+
/*
* Data Access Emulation for M88100 exceptions
*/
@@ -305,3 +310,35 @@ m88100_apply_patches()
}
#endif
}
+
+#ifdef MULTIPROCESSOR
+void
+m88100_smp_setup(struct cpu_info *ci)
+{
+ /*
+ * Setup function pointers for mplock operation.
+ */
+
+ ci->ci_mp_atomic_begin = m88100_mp_atomic_begin;
+ ci->ci_mp_atomic_end = m88100_mp_atomic_end;
+}
+
+uint32_t
+m88100_mp_atomic_begin(__cpu_simple_lock_t *lock, uint *csr)
+{
+ uint32_t psr;
+
+ psr = get_psr();
+ set_psr(psr | PSR_IND);
+ __cpu_simple_lock(lock);
+
+ return psr;
+}
+
+void
+m88100_mp_atomic_end(uint32_t psr, __cpu_simple_lock_t *lock, uint csr)
+{
+ __cpu_simple_unlock(lock);
+ set_psr(psr);
+}
+#endif
diff --git a/sys/arch/m88k/m88k/mplock.c b/sys/arch/m88k/m88k/mplock.c
index 8e8903be465..7bb0fddcbcd 100644
--- a/sys/arch/m88k/m88k/mplock.c
+++ b/sys/arch/m88k/m88k/mplock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mplock.c,v 1.1 2007/12/02 21:20:17 miod Exp $ */
+/* $OpenBSD: mplock.c,v 1.2 2009/02/21 18:37:48 miod Exp $ */
/*
* Copyright (c) 2004 Niklas Hallqvist. All rights reserved.
@@ -67,6 +67,8 @@ void
__mp_lock(struct __mp_lock *mpl)
{
struct cpu_info *ci = curcpu();
+ uint32_t psr;
+ uint gcsr;
/*
* Please notice that mpl_count gets incremented twice for the
@@ -81,22 +83,18 @@ __mp_lock(struct __mp_lock *mpl)
*/
for (;;) {
- u_int32_t psr = get_psr();
+ psr = (*ci->ci_mp_atomic_begin)(&mpl->mpl_lock, &gcsr);
- set_psr(psr | PSR_IND);
- __cpu_simple_lock(&mpl->mpl_lock);
if (mpl->mpl_count == 0) {
mpl->mpl_count = 1;
mpl->mpl_cpu = ci;
}
if (mpl->mpl_cpu == ci) {
mpl->mpl_count++;
- __cpu_simple_unlock(&mpl->mpl_lock);
- set_psr(psr);
+ (*ci->ci_mp_atomic_end)(psr, &mpl->mpl_lock, gcsr);
break;
}
- __cpu_simple_unlock(&mpl->mpl_lock);
- set_psr(psr);
+ (*ci->ci_mp_atomic_end)(psr, &mpl->mpl_lock, gcsr);
__mp_lock_spin(mpl);
}
@@ -105,45 +103,45 @@ __mp_lock(struct __mp_lock *mpl)
void
__mp_unlock(struct __mp_lock *mpl)
{
- u_int32_t psr = get_psr();
+ struct cpu_info *ci = curcpu();
+ u_int32_t psr;
+ uint gcsr;
#ifdef MP_LOCKDEBUG
- if (mpl->mpl_cpu != curcpu()) {
+ if (mpl->mpl_cpu != ci) {
db_printf("__mp_unlock(%p): not held lock\n", mpl);
Debugger();
}
#endif
- set_psr(psr | PSR_IND);
- __cpu_simple_lock(&mpl->mpl_lock);
+ psr = (*ci->ci_mp_atomic_begin)(&mpl->mpl_lock, &gcsr);
if (--mpl->mpl_count == 1) {
mpl->mpl_cpu = NULL;
mpl->mpl_count = 0;
}
- __cpu_simple_unlock(&mpl->mpl_lock);
- set_psr(psr);
+ (*ci->ci_mp_atomic_end)(psr, &mpl->mpl_lock, gcsr);
}
int
__mp_release_all(struct __mp_lock *mpl)
{
- u_int32_t psr = get_psr();
+ struct cpu_info *ci = curcpu();
+ u_int32_t psr;
+ uint gcsr;
int rv;
#ifdef MP_LOCKDEBUG
- if (mpl->mpl_cpu != curcpu()) {
+ if (mpl->mpl_cpu != ci) {
db_printf("__mp_release_all(%p): not held lock\n", mpl);
Debugger();
}
#endif
- set_psr(psr | PSR_IND);
- __cpu_simple_lock(&mpl->mpl_lock);
+ psr = (*ci->ci_mp_atomic_begin)(&mpl->mpl_lock, &gcsr);
rv = mpl->mpl_count - 1;
mpl->mpl_cpu = NULL;
mpl->mpl_count = 0;
- __cpu_simple_unlock(&mpl->mpl_lock);
- set_psr(psr);
+ (*ci->ci_mp_atomic_end)(psr, &mpl->mpl_lock, gcsr);
return (rv);
}
@@ -151,22 +149,22 @@ __mp_release_all(struct __mp_lock *mpl)
int
__mp_release_all_but_one(struct __mp_lock *mpl)
{
- u_int32_t psr = get_psr();
+ struct cpu_info *ci = curcpu();
+ u_int32_t psr;
+ uint gcsr;
int rv;
#ifdef MP_LOCKDEBUG
- if (mpl->mpl_cpu != curcpu()) {
+ if (mpl->mpl_cpu != ci) {
db_printf("__mp_release_all_but_one(%p): not held lock\n", mpl);
Debugger();
}
#endif
- set_psr(psr | PSR_IND);
- __cpu_simple_lock(&mpl->mpl_lock);
+ psr = (*ci->ci_mp_atomic_begin)(&mpl->mpl_lock, &gcsr);
rv = mpl->mpl_count - 2;
mpl->mpl_count = 2;
- __cpu_simple_unlock(&mpl->mpl_lock);
- set_psr(psr);
+ (*ci->ci_mp_atomic_end)(psr, &mpl->mpl_lock, gcsr);
return (rv);
}
diff --git a/sys/arch/mvme88k/include/cpu.h b/sys/arch/mvme88k/include/cpu.h
index c386d65e2de..a4e5de1a1f3 100644
--- a/sys/arch/mvme88k/include/cpu.h
+++ b/sys/arch/mvme88k/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.41 2009/02/16 23:03:33 miod Exp $ */
+/* $OpenBSD: cpu.h,v 1.42 2009/02/21 18:37:48 miod Exp $ */
/*
* Copyright (c) 1996 Nivas Madhur
* Copyright (c) 1992, 1993
@@ -57,6 +57,7 @@ extern void (*md_init_clocks)(void);
extern void (*md_send_ipi)(int, cpuid_t);
extern void (*md_delay)(int);
extern void (*md_soft_ipi)(void);
+extern void (*md_smp_setup)(struct cpu_info *);
struct intrhand {
SLIST_ENTRY(intrhand) ih_link;
diff --git a/sys/arch/mvme88k/mvme88k/locore.S b/sys/arch/mvme88k/mvme88k/locore.S
index 479fc43280f..49691210319 100644
--- a/sys/arch/mvme88k/mvme88k/locore.S
+++ b/sys/arch/mvme88k/mvme88k/locore.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.S,v 1.64 2009/02/21 18:35:22 miod Exp $ */
+/* $OpenBSD: locore.S,v 1.65 2009/02/21 18:37:48 miod Exp $ */
/*
* Copyright (c) 2005, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -230,6 +230,14 @@ GLOBAL(secondary_start)
bsr.n _C_LABEL(secondary_main)
addu r31, r2, USPACE /* switch to startup stack */
+ /*
+ * Dummy mp_atomic_begin() and mp_atomic_end() routine, so that
+ * we can interact with ddb if things go wrong very early during
+ * bootstrap. Of course this should never happen (-:
+ */
+ASLOCAL(dummy_mplock)
+ jmp r1
+
#endif /* MULTIPROCESSOR */
/*
@@ -350,7 +358,10 @@ ASLOCAL(dummy_cpu)
word 0 /* ci_curproc */
word 0 /* ci_curpcb */
word 0 /* ci_cpuid */
- space CPU_INFO_SIZEOF - 4 * 4
+ word _ASM_LABEL(dummy_mplock) /* ci_mp_atomic_begin */
+ word _ASM_LABEL(dummy_mplock) /* ci_mp_atomic_end */
+
+ space CPU_INFO_SIZEOF - 6 * 4
#endif /* MULTIPROCESSOR */
#if defined(DDB) || NKSYMS > 0
diff --git a/sys/arch/mvme88k/mvme88k/m188_machdep.c b/sys/arch/mvme88k/mvme88k/m188_machdep.c
index 31806f1f708..9ed61c605d1 100644
--- a/sys/arch/mvme88k/mvme88k/m188_machdep.c
+++ b/sys/arch/mvme88k/mvme88k/m188_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m188_machdep.c,v 1.49 2009/02/20 23:35:11 miod Exp $ */
+/* $OpenBSD: m188_machdep.c,v 1.50 2009/02/21 18:37:48 miod Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -224,6 +224,9 @@ m188_bootstrap()
md_soft_ipi = m188_soft_ipi;
#endif
md_delay = m188_delay;
+#ifdef MULTIPROCESSOR
+ md_smp_setup = m88100_smp_setup;
+#endif
/* clear and disable all interrupts */
*(volatile u_int32_t *)MVME188_IENALL = 0;
diff --git a/sys/arch/mvme88k/mvme88k/m197_machdep.c b/sys/arch/mvme88k/mvme88k/m197_machdep.c
index 1614020694a..027fad9e43b 100644
--- a/sys/arch/mvme88k/mvme88k/m197_machdep.c
+++ b/sys/arch/mvme88k/mvme88k/m197_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m197_machdep.c,v 1.35 2009/02/21 18:35:22 miod Exp $ */
+/* $OpenBSD: m197_machdep.c,v 1.36 2009/02/21 18:37:49 miod Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -89,9 +89,12 @@ void m197_ext_int(struct trapframe *);
u_int m197_getipl(void);
void m197_ipi_handler(struct trapframe *);
vaddr_t m197_memsize(void);
+uint32_t m197_mp_atomic_begin(__cpu_simple_lock_t *, uint *);
+void m197_mp_atomic_end(uint32_t, __cpu_simple_lock_t *, uint);
void m197_nmi(struct trapframe *);
u_int m197_raiseipl(u_int);
u_int m197_setipl(u_int);
+void m197_smp_setup(struct cpu_info *);
void m197_soft_ipi(void);
void m197_startup(void);
@@ -406,6 +409,7 @@ m197_bootstrap()
md_send_ipi = m197_send_ipi;
md_soft_ipi = m197_soft_ipi;
md_delay = m197_delay;
+ md_smp_setup = m197_smp_setup;
#else
md_delay = m1x7_delay;
#endif
@@ -647,4 +651,40 @@ m197_delay(int us)
}
}
+void
+m197_smp_setup(struct cpu_info *ci)
+{
+ /*
+ * Setup function pointers for mplock operation.
+ */
+
+ ci->ci_mp_atomic_begin = m197_mp_atomic_begin;
+ ci->ci_mp_atomic_end = m197_mp_atomic_end;
+}
+
+uint32_t
+m197_mp_atomic_begin(__cpu_simple_lock_t *lock, uint *csr)
+{
+ uint32_t psr;
+
+ psr = get_psr();
+ set_psr(psr | PSR_IND);
+
+ *csr = *(volatile uint8_t *)(BS_BASE + BS_CPINT);
+ *(volatile uint8_t *)(BS_BASE + BS_CPINT) = 0;
+
+ __cpu_simple_lock(lock);
+
+ return psr;
+}
+
+void
+m197_mp_atomic_end(uint32_t psr, __cpu_simple_lock_t *lock, uint csr)
+{
+ __cpu_simple_unlock(lock);
+
+ *(volatile uint8_t *)(BS_BASE + BS_CPINT) = csr & BS_CPI_IEN;
+
+ set_psr(psr);
+}
#endif /* MULTIPROCESSOR */
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c
index 17228943858..e175e5c5b13 100644
--- a/sys/arch/mvme88k/mvme88k/machdep.c
+++ b/sys/arch/mvme88k/mvme88k/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.224 2009/02/21 18:35:22 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.225 2009/02/21 18:37:49 miod Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -136,6 +136,9 @@ void (*md_send_ipi)(int, cpuid_t);
void (*md_soft_ipi)(void);
#endif
void (*md_delay)(int) = dumb_delay;
+#ifdef MULTIPROCESSOR
+void (*md_smp_setup)(struct cpu_info *);
+#endif
int physmem; /* available physical memory, in pages */
@@ -714,6 +717,7 @@ secondary_pre_main()
set_cpu_number(cmmu_cpu_number()); /* Determine cpu number by CMMU */
ci = curcpu();
ci->ci_curproc = &proc0;
+ (*md_smp_setup)(ci);
splhigh();
@@ -1011,9 +1015,11 @@ mvme_bootstrap()
setup_board_config();
master_cpu = cmmu_init();
set_cpu_number(master_cpu);
+#ifdef MULTIPROCESSOR
+ (*md_smp_setup)(curcpu());
+#endif
SET(curcpu()->ci_flags, CIF_ALIVE | CIF_PRIMARY);
-
#ifdef M88100
if (CPU_IS88100) {
m88100_apply_patches();