Commit a5ac0129 authored by Sonic Zhang's avatar Sonic Zhang Committed by Bryan Wu

Blackfin arch: add supporting for kgdb

Signed-off-by: default avatarSonic Zhang <sonic.zhang@analog.com>
Signed-off-by: default avatarBryan Wu <cooloney@kernel.org>
parent 5d2e3213
A Simple Guide to Configure KGDB
Sonic Zhang <sonic.zhang@analog.com>
Aug. 24th 2006
This KGDB patch enables the kernel developer to do source level debugging on
the kernel for the Blackfin architecture. The debugging works over either the
ethernet interface or one of the uarts. Both software breakpoints and
hardware breakpoints are supported in this version.
http://docs.blackfin.uclinux.org/doku.php?id=kgdb
2 known issues:
1. This bug:
http://blackfin.uclinux.org/tracker/index.php?func=detail&aid=544&group_id=18&atid=145
The GDB client for Blackfin uClinux causes incorrect values of local
variables to be displayed when the user breaks the running of kernel in GDB.
2. Because of a hardware bug in Blackfin 533 v1.0.3:
05000067 - Watchpoints (Hardware Breakpoints) are not supported
Hardware breakpoints cannot be set properly.
Debug over Ethernet:
1. Compile and install the cross platform version of gdb for blackfin, which
can be found at $(BINROOT)/bfin-elf-gdb.
2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under
"Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
With this selected, option "Full Symbolic/Source Debugging support" and
"Compile the kernel with frame pointers" are also selected.
3. Select option "KGDB: connect over (Ethernet)". Add "kgdboe=@target-IP/,@host-IP/" to
the option "Compiled-in Kernel Boot Parameter" under "Kernel hacking".
4. Connect minicom to the serial port and boot the kernel image.
5. Configure the IP "/> ifconfig eth0 target-IP"
6. Start GDB client "bfin-elf-gdb vmlinux".
7. Connect to the target "(gdb) target remote udp:target-IP:6443".
8. Set software breakpoint "(gdb) break sys_open".
9. Continue "(gdb) c".
10. Run ls in the target console "/> ls".
11. Breakpoint hits. "Breakpoint 1: sys_open(..."
12. Display local variables and function paramters.
(*) This operation gives wrong results, see known issue 1.
13. Single stepping "(gdb) si".
14. Remove breakpoint 1. "(gdb) del 1"
15. Set hardware breakpoint "(gdb) hbreak sys_open".
16. Continue "(gdb) c".
17. Run ls in the target console "/> ls".
18. Hardware breakpoint hits. "Breakpoint 1: sys_open(...".
(*) This hardware breakpoint will not be hit, see known issue 2.
19. Continue "(gdb) c".
20. Interrupt the target in GDB "Ctrl+C".
21. Detach from the target "(gdb) detach".
22. Exit GDB "(gdb) quit".
Debug over the UART:
1. Compile and install the cross platform version of gdb for blackfin, which
can be found at $(BINROOT)/bfin-elf-gdb.
2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under
"Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
With this selected, option "Full Symbolic/Source Debugging support" and
"Compile the kernel with frame pointers" are also selected.
3. Select option "KGDB: connect over (UART)". Set "KGDB: UART port number" to be
a different one from the console. Don't forget to change the mode of
blackfin serial driver to PIO. Otherwise kgdb works incorrectly on UART.
4. If you want connect to kgdb when the kernel boots, enable
"KGDB: Wait for gdb connection early"
5. Compile kernel.
6. Connect minicom to the serial port of the console and boot the kernel image.
7. Start GDB client "bfin-elf-gdb vmlinux".
8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
9. Connect to the target on the second serial port "(gdb) target remote /dev/ttyS1".
10. Set software breakpoint "(gdb) break sys_open".
11. Continue "(gdb) c".
12. Run ls in the target console "/> ls".
13. A breakpoint is hit. "Breakpoint 1: sys_open(..."
14. All other operations are the same as that in KGDB over Ethernet.
Debug over the same UART as console:
1. Compile and install the cross platform version of gdb for blackfin, which
can be found at $(BINROOT)/bfin-elf-gdb.
2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under
"Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
With this selected, option "Full Symbolic/Source Debugging support" and
"Compile the kernel with frame pointers" are also selected.
3. Select option "KGDB: connect over UART". Set "KGDB: UART port number" to console.
Don't forget to change the mode of blackfin serial driver to PIO.
Otherwise kgdb works incorrectly on UART.
4. If you want connect to kgdb when the kernel boots, enable
"KGDB: Wait for gdb connection early"
5. Connect minicom to the serial port and boot the kernel image.
6. (Optional) Ask target to wait for gdb connection by entering Ctrl+A. In minicom, you should enter Ctrl+A+A.
7. Start GDB client "bfin-elf-gdb vmlinux".
8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
9. Connect to the target "(gdb) target remote /dev/ttyS0".
10. Set software breakpoint "(gdb) break sys_open".
11. Continue "(gdb) c". Then enter Ctrl+C twice to stop GDB connection.
12. Run ls in the target console "/> ls". Dummy string can be seen on the console.
13. Then connect the gdb to target again. "(gdb) target remote /dev/ttyS0".
Now you will find a breakpoint is hit. "Breakpoint 1: sys_open(..."
14. All other operations are the same as that in KGDB over Ethernet. The only
difference is that after continue command in GDB, please stop GDB
connection by 2 "Ctrl+C"s and connect again after breakpoints are hit or
Ctrl+A is entered.
...@@ -2,6 +2,9 @@ menu "Kernel hacking" ...@@ -2,6 +2,9 @@ menu "Kernel hacking"
source "lib/Kconfig.debug" source "lib/Kconfig.debug"
config HAVE_ARCH_KGDB
def_bool y
config DEBUG_MMRS config DEBUG_MMRS
bool "Generate Blackfin MMR tree" bool "Generate Blackfin MMR tree"
select DEBUG_FS select DEBUG_FS
......
...@@ -124,9 +124,16 @@ enum regnames { ...@@ -124,9 +124,16 @@ enum regnames {
/* Number of bytes of registers. */ /* Number of bytes of registers. */
#define NUMREGBYTES BFIN_NUM_REGS*4 #define NUMREGBYTES BFIN_NUM_REGS*4
#define BREAKPOINT() asm(" EXCPT 2;"); static inline void arch_kgdb_breakpoint(void)
#define BREAK_INSTR_SIZE 2 {
#define HW_BREAKPOINT_NUM 6 asm(" EXCPT 2;");
}
#define BREAK_INSTR_SIZE 2
#define CACHE_FLUSH_IS_SAFE 1
#define HW_INST_WATCHPOINT_NUM 6
#define HW_WATCHPOINT_NUM 8
#define TYPE_INST_WATCHPOINT 0
#define TYPE_DATA_WATCHPOINT 1
/* Instruction watchpoint address control register bits mask */ /* Instruction watchpoint address control register bits mask */
#define WPPWR 0x1 #define WPPWR 0x1
...@@ -163,10 +170,11 @@ enum regnames { ...@@ -163,10 +170,11 @@ enum regnames {
#define WPDAEN1 0x8 #define WPDAEN1 0x8
#define WPDCNTEN0 0x10 #define WPDCNTEN0 0x10
#define WPDCNTEN1 0x20 #define WPDCNTEN1 0x20
#define WPDSRC0 0xc0 #define WPDSRC0 0xc0
#define WPDACC0 0x300 #define WPDACC0_OFFSET 8
#define WPDSRC1 0xc00 #define WPDSRC1 0xc00
#define WPDACC1 0x3000 #define WPDACC1_OFFSET 12
/* Watchpoint status register bits mask */ /* Watchpoint status register bits mask */
#define STATIA0 0x1 #define STATIA0 0x1
...@@ -178,7 +186,4 @@ enum regnames { ...@@ -178,7 +186,4 @@ enum regnames {
#define STATDA0 0x40 #define STATDA0 0x40
#define STATDA1 0x80 #define STATDA1 0x80
extern void kgdb_print(const char *fmt, ...);
extern void init_kgdb_uart(void);
#endif #endif
This diff is collapsed.
...@@ -43,12 +43,11 @@ ...@@ -43,12 +43,11 @@
#include <asm/dma.h> #include <asm/dma.h>
#ifdef CONFIG_KGDB #ifdef CONFIG_KGDB
# include <linux/debugger.h>
# include <linux/kgdb.h> # include <linux/kgdb.h>
# define CHK_DEBUGGER_TRAP() \ # define CHK_DEBUGGER_TRAP() \
do { \ do { \
CHK_DEBUGGER(trapnr, sig, info.si_code, fp, ); \ kgdb_handle_exception(trapnr, sig, info.si_code, fp); \
} while (0) } while (0)
# define CHK_DEBUGGER_TRAP_MAYBE() \ # define CHK_DEBUGGER_TRAP_MAYBE() \
do { \ do { \
...@@ -300,7 +299,7 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -300,7 +299,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
info.si_code = SEGV_STACKFLOW; info.si_code = SEGV_STACKFLOW;
sig = SIGSEGV; sig = SIGSEGV;
printk(KERN_NOTICE EXC_0x03(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x03(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x04 - User Defined, Caught by default */ /* 0x04 - User Defined, Caught by default */
/* 0x05 - User Defined, Caught by default */ /* 0x05 - User Defined, Caught by default */
...@@ -329,7 +328,7 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -329,7 +328,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
info.si_code = TRAP_TRACEFLOW; info.si_code = TRAP_TRACEFLOW;
sig = SIGTRAP; sig = SIGTRAP;
printk(KERN_NOTICE EXC_0x11(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x11(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x12 - Reserved, Caught by default */ /* 0x12 - Reserved, Caught by default */
/* 0x13 - Reserved, Caught by default */ /* 0x13 - Reserved, Caught by default */
...@@ -351,35 +350,35 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -351,35 +350,35 @@ asmlinkage void trap_c(struct pt_regs *fp)
info.si_code = ILL_ILLOPC; info.si_code = ILL_ILLOPC;
sig = SIGILL; sig = SIGILL;
printk(KERN_NOTICE EXC_0x21(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x21(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x22 - Illegal Instruction Combination, handled here */ /* 0x22 - Illegal Instruction Combination, handled here */
case VEC_ILGAL_I: case VEC_ILGAL_I:
info.si_code = ILL_ILLPARAOP; info.si_code = ILL_ILLPARAOP;
sig = SIGILL; sig = SIGILL;
printk(KERN_NOTICE EXC_0x22(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x22(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x23 - Data CPLB protection violation, handled here */ /* 0x23 - Data CPLB protection violation, handled here */
case VEC_CPLB_VL: case VEC_CPLB_VL:
info.si_code = ILL_CPLB_VI; info.si_code = ILL_CPLB_VI;
sig = SIGBUS; sig = SIGBUS;
printk(KERN_NOTICE EXC_0x23(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x23(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x24 - Data access misaligned, handled here */ /* 0x24 - Data access misaligned, handled here */
case VEC_MISALI_D: case VEC_MISALI_D:
info.si_code = BUS_ADRALN; info.si_code = BUS_ADRALN;
sig = SIGBUS; sig = SIGBUS;
printk(KERN_NOTICE EXC_0x24(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x24(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x25 - Unrecoverable Event, handled here */ /* 0x25 - Unrecoverable Event, handled here */
case VEC_UNCOV: case VEC_UNCOV:
info.si_code = ILL_ILLEXCPT; info.si_code = ILL_ILLEXCPT;
sig = SIGILL; sig = SIGILL;
printk(KERN_NOTICE EXC_0x25(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x25(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr,
error case is handled here */ error case is handled here */
...@@ -387,7 +386,6 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -387,7 +386,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
info.si_code = BUS_ADRALN; info.si_code = BUS_ADRALN;
sig = SIGBUS; sig = SIGBUS;
printk(KERN_NOTICE EXC_0x26(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x26(KERN_NOTICE));
CHK_DEBUGGER_TRAP();
break; break;
/* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */
case VEC_CPLB_MHIT: case VEC_CPLB_MHIT:
...@@ -399,7 +397,7 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -399,7 +397,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
else else
#endif #endif
printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x27(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x28 - Emulation Watchpoint, handled here */ /* 0x28 - Emulation Watchpoint, handled here */
case VEC_WATCH: case VEC_WATCH:
...@@ -418,7 +416,7 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -418,7 +416,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
info.si_code = BUS_OPFETCH; info.si_code = BUS_OPFETCH;
sig = SIGBUS; sig = SIGBUS;
printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n"); printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n");
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
#else #else
/* 0x29 - Reserved, Caught by default */ /* 0x29 - Reserved, Caught by default */
...@@ -428,21 +426,20 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -428,21 +426,20 @@ asmlinkage void trap_c(struct pt_regs *fp)
info.si_code = BUS_ADRALN; info.si_code = BUS_ADRALN;
sig = SIGBUS; sig = SIGBUS;
printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x2B - Instruction CPLB protection violation, handled here */ /* 0x2B - Instruction CPLB protection violation, handled here */
case VEC_CPLB_I_VL: case VEC_CPLB_I_VL:
info.si_code = ILL_CPLB_VI; info.si_code = ILL_CPLB_VI;
sig = SIGBUS; sig = SIGBUS;
printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */
case VEC_CPLB_I_M: case VEC_CPLB_I_M:
info.si_code = ILL_CPLB_MISS; info.si_code = ILL_CPLB_MISS;
sig = SIGBUS; sig = SIGBUS;
printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE));
CHK_DEBUGGER_TRAP();
break; break;
/* 0x2D - Instruction CPLB Multiple Hits, handled here */ /* 0x2D - Instruction CPLB Multiple Hits, handled here */
case VEC_CPLB_I_MHIT: case VEC_CPLB_I_MHIT:
...@@ -454,14 +451,14 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -454,14 +451,14 @@ asmlinkage void trap_c(struct pt_regs *fp)
else else
#endif #endif
printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x2E - Illegal use of Supervisor Resource, handled here */ /* 0x2E - Illegal use of Supervisor Resource, handled here */
case VEC_ILL_RES: case VEC_ILL_RES:
info.si_code = ILL_PRVOPC; info.si_code = ILL_PRVOPC;
sig = SIGILL; sig = SIGILL;
printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE)); printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
/* 0x2F - Reserved, Caught by default */ /* 0x2F - Reserved, Caught by default */
/* 0x30 - Reserved, Caught by default */ /* 0x30 - Reserved, Caught by default */
...@@ -508,14 +505,14 @@ asmlinkage void trap_c(struct pt_regs *fp) ...@@ -508,14 +505,14 @@ asmlinkage void trap_c(struct pt_regs *fp)
printk(KERN_NOTICE HWC_default(KERN_NOTICE)); printk(KERN_NOTICE HWC_default(KERN_NOTICE));
break; break;
} }
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
default: default:
info.si_code = TRAP_ILLTRAP; info.si_code = TRAP_ILLTRAP;
sig = SIGTRAP; sig = SIGTRAP;
printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
(fp->seqstat & SEQSTAT_EXCAUSE)); (fp->seqstat & SEQSTAT_EXCAUSE));
CHK_DEBUGGER_TRAP(); CHK_DEBUGGER_TRAP_MAYBE();
break; break;
} }
......
...@@ -35,9 +35,16 @@ ...@@ -35,9 +35,16 @@
/* Memory Map for ADSP-BF561 processors */ /* Memory Map for ADSP-BF561 processors */
#ifdef CONFIG_BF561 #ifdef CONFIG_BF561
#define L1_CODE_START 0xFFA00000 #define COREA_L1_CODE_START 0xFFA00000
#define L1_DATA_A_START 0xFF800000 #define COREA_L1_DATA_A_START 0xFF800000
#define L1_DATA_B_START 0xFF900000 #define COREA_L1_DATA_B_START 0xFF900000
#define COREB_L1_CODE_START 0xFF600000
#define COREB_L1_DATA_A_START 0xFF500000
#define COREB_L1_DATA_B_START 0xFF400000
#define L1_CODE_START COREA_L1_CODE_START
#define L1_DATA_A_START COREA_L1_DATA_A_START
#define L1_DATA_B_START COREA_L1_DATA_B_START
#define L1_CODE_LENGTH 0x4000 #define L1_CODE_LENGTH 0x4000
...@@ -72,7 +79,10 @@ ...@@ -72,7 +79,10 @@
/* Scratch Pad Memory */ /* Scratch Pad Memory */
#define L1_SCRATCH_START 0xFFB00000 #define COREA_L1_SCRATCH_START 0xFFB00000
#define COREB_L1_SCRATCH_START 0xFF700000
#define L1_SCRATCH_START COREA_L1_SCRATCH_START
#define L1_SCRATCH_LENGTH 0x1000 #define L1_SCRATCH_LENGTH 0x1000
#endif /* _MEM_MAP_533_H_ */ #endif /* _MEM_MAP_533_H_ */
...@@ -190,8 +190,8 @@ ENTRY(_ex_single_step) ...@@ -190,8 +190,8 @@ ENTRY(_ex_single_step)
if cc jump .Lfind_priority_done; if cc jump .Lfind_priority_done;
jump.s .Lfind_priority_start; jump.s .Lfind_priority_start;
.Lfind_priority_done: .Lfind_priority_done:
p4.l = _debugger_step; p4.l = _kgdb_single_step;
p4.h = _debugger_step; p4.h = _kgdb_single_step;
r6 = [p4]; r6 = [p4];
cc = r6 == 0; cc = r6 == 0;
if cc jump .Ldo_single_step; if cc jump .Ldo_single_step;
...@@ -1071,7 +1071,12 @@ ENTRY(_ex_table) ...@@ -1071,7 +1071,12 @@ ENTRY(_ex_table)
*/ */
.long _ex_syscall /* 0x00 - User Defined - Linux Syscall */ .long _ex_syscall /* 0x00 - User Defined - Linux Syscall */
.long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */
#ifdef CONFIG_KGDB
.long _ex_trap_c /* 0x02 - User Defined - KGDB initial connection
and break signal trap */
#else
.long _ex_replaceable /* 0x02 - User Defined */ .long _ex_replaceable /* 0x02 - User Defined */
#endif
.long _ex_trap_c /* 0x03 - User Defined - userspace stack overflow */ .long _ex_trap_c /* 0x03 - User Defined - userspace stack overflow */
.long _ex_trap_c /* 0x04 - User Defined - dump trace buffer */ .long _ex_trap_c /* 0x04 - User Defined - dump trace buffer */
.long _ex_replaceable /* 0x05 - User Defined */ .long _ex_replaceable /* 0x05 - User Defined */
......
...@@ -1136,8 +1136,4 @@ void do_irq(int vec, struct pt_regs *fp) ...@@ -1136,8 +1136,4 @@ void do_irq(int vec, struct pt_regs *fp)
vec = ivg->irqno; vec = ivg->irqno;
} }
asm_do_IRQ(vec, fp); asm_do_IRQ(vec, fp);
#ifdef CONFIG_KGDB
kgdb_process_breakpoint();
#endif
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment