PERFORCE change 48960 for review

Marcel Moolenaar marcel at FreeBSD.org
Sun Mar 14 00:15:01 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=48960

Change 48960 by marcel at marcel_nfs on 2004/03/14 00:14:43

	The beginnings of a new gdb backend. The meat is machine
	independent and shared by all platforms. The machine
	dependent bits mostly relate to registers and will have
	the necessary callbacks.
	
	The backend will support threads if all goes well. That
	way one can easily list all kernel threads in gdb and
	print backtraces and dump registers for them.
	
	While on the subject, implement support for a debug port
	on sparc64. Since there's no facility for specifying a
	debug port in the OF, we need to use environment variables.
	On sparc64, one needs to set debug_port to some OF device
	name or predefined alias (e.g set debug_port=ttyb).

Affected files ...

.. //depot/projects/gdb/sys/conf/files#7 edit
.. //depot/projects/gdb/sys/conf/files.i386#5 edit
.. //depot/projects/gdb/sys/dev/uart/uart_cpu_sparc64.c#2 edit
.. //depot/projects/gdb/sys/gdb/gdb.h#4 edit
.. //depot/projects/gdb/sys/gdb/gdb_int.h#1 add
.. //depot/projects/gdb/sys/gdb/gdb_main.c#3 edit
.. //depot/projects/gdb/sys/gdb/gdb_packet.c#1 add
.. //depot/projects/gdb/sys/i386/i386/gdb_machdep.c#1 add
.. //depot/projects/gdb/sys/i386/i386/i386-gdbstub.c#2 delete
.. //depot/projects/gdb/sys/i386/include/gdb_machdep.h#1 add

Differences ...

==== //depot/projects/gdb/sys/conf/files#7 (text+ko) ====

@@ -956,7 +956,8 @@
 fs/unionfs/union_subr.c	optional unionfs
 fs/unionfs/union_vfsops.c	optional unionfs
 fs/unionfs/union_vnops.c	optional unionfs
-gdb/gdb_main.c			optional gdb
+gdb/gdb_main.c			optional	gdb
+gdb/gdb_packet.c		optional	gdb
 geom/bde/g_bde.c		optional geom_bde
 geom/bde/g_bde_crypt.c		optional geom_bde
 geom/bde/g_bde_lock.c		optional geom_bde

==== //depot/projects/gdb/sys/conf/files.i386#5 (text+ko) ====

@@ -204,8 +204,8 @@
 i386/i386/elan-mmcr.c		optional	cpu_soekris
 i386/i386/elf_machdep.c		standard
 i386/i386/exception.s		standard
+i386/i386/gdb_machdep.c		optional	gdb
 i386/i386/geode.c		optional	cpu_geode
-i386/i386/i386-gdbstub.c	optional	gdb
 i386/i386/i686_mem.c		standard
 i386/i386/identcpu.c		standard
 i386/i386/in_cksum.c		optional	inet

==== //depot/projects/gdb/sys/dev/uart/uart_cpu_sparc64.c#2 (text+ko) ====

@@ -39,8 +39,6 @@
 #include <dev/uart/uart.h>
 #include <dev/uart/uart_cpu.h>
 
-static phandle_t uart_cpu_getdev_keyboard(phandle_t root);
-
 static struct bus_space_tag bst_store[3];
 
 static int
@@ -67,21 +65,83 @@
 	return ((b1->bsh == b2->bsh) ? 1 : 0);
 }
 
+/*
+ * Get the address of the UART that is selected as the console, if the
+ * console is an UART of course. Note that we enforce that both stdin and
+ * stdout are selected. For weird configurations, use ofw_console(4).
+ * Note that the currently active console (i.e. /chosen/stdout and
+ * /chosen/stdin) may not be the same as the device selected in the
+ * environment (ie /options/output-device and /options/input-device) because
+ * the user may have changed the environment. In that case I would assume
+ * that the user expects that FreeBSD uses the new console setting. There's
+ * no choice, really.
+ */
 static phandle_t
-uart_cpu_getdev_keyboard(phandle_t root)
+uart_cpu_getdev_console(phandle_t options, char *dev, size_t devsz)
+{
+	char buf[32];
+	phandle_t input;
+
+	if (OF_getprop(options, "input-device", dev, devsz) == -1)
+		return (-1);
+	if ((input = OF_finddevice(dev)) == -1)
+		return (-1);
+	if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
+		return (-1);
+	if (strcmp(buf, "serial") != 0)
+		return (-1);
+	if (OF_getprop(options, "output-device", buf, sizeof(buf)) == -1)
+		return (-1);
+	if (OF_finddevice(buf) != input)
+		return (-1);
+	return (input);
+}
+
+/*
+ * Get the address of the UART that's selected as the debug port. Since
+ * there's no place for this in the OF, we use the kernel environment.
+ * The environment variable is "debug_port" and its value is the device
+ * name (or an alias) known by the OF.
+ */
+static phandle_t
+uart_cpu_getdev_dbgport(phandle_t options, char *dev, size_t devsz)
+{
+	char buf[32];
+	phandle_t input;
+
+	if (!getenv_string("debug_port", dev, devsz))
+		return (-1);
+	if ((input = OF_finddevice(dev)) == -1)
+		return (-1);
+	if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
+		return (-1);
+	if (strcmp(buf, "serial") != 0)
+		return (-1);
+	/* Rudimentary sanity check: the debug port cannot be the console. */
+	if (OF_getprop(options, "input-device", buf, sizeof(buf)) == -1)
+		return (-1);
+	if (OF_finddevice(buf) == input)
+		return (-1);
+	return (input);
+}
+
+static phandle_t
+uart_cpu_getdev_keyboard(phandle_t root, char *dev, size_t devsz)
 {
-	phandle_t child;
-	phandle_t node;
 	char buf[32];
+	phandle_t child, node;
 
-	for (child = OF_child(root); child != 0 && child != -1;
-	    child = OF_peer(child)) {
+	child = OF_child(root);
+	while (child != 0 && child != -1) {
 		if (OF_getprop(child, "device_type", buf, sizeof(buf)) != -1 &&
 		    !strcmp(buf, "serial") &&
-		    OF_getprop(child, "keyboard", buf, sizeof(buf)) != -1)
+		    OF_getprop(child, "keyboard", buf, sizeof(buf)) != -1) {
+			OF_getprop(child, "name", dev, devsz);
 			return (child);
-		if ((node = uart_cpu_getdev_keyboard(child)) != -1)
+		}
+		if ((node = uart_cpu_getdev_keyboard(child, dev, devsz)) != -1)
 			return (node);
+		child = OF_peer(child);
 	}
 	return (-1);
 }
@@ -90,47 +150,29 @@
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
 	char buf[32], dev[32], compat[32];
-	phandle_t input, options, output;
+	phandle_t input, options;
 	bus_addr_t addr;
 	int baud, bits, error, space, stop;
 	char flag, par;
 
