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