aboutsummaryrefslogtreecommitdiff
path: root/arch/frv/kernel/gdb-stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv/kernel/gdb-stub.c')
-rw-r--r--arch/frv/kernel/gdb-stub.c182
1 files changed, 113 insertions, 69 deletions
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
index 9550f37fb62..bbe78b0bffe 100644
--- a/arch/frv/kernel/gdb-stub.c
+++ b/arch/frv/kernel/gdb-stub.c
@@ -87,7 +87,7 @@
* Example:
* $ cd ~/linux
* $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
- * $ make dep; make vmlinux
+ * $ make vmlinux
*
* Step 3:
* Download the kernel to the remote target and start
@@ -126,7 +126,6 @@
#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
#include <asm/gdb-stub.h>
#define LEDS(x) do { /* *(u32*)0xe1200004 = ~(x); mb(); */ } while(0)
@@ -182,8 +181,6 @@ extern volatile u32 __attribute__((section(".bss"))) gdbstub_trace_through_excep
static char input_buffer[BUFMAX];
static char output_buffer[BUFMAX];
-static const char hexchars[] = "0123456789abcdef";
-
static const char *regnames[] = {
"PSR ", "ISR ", "CCR ", "CCCR",
"LR ", "LCR ", "PC ", "_stt",
@@ -383,8 +380,8 @@ static int gdbstub_send_packet(char *buffer)
}
gdbstub_tx_char('#');
- gdbstub_tx_char(hexchars[checksum >> 4]);
- gdbstub_tx_char(hexchars[checksum & 0xf]);
+ gdbstub_tx_char(hex_asc_hi(checksum));
+ gdbstub_tx_char(hex_asc_lo(checksum));
} while (gdbstub_rx_char(&ch,0),
#ifdef GDBSTUB_DEBUG_PROTOCOL
@@ -647,17 +644,11 @@ void debug_to_serial(const char *p, int n)
}
#endif
-#ifdef CONFIG_GDBSTUB_CONSOLE
-
-static kdev_t gdbstub_console_dev(struct console *con)
-{
- return MKDEV(1,3); /* /dev/null */
-}
+#ifdef CONFIG_GDB_CONSOLE
static struct console gdbstub_console = {
.name = "gdb",
.write = gdbstub_console_write, /* in break.S */
- .device = gdbstub_console_dev,
.flags = CON_PRINTBUFFER,
.index = -1,
};
@@ -680,8 +671,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if ((uint32_t)mem&1 && count>=1) {
if (!gdbstub_read_byte(mem,ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
mem++;
count--;
}
@@ -689,10 +679,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if ((uint32_t)mem&3 && count>=2) {
if (!gdbstub_read_word(mem,(uint16_t *)ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
- *buf++ = hexchars[ch[1] >> 4];
- *buf++ = hexchars[ch[1] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
+ buf = hex_byte_pack(buf, ch[1]);
mem += 2;
count -= 2;
}
@@ -700,14 +688,10 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
while (count>=4) {
if (!gdbstub_read_dword(mem,(uint32_t *)ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
- *buf++ = hexchars[ch[1] >> 4];
- *buf++ = hexchars[ch[1] & 0xf];
- *buf++ = hexchars[ch[2] >> 4];
- *buf++ = hexchars[ch[2] & 0xf];
- *buf++ = hexchars[ch[3] >> 4];
- *buf++ = hexchars[ch[3] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
+ buf = hex_byte_pack(buf, ch[1]);
+ buf = hex_byte_pack(buf, ch[2]);
+ buf = hex_byte_pack(buf, ch[3]);
mem += 4;
count -= 4;
}
@@ -715,10 +699,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if (count>=2) {
if (!gdbstub_read_word(mem,(uint16_t *)ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
- *buf++ = hexchars[ch[1] >> 4];
- *buf++ = hexchars[ch[1] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
+ buf = hex_byte_pack(buf, ch[1]);
mem += 2;
count -= 2;
}
@@ -726,8 +708,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if (count>=1) {
if (!gdbstub_read_byte(mem,ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
}
*buf = 0;
@@ -1195,7 +1176,7 @@ static void gdbstub_check_breakpoint(void)
/*
*
*/
-static void __attribute__((unused)) gdbstub_show_regs(void)
+static void __maybe_unused gdbstub_show_regs(void)
{
unsigned long *reg;
int loop;
@@ -1223,7 +1204,7 @@ static void __attribute__((unused)) gdbstub_show_regs(void)
/*
* dump debugging regs
*/
-static void __attribute__((unused)) gdbstub_dump_debugregs(void)
+static void __maybe_unused gdbstub_dump_debugregs(void)
{
gdbstub_printk("DCR %08lx ", __debug_status.dcr);
gdbstub_printk("BRR %08lx\n", __debug_status.brr);
@@ -1362,6 +1343,44 @@ void gdbstub_get_mmu_state(void)
} /* end gdbstub_get_mmu_state() */
+/*
+ * handle general query commands of the form 'qXXXXX'
+ */
+static void gdbstub_handle_query(void)
+{
+ if (strcmp(input_buffer, "qAttached") == 0) {
+ /* return current thread ID */
+ sprintf(output_buffer, "1");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qC") == 0) {
+ /* return current thread ID */
+ sprintf(output_buffer, "QC 0");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qOffsets") == 0) {
+ /* return relocation offset of text and data segments */
+ sprintf(output_buffer, "Text=0;Data=0;Bss=0");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qSymbol::") == 0) {
+ sprintf(output_buffer, "OK");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qSupported") == 0) {
+ /* query of supported features */
+ sprintf(output_buffer, "PacketSize=%u;ReverseContinue-;ReverseStep-",
+ sizeof(input_buffer));
+ return;
+ }
+
+ gdbstub_strcpy(output_buffer,"E01");
+}
+
/*****************************************************************************/
/*
* handle event interception and GDB remote protocol processing
@@ -1477,22 +1496,22 @@ void gdbstub(int sigval)
*ptr++ = 'O';
ptr = mem2hex(title, ptr, sizeof(title) - 1,0);
- hx = hexchars[(brr & 0xf0000000) >> 28];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x0f000000) >> 24];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x00f00000) >> 20];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x000f0000) >> 16];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x0000f000) >> 12];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x00000f00) >> 8];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x000000f0) >> 4];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x0000000f)];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
+ hx = hex_asc_hi(brr >> 24);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr >> 24);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_hi(brr >> 16);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr >> 16);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_hi(brr >> 8);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr >> 8);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_hi(brr);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr);
+ ptr = hex_byte_pack(ptr, hx);
ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0);
*ptr = 0;
@@ -1506,12 +1525,10 @@ void gdbstub(int sigval)
/* Send trap type (converted to signal) */
*ptr++ = 'T';
- *ptr++ = hexchars[sigval >> 4];
- *ptr++ = hexchars[sigval & 0xf];
+ ptr = hex_byte_pack(ptr, sigval);
/* Send Error PC */
- *ptr++ = hexchars[GDB_REG_PC >> 4];
- *ptr++ = hexchars[GDB_REG_PC & 0xf];
+ ptr = hex_byte_pack(ptr, GDB_REG_PC);
*ptr++ = ':';
ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0);
*ptr++ = ';';
@@ -1519,8 +1536,7 @@ void gdbstub(int sigval)
/*
* Send frame pointer
*/
- *ptr++ = hexchars[GDB_REG_FP >> 4];
- *ptr++ = hexchars[GDB_REG_FP & 0xf];
+ ptr = hex_byte_pack(ptr, GDB_REG_FP);
*ptr++ = ':';
ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0);
*ptr++ = ';';
@@ -1528,8 +1544,7 @@ void gdbstub(int sigval)
/*
* Send stack pointer
*/
- *ptr++ = hexchars[GDB_REG_SP >> 4];
- *ptr++ = hexchars[GDB_REG_SP & 0xf];
+ ptr = hex_byte_pack(ptr, GDB_REG_SP);
*ptr++ = ':';
ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0);
*ptr++ = ';';
@@ -1554,8 +1569,8 @@ void gdbstub(int sigval)
/* request repeat of last signal number */
case '?':
output_buffer[0] = 'S';
- output_buffer[1] = hexchars[sigval >> 4];
- output_buffer[2] = hexchars[sigval & 0xf];
+ output_buffer[1] = hex_asc_hi(sigval);
+ output_buffer[2] = hex_asc_lo(sigval);
output_buffer[3] = 0;
break;
@@ -1773,6 +1788,12 @@ void gdbstub(int sigval)
flush_cache = 1;
break;
+ /* pNN: Read value of reg N and return it */
+ case 'p':
+ /* return no value, indicating that we don't support
+ * this command and that gdb should use 'g' instead */
+ break;
+
/* PNN,=RRRRRRRR: Write value R to reg N return OK */
case 'P':
ptr = &input_buffer[1];
@@ -1862,6 +1883,10 @@ void gdbstub(int sigval)
case 'k' :
goto done; /* just continue */
+ /* detach */
+ case 'D':
+ gdbstub_strcpy(output_buffer, "OK");
+ break;
/* reset the whole machine (FIXME: system dependent) */
case 'r':
@@ -1874,6 +1899,14 @@ void gdbstub(int sigval)
__debug_status.dcr |= DCR_SE;
goto done;
+ /* extended command */
+ case 'v':
+ if (strcmp(input_buffer, "vCont?") == 0) {
+ output_buffer[0] = 0;
+ break;
+ }
+ goto unsupported_cmd;
+
/* set baud rate (bBB) */
case 'b':
ptr = &input_buffer[1];
@@ -1945,8 +1978,19 @@ void gdbstub(int sigval)
gdbstub_strcpy(output_buffer,"OK");
break;
+ /* Thread-setting packet */
+ case 'H':
+ gdbstub_strcpy(output_buffer, "OK");
+ break;
+
+ case 'q':
+ gdbstub_handle_query();
+ break;
+
default:
+ unsupported_cmd:
gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer);
+ gdbstub_strcpy(output_buffer,"E01");
break;
}
@@ -2021,7 +2065,7 @@ void __init gdbstub_init(void)
ptr = mem2hex(gdbstub_banner, ptr, sizeof(gdbstub_banner) - 1, 0);
gdbstub_send_packet(output_buffer);
#endif
-#if defined(CONFIG_GDBSTUB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE)
+#if defined(CONFIG_GDB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE)
register_console(&gdbstub_console);
#endif
@@ -2031,7 +2075,7 @@ void __init gdbstub_init(void)
/*
* register the console at a more appropriate time
*/
-#if defined (CONFIG_GDBSTUB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)
+#if defined (CONFIG_GDB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)
static int __init gdbstub_postinit(void)
{
printk("registering console\n");
@@ -2065,8 +2109,8 @@ void gdbstub_exit(int status)
}
gdbstub_tx_char('#');
- gdbstub_tx_char(hexchars[checksum >> 4]);
- gdbstub_tx_char(hexchars[checksum & 0xf]);
+ gdbstub_tx_char(hex_asc_hi(checksum));
+ gdbstub_tx_char(hex_asc_lo(checksum));
/* make sure the output is flushed, or else RedBoot might clobber it */
gdbstub_tx_char('-');
@@ -2079,25 +2123,25 @@ void gdbstub_exit(int status)
* GDB wants to call malloc() and free() to allocate memory for calling kernel
* functions directly from its command line
*/
-static void *malloc(size_t size) __attribute__((unused));
+static void *malloc(size_t size) __maybe_unused;
static void *malloc(size_t size)
{
return kmalloc(size, GFP_ATOMIC);
}
-static void free(void *p) __attribute__((unused));
+static void free(void *p) __maybe_unused;
static void free(void *p)
{
kfree(p);
}
-static uint32_t ___get_HSR0(void) __attribute__((unused));
+static uint32_t ___get_HSR0(void) __maybe_unused;
static uint32_t ___get_HSR0(void)
{
return __get_HSR(0);
}
-static uint32_t ___set_HSR0(uint32_t x) __attribute__((unused));
+static uint32_t ___set_HSR0(uint32_t x) __maybe_unused;
static uint32_t ___set_HSR0(uint32_t x)
{
__set_HSR(0, x);