Subject: Re: kgdb in virtex port
To: Jean-Francois Boudreault <jfboudre@gel.ulaval.ca>
From: Jachym Holecek <freza@dspfpga.com>
List: port-powerpc
Date: 02/01/2007 21:20:42
Hello,
# Jean-Francois Boudreault 2007-01-31:
> I've been playing with Jachym's virtex port for a while. I added support
> for KGDB in your port but can't get it working right.
I think the code needs to work a bit differently, can you please try the
below (diff against -current sys/arch/{powerpc,evbppc/virtex})? It moves
most of kgdb handling to consinit(), xlcom() only provides leaf routines
(as was done with console support) and makes sure not to step on kgdb's
toe. As a side-effect, I've changed virtex_console_tag() to return bus
space tag by name and renamed the function to virtex_bus_space_tag().
A few general notes for the future:
* Please use unified diffs, it's easier on the eyes.
* Make sure your code works even when the options you're interested in
are turned off (be it defines or higher-level logic).
Thanks,
-- Jachym
Index: evbppc/virtex/consinit.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/virtex/consinit.c,v
retrieving revision 1.1
diff -d -p -u -r1.1 consinit.c
--- evbppc/virtex/consinit.c 2 Dec 2006 22:18:47 -0000 1.1
+++ evbppc/virtex/consinit.c 1 Feb 2007 20:17:00 -0000
@@ -49,12 +49,18 @@ __KERNEL_RCSID(0, "$NetBSD: consinit.c,v
#if NXLCOM > 0
extern struct consdev consdev_xlcom;
void xlcom_cninit(struct consdev *, bus_addr_t);
+#if defined(KGDB)
+void xlcom_kgdbinit(void);
+#endif
#endif
struct consdev *cn_tab = NULL;
bus_space_tag_t consdev_iot;
bus_space_handle_t consdev_ioh;
+bus_space_tag_t kgdb_iot;
+bus_space_handle_t kgdb_ioh;
+
/*
* Initialize the system console (hmm, as if anyone can see those panics).
@@ -68,10 +74,25 @@ consinit(void)
return;
/* Pick MD knowledge about console. */
- if (virtex_console_tag(CONS_NAME, &consdev_iot))
+ if (virtex_bus_space_tag(CONS_NAME, &consdev_iot))
panic("No bus space for %s console", CONS_NAME);
+#if defined(KGDB)
+ if (virtex_bus_space_tag(KGDB_NAME, &kgdb_iot))
+ panic("No bus space for %s kgdb", KGDB_NAME);
+#endif
+
#if NXLCOM > 0
+#if defined(KGDB)
+ if (strncmp("xlcom", KGDB_NAME, 5)) {
+ xlcom_kgdbinit();
+
+ /* Overtake console device, we're higher priority. */
+ if (strcmp(KGDB_NAME, CONS_NAME) == 0 &&
+ KGDB_ADDR == CONS_ADDR)
+ goto done;
+ }
+#endif
if (strncmp("xlcom", CONS_NAME, 5) == 0) {
cn_tab = &consdev_xlcom;
xlcom_cninit(cn_tab, CONS_ADDR);
@@ -82,5 +103,6 @@ consinit(void)
panic("No console"); /* XXX really panic? */
done:
+ /* If kgdb overtook console, cn_tab is NULL and dev/cons.c deals. */
initted = 1;
}
Index: evbppc/virtex/design_gsrd1.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/virtex/design_gsrd1.c,v
retrieving revision 1.1
diff -d -p -u -r1.1 design_gsrd1.c
--- evbppc/virtex/design_gsrd1.c 2 Dec 2006 22:18:47 -0000 1.1
+++ evbppc/virtex/design_gsrd1.c 1 Feb 2007 20:17:03 -0000
@@ -400,7 +400,7 @@ ll_dmac_intr_disestablish(int chan, void
}
int
-virtex_console_tag(const char *xname, bus_space_tag_t *bst)
+virtex_bus_space_tag(const char *xname, bus_space_tag_t *bst)
{
if (strncmp(xname, "xlcom", 5) == 0) {
*bst = &xlcom_bst;
Index: evbppc/virtex/design_gsrd2.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/virtex/design_gsrd2.c,v
retrieving revision 1.1
diff -d -p -u -r1.1 design_gsrd2.c
--- evbppc/virtex/design_gsrd2.c 2 Dec 2006 22:18:47 -0000 1.1
+++ evbppc/virtex/design_gsrd2.c 1 Feb 2007 20:17:03 -0000
@@ -442,7 +442,7 @@ ll_dmac_intr_disestablish(int chan, void
}
int
-virtex_console_tag(const char *xname, bus_space_tag_t *bst)
+virtex_bus_space_tag(const char *xname, bus_space_tag_t *bst)
{
if (strncmp(xname, "xlcom", 5) == 0) {
*bst = &opb_bst;
Index: evbppc/virtex/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/virtex/machdep.c,v
retrieving revision 1.1
diff -d -p -u -r1.1 machdep.c
--- evbppc/virtex/machdep.c 2 Dec 2006 22:18:47 -0000 1.1
+++ evbppc/virtex/machdep.c 1 Feb 2007 20:17:03 -0000
@@ -40,6 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v
#include "opt_ddb.h"
#include "opt_ipkdb.h"
#include "opt_virtex.h"
+#include "opt_kgdb.h"
#include <sys/param.h>
#include <sys/buf.h>
@@ -81,6 +82,9 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v
#include <ddb/db_extern.h>
#endif
+#if defined(KGDB)
+#include <sys/kgdb.h>
+#endif
/*
* Global variables used here and there
@@ -258,6 +262,12 @@ initppc(u_int startkernel, u_int endkern
if (boothowto & RB_KDB)
ipkdb_connect(0);
#endif
+#ifdef KGDB
+ /*
+ * Now trap to KGDB
+ */
+ kgdb_connect(1);
+#endif /* KGDB */
}
/*
@@ -424,6 +434,11 @@ cpu_reboot(int howto, char *what)
while(1)
Debugger();
#endif
+#ifdef KGDB
+ printf("dropping to kgdb\n");
+ while(1)
+ kgdb_connect(1);
+#endif
}
printf("rebooting\n\n");
@@ -455,6 +470,10 @@ cpu_reboot(int howto, char *what)
#ifdef DDB
while(1)
Debugger();
+#endif
+#ifdef KGDB
+ while(1)
+ kgdb_connect(1);
#else
while (1)
/* nothing */;
Index: evbppc/virtex/virtex.h
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/virtex/virtex.h,v
retrieving revision 1.1
diff -d -p -u -r1.1 virtex.h
--- evbppc/virtex/virtex.h 2 Dec 2006 22:18:47 -0000 1.1
+++ evbppc/virtex/virtex.h 1 Feb 2007 20:17:03 -0000
@@ -34,8 +34,15 @@
#ifdef _KERNEL_OPT
#include "opt_cons.h"
+#include "opt_kgdb.h"
#endif
+/*
+ * Console and kgdb name are just private tags for design_<foo>.c
+ * to identify the right device instance. Should be the same as
+ * device_xname() if there's only one UART available, though.
+ */
+
#ifndef CONS_NAME
#define CONS_NAME "xlcom0"
#endif
@@ -44,17 +51,36 @@
#define CONS_ADDR 0x00
#endif
+#if defined(KGDB)
+
+#ifndef KGDB_NAME
+#define KGDB_NAME CONS_NAME
+#endif
+
+#ifndef KGDB_ADDR
+#define KGDB_ADDR CONS_ADDR
+#endif
+
+#endif /* KGDB */
+
struct mem_region;
-/* Setup console bus space. */
-int virtex_console_tag(const char *, bus_space_tag_t *);
+/* Early bus space setup, for console and kgdb. Name is purely symbolic. */
+int virtex_bus_space_tag(const char *, bus_space_tag_t *);
/* Called after RAM is linear mapped. Translation & console still off. */
void virtex_machdep_init(vaddr_t, vsize_t, struct mem_region *,
struct mem_region *);
-/* For use by console. Tag is initialized before <foo>_cninit. */
-extern bus_space_tag_t consdev_iot;
-extern bus_space_handle_t consdev_ioh;
+/* For use by console and kgdb. Tag is initialized before <foo>_cninit. */
+extern bus_space_tag_t consdev_iot; /* consinit.c */
+extern bus_space_handle_t consdev_ioh; /* console device */
+
+#if defined(KGDB)
+
+extern bus_space_tag_t kgdb_iot; /* consinit.c */
+extern bus_space_handle_t kgdb_ioh; /* kgdb device */
+
+#endif /* KGDB */
#endif /*_VIRTEX_H_*/
Index: evbppc/virtex/dev/xlcom.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/virtex/dev/xlcom.c,v
retrieving revision 1.1
diff -d -p -u -r1.1 xlcom.c
--- evbppc/virtex/dev/xlcom.c 2 Dec 2006 22:18:47 -0000 1.1
+++ evbppc/virtex/dev/xlcom.c 1 Feb 2007 20:17:06 -0000
@@ -29,11 +29,11 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* TODO: kgdb support */
-
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: xlcom.c,v 1.1 2006/12/02 22:18:47 freza Exp $");
+#include "opt_kgdb.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
@@ -47,6 +47,10 @@ __KERNEL_RCSID(0, "$NetBSD: xlcom.c,v 1.
#include <sys/time.h>
#include <sys/syslog.h>
+#if defined(KGDB)
+#include <sys/kgdb.h>
+#endif /* KGDB */
+
#include <dev/cons.h>
#include <machine/intr.h>
@@ -96,12 +100,22 @@ static int xlcom_intr(void *);
static void xlcom_rx_soft(void *);
static void xlcom_tx_soft(void *);
static void xlcom_reset(bus_space_tag_t, bus_space_handle_t);
+static int xlcom_busy_getc(bus_space_tag_t, bus_space_handle_t);
+static void xlcom_busy_putc(bus_space_tag_t, bus_space_handle_t, int);
/* System console interface. */
static int xlcom_cngetc(dev_t);
static void xlcom_cnputc(dev_t, int);
void xlcom_cninit(struct consdev *);
+#if defined(KGDB)
+
+void xlcom_kgdbinit(void);
+static void xlcom_kgdb_putc(void *, int);
+static int xlcom_kgdb_getc(void *);
+
+#endif /* KGDB */
+
static struct cnm_state xlcom_cnm_state;
struct consdev consdev_xlcom = {
@@ -152,6 +166,14 @@ xlcom_attach(struct device *parent, stru
printf(": UartLite serial port\n");
+#if defined(KGDB)
+ /* We don't want to share kgdb port with the user. */
+ if (sc->sc_iot == kgdb_iot && sc->sc_ioh == kgdb_ioh) {
+ printf("%s: already in use by kgdb\n", device_xname(self));
+ return;
+ }
+#endif /* KGDB */
+
if ((sc->sc_ih = intr_establish(vaa->vaa_intr, IST_LEVEL, IPL_SERIAL,
xlcom_intr, sc)) == NULL) {
printf("%s: could not establish interrupt\n",
@@ -616,6 +638,24 @@ xlcom_reset(bus_space_tag_t iot, bus_spa
bus_space_write_4(iot, ioh, XLCOM_CNTL, CNTL_RX_CLEAR | CNTL_TX_CLEAR);
}
+static int
+xlcom_busy_getc(bus_space_tag_t t, bus_space_handle_t h)
+{
+ while (! (bus_space_read_4(t, h, XLCOM_STAT) & STAT_RX_DATA))
+ ;
+
+ return (bus_space_read_4(t, h, XLCOM_RX_FIFO));
+}
+
+static void
+xlcom_busy_putc(bus_space_tag_t t, bus_space_handle_t h, int c)
+{
+ while (bus_space_read_4(t, h, XLCOM_STAT) & STAT_TX_FULL)
+ ;
+
+ bus_space_write_4(t, h, XLCOM_TX_FIFO, c);
+}
+
/*
* Console on UartLite.
*/
@@ -636,20 +676,42 @@ xlcom_cninit(struct consdev *cn)
static int
xlcom_cngetc(dev_t dev)
{
- while (! (bus_space_read_4(consdev_iot, consdev_ioh, XLCOM_STAT) &
- STAT_RX_DATA))
- ;
-
- return (bus_space_read_4(consdev_iot, consdev_ioh,
- XLCOM_RX_FIFO));
+ return (xlcom_busy_getc(consdev_iot, consdev_ioh));
}
static void
xlcom_cnputc(dev_t dev, int c)
{
- while (bus_space_read_4(consdev_iot, consdev_ioh, XLCOM_STAT) &
- STAT_TX_FULL)
- ;
+ xlcom_busy_putc(consdev_iot, consdev_ioh, c);
+}
- bus_space_write_4(consdev_iot, consdev_ioh, XLCOM_TX_FIFO, c);
+/*
+ * Remote GDB (aka "kgdb") interface.
+ */
+#if defined(KGDB)
+
+static int
+xlcom_kgdb_getc(void *arg)
+{
+ return (xlcom_busy_getc(kgdb_iot, kgdb_ioh));
}
+
+static void
+xlcom_kgdb_putc(void *arg, int c)
+{
+ xlcom_busy_putc(kgdb_iot, kgdb_ioh, c);
+}
+
+void
+xlcom_kgdbinit(void)
+{
+ if (bus_space_map(kgdb_iot, KGDB_ADDR, XLCOM_SIZE, 0, &kgdb_ioh))
+ panic("xlcom_kgdbinit: could not map kgdb_ioh");
+
+ xlcom_reset(kgdb_iot, kgdb_ioh);
+
+ kgdb_attach(xlcom_kgdb_getc, xlcom_kgdb_putc, NULL);
+ kgdb_dev = 123; /* arbitrary strictly positive value */
+}
+
+#endif /* KGDB */
Index: powerpc/ibm4xx/trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/trap.c,v
retrieving revision 1.37
diff -d -p -u -r1.37 trap.c
--- powerpc/ibm4xx/trap.c 5 Oct 2006 14:48:32 -0000 1.37
+++ powerpc/ibm4xx/trap.c 1 Feb 2007 20:17:42 -0000
@@ -71,6 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.3
#include "opt_altivec.h"
#include "opt_ddb.h"
+#include "opt_kgdb.h"
#include <sys/param.h>
#include <sys/proc.h>
@@ -84,6 +85,10 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.3
#include <sys/userret.h>
#include <sys/kauth.h>
+#if defined(KGDB)
+#include <sys/kgdb.h>
+#endif
+
#include <uvm/uvm_extern.h>
#include <dev/cons.h>
@@ -364,7 +369,7 @@ trap(struct trapframe *frame)
default:
brain_damage:
printf("trap type 0x%x at 0x%lx\n", type, frame->srr0);
-#ifdef DDB
+#if defined(DDB) || defined(KGDB)
if (kdb_trap(type, frame))
goto done;
#endif
Index: powerpc/ibm4xx/trap_subr.S
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/trap_subr.S,v
retrieving revision 1.10
diff -d -p -u -r1.10 trap_subr.S
--- powerpc/ibm4xx/trap_subr.S 11 Dec 2005 12:18:42 -0000 1.10
+++ powerpc/ibm4xx/trap_subr.S 1 Feb 2007 20:17:44 -0000
@@ -177,7 +177,7 @@ _C_LABEL(extint):
_C_LABEL(extsize) = .-_C_LABEL(extint)
-#ifdef DDB
+#if defined(DDB) || defined(KGDB)
#define ddbsave 0xde0 /* primary save area for DDB */
/*
* In case of DDB we want a separate trap catcher for it
@@ -195,7 +195,7 @@ _C_LABEL(ddblow):
addi 1,1,ddbstk+INTSTK@l
bla ddbtrap
_C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
-#endif /* DDB */
+#endif /* DDB || KGDB */
#ifdef IPKDB
#define ipkdbsave 0xde0 /* primary save area for IPKDB */
@@ -543,7 +543,7 @@ fitint:
bl _C_LABEL(stat_intr)
b intr_exit
-#ifdef DDB
+#if defined(DDB) || defined(KGDB)
/*
* Deliberate entry to ddbtrap
*/
@@ -562,7 +562,7 @@ _C_LABEL(ddb_trap):
mtsrr0 28
/*
- * Now the ddb trap catching code.
+ * Now the ddb/kgdb trap catching code.
*/
ddbtrap:
FRAME_SETUP(ddbsave)
@@ -586,7 +586,7 @@ ddbleave:
FRAME_LEAVE(ddbsave)
rfi
ba . /* Protect against prefetch */
-#endif /* DDB */
+#endif /* DDB || KGDB */
#ifdef IPKDB
/*
Index: powerpc/powerpc/db_interface.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/db_interface.c,v
retrieving revision 1.36
diff -d -p -u -r1.36 db_interface.c
--- powerpc/powerpc/db_interface.c 24 Dec 2005 22:45:36 -0000 1.36
+++ powerpc/powerpc/db_interface.c 1 Feb 2007 20:17:46 -0000
@@ -36,6 +36,7 @@ __KERNEL_RCSID(0, "$NetBSD: db_interface
#ifdef KGDB
#include <sys/kgdb.h>
+#define db_printf printf
#endif
#include <dev/ofw/openfirm.h>
@@ -47,6 +48,7 @@ db_regs_t ddb_regs;
void ddb_trap(void); /* Call into trap_subr.S */
int ddb_trap_glue(struct trapframe *); /* Called from trap_subr.S */
#ifdef PPC_IBM4XX
+#ifdef DDB
static void db_ppc4xx_ctx(db_expr_t, int, db_expr_t, const char *);
static void db_ppc4xx_pv(db_expr_t, int, db_expr_t, const char *);
static void db_ppc4xx_reset(db_expr_t, int, db_expr_t, const char *);
@@ -58,6 +60,7 @@ static void db_ppc4xx_mtdcr(db_expr_t, d
#ifdef USERACC
static void db_ppc4xx_useracc(db_expr_t, int, db_expr_t, const char *);
#endif
+#endif /* DDB */
#endif /* PPC_IBM4XX */
#ifdef DDB
@@ -191,6 +194,7 @@ branch_taken(int inst, db_addr_t pc, db_
return (0);
}
+#ifdef DDB
const struct db_command db_machine_command_table[] = {
{ "ctx", db_ppc4xx_ctx, 0, 0 },
{ "pv", db_ppc4xx_pv, 0, 0 },
@@ -485,4 +489,6 @@ db_ppc4xx_useracc(db_expr_t addr, int ha
}
#endif
+#endif /* DDB */
+
#endif /* PPC_IBM4XX */