* [U-Boot] [PATCH v2 2/4] [ARM] Add KGDB support for ARM platforms
@ 2010-06-28 21:40 Ben Baron
0 siblings, 0 replies; 2+ messages in thread
From: Ben Baron @ 2010-06-28 21:40 UTC (permalink / raw)
To: u-boot
I was looking at using this code for Marvell's ARM-like platform. Was
this patch ever accepted in uboot? I don't see it in the current git tree.
Thanks!
Ben Baron
Oracle Development Engineer.
^ permalink raw reply [flat|nested] 2+ messages in thread
* [U-Boot] [PATCH] KGDB set / remove breakpoints
@ 2010-04-17 17:20 Tonny Tzeng
2010-04-17 18:10 ` [U-Boot] [PATCH v2 0/4] [ARM] Add KGDB support for ARM platforms Tonny Tzeng
0 siblings, 1 reply; 2+ messages in thread
From: Tonny Tzeng @ 2010-04-17 17:20 UTC (permalink / raw)
To: u-boot
This patch extends the current KGDB logic to handle 'Z' and 'z'
GDB packets for setting or removing breakpoints.
Two weak functions have been added to the kgdb_stub.c:
arch_kgdb_set_sw_break() and arch_kgdb_remove_sw_break() could be
overrode by the arch implementations.
Please note, after applying this patch, those architectures, which
already enabled KGDB support, have to create a new asm/kgdb.h and
define the length of the break instruction (BREAK_INSTR_SIZE) in that
file.
Signed-off-by: Tonny Tzeng <tonny.tzeng@gmail.com>
---
common/kgdb.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++
common/kgdb_stubs.c | 12 +++++++
include/kgdb.h | 31 ++++++++++++++++++
3 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/common/kgdb.c b/common/kgdb.c
index 0531452..66378e5 100644
--- a/common/kgdb.c
+++ b/common/kgdb.c
@@ -220,6 +220,85 @@ hexToInt(char **ptr, int *intValue)
return (numChars);
}
+/*
+ * Holds information about breakpoints in a kernel. These breakpoints are
+ * added and removed by gdb.
+ */
+static struct kgdb_bkpt kgdb_break[KGDB_MAX_BREAKPOINTS];
+
+static int kgdb_set_sw_break(int addr)
+{
+ int i, breakno = -1;
+ struct kgdb_bkpt *bkpt;
+
+ for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
+ if ((kgdb_break[i].state == BP_SET) &&
+ (kgdb_break[i].bpt_addr == addr))
+ return -KGDBERR_BPEXIST;
+ if ((kgdb_break[i].state == BP_REMOVED) &&
+ (kgdb_break[i].bpt_addr == addr)) {
+ breakno = i;
+ break;
+ }
+ }
+ if (breakno == -1)
+ for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
+ if (kgdb_break[i].state == BP_UNDEFINED) {
+ breakno = i;
+ break;
+ }
+ }
+ if (breakno == -1)
+ return -KGDBERR_BPNOENT;
+
+ bkpt = kgdb_break + breakno;
+ bkpt->state = BP_SET;
+ bkpt->type = BP_BREAKPOINT;
+ bkpt->bpt_addr = addr;
+ arch_kgdb_set_sw_break(bkpt);
+
+ return 0;
+}
+
+static int kgdb_remove_sw_break(int addr)
+{
+ int i;
+ struct kgdb_bkpt *bkpt;
+
+ for (i = 0; i < KGDB_MAX_BREAKPOINTS; i++) {
+ bkpt = kgdb_break + i;
+ if ((bkpt->state == BP_SET) && (bkpt->bpt_addr == addr)) {
+ bkpt->state = BP_REMOVED;
+ arch_kgdb_remove_sw_break(bkpt);
+ return 0;
+ }
+ }
+ return -KGDBERR_BPNOENT;
+}
+
+/* Handle the 'z' or 'Z' breakpoint remove or set packets */
+static void gdb_cmd_break(kgdb_data *kdp)
+{
+ /*
+ * Since GDB-5.3, it's been drafted that '0' is a software
+ * breakpoint, '1' is a hardware breakpoint, so let's do that.
+ */
+ char *bpt_type = &remcomInBuffer[1];
+ char *ptr = &remcomInBuffer[2];
+ int addr, length;
+
+ if (*bpt_type != '0')
+ return; /* Unsupported. */
+ if (*ptr++ != ',' || !hexToInt(&ptr, &addr) ||
+ *ptr++ != ',' || !hexToInt(&ptr, &length)) {
+ kgdb_error(KGDBERR_BADPARAMS);
+ }
+
+ if ((remcomInBuffer[0] == 'Z' && kgdb_set_sw_break(addr) == 0) ||
+ (remcomInBuffer[0] == 'z' && kgdb_remove_sw_break(addr) == 0))
+ strcpy(remcomOutBuffer, "OK");
+}
+
/* scan for the sequence $<data>#<checksum> */
static void
getpacket(char *buffer)
@@ -341,7 +420,9 @@ handle_exception (struct pt_regs *regs)
kgdb_interruptible(0);
+#ifdef KGDB_DEBUG
printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs));
+#endif
if (kgdb_setjmp(error_jmp_buf) != 0)
panic("kgdb: error or fault in entry init!\n");
@@ -516,6 +597,10 @@ handle_exception (struct pt_regs *regs)
kgdb_error(KGDBERR_BADPARAMS);
}
break;
+ case 'Z': /* [Z|z]N,AA..AA,LLLL Set/Remove breakpoint type N */
+ case 'z': /* LLLL bytes at address AA.AA return OK */
+ gdb_cmd_break(&kd);
+ break;
} /* switch */
if (errnum != 0)
diff --git a/common/kgdb_stubs.c b/common/kgdb_stubs.c
index 19b0c18..2b3f424 100644
--- a/common/kgdb_stubs.c
+++ b/common/kgdb_stubs.c
@@ -45,6 +45,18 @@ void kgdb_interruptible(int yes)
}
__attribute__((weak))
+void arch_kgdb_set_sw_break(struct kgdb_bkpt *bkpt)
+{
+ return;
+}
+
+__attribute__((weak))
+void arch_kgdb_remove_sw_break(struct kgdb_bkpt *bkpt)
+{
+ return;
+}
+
+__attribute__((weak))
void kgdb_flush_cache_range(void *from, void *to)
{
flush_cache((unsigned long)from, (unsigned long)(to - from));
diff --git a/include/kgdb.h b/include/kgdb.h
index f543cd6..82ae8ab 100644
--- a/include/kgdb.h
+++ b/include/kgdb.h
@@ -2,12 +2,41 @@
#define __KGDB_H__
#include <asm/ptrace.h>
+#include <asm/kgdb.h>
#define KGDBERR_BADPARAMS 1
#define KGDBERR_NOTHEXDIG 2
#define KGDBERR_MEMFAULT 3
#define KGDBERR_NOSPACE 4
#define KGDBERR_ALIGNFAULT 5
+#define KGDBERR_BPEXIST 6
+#define KGDBERR_BPNOENT 7
+
+#ifndef KGDB_MAX_BREAKPOINTS
+#define KGDB_MAX_BREAKPOINTS 1000
+#endif
+
+enum kgdb_bptype {
+ BP_BREAKPOINT = 0,
+ BP_HARDWARE_BREAKPOINT,
+ BP_WRITE_WATCHPOINT,
+ BP_READ_WATCHPOINT,
+ BP_ACCESS_WATCHPOINT
+};
+
+enum kgdb_bpstate {
+ BP_UNDEFINED = 0,
+ BP_REMOVED,
+ BP_SET,
+ BP_ACTIVE
+};
+
+struct kgdb_bkpt {
+ unsigned long bpt_addr;
+ unsigned char saved_instr[BREAK_INSTR_SIZE];
+ enum kgdb_bptype type;
+ enum kgdb_bpstate state;
+};
#define KGDBDATA_MAXREGS 8
#define KGDBDATA_MAXPRIV 8
@@ -56,6 +85,8 @@ extern void kgdb_putreg(struct pt_regs *, int, char *, int);
extern void kgdb_putregs(struct pt_regs *, char *, int);
extern int kgdb_trap(struct pt_regs *);
extern void kgdb_breakpoint(int argc, char *argv[]);
+extern void arch_kgdb_set_sw_break(struct kgdb_bkpt *);
+extern void arch_kgdb_remove_sw_break(struct kgdb_bkpt *);
/* these functions are provided by the platform serial driver */
extern void kgdb_serial_init(void);
--
1.6.0.6
^ permalink raw reply related [flat|nested] 2+ messages in thread* [U-Boot] [PATCH v2 0/4] [ARM] Add KGDB support for ARM platforms
2010-04-17 17:20 [U-Boot] [PATCH] KGDB set / remove breakpoints Tonny Tzeng
@ 2010-04-17 18:10 ` Tonny Tzeng
2010-04-17 18:12 ` [U-Boot] [PATCH v2 1/4] " Tonny Tzeng
0 siblings, 1 reply; 2+ messages in thread
From: Tonny Tzeng @ 2010-04-17 18:10 UTC (permalink / raw)
To: u-boot
This patchset adds KGDB support for ARM platforms.
Since the KGDB support for ARM is through the undef instruction handler,
we need to add code to the startup file to restore the user context after
exception. Unfortunately, each ARM variant has his own start.S, so please
reference the patch designed for arm720 to add the 'bad_restore_user_regs'
logic to your ARM start-up file.
v1 - initial patchset
v2 - (a) move code, which should be common to all arch, to common/kgdb.c;
add two new weak funcs to common/kgdb_stubs.c, and separate these
common code to the patch "KGDB set / remove breakpoints".
(b) remove the watchdog func during the board initialization.
(c) flush all cache after mangling instructions.
Best Regards,
Tonny
^ permalink raw reply [flat|nested] 2+ messages in thread* [U-Boot] [PATCH v2 1/4] [ARM] Add KGDB support for ARM platforms
2010-04-17 18:10 ` [U-Boot] [PATCH v2 0/4] [ARM] Add KGDB support for ARM platforms Tonny Tzeng
@ 2010-04-17 18:12 ` Tonny Tzeng
2010-04-17 18:15 ` [U-Boot] [PATCH v2 2/4] " Tonny Tzeng
0 siblings, 1 reply; 2+ messages in thread
From: Tonny Tzeng @ 2010-04-17 18:12 UTC (permalink / raw)
To: u-boot
Signed-off-by: Tonny Tzeng <tonny.tzeng@gmail.com>
---
arch/arm/lib/board.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index f5660a9..f2b028c 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -381,6 +381,10 @@ void start_armboot (void)
/* miscellaneous platform dependent initialisations */
misc_init_r ();
#endif
+#if defined(CONFIG_CMD_KGDB)
+ puts("KGDB: ");
+ kgdb_init();
+#endif
/* enable exceptions */
enable_interrupts ();
--
1.6.0.6
^ permalink raw reply related [flat|nested] 2+ messages in thread* [U-Boot] [PATCH v2 2/4] [ARM] Add KGDB support for ARM platforms
2010-04-17 18:12 ` [U-Boot] [PATCH v2 1/4] " Tonny Tzeng
@ 2010-04-17 18:15 ` Tonny Tzeng
0 siblings, 0 replies; 2+ messages in thread
From: Tonny Tzeng @ 2010-04-17 18:15 UTC (permalink / raw)
To: u-boot
Signed-off-by: Tonny Tzeng <tonny.tzeng@gmail.com>
---
arch/arm/lib/interrupts.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/arm/lib/interrupts.c b/arch/arm/lib/interrupts.c
index 1f2b815..6ee4309 100644
--- a/arch/arm/lib/interrupts.c
+++ b/arch/arm/lib/interrupts.c
@@ -37,6 +37,9 @@
#include <common.h>
#include <asm/proc-armv/ptrace.h>
+#ifdef CONFIG_CMD_KGDB
+#include <kgdb.h>
+#endif
#ifdef CONFIG_USE_IRQ
DECLARE_GLOBAL_DATA_PTR;
@@ -137,6 +140,12 @@ void show_regs (struct pt_regs *regs)
void do_undefined_instruction (struct pt_regs *pt_regs)
{
+#ifdef CONFIG_CMD_KGDB
+ if (*(unsigned long *)(instruction_pointer(pt_regs) - 4) == KGDB_COMPILED_BREAK) {
+ (*debugger_exception_handler)(pt_regs);
+ return;
+ }
+#endif
printf ("undefined instruction\n");
show_regs (pt_regs);
bad_mode ();
--
1.6.0.6
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-06-28 21:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-28 21:40 [U-Boot] [PATCH v2 2/4] [ARM] Add KGDB support for ARM platforms Ben Baron
-- strict thread matches above, loose matches on Subject: below --
2010-04-17 17:20 [U-Boot] [PATCH] KGDB set / remove breakpoints Tonny Tzeng
2010-04-17 18:10 ` [U-Boot] [PATCH v2 0/4] [ARM] Add KGDB support for ARM platforms Tonny Tzeng
2010-04-17 18:12 ` [U-Boot] [PATCH v2 1/4] " Tonny Tzeng
2010-04-17 18:15 ` [U-Boot] [PATCH v2 2/4] " Tonny Tzeng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox