Module Name:    src
Committed By:   skrll
Date:           Tue Sep 27 08:18:21 UTC 2022

Modified Files:
        src/sys/arch/riscv/conf: GENERIC files.riscv
        src/sys/arch/riscv/include: db_machdep.h
        src/sys/arch/riscv/riscv: db_machdep.c db_trace.c locore.S trap.c
Added Files:
        src/sys/arch/riscv/riscv: db_interface.c

Log Message:
Basic ddb and backtrace support.

[   1.0000000] panic: kernel diagnostic assertion "msgbufaddr != 0" failed: 
file "/home/nick/netbsd/nbcvs/src/sys/arch/riscv/riscv/riscv_machdep.c", line 
564
[   1.0000000] cpu0: Begin traceback...
[   1.0000000] trace fp ffffffc000801dd0
[   1.0000000] fp ffffffc000801e10 ?() at ffffffc0001eee98
[   1.0000000] fp ffffffc000801e30 ?() at ffffffc0002ad984
[   1.0000000] fp ffffffc000801ee0 ?() at ffffffc000005430
[   1.0000000] cpu0: End traceback...
[   1.0000000] Trapframe @ 0xffffffc000801cb0 (cause=3 (breakpoint), 
status=0x100, pc=0xffffffc0000007e4, va=0):
[   1.0000000] ra =0xffffffc0001eee9c, sp =0xffffffc000801dd0, gp 
=0xffffffc0006a8f40, tp =                 0
[   1.0000000] s0 =0xffffffc000600ac0, s1 =            0x1000, s2 
=0xffffffc000438df0, s3 =0xffffffc000801d80
[   1.0000000] s4 =0xffffffc0001eed78, s5 =0xffffffc0006d55f8, s6 
=0xffffffc000801d88, s7 =0xffffffc0006dfdb8
[   1.0000000] s8 =0xffffffc000428c18, s9 =0xffffffc000801dd0, 
s10=0xffffffc0000a3822, s11=0xffffffc0006d55f8
[   1.0000000] a0 =              0x17, a1 =               0xa, a2 =             
    0, a3 =0xffffffc00041f658
[   1.0000000] a4 =                 0, a5 =               0x1, a5 =             
    0, a7 =               0x1
[   1.0000000] t0 =0xffffffc0006dfe30, t1 =0xffffffc000801bb8, t2 
=0xffffffc000803000, t3 =              0x75
[   1.0000000] t4 =                 0, t5 =              0x63, t6 =             
  0x1
[   1.0000000] kernel: breakpoint
Stopped in pid 0.0 (system) at  ffffffc0000007e4:       c.ebreak
db>


To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/riscv/conf/GENERIC
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/riscv/conf/files.riscv
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/riscv/include/db_machdep.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/riscv/riscv/db_interface.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/riscv/riscv/db_machdep.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/riscv/riscv/db_trace.c
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/riscv/riscv/locore.S
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/riscv/riscv/trap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/riscv/conf/GENERIC
diff -u src/sys/arch/riscv/conf/GENERIC:1.14 src/sys/arch/riscv/conf/GENERIC:1.15
--- src/sys/arch/riscv/conf/GENERIC:1.14	Sun Sep 11 15:31:11 2022
+++ src/sys/arch/riscv/conf/GENERIC	Tue Sep 27 08:18:21 2022
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.14 2022/09/11 15:31:11 skrll Exp $
+# $NetBSD: GENERIC,v 1.15 2022/09/27 08:18:21 skrll Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@ include	"arch/riscv/conf/std.riscv64"
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"GENERIC-$Revision: 1.14 $"
+#ident 		"GENERIC-$Revision: 1.15 $"
 
 maxusers	64		# estimated number of users
 
@@ -74,7 +74,7 @@ options 	DIAGNOSTIC	# inexpensive kernel
 # Because gcc omits the frame pointer for any -O level, the line below
 # is needed to make backtraces in DDB work.
 #
