Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha Several changes, which get us generally furth...



details:   https://anonhg.NetBSD.org/src/rev/3ca906b0bf43
branches:  trunk
changeset: 499548:3ca906b0bf43
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Nov 22 08:39:46 2000 +0000

description:
Several changes, which get us generally further along with
multiprocessor support:
- Implement MP-safe halt.
- Make the FPU saving code more like Bill's on the i386 MP branch.
  XXX This code will no doubt be revisited again.
- Pass the cpu_info and trapframe to IPI handlers, saving some work
  in the handlers themselves, and also making it possible for the
  "pause" handler to reference register state for DDB.
- Add "machine cpu" to DDB, making it possible to reference other
  CPUs registers (and thus get e.g. a traceback) from whichever
  CPU is actually running the debugger.
- Garbage-collect "machine halt" and "machine reboot" DDB commands.
  They don't have a prayer of working properly in multiprocessor
  kernels, and didn't really work all that well in uniprocessor kernels.

diffstat:

 sys/arch/alpha/alpha/compat_13_machdep.c |    6 +-
 sys/arch/alpha/alpha/cpu.c               |   79 +++++++++-------
 sys/arch/alpha/alpha/db_interface.c      |   68 +++++++++----
 sys/arch/alpha/alpha/interrupt.c         |    6 +-
 sys/arch/alpha/alpha/ipifuncs.c          |  112 +++++++++++++----------
 sys/arch/alpha/alpha/machdep.c           |  146 ++++++++++++++++++------------
 sys/arch/alpha/alpha/pmap.c              |    8 +-
 sys/arch/alpha/alpha/process_machdep.c   |    8 +-
 sys/arch/alpha/alpha/trap.c              |   46 +++++++-
 sys/arch/alpha/alpha/vm_machdep.c        |   12 +-
 sys/arch/alpha/include/alpha.h           |   11 +-
 sys/arch/alpha/include/cpu.h             |    6 +-
 sys/arch/alpha/include/intr.h            |    5 +-
 sys/arch/alpha/include/pmap.h            |    7 +-
 14 files changed, 318 insertions(+), 202 deletions(-)

diffs (truncated from 1126 to 300 lines):

diff -r 36d9cc1fab36 -r 3ca906b0bf43 sys/arch/alpha/alpha/compat_13_machdep.c
--- a/sys/arch/alpha/alpha/compat_13_machdep.c  Wed Nov 22 07:44:01 2000 +0000
+++ b/sys/arch/alpha/alpha/compat_13_machdep.c  Wed Nov 22 08:39:46 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: compat_13_machdep.c,v 1.7 2000/08/15 22:16:17 thorpej Exp $ */
+/* $NetBSD: compat_13_machdep.c,v 1.8 2000/11/22 08:39:46 thorpej Exp $ */
 
 /*
  * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -29,7 +29,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.7 2000/08/15 22:16:17 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: compat_13_machdep.c,v 1.8 2000/11/22 08:39:46 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -93,7 +93,7 @@
 
        /* XXX ksc.sc_ownedfp ? */
        if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
-               synchronize_fpstate(p, 0);
+               fpusave_proc(p, 0);
        bcopy((struct fpreg *)ksc.sc_fpregs, &p->p_addr->u_pcb.pcb_fp,
            sizeof(struct fpreg));
        /* XXX ksc.sc_fp_control ? */
