Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc/sparc more SMP work:
details: https://anonhg.NetBSD.org/src/rev/8d312ed89e6d
branches: trunk
changeset: 510866:8d312ed89e6d
user: mrg <mrg%NetBSD.org@localhost>
date: Thu Jun 07 17:59:47 2001 +0000
description:
more SMP work:
make IPI's work. modify boot_secondary_processors() to clear the startup flag
in each cpu. new raise_ipi_wait_and_unlock() that calls raise_ipi(), waits
for the cpu to acknowledge it got the message, and then unlocks the msglock.
use the new framework in mp_{pause,resume}_cpus(). nmi_soft() takes a
`struct trapframe *', to be used by ddb.
diffstat:
sys/arch/sparc/sparc/cpu.c | 73 +++++++++++++++++++++++++++++++-----------
sys/arch/sparc/sparc/cpuvar.h | 5 ++-
sys/arch/sparc/sparc/intr.c | 27 ++++++---------
3 files changed, 69 insertions(+), 36 deletions(-)
diffs (276 lines):
diff -r dfcb056cae4f -r 8d312ed89e6d sys/arch/sparc/sparc/cpu.c
--- a/sys/arch/sparc/sparc/cpu.c Thu Jun 07 17:54:35 2001 +0000
+++ b/sys/arch/sparc/sparc/cpu.c Thu Jun 07 17:59:47 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.118 2001/05/26 21:27:14 chs Exp $ */
+/* $NetBSD: cpu.c,v 1.119 2001/06/07 17:59:47 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -52,12 +52,14 @@
*/
#include "opt_multiprocessor.h"
+#include "opt_lockdebug.h"
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
+#include <sys/lock.h>
#include <uvm/uvm.h>
@@ -104,7 +106,6 @@
static char *fsrtoname __P((int, int, int));
void cache_print __P((struct cpu_softc *));
void cpu_setup __P((struct cpu_softc *));
-void cpu_spinup __P((struct cpu_softc *));
void fpu_init __P((struct cpu_info *));
#define IU_IMPL(psr) ((u_int)(psr) >> 28)
@@ -114,9 +115,11 @@
#define SRMMU_VERS(mmusr) (((mmusr) >> 24) & 0xf)
#if defined(MULTIPROCESSOR)
+void cpu_spinup __P((struct cpu_softc *));
struct cpu_info *alloc_cpuinfo_global_va __P((int, vsize_t *));
struct cpu_info *alloc_cpuinfo __P((void));
+
struct cpu_info *
alloc_cpuinfo_global_va(ismaster, sizep)
int ismaster;
@@ -203,6 +206,7 @@
pmap_update();
bzero((void *)cpi, sz);
+ cpi->flags = CPUFLG_STARTUP;
cpi->eintstack = (void *)((vaddr_t)cpi + sz);
cpi->idle_u = (void *)((vaddr_t)cpi + sz - INT_STACK_SIZE - USPACE);
@@ -398,19 +402,31 @@
void
cpu_boot_secondary_processors()
{
-
- /*
- * XXX This is currently a noop; the CPUs are already running, but
- * XXX aren't doing anything. Eventually, this will release a
- * XXX semaphore that all those secondary processors are anxiously
- * XXX waiting on.
- */
+ int n;
if (cpu_instance != ncpu) {
printf("NOTICE: only %d out of %d CPUs were configured\n",
cpu_instance, ncpu);
return;
}
+
+ if (cpus == NULL)
+ return;
+
+ /* Tell the other CPU's to start up. */
+ printf("cpu0: booting secondary processors:");
+ for (n = 0; n < ncpu; n++) {
+ struct cpu_info *cpi = cpus[n];
+
+ if (cpi == NULL || cpuinfo.mid == cpi->mid)
+ continue;
+
+ printf(" cpu%d", cpi->ci_cpuid);
+
+ /* tell it to continue */
+ //cpi->flags &= ~CPUFLG_STARTUP;
+ }
+ printf("\n");
}
#endif /* MULTIPROCESSOR */
@@ -444,6 +460,7 @@
#endif
}
+#if defined(MULTIPROCESSOR)
/*
* Allocate per-CPU data, then start up this CPU using PROM.
*/
@@ -451,7 +468,6 @@
cpu_spinup(sc)
struct cpu_softc *sc;
{
-#if defined(MULTIPROCESSOR)
struct cpu_info *cpi = sc->sc_cpuinfo;
int n;
extern void cpu_hatch __P((void)); /* in locore.s */
@@ -491,13 +507,31 @@
delay(100);
}
printf("CPU did not spin up\n");
-#endif
+}
+
+void
+raise_ipi_wait_and_unlock(cpi)
+ struct cpu_info *cpi;
+{
+ int i;
+
+ raise_ipi(cpi);
+ i = 0;
+ while ((cpi->flags & CPUFLG_GOTMSG) == 0) {
+ if (i++ > 10000) {
+ printf("raise_ipi_wait_and_unlock(cpu%d): couldn't ping cpu%d\n",
+ cpuinfo.ci_cpuid, cpi->ci_cpuid);
+ break;
+ }
+ delay(1);
+ cpuinfo.cache_flush((caddr_t)&cpi->flags, sizeof(cpi->flags));
+ }
+ simple_unlock(&cpi->msg.lock);
}
void
mp_pause_cpus()
{
-#if defined(MULTIPROCESSOR)
int n;
if (cpus == NULL)
@@ -505,19 +539,20 @@
for (n = 0; n < ncpu; n++) {
struct cpu_info *cpi = cpus[n];
+
if (cpi == NULL || cpuinfo.mid == cpi->mid)
continue;
+
simple_lock(&cpi->msg.lock);
cpi->msg.tag = XPMSG_PAUSECPU;
- raise_ipi(cpi);
+ cpi->flags &= ~CPUFLG_GOTMSG;
+ raise_ipi_wait_and_unlock(cpi);
}
-#endif
}
void
mp_resume_cpus()
{
-#if defined(MULTIPROCESSOR)
int n;
if (cpus == NULL)
@@ -525,15 +560,15 @@
for (n = 0; n < ncpu; n++) {
struct cpu_info *cpi = cpus[n];
+
if (cpi == NULL || cpuinfo.mid == cpi->mid)
continue;
- simple_lock(&cpi->msg.lock);
- cpi->msg.tag = XPMSG_RESUMECPU;
- raise_ipi(cpi);
+ /* tell it to continue */
+ cpi->flags &= ~CPUFLG_PAUSED;
}
-#endif
}
+#endif /* MULTIPROCESSOR */
/*
* fpu_init() must be run on associated CPU.
diff -r dfcb056cae4f -r 8d312ed89e6d sys/arch/sparc/sparc/cpuvar.h
--- a/sys/arch/sparc/sparc/cpuvar.h Thu Jun 07 17:54:35 2001 +0000
+++ b/sys/arch/sparc/sparc/cpuvar.h Thu Jun 07 17:59:47 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuvar.h,v 1.33 2001/06/03 04:03:29 mrg Exp $ */
+/* $NetBSD: cpuvar.h,v 1.34 2001/06/07 17:59:48 mrg Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -393,6 +393,9 @@
void mmu_install_tables __P((struct cpu_info *));
void pmap_alloc_cpu __P((struct cpu_info *));
void pmap_globalize_boot_cpu __P((struct cpu_info *));
+#if defined(MULTIPROCESSOR)
+void raise_ipi_wait_and_unlock __P((struct cpu_info *));
+#endif
extern struct cpu_info **cpus;
diff -r dfcb056cae4f -r 8d312ed89e6d sys/arch/sparc/sparc/intr.c
--- a/sys/arch/sparc/sparc/intr.c Thu Jun 07 17:54:35 2001 +0000
+++ b/sys/arch/sparc/sparc/intr.c Thu Jun 07 17:59:47 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.50 2001/03/22 15:56:43 mrg Exp $ */
+/* $NetBSD: intr.c,v 1.51 2001/06/07 17:59:48 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -159,7 +159,7 @@
#if defined(SUN4M)
void nmi_hard __P((void));
-void nmi_soft __P((void));
+void nmi_soft __P((struct trapframe *));
int (*memerr_handler) __P((void));
int (*sbuserr_handler) __P((void));
@@ -198,7 +198,7 @@
* Examine pending system interrupts.
*/
si = *((u_int32_t *)ICR_SI_PEND);
- printf("NMI: system interrupts: %s\n",
+ printf("cpu%d: NMI: system interrupts: %s\n", cpu_number(),
bitmask_snprintf(si, SINTR_BITS, bits, sizeof(bits)));
if ((si & SINTR_M) != 0) {
@@ -227,28 +227,24 @@
}
void
-nmi_soft()
+nmi_soft(tf)
+ struct trapframe *tf;
{
#ifdef MULTIPROCESSOR
switch (cpuinfo.msg.tag) {
case XPMSG_SAVEFPU: {
savefpstate(cpuinfo.fpproc->p_md.md_fpstate);
+ cpuinfo.fpproc->p_md.md_fpumid = -1;
+ cpuinfo.fpproc = NULL;
}
break;
case XPMSG_PAUSECPU: {
- cpuinfo.flags |= 0x4000;
- while (cpuinfo.flags & 0x4000) {
- simple_unlock(&cpuinfo.msg.lock);
- delay(1);
- simple_lock(&cpuinfo.msg.lock);
+ cpuinfo.flags |= CPUFLG_PAUSED|CPUFLG_GOTMSG;
+ while (cpuinfo.flags & CPUFLG_PAUSED)
+ cpuinfo.cache_flush((caddr_t)&cpuinfo.flags, sizeof(cpuinfo.flags));
+ return;
}
- }
- break;
- case XPMSG_RESUMECPU: {
- cpuinfo.flags &= ~0x4000;
- }
- break;
case XPMSG_VCACHE_FLUSH_PAGE: {
struct xpmsg_flush_page *p = &cpuinfo.msg.u.xpmsg_flush_page;
int ctx = getcontext();
@@ -290,7 +286,6 @@
}
break;
}
- simple_unlock(&cpuinfo.msg.lock);
#endif
}
#endif
Home |
Main Index |
Thread Index |
Old Index