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