diff -r 36d9cc1fab36 -r 3ca906b0bf43 sys/arch/alpha/alpha/cpu.c
--- a/sys/arch/alpha/alpha/cpu.c        Wed Nov 22 07:44:01 2000 +0000
+++ b/sys/arch/alpha/alpha/cpu.c        Wed Nov 22 08:39:46 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.59 2000/11/19 19:18:19 thorpej Exp $ */
+/* $NetBSD: cpu.c,v 1.60 2000/11/22 08:39:47 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -66,8 +66,9 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.59 2000/11/19 19:18:19 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.60 2000/11/22 08:39:47 thorpej Exp $");
 
+#include "opt_ddb.h"
 #include "opt_multiprocessor.h"
 
 #include <sys/param.h>
@@ -481,9 +482,6 @@
 void
 cpu_pause_resume(u_long cpu_id, int pause)
 {
-#if 1
-       return;
-#else
        u_long cpu_mask = (1UL << cpu_id);
 
        if (pause) {
@@ -491,7 +489,6 @@
                alpha_send_ipi(cpu_id, ALPHA_IPI_PAUSE);
        } else
                atomic_clearbits_ulong(&cpus_paused, cpu_mask);
-#endif
 }
 
 void
@@ -509,38 +506,21 @@
 }
 
 void
-cpu_halt_secondary(cpu_id)
-       u_long cpu_id;
+cpu_halt(void)
 {
-       long timeout;
-       u_long cpumask = (1UL << cpu_id);
+       struct cpu_info *ci = curcpu();
+       u_long cpu_id = cpu_number();
+       struct pcs *pcsp = LOCATE_PCS(hwrpb, cpu_id);
 
-#ifdef DIAGNOSTIC
-       if (cpu_id >= hwrpb->rpb_pcs_cnt ||
-           cpu_info[cpu_id].ci_softc == NULL)
-               panic("cpu_halt_secondary: bogus cpu_id");
-#endif
+       printf("%s: shutting down...\n", ci->ci_softc->sc_dev.dv_xname);
 
-       alpha_mb();
-       if ((cpus_running & cpumask) == 0) {
-               /* Processor not running. */
-               return;
-       }
-
-       /* Send the HALT IPI to the secondary. */
-       alpha_send_ipi(cpu_id, ALPHA_IPI_HALT);
+       pcsp->pcs_flags &= ~(PCS_RC | PCS_HALT_REQ);
+       pcsp->pcs_flags |= PCS_HALT_STAY_HALTED;
 
-       /* ...and wait for it to shut down. */
-       for (timeout = 10000; timeout != 0; timeout--) {
-               alpha_mb();
-               if ((cpus_running & cpumask) == 0)
-                       return;
-               delay(1000);
-       }
+       atomic_clearbits_ulong(&cpus_running, (1UL << cpu_id));
 
-       /* Erk, secondary failed to halt. */
-       printf("WARNING: %s (ID %lu) failed to halt\n",
-           cpu_info[cpu_id].ci_softc->sc_dev.dv_xname, cpu_id);
+       alpha_pal_halt();
+       /* NOTREACHED */
 }
 
 void
@@ -644,4 +624,37 @@
        hwrpb->rpb_txrdy = 0;
        alpha_mb();
 }
+
+#if defined(DDB)
+
+#include <ddb/db_output.h>
+#include <machine/db_machdep.h>
+
+/*
+ * Dump CPU information from DDB.
+ */
+void
+cpu_debug_dump(void)
+{
+       struct cpu_info *ci;
+       int i;
+
+       db_printf("addr         dev     id      flags   ipis    curproc         fpcurproc\n");
+       for (i = 0; i < ALPHA_MAXPROCS; i++) {
+               ci = &cpu_info[i];
+               if (ci->ci_softc == NULL)
+                       continue;
+               db_printf("%p   %s      %lu     %lx     %lx     %p      %p\n",
+                   ci,
+                   ci->ci_softc->sc_dev.dv_xname,
+                   ci->ci_cpuid,
+                   ci->ci_flags,
+                   ci->ci_ipis,
+                   ci->ci_curproc,
+                   ci->ci_fpcurproc);
+       }
+}
+
+#endif /* DDB */
+
 #endif /* MULTIPROCESSOR */
diff -r 36d9cc1fab36 -r 3ca906b0bf43 sys/arch/alpha/alpha/db_interface.c
--- a/sys/arch/alpha/alpha/db_interface.c       Wed Nov 22 07:44:01 2000 +0000
+++ b/sys/arch/alpha/alpha/db_interface.c       Wed Nov 22 08:39:46 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: db_interface.c,v 1.11 2000/11/22 02:25:52 thorpej Exp $ */
+/* $NetBSD: db_interface.c,v 1.12 2000/11/22 08:39:47 thorpej Exp $ */
 
 /* 
  * Mach Operating System
@@ -48,10 +48,11 @@
  */
 
 #include "opt_ddb.h"
+#include "opt_multiprocessor.h"
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.11 2000/11/22 02:25:52 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.12 2000/11/22 08:39:47 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -62,6 +63,7 @@
 
 #include <dev/cons.h>
 