-	/*
-	 * Get the address of the UART that is selected as the console, if
-	 * the console is an UART of course. Note that we enforce that both
-	 * stdin and stdout are selected. For weird configurations, use
-	 * ofw_console(4).
-	 * Note that the currently active console (ie /chosen/stdout and
-	 * /chosen/stdin) may not be the same as the device selected in the
-	 * environment (ie /options/output-device and /options/input-device)
-	 * because the user may have changed the environment. In that case
-	 * I would assume that the user expects that FreeBSD uses the new
-	 * console setting. There's choice choice, really.
-	 */
-	 if ((options = OF_finddevice("/options")) == -1)
-		 return (ENXIO);
-	if (devtype == UART_DEV_CONSOLE) {
-		if (OF_getprop(options, "input-device", dev, sizeof(dev)) == -1)
-			return (ENXIO);
-		if ((input = OF_finddevice(dev)) == -1)
-			return (ENXIO);
-		if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1)
-			return (ENXIO);
-		if (strcmp(buf, "serial"))
-			return (ENODEV);
-		if (OF_getprop(options, "output-device", buf, sizeof(buf))
-		    == -1)
-			return (ENXIO);
-		if ((output = OF_finddevice(buf)) == -1)
-			return (ENXIO);
-		if (input != output)
-			return (ENXIO);
-	} else if (devtype == UART_DEV_KEYBOARD) {
-		if ((input = uart_cpu_getdev_keyboard(OF_peer(0))) == -1)
-			return (ENXIO);
-	} else
-		return (ENODEV);
-
+	if ((options = OF_finddevice("/options")) == -1)
+		return (ENXIO);
+	switch (devtype) {
+	case UART_DEV_CONSOLE:
+		input = uart_cpu_getdev_console(options, dev, sizeof(dev));
+		break;
+	case UART_DEV_DBGPORT:
+		input = uart_cpu_getdev_dbgport(options, dev, sizeof(dev));
+		break;
+	case UART_DEV_KEYBOARD:
+		input = uart_cpu_getdev_keyboard(OF_peer(0), dev, sizeof(dev));
+		break;
+	default:
+		input = -1;
+		break;
+	}
+	if (input == -1)
+		return (ENXIO);
 	error = OF_decode_addr(input, &space, &addr);
 	if (error)
 		return (error);

==== //depot/projects/gdb/sys/gdb/gdb.h#4 (text+ko) ====

@@ -59,6 +59,10 @@
 	};								\
 	DATA_SET(gdb_dbgport_set, name##_gdb_dbgport)
 
-extern struct gdb_dbgport *gdb_cur;
+struct trapframe;
+
+int gdb_cpu_regsz(int);
+uintmax_t gdb_cpu_regval(int, struct trapframe *);
+int gdb_cpu_signal(int, int);
 
 #endif /* !_GDB_GDB_H_ */

==== //depot/projects/gdb/sys/gdb/gdb_main.c#3 (text+ko) ====

@@ -31,8 +31,12 @@
 #include <sys/systm.h>
 #include <sys/kdb.h>
 #include <sys/kernel.h>
+#include <sys/pcpu.h>
+
+#include <machine/gdb_machdep.h>
 
 #include <gdb/gdb.h>
+#include <gdb/gdb_int.h>
 
 static dbbe_init_f gdb_init;
 static dbbe_trap_f gdb_trap;
@@ -42,7 +46,7 @@
 GDB_DBGPORT(null, NULL, NULL, NULL, NULL, NULL, NULL);
 SET_DECLARE(gdb_dbgport_set, struct gdb_dbgport);
 
-static struct gdb_dbgport *gdb_cur = NULL;
+struct gdb_dbgport *gdb_cur = NULL;
 
 static int
 gdb_init(void)
@@ -81,5 +85,30 @@
 static int
 gdb_trap(int type, int code, struct trapframe *tf)
 {
+	const char *p;
+
+	/*
+	 * Send a T packet. We currently do not support watchpoints (the
+	 * awatch, rwatch or watch elements).
+	 */
+	gdb_tx_begin('T');
+	gdb_tx_hex(gdb_cpu_signal(type, code), 2);
+	gdb_tx_reg(GDB_REG_PC, tf);
+	gdb_tx_char(';');
+	gdb_tx_reg(GDB_REG_FP, tf);
+	gdb_tx_char(';');
+	gdb_tx_reg(GDB_REG_SP, tf);
+	gdb_tx_char(';');
+	gdb_tx_str("thread:");
+	gdb_tx_varhex((uintptr_t)curthread);
+	gdb_tx_end();			/* XXX check error condition. */
+
+	while (gdb_rx_begin() == 0) {
+		p = gdb_rxp;
+		switch (gdb_rx_char()) {
+		case 'c':	/* continue */
+			return (1);
+		}
+	}
 	return (0);
 }


More information about the p4-projects mailing list