diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-21 18:37:50 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2009-02-21 18:37:50 +0000 |
commit | e075faf7c1a9f5957b847d3d593556f95ce7264e (patch) | |
tree | d1926699111e1683de98fe5983db040b34f75583 /sys | |
parent | faa75621447538e222604390362935041779baf0 (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.h | 15 | ||||
-rw-r--r-- | sys/arch/m88k/include/m88100.h | 3 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/m88100_machdep.c | 39 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/mplock.c | 50 | ||||
-rw-r--r-- | sys/arch/mvme88k/include/cpu.h | 3 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/locore.S | 15 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/m188_machdep.c | 5 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/m197_machdep.c | 42 | ||||
-rw-r--r-- | sys/arch/mvme88k/mvme88k/machdep.c | 10 |
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(); |