+#include <machine/alpha.h>
 #include <machine/db_machdep.h>
 #include <machine/pal.h>
 #include <machine/prom.h>
@@ -88,12 +90,14 @@
 
 db_regs_t *ddb_regp;
 
-void   db_mach_halt __P((db_expr_t, int, db_expr_t, char *));
-void   db_mach_reboot __P((db_expr_t, int, db_expr_t, char *));
+#if defined(MULTIPROCESSOR)
+void   db_mach_cpu __P((db_expr_t, int, db_expr_t, char *));
+#endif
 
 struct db_command db_machine_cmds[] = {
-       { "halt",       db_mach_halt,   0,      0 },
-       { "reboot",     db_mach_reboot, 0,      0 },
+#if defined(MULTIPROCESSOR)
+       { "cpu",        db_mach_cpu,    0,      0 },
+#endif
        { (char *)0, },
 };
 
@@ -168,6 +172,7 @@
        unsigned long a0, a1, a2, entry;
        db_regs_t *regs;
 {
+       struct cpu_info *ci = curcpu();
        int s;
 
        if (entry != ALPHA_KENTRY_IF ||
@@ -190,7 +195,7 @@
         */
 
        /* Our register state is simply the trapframe. */
-       ddb_regp = regs;
+       ddb_regp = ci->ci_db_regs = regs;
 
        s = splhigh();
 
@@ -204,7 +209,7 @@
 
        splx(s);
 
-       ddb_regp = NULL;
+       ddb_regp = ci->ci_db_regs = NULL;
 
        /*
         * Tell caller "We HAVE handled the trap."
@@ -266,31 +271,52 @@
 /*
  * Alpha-specific ddb commands:
  *
- *     halt            set halt bit in rpb and halt
- *     reboot          set reboot bit in rpb and halt
+ *     cpu             tell DDB to use register state from the
+ *                     CPU specified (MULTIPROCESSOR)
  */
 
+#if defined(MULTIPROCESSOR)
 void
-db_mach_halt(addr, have_addr, count, modif)
+db_mach_cpu(addr, have_addr, count, modif)
        db_expr_t       addr;
        int             have_addr;
        db_expr_t       count;
        char *          modif;
 {
+       struct cpu_info *ci;
 
-       prom_halt(1);
-}
+       if (have_addr == 0) {
+               cpu_debug_dump();
+               return;
+       }
+
+       if (addr < 0 || addr >= ALPHA_MAXPROCS) {
+               db_printf("CPU %ld out of range\n", addr);
+               return;
+       }
 
-void
-db_mach_reboot(addr, have_addr, count, modif)
-       db_expr_t       addr;
-       int             have_addr;
-       db_expr_t       count;
-       char *          modif;
-{
+       ci = &cpu_info[addr];
+       if (ci->ci_softc == NULL) {
+               db_printf("CPU %ld is not configured\n", addr);
+               return;
+       }
 
-       prom_halt(0);
+       if (ci != curcpu()) {
+               if ((ci->ci_flags & CPUF_PAUSED) == 0) {
+                       db_printf("CPU %ld not paused\n", addr);
+                       return;
+               }
+       }
+
+       if (ci->ci_db_regs == NULL) {
+               db_printf("CPU %ld has no register state\n", addr);
+               return;
+       }
+
+       db_printf("Using CPU %ld\n", addr);
+       ddb_regp = ci->ci_db_regs;
 }
+#endif /* MULTIPROCESSOR */
 
 /*
  * Map Alpha register numbers to trapframe/db_regs_t offsets.
diff -r 36d9cc1fab36 -r 3ca906b0bf43 sys/arch/alpha/alpha/interrupt.c
--- a/sys/arch/alpha/alpha/interrupt.c  Wed Nov 22 07:44:01 2000 +0000
+++ b/sys/arch/alpha/alpha/interrupt.c  Wed Nov 22 08:39:46 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: interrupt.c,v 1.53 2000/11/20 19:24:36 thorpej Exp $ */
+/* $NetBSD: interrupt.c,v 1.54 2000/11/22 08:39:48 thorpej Exp $ */
 



Home | Main Index | Thread Index | Old Index