Add KGDB support for ARM platforms
PATCH 1/1 Add KGDB support for ARM platforms
These patches add kgdb support for ARM platforms.
The add and invocation of the bad_restore_user_regs macro in cpu/arm720t/start.S should be made to other cpu/arm*/start.S files as well.
--- common/kgdb.c | 30 ++++++ cpu/arm720t/start.S | 7 ++ include/asm-arm/kgdb.h | 67 ++++++++++++ include/kgdb.h | 33 ++++++ lib_arm/Makefile | 1 + lib_arm/board.c | 6 + lib_arm/interrupts.c | 10 ++ lib_arm/kgdb.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 416 insertions(+), 0 deletions(-) create mode 100644 include/asm-arm/kgdb.h create mode 100644 lib_arm/kgdb.c
common/kgdb.c +30 -0
@@ -220,6 +220,29 @@ hexToInt(char **ptr, int *intValue)return (numChars); } +/* 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 (kdp->hook_break && + !(*kdp->hook_break)(remcomInBuffer[0 ] =='Z' , addr)) +strcpy (remcomOutBuffer,"OK" ); +} +/* scan for the sequence $<data>#<checksum> */ static void getpacket (char *buffer)
@@ -341,11 +364,14 @@ 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" ); +memset (&kd,0 ,sizeof (kgdb_data));kgdb_enter (regs, &kd);if (first_entry) {
@@ -516,6 +542,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 LLLL bytes at address AA.AA return OK */ +case 'z' : +gdb_cmd_break (&kd); +break ; }/* switch */ if (errnum !=0 )
cpu/arm720t/start.S +7 -0
@@ -455,6 +455,12 @@ lock_loop: mov r0, sp .endm + .macro bad_restore_user_regs + ldr lr, [sp, #S_PSR] @ Get SVC cpsr + msr spsr_cxsf, lr + ldmia sp, {r0 - pc}^ @ Restore SVC registers + .endm + .macro irq_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12
@@ -506,6 +512,7 @@ undefined_instruction: get_bad_stack bad_save_user_regs bl do_undefined_instruction + bad_restore_user_regs .align 5 software_interrupt:
include/asm-arm/kgdb.h new file +67 -0
67 lines not on this page · raw message
include/kgdb.h +33 -0
@@ -8,6 +8,38 @@#define KGDBERR_MEMFAULT 3#define KGDBERR_NOSPACE 4#define KGDBERR_ALIGNFAULT 5 +#define KGDBERR_BPEXIST 6 +#define KGDBERR_BPNOENT 7 + +#ifndef BREAK_INSTR_SIZE +#define BREAK_INSTR_SIZE 4 +#endif + +#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
@@ -35,6 +67,7 @@ typedefint nregs;kgdb_reg regs[KGDBDATA_MAXREGS ];unsigned long private[KGDBDATA_MAXPRIV ]; +int (*hook_break)(int set,int addr); } kgdb_data;
lib_arm/Makefile +1 -0
@@ -44,6 +44,7 @@ COBJS-y += cache-cp15.o endif COBJS-y += interrupts.o COBJS-y += reset.o +COBJS-$(CONFIG_CMD_KGDB) += kgdb.o SRCS := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \ $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
lib_arm/board.c +6 -0
@@ -39,6 +39,7 @@*/ #include <common.h> +#include <watchdog.h> #include <command.h> #include <malloc.h> #include <stdio_dev.h>
@@ -381,6 +382,11 @@ void start_armboot (void)/* miscellaneous platform dependent initialisations */ misc_init_r ();#endif +#if defined(CONFIG_CMD_KGDB ) +WATCHDOG_RESET (); +puts ("KGDB: " ); +kgdb_init (); +#endif /* enable exceptions */ enable_interrupts ();
lib_arm/interrupts.c +10 -0
@@ -37,6 +37,10 @@#include <common.h> #include <asm/proc-armv/ptrace.h> +#include <kgdb.h> +#ifdef CONFIG_CMD_KGDB +#include <asm/kgdb.h> +#endif #ifdef CONFIG_USE_IRQ DECLARE_GLOBAL_DATA_PTR ;
@@ -137,6 +141,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 ();
lib_arm/kgdb.c new file +262 -0
262 lines not on this page · raw message
Signature · 1 line
1.6.0.6
PATCH 1/1 Add KGDB support for ARM platforms
These patches add kgdb support for ARM platforms.
The add and invocation of the bad_restore_user_regs macro in cpu/arm720t/start.S should be made to other cpu/arm*/start.S files as well.
---
?common/kgdb.c ? ? ? ? ?| ? 30 ++++++ ?cpu/arm720t/start.S ? ?| ? ?7 ++ ?include/asm-arm/kgdb.h | ? 67 ++++++++++++ ?include/kgdb.h ? ? ? ? | ? 33 ++++++ ?lib_arm/Makefile ? ? ? | ? ?1 + ?lib_arm/board.c ? ? ? ?| ? ?6 + ?lib_arm/interrupts.c ? | ? 10 ++ ?lib_arm/kgdb.c ? ? ? ? | ?262 ++++++++++++++++++++++++++++++++++++++++++++++++
?8 files changed, 416 insertions(+), 0 deletions(-) ?create mode 100644 include/asm-arm/kgdb.h ?create mode 100644 lib_arm/kgdb.c
common/kgdb.c +0 -0
@@ -220,6 +220,29 @@ hexToInt(char **ptr, int *intValue)
? ? ? ?return (numChars);
?}
+/* 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 (kdp->hook_break &&
+ ? ? ? ? ? !(*kdp->hook_break)(remcomInBuffer[0] == 'Z', addr))
+ ? ? ? ? ? ? ? strcpy(remcomOutBuffer, "OK");
+}
+
?/* scan for the sequence $<data>#<checksum> ? ? */ ?static void
?getpacket(char *buffer)
@@ -341,11 +364,14 @@ 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");
+ ? ? ? memset(&kd, 0, sizeof(kgdb_data));
? ? ? ?kgdb_enter(regs, &kd);
? ? ? ?if (first_entry) {
@@ -516,6 +542,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 LLLL bytes at address AA.AA return OK */
+ ? ? ? ? ? ? ? case 'z':
+ ? ? ? ? ? ? ? ? ? ? ? gdb_cmd_break(&kd);
+ ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? /* switch */
? ? ? ? ? ? ? ?if (errnum != 0)
cpu/arm720t/start.S +0 -0
@@ -455,6 +455,12 @@ lock_loop:
? ? ? ?mov ? ? r0, sp
? ? ? ?.endm
+ ? ? ? .macro ?bad_restore_user_regs
+ ? ? ? ldr ? ? lr, [sp, #S_PSR] ? ? ? ? ? ? ? ?@ Get SVC cpsr
+ ? ? ? msr ? ? spsr_cxsf, lr
+ ? ? ? ldmia ? sp, {r0 - pc}^ ? ? ? ? ? ? ? ? ?@ Restore SVC registers
+ ? ? ? .endm
+
? ? ? ?.macro ?irq_save_user_regs
? ? ? ?sub ? ? sp, sp, #S_FRAME_SIZE
? ? ? ?stmia ? sp, {r0 - r12} ? ? ? ? ? ? ? ? ?@ Calling r0-r12 @@ -506,6 +512,7 @@ undefined_instruction:
? ? ? ?get_bad_stack
? ? ? ?bad_save_user_regs
? ? ? ?bl ? ? ?do_undefined_instruction
+ ? ? ? bad_restore_user_regs
? ? ? ?.align ?5
?software_interrupt:
include/asm-arm/kgdb.h new file +67 -0
67 lines not on this page · raw message
include/kgdb.h +0 -0
@@ -8,6 +8,38 @@
?#define KGDBERR_MEMFAULT ? ? ? 3
?#define KGDBERR_NOSPACE ? ? ? ? ? ? ? ?4
?#define KGDBERR_ALIGNFAULT ? ? 5
+#define KGDBERR_BPEXIST ? ? ? ? ? ? ? ?6
+#define KGDBERR_BPNOENT ? ? ? ? ? ? ? ?7
+
+#ifndef BREAK_INSTR_SIZE
+#define BREAK_INSTR_SIZE ? ? ? 4
+#endif
+
+#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
@@ -35,6 +67,7 @@ typedef
? ? ? ? ? ? ? ?int nregs;
? ? ? ? ? ? ? ?kgdb_reg regs[KGDBDATA_MAXREGS]; ? ? ? ? ? ? ? ?unsigned long private[KGDBDATA_MAXPRIV];
+ ? ? ? ? ? ? ? int (*hook_break)(int set, int addr); ? ? ? ?}
?kgdb_data;
lib_arm/Makefile +0 -0
@@ -44,6 +44,7 @@ COBJS-y ? ? ? += cache-cp15.o
?endif
?COBJS-y ? ? ? ?+= interrupts.o
?COBJS-y ? ? ? ?+= reset.o
+COBJS-$(CONFIG_CMD_KGDB) += kgdb.o
?SRCS ? := $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \
? ? ? ? ? $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
lib_arm/board.c +0 -0
@@ -39,6 +39,7 @@
?*/
?#include <common.h>
+#include <watchdog.h>
?#include <command.h>
?#include <malloc.h>
?#include <stdio_dev.h>
@@ -381,6 +382,11 @@ void start_armboot (void)
? ? ? ?/* miscellaneous platform dependent initialisations */ ? ? ? ?misc_init_r ();
?#endif
+#if defined(CONFIG_CMD_KGDB)
+ ? ? ? WATCHDOG_RESET();
+ ? ? ? puts("KGDB: ?");
+ ? ? ? kgdb_init();
+#endif
? ? ? ?/* enable exceptions */
? ? ? ?enable_interrupts ();
lib_arm/interrupts.c +0 -0
@@ -37,6 +37,10 @@
?#include <common.h>
?#include <asm/proc-armv/ptrace.h>
+#include <kgdb.h>
+#ifdef CONFIG_CMD_KGDB
+#include <asm/kgdb.h>
+#endif
?#ifdef CONFIG_USE_IRQ
?DECLARE_GLOBAL_DATA_PTR;
@@ -137,6 +141,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 ();
lib_arm/kgdb.c new file +262 -0
262 lines not on this page · raw message
--
1.6.0.6
PATCH 1/1 Add KGDB support for ARM platforms
common/kgdb.c hexToInt(char **ptr, int *intValue) · line 224
Quoted 8 lines · On Thursday 08 April 2010 05:40:02 Tonny Tzeng wrote:
common/kgdb.c +2
-0@@ -220,6 +220,29 @@ hexToInt(char **ptr, int *intValue)return (numChars); } +/* Handle the 'z' or 'Z' breakpoint remove or set packets */ +static void gdb_cmd_break (kgdb_data *kdp)
this breakpoint support isnt related to ARM KGDB at all. it should be split into a separate changeset.
common/kgdb.c hexToInt(char **ptr, int *intValue) · line 228
Quoted 4 lines
common/kgdb.c +1
-0if (kgdb_setjmp (error_jmp_buf) !=0 )panic ("kgdb: error or fault in entry init!\n" ); +memset (&kd,0 ,sizeof (kgdb_data));
there is no logic as to why this is needed. should probably be a different changeset too. personally, i'd also use sizeof(kd).
include/kgdb.h
Quoted 5 lines
include/kgdb.h +3
-0+#ifndef BREAK_INSTR_SIZE +#define BREAK_INSTR_SIZE 4 +#endif
i'm not sure this makes sense. every arch should define it themselves.
lib_arm/board.c void start_armboot (void) · line 389
Quoted 11 lines
lib_arm/board.c +5
-0@@ -381,6 +382,11 @@ void start_armboot (void)/* miscellaneous platform dependent initialisations */ misc_init_r ();#endif +#if defined(CONFIG_CMD_KGDB ) +WATCHDOG_RESET (); +puts ("KGDB: " ); +kgdb_init (); +#endif
the serial funcs (like puts()) already call the watchdog funcs. this call is spurious.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100408/f57875cb/attachment.pgp
PATCH 1/1 Add KGDB support for ARM platforms
Mike, thanks for your review. Here need your further clarifications, thanks in advance.
Quoted 7 lines · Mike Frysinger
Quoted 6 lines · On Thursday 08 April 2010 05:40:02 Tonny Tzeng wrote:
common/kgdb.c +0
-0@@ -220,6 +220,29 @@ hexToInt(char **ptr, int *intValue) ? ? ? ?return (numChars); ?}
Quoted 5 lines
common/kgdb.c hexToInt(char **ptr, int *intValue) · line 224
Quoted 2 lines
common/kgdb.c +2
-0+/* Handle the 'z' or 'Z' breakpoint remove or set packets */ +static void gdb_cmd_break (kgdb_data *kdp)this breakpoint support isnt related to ARM KGDB at all. ?it should be split into a separate changeset.
Yes, these 2 breakpoint commands are not specific to ARM, but I think they are mandatory required for debugging ARM kernel space, otherwise gdb will use M command to write a SWI instruction code to the trap location.
Anyway, agree with you that it might be more clear to separate these code to other patch, as this is going to modify to common/kgdb.c which is architecture / platform independent.
Quoted 7 lines
common/kgdb.c hexToInt(char **ptr, int *intValue) · line 228
Quoted 4 lines
common/kgdb.c +1
-0? ? ? ?if (kgdb_setjmp(error_jmp_buf) != 0) ? ? ? ? ? ? ? ?panic("kgdb: error or fault in entry init!\n"); + ? ? ? memset(&kd, 0, sizeof(kgdb_data));there is no logic as to why this is needed. ?should probably be a different changeset too. ?personally, i'd also use sizeof(kd).
Since I added a (*hook_break)() to the kgdb_data structure, and in order to make it transparent to other architectures (e.g. ppc, blackfin), I believe we need to clear the entire kd here. But will separate this into other patchset as your suggestion.
Quoted 7 lines
include/kgdb.h
Quoted 5 lines
include/kgdb.h +3
-0+#ifndef BREAK_INSTR_SIZE +#define BREAK_INSTR_SIZE ? ? ? 4 +#endif i'm not sure this makes sense. ?every arch should define it themselves.
Since this include/kgdb.h file has been referenced by other architectures, the existing code may not define BREAK_INSTR_SIZE, so this is to prevent the new added code break the KGDB support for other architectures.
Quoted 7 lines
Quoted 7 lines
lib_arm/board.c +0
-0@@ -381,6 +382,11 @@ void start_armboot (void)? ? ? ?/* miscellaneous platform dependent initialisations */ ? ? ? ?misc_init_r ();
?#endif
+#ifdefined(CONFIG_CMD_KGDB)
Quoted 8 lines
Quoted 4 lines
+ ? ? ?
WATCHDOG_RESET();
+ ? ? ?puts("KGDB: ?");
+ ? ? ?kgdb_init();
+#endifthe serial funcs (like
puts()) already call the watchdog funcs. ?this call is spurious.
-mike
These code are identical as ppc, m68k, and i386 architectures, and I check the serial driver of my board, it looks like some serial drivers may not call watchdog funcs, so I'd keep these changes. Any comment on this? Thanks.
Best Regards,
Tonny
PATCH 1/1 Add KGDB support for ARM platforms
Quoted 7 lines · On Friday 09 April 2010 11:32:19 Tonny Tzeng wrote:
Quoted 6 lines · Mike Frysinger
Quoted 4 lines · On Thursday 08 April 2010 05:40:02 Tonny Tzeng wrote:
if (kgdb_setjmp(error_jmp_buf) != 0) panic("kgdb: error or fault in entry init!\n");+
memset(&kd, 0, sizeof(kgdb_data));
Quoted 7 lines
Quoted 2 lines
there is no logic as to why this is needed. should probably be a different changeset too. personally, i'd also use sizeof(kd).
Since I added a (*hook_break)() to the
kgdb_datastructure, and in order to make it transparent to other architectures (e.g. ppc, blackfin), I believe we need to clear the entire kd here. But will separate this into other patchset as your suggestion.
hmm, kgdb_enter() is more for initializing state, not new hooks. my understanding is that either an arch always implements hook_break or it doesnt, it doesnt just do it some of the time.
that means the better way to add breakpoint support is via kgdb_stubs.c. add a new weak func to that where it always returns 0. then the remaining kgdb code can always assume the func exists and merely checks the return value.
although, now that i look at the breakpoint logic added to lib_arm/kgdb.c, it looks like most of that should be common code. the interface between common bp code and arch bp code should be the breakinst value (perhaps an unsigned char array encoding the opcode) and the size of the breakpoint array.
also, unless i missed something, your code that sets the bp is missing an icache flush.
Quoted 8 lines
Quoted 7 lines
include/kgdb.h
Quoted 5 lines
include/kgdb.h +3
-0+#ifndef BREAK_INSTR_SIZE +#define BREAK_INSTR_SIZE 4 +#endif i'm not sure this makes sense. every arch should define it themselves.
Quoted 4 lines
Since this
include/kgdb.hfile has been referenced by other architectures, the existing code may not defineBREAK_INSTR_SIZE, so this is to prevent the new added code break the KGDB support for other architectures.
i think an undefined size should be used as a tip that the arch doesnt yet support break points
Quoted 15 lines
Quoted 6 lines
Quoted 6 lines
lib_arm/board.c +0
-0@@ -381,6 +382,11 @@ void start_armboot (void)/* miscellaneous platform dependent initialisations */ misc_init_r ();#endif Quoted 8 lines
lib_arm/board.c void start_armboot (void) · line 389
Quoted 5 lines
lib_arm/board.c +5
-0+#if defined(CONFIG_CMD_KGDB ) +WATCHDOG_RESET (); +puts ("KGDB: " ); +kgdb_init (); +#endif the serial funcs (like
puts()) already call the watchdog funcs. this call is spurious.
Quoted 4 lines
These code are identical as ppc, m68k, and i386 architectures, and I check the serial driver of my board, it looks like some serial drivers may not call watchdog funcs, so I'd keep these changes. Any comment on this?
historical warts should be fixed, not extended. in other words, any serial driver not calling WATCHDOG_RESET() in putc()/tstc() is broken. i know this isnt documented properly, but it's still true. look at the cpu/blackfin/serial.c driver for a simple example.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100409/cac18593/attachment.pgp