-#makeoptions	COPTS="-O2 -fno-omit-frame-pointer"
+makeoptions	COPTS="-O2 -fno-omit-frame-pointer"
 makeoptions	COPY_SYMTAB=1
 options 	DDB		# in-kernel debugger
 #options	DDB_COMMANDONENTER="bt"	# execute command when ddb is entered

Index: src/sys/arch/riscv/conf/files.riscv
diff -u src/sys/arch/riscv/conf/files.riscv:1.9 src/sys/arch/riscv/conf/files.riscv:1.10
--- src/sys/arch/riscv/conf/files.riscv:1.9	Mon Sep 19 09:15:01 2022
+++ src/sys/arch/riscv/conf/files.riscv	Tue Sep 27 08:18:21 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: files.riscv,v 1.9 2022/09/19 09:15:01 skrll Exp $
+#	$NetBSD: files.riscv,v 1.10 2022/09/27 08:18:21 skrll Exp $
 #
 
 maxpartitions	16
@@ -21,6 +21,7 @@ file	arch/riscv/riscv/bus_space_notimpl.
 file	arch/riscv/riscv/clock_machdep.c
 file	arch/riscv/riscv/core_machdep.c		coredump
 file	arch/riscv/riscv/cpu_subr.c
+file	arch/riscv/riscv/db_interface.c		ddb
 file	arch/riscv/riscv/db_disasm.c		ddb
 file	arch/riscv/riscv/db_machdep.c		ddb | kgdb
 file	arch/riscv/riscv/db_trace.c		ddb

Index: src/sys/arch/riscv/include/db_machdep.h
diff -u src/sys/arch/riscv/include/db_machdep.h:1.5 src/sys/arch/riscv/include/db_machdep.h:1.6
--- src/sys/arch/riscv/include/db_machdep.h:1.5	Tue May 18 06:42:11 2021
+++ src/sys/arch/riscv/include/db_machdep.h	Tue Sep 27 08:18:21 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: db_machdep.h,v 1.5 2021/05/18 06:42:11 skrll Exp $ */
+/* $NetBSD: db_machdep.h,v 1.6 2022/09/27 08:18:21 skrll Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -43,7 +43,8 @@ typedef	long		db_expr_t;	/* expression -
 typedef struct trapframe db_regs_t;
 
 extern const uint32_t __cpu_Debugger_insn[1];
-#define	DDB_REGS	(curcpu()->ci_ddb_regs)
+extern db_regs_t ddb_regs;
+#define	DDB_REGS	(&ddb_regs)
 
 #define	PC_REGS(tf)	((tf)->tf_pc)
 
@@ -87,7 +88,7 @@ db_addr_t	db_disasm_insn(uint32_t, db_ad
  * Entrypoints to DDB for kernel, keyboard drivers, init hook
  */
 void 	kdb_kbd_trap(db_regs_t *);
-int 	kdb_trap(int, struct trapframe *);
+int 	kdb_trap(int, db_regs_t *);
 
 static inline void
 db_set_ddb_regs(int type, struct trapframe *tf)
@@ -130,4 +131,6 @@ void db_resume_others(void);
 #define	DB_MACHINE_COMMANDS
 #endif
 
+void dump_trapframe(const struct trapframe *, void (*)(const char *, ...) __printflike(1, 2));
+
 #endif	/* _RISCV_DB_MACHDEP_H_ */

Index: src/sys/arch/riscv/riscv/db_machdep.c
diff -u src/sys/arch/riscv/riscv/db_machdep.c:1.8 src/sys/arch/riscv/riscv/db_machdep.c:1.9
--- src/sys/arch/riscv/riscv/db_machdep.c:1.8	Sun May 23 23:22:55 2021
+++ src/sys/arch/riscv/riscv/db_machdep.c	Tue Sep 27 08:18:21 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: db_machdep.c,v 1.8 2021/05/23 23:22:55 dholland Exp $	*/
+/*	$NetBSD: db_machdep.c,v 1.9 2022/09/27 08:18:21 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__RCSID("$NetBSD: db_machdep.c,v 1.8 2021/05/23 23:22:55 dholland Exp $");
+__RCSID("$NetBSD: db_machdep.c,v 1.9 2022/09/27 08:18:21 skrll Exp $");
 
 #include <sys/param.h>
 
@@ -44,8 +44,6 @@ __RCSID("$NetBSD: db_machdep.c,v 1.8 202
 #include <ddb/db_variables.h>
 #include <ddb/db_output.h>
 
-int db_active = 0;
-
 static int db_rw_ddbreg(const struct db_variable *, db_expr_t *, int);
 
 const struct db_variable db_regs[] = {

Index: src/sys/arch/riscv/riscv/db_trace.c
diff -u src/sys/arch/riscv/riscv/db_trace.c:1.2 src/sys/arch/riscv/riscv/db_trace.c:1.3
--- src/sys/arch/riscv/riscv/db_trace.c:1.2	Wed Nov  4 07:09:46 2020
+++ src/sys/arch/riscv/riscv/db_trace.c	Tue Sep 27 08:18:21 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: db_trace.c,v 1.2 2020/11/04 07:09:46 skrll Exp $	*/
+/*	$NetBSD: db_trace.c,v 1.3 2022/09/27 08:18:21 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -31,17 +31,224 @@
 
 #include <sys/cdefs.h>
 
-__RCSID("$NetBSD: db_trace.c,v 1.2 2020/11/04 07:09:46 skrll Exp $");
+__RCSID("$NetBSD: db_trace.c,v 1.3 2022/09/27 08:18:21 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 
 #include <riscv/db_machdep.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <ddb/db_access.h>
+#include <ddb/db_command.h>
+#include <ddb/db_output.h>
+#include <ddb/db_variables.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_proc.h>
+#include <ddb/db_lwp.h>
+#include <ddb/db_extern.h>
 #include <ddb/db_interface.h>
 
+#define MAXBACKTRACE	128	/* against infinite loop */
+#define TRACEFLAG_LOOKUPLWP	0x00000001
+
+__CTASSERT(VM_MIN_ADDRESS == 0);
+#define IN_USER_VM_ADDRESS(addr)	\
+	((addr) < VM_MAX_ADDRESS)
+#define IN_KERNEL_VM_ADDRESS(addr)	\
+	((VM_MIN_KERNEL_ADDRESS <= (addr)) && ((addr) < VM_MAX_KERNEL_ADDRESS))
+
+static bool __unused
+is_lwp(void *p)
+{
+	lwp_t *lwp;
+
+	for (lwp = db_lwp_first(); lwp != NULL; lwp = db_lwp_next(lwp)) {
+		if (lwp == p)
+			return true;
+	}
+	return false;
+}
+
+static const char *
+getlwpnamebysp(uint64_t sp)
+{
+#if defined(_KERNEL)
+	lwp_t *lwp;
+
+	for (lwp = db_lwp_first(); lwp != NULL; lwp = db_lwp_next(lwp)) {
+		uint64_t uarea = uvm_lwp_getuarea(lwp);
+		if ((uarea <= sp) && (sp < (uarea + USPACE))) {
+			return lwp->l_name;
+		}
+	}
+#endif
+	return "unknown";
+}
+
+static void
+pr_traceaddr(const char *prefix, uint64_t frame, uint64_t pc, int flags,
+    void (*pr)(const char *, ...) __printflike(1, 2))
+{
+	db_expr_t offset;
+	db_sym_t sym;
+	const char *name;
+
+	sym = db_search_symbol(pc, DB_STGY_ANY, &offset);
+	if (sym != DB_SYM_NULL) {
+		db_symbol_values(sym, &name, NULL);
+
+		if (flags & TRACEFLAG_LOOKUPLWP) {
+			(*pr)("%s %016" PRIx64 " %s %s() at %016" PRIx64,
+			    prefix, frame, getlwpnamebysp(frame), name, pc);
+		} else {
+			(*pr)("%s %016" PRIx64 " %s() at %016" PRIx64 " ",
+			    prefix, frame, name, pc);
+		}
+		db_printsym(pc, DB_STGY_PROC, pr);
+		(*pr)("\n");
+	} else {
+		if (flags & TRACEFLAG_LOOKUPLWP) {
+			(*pr)("%s %016" PRIx64 " %s ?() at %016" PRIx64 "\n",
+			    prefix, frame, getlwpnamebysp(frame), pc);
+		} else {
+			(*pr)("%s %016" PRIx64 " ?() at %016" PRIx64 "\n", prefix, frame, pc);
+		}
+	}
+}
+
 void
 db_stack_trace_print(db_expr_t addr, bool have_addr, db_expr_t count,
-    const char *modif, void (*pr)(const char *, ...))
+    const char *modif, void (*pr)(const char *, ...) __printflike(1, 2))
 {
-	/* TBD!! */
+	register_t ra, fp, lastra, lastfp;
+	struct trapframe *tf = NULL;
+	int flags = 0;
+	bool trace_user = false;
+	bool trace_thread = false;
+	bool trace_lwp = false;
+
+	for (; *modif != '\0'; modif++) {
+		switch (*modif) {
+		case 'a':
+			trace_lwp = true;
+			trace_thread = false;
+			break;
+		case 'l':
+			break;
+		case 't':
+			trace_thread = true;
+			trace_lwp = false;
+			break;
+		case 'u':
+			trace_user = true;
+			break;
+		case 'x':
+			flags |= TRACEFLAG_LOOKUPLWP;
+			break;
+		default:
+			pr("usage: bt[/ulx] [frame-address][,count]\n");
+			pr("       bt/t[ulx] [pid][,count]\n");
+			pr("       bt/a[ulx] [lwpaddr][,count]\n");
+			pr("\n");
+			pr("       /x      reverse lookup lwp name from sp\n");
+			return;
+		}
+	}
+
+#if defined(_KERNEL)
+	if (!have_addr) {
+		if (trace_lwp) {
+			addr = (db_expr_t)curlwp;
+		} else if (trace_thread) {
+			addr = curlwp->l_proc->p_pid;
+		} else {
+			tf = DDB_REGS;
+		}
+	}
+#endif
+
+	if (trace_thread) {
+		proc_t *pp, p;
+
+		if ((pp = db_proc_find((pid_t)addr)) == 0) {
+			(*pr)("trace: pid %d: not found\n", (int)addr);
+			return;
+		}
+		db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
+		addr = (db_addr_t)p.p_lwps.lh_first;
+		trace_thread = false;
+		trace_lwp = true;
+	}
+
+#if 0
+	/* "/a" is abbreviated? */
+	if (!trace_lwp && is_lwp(addr))
+		trace_lwp = true;
+#endif
+
+	if (trace_lwp) {
+		proc_t p;
+		struct lwp l;
+
+		db_read_bytes(addr, sizeof(l), (char *)&l);
+		db_read_bytes((db_addr_t)l.l_proc, sizeof(p), (char *)&p);
+
+#if defined(_KERNEL)
+		if (addr == (db_expr_t)curlwp) {
+			fp = (register_t)&DDB_REGS->tf_s0; /* s0 = fp */
+			tf = DDB_REGS;
+			(*pr)("trace: pid %d lid %d (curlwp) at tf %p\n",
+			    p.p_pid, l.l_lid, tf);
+		} else
+#endif
+		{
+			tf = l.l_md.md_ktf;
+			db_read_bytes((db_addr_t)&tf->tf_s0, sizeof(fp), (char *)&fp);
+			(*pr)("trace: pid %d lid %d at tf %p\n",
+			    p.p_pid, l.l_lid, tf);
+		}
+	} else if (tf == NULL) {
+		fp = addr;
+		pr("trace fp %016" PRIxREGISTER "\n", fp);
+	} else {
+		pr("trace tf %p\n", tf);
+	}
+
+	if (count > MAXBACKTRACE)
+		count = MAXBACKTRACE;
+
+	if (tf != NULL) {
+#if defined(_KERNEL)
+		(*pr)("---- trapframe %p (%zu bytes) ----\n",
+		    tf, sizeof(*tf));
+		dump_trapframe(tf, pr);
+		(*pr)("------------------------"
+		      "------------------------\n");
+
+#endif
+		lastfp = lastra = ra = fp = 0;
+		db_read_bytes((db_addr_t)&tf->tf_ra, sizeof(ra), (char *)&ra);
+		db_read_bytes((db_addr_t)&tf->tf_s0, sizeof(fp), (char *)&fp);
+
+		pr_traceaddr("fp", fp, ra - 4, flags, pr);
+	}
+	for (; (count > 0) && (fp != 0); count--) {
+
+		lastfp = fp;
+		fp = ra = 0;
+		/*
+		 * normal stack frame
+		 *  fp[-1]  saved fp(s0) value
+		 *  fp[-2]  saved ra value
+		 */
+		db_read_bytes(lastfp - 1 * sizeof(register_t), sizeof(ra), (char *)&ra);
+		db_read_bytes(lastfp - 2 * sizeof(register_t), sizeof(fp), (char *)&fp);
+
+		if (!trace_user && (IN_USER_VM_ADDRESS(ra) || IN_USER_VM_ADDRESS(fp)))
+			break;
+
+		pr_traceaddr("fp", fp, ra - 4, flags, pr);
+	}
 }

Index: src/sys/arch/riscv/riscv/locore.S
diff -u src/sys/arch/riscv/riscv/locore.S:1.25 src/sys/arch/riscv/riscv/locore.S:1.26
--- src/sys/arch/riscv/riscv/locore.S:1.25	Tue Sep 20 07:18:23 2022
+++ src/sys/arch/riscv/riscv/locore.S	Tue Sep 27 08:18:21 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.S,v 1.25 2022/09/20 07:18:23 skrll Exp $ */
+/* $NetBSD: locore.S,v 1.26 2022/09/27 08:18:21 skrll Exp $ */
 
 /*-
  * Copyright (c) 2014, 2022 The NetBSD Foundation, Inc.
@@ -363,6 +363,8 @@ vstart:
 	mv	a0, s0			// hartid
 	mv	a1, t0			// vdtb
 	//mv	a1, s1			// dtb (physical)
+
+	li	s0, 0			// zero frame pointer
 	call	_C_LABEL(init_riscv)	// do MD startup
 	tail	_C_LABEL(main)		// and transfer to main
 	/* No return from main */

Index: src/sys/arch/riscv/riscv/trap.c
diff -u src/sys/arch/riscv/riscv/trap.c:1.17 src/sys/arch/riscv/riscv/trap.c:1.18
--- src/sys/arch/riscv/riscv/trap.c:1.17	Wed Sep 21 07:07:34 2022
+++ src/sys/arch/riscv/riscv/trap.c	Tue Sep 27 08:18:21 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: trap.c,v 1.17 2022/09/21 07:07:34 skrll Exp $	*/
+/*	$NetBSD: trap.c,v 1.18 2022/09/27 08:18:21 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
 #define __PMAP_PRIVATE
 #define __UFETCHSTORE_PRIVATE
 
-__RCSID("$NetBSD: trap.c,v 1.17 2022/09/21 07:07:34 skrll Exp $");
+__RCSID("$NetBSD: trap.c,v 1.18 2022/09/27 08:18:21 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,7 +46,8 @@ __RCSID("$NetBSD: trap.c,v 1.17 2022/09/
 
 #include <uvm/uvm.h>
 
-#include <riscv/locore.h>
+#include <machine/locore.h>
+#include <machine/db_machdep.h>
 
 #define	MACHINE_ECALL_TRAP_MASK	(__BIT(CAUSE_MACHINE_ECALL))
 
@@ -177,7 +178,7 @@ copyoutstr(const void *kaddr, void *uadd
 	return error;
 }
 
-static void
+void
 dump_trapframe(const struct trapframe *tf, void (*pr)(const char *, ...))
 {
 	const char *causestr = "?";
@@ -425,9 +426,15 @@ cpu_trap(struct trapframe *tf, register_
 	} else if (fault_mask & MISALIGNED_TRAP_MASK) {
 		ok = trap_misalignment(tf, epc, status, cause, addr,
 		    usertrap_p, &ksi);
-	} else {
-		dump_trapframe(tf, printf);
-		panic("%s: unknown kernel trap", __func__);
+	} else if (fault_mask & BREAKPOINT_TRAP_MASK) {
+		if (!usertrap_p) {
+			dump_trapframe(tf, printf);
+#if defined(DDB)
+			kdb_trap(cause, tf);
+			return;	/* KERN */
+#endif
+			panic("%s: unknown kernel trap", __func__);
+		}
 	}
 
 	if (usertrap_p) {

Added files:

Index: src/sys/arch/riscv/riscv/db_interface.c
diff -u /dev/null src/sys/arch/riscv/riscv/db_interface.c:1.1
--- /dev/null	Tue Sep 27 08:18:21 2022
+++ src/sys/arch/riscv/riscv/db_interface.c	Tue Sep 27 08:18:21 2022
@@ -0,0 +1,248 @@
+/*	$NetBSD: db_interface.c,v 1.1 2022/09/27 08:18:21 skrll Exp $	*/
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  software.distribut...@cs.cmu.edu
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.1 2022/09/27 08:18:21 skrll Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_multiprocessor.h"
+#include "opt_ddb.h"
+#include "opt_kgdb.h"
+#endif
+
+#define __PMAP_PRIVATE
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <sys/atomic.h>
+#include <sys/cpu.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/systm.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <dev/cons.h>
+
+#include <machine/db_machdep.h>
+
+#include <ddb/db_access.h>
+#include <ddb/db_user.h>
+#ifndef KGDB
+#include <ddb/db_command.h>
+#include <ddb/db_output.h>
+#include <ddb/db_sym.h>
+#include <ddb/db_extern.h>
+#include <ddb/db_interface.h>
+#include <ddb/db_lex.h>
+#include <ddb/db_run.h>	/* for db_continue_cmd() proto */
+#endif
+
+#define NOCPU   ~0
+volatile u_int ddb_cpu = NOCPU;
+
+int		db_active = 0;
+
+#ifdef _KERNEL
+db_regs_t	ddb_regs;
+#endif
+
+#ifdef MULTIPROCESSOR
+static void db_mach_cpu_cmd(db_expr_t, bool, db_expr_t, const char *);
+#endif
+
+void db_tlbdump_cmd(db_expr_t, bool, db_expr_t, const char *);
+void db_kvtophys_cmd(db_expr_t, bool, db_expr_t, const char *);
+
+paddr_t kvtophys(vaddr_t);
+
+#ifdef _KERNEL
+
+#ifndef KGDB
+int
+kdb_trap(int type, db_regs_t *regs)
+{
+	int s;
+
+	switch (type) {
+	case CAUSE_BREAKPOINT:	/* breakpoint */
+		printf("kernel: breakpoint\n");
+		break;
+	case -1:		/* keyboard interrupt */
+		printf("kernel: kdbint trap\n");
+		break;
+	default:
+		printf("kernel: cause %d\n", type);
+		if (db_recover != 0) {
+			db_error("Faulted in DDB; continuing...\n");
+			/*NOTREACHED*/
+		}
+		break;
+	}
+
+	s = splhigh();
+
+#if defined(MULTIPROCESSOR)
+	bool first_in_ddb = false;
+	const u_int cpu_me = cpu_number();
+	const u_int old_ddb_cpu = atomic_cas_uint(&ddb_cpu, NOCPU, cpu_me);
+	if (old_ddb_cpu == NOCPU) {
+		first_in_ddb = true;
+		cpu_pause_others();
+	} else {
+		if (old_ddb_cpu != cpu_me) {
+			KASSERT(cpu_is_paused(cpu_me));
+			cpu_pause(regs);
+			splx(s);
+			return 1;
+		}
+	}
+	KASSERT(! cpu_is_paused(cpu_me));
+#endif
+
+	ddb_regs = *regs;
+	db_active++;
+	cnpollc(1);
+	db_trap(type, 0 /*code*/);
+	cnpollc(0);
+	db_active--;
+	*regs = ddb_regs;
+
+#if defined(MULTIPROCESSOR)
+	if (atomic_cas_uint(&ddb_cpu, cpu_me, NOCPU) == cpu_me) {
+		cpu_resume_others();
+	} else {
+		cpu_resume(ddb_cpu);
+		if (first_in_ddb)
+			cpu_pause(regs);
+	}
+#endif
+
+	splx(s);
+	return 1;
+}
+#endif	/* !KGDB */
+
+
+#ifndef KGDB
+void
+db_tlbdump_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
+	       const char *modif)
+{
+}
+
+void
+db_kvtophys_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
+		const char *modif)
+{
+
+	if (!have_addr)
+		return;
+}
+
+
+static void
+db_mach_reset_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
+		const char *modif)
+{
+}
+
+
+const struct db_command db_machine_command_table[] = {
+#ifdef MULTIPROCESSOR
+	{ DDB_ADD_CMD("cpu",	db_mach_cpu_cmd,	0,
+	  "switch to another cpu", "cpu#", NULL) },
+#endif
+	{ DDB_ADD_CMD("kvtop",	db_kvtophys_cmd,	0,
+		"Print the physical address for a given kernel virtual address",
+		"address",
+		"   address:\tvirtual address to look up") },
+	{ DDB_ADD_CMD("reset", 	db_mach_reset_cmd,	CS_NOREPEAT,
+		"Initiate hardware reset",
+		NULL, NULL) },
+	{ DDB_ADD_CMD("tlb",	db_tlbdump_cmd,		0,
+		"Print out TLB entries. (only works with options DEBUG)",
+		NULL, NULL) },
+	{ DDB_END_CMD },
+};
+#endif	/* !KGDB */
+
+#ifdef MULTIPROCESSOR
+
+bool
+ddb_running_on_this_cpu_p(void)
+{
+	return ddb_cpu == cpu_number();
+}
+
+bool
+ddb_running_on_any_cpu_p(void)
+{
+	return ddb_cpu != NOCPU;
+}
+
+void
+db_resume_others(void)
+{
+	u_int cpu_me = cpu_number();
+
+	if (atomic_cas_uint(&ddb_cpu, cpu_me, NOCPU) == cpu_me)
+		cpu_resume_others();
+}
+
+static void
+db_mach_cpu_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
+{
+	CPU_INFO_ITERATOR cii;
+	struct cpu_info *ci;
+
+	if (!have_addr) {
+		cpu_debug_dump();
+		return;
+	}
+	for (CPU_INFO_FOREACH(cii, ci)) {
+		if (cpu_index(ci) == addr)
+			break;
+	}
+	if (ci == NULL) {
+		db_printf("CPU %ld not configured\n", (long)addr);
+		return;
+	}
+	if (ci != curcpu()) {
+		if (!cpu_is_paused(cpu_index(ci))) {
+			db_printf("CPU %ld not paused\n", (long)addr);
+			return;
+		}
+		(void)atomic_cas_uint(&ddb_cpu, cpu_number(), cpu_index(ci));
+		db_continue_cmd(0, false, 0, "");
+	}
+}
+#endif	/* MULTIPROCESSOR */
+
+#endif	/* _KERNEL */

Reply via email to