I've just written and tested this kgdb patch for ARM920T cpus.
The development was aimed at providing a low-cost cross-debugging environment for a Samsung ARM board produced from SERP (www.serp.it) used in an Computer Architecture course taught at the university of Padova (IT) (www.dei.unipd.it).

It works with gdb software breakpoint (on the host computer). Also with an arm-linux- toolchain.

Eng. Antonio Barbalace
Istituto Gas Ionizzati del CNR
Consorzio RFX - Associazione EURATOM/ENEA sulla Fusione
Corso Stati Uniti 4, 35127 Padova - Italy
[email protected], http://www.igi.cnr.it


----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.

diff -r -u u-boot/common/kgdb.c u-boot-UniPd/common/kgdb.c
--- u-boot/common/kgdb.c        2007-11-06 18:07:07.000000000 +0100
+++ u-boot-UniPd/common/kgdb.c  2009-02-23 16:47:31.000000000 +0100
@@ -322,7 +322,7 @@
 
        kgdb_interruptible(0);
 
-       printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs));
+//     printf("kgdb: handle_exception; trap [0x%x]\n", kgdb_trap(regs));
 
        if (kgdb_setjmp((long*)error_jmp_buf) != 0)
                panic("kgdb: error or fault in entry init!\n");
@@ -457,10 +457,11 @@
                        }
 
                        goto doexit;
-
-               case 'S':    /* SSS  single step with signal SS */
-                       *ptr = '\0';    /* ignore the signal number for now */
-                       /* fall through */
+/*
+#ifdef _PPC
+               case 'S':    // SSS  single step with signal SS
+                       *ptr = '\0';    // ignore the signal number for now
+                       // fall through 
 
                case 's':
                        kd.extype = KGDBEXIT_SINGLE;
@@ -469,7 +470,8 @@
                                kd.exaddr = addr;
                                kd.extype |= KGDBEXIT_WITHADDR;
                        }
-
+#endif
+*/
                doexit:
 /* Need to flush the instruction cache here, as we may have deposited a
  * breakpoint, and the icache probably has no way of knowing that a data ref to
@@ -496,8 +498,12 @@
                        } else {
                                kgdb_error(KGDBERR_BADPARAMS);
                        }
-                       break;
-               }                       /* switch */
+               case 'q':
+                       if (!(strcmp(ptr, "Supported"))) {
+                               sprintf(remcomOutBuffer, "PacketSize=%d", 
BUFMAX);
+                       }
+                       break;                  
+               } /* switch */
 
                if (errnum != 0)
                        sprintf(remcomOutBuffer, "E%02d", errnum);
diff -r -u u-boot/cpu/arm920t/Makefile u-boot-UniPd/cpu/arm920t/Makefile
--- u-boot/cpu/arm920t/Makefile 2007-11-07 17:18:30.000000000 +0100
+++ u-boot-UniPd/cpu/arm920t/Makefile   2009-01-15 17:01:58.000000000 +0100
@@ -26,7 +26,8 @@
 LIB    = $(obj)lib$(CPU).a
 
 START  = start.o
-COBJS  = cpu.o interrupts.o 
+COBJS  = cpu.o interrupts.o
+SOBJS  = kgdb.o
 
 SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS) $(SOBJS))
diff -r -u u-boot/cpu/arm920t/interrupts.c u-boot-UniPd/cpu/arm920t/interrupts.c
--- u-boot/cpu/arm920t/interrupts.c     2007-11-06 18:11:29.000000000 +0100
+++ u-boot-UniPd/cpu/arm920t/interrupts.c       2009-01-19 22:55:29.000000000 
+0100
@@ -33,6 +33,10 @@
 #include <arm920t.h>
 #include <asm/proc-armv/ptrace.h>
 
+#if defined(CONFIG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
 #ifdef CONFIG_USE_IRQ
 /* enable IRQ interrupts */
 void enable_interrupts (void)
@@ -119,13 +123,26 @@
 
 void do_undefined_instruction (struct pt_regs *pt_regs)
 {
+#if defined(CONFIG_CMD_KGDB)
+       pt_regs->ARM_pc -= 4;
+       if (debugger_exception_handler && 
(*debugger_exception_handler)(pt_regs)) {
+               return;
+       }
+#else
        printf ("undefined instruction\n");
        show_regs (pt_regs);
        bad_mode ();
+#endif
 }
 
 void do_software_interrupt (struct pt_regs *pt_regs)
 {
+/*
+#if defined(CONFIG_CMD_KGDB)
+       if (debugger_exception_handler && 
(*debugger_exception_handler)(pt_regs))
+               return;
+#endif
+*/
        printf ("software interrupt\n");
        show_regs (pt_regs);
        bad_mode ();
@@ -133,13 +150,24 @@
 
 void do_prefetch_abort (struct pt_regs *pt_regs)
 {
+/*
+#if defined(CONFIG_CMD_KGDB)
+       if (debugger_exception_handler && 
(*debugger_exception_handler)(pt_regs))
+               return;
+#endif
+*/
        printf ("prefetch abort\n");
        show_regs (pt_regs);
        bad_mode ();
 }
 
 void do_data_abort (struct pt_regs *pt_regs)
-{
+{/*
+#if defined(CONFIG_CMD_KGDB)
+       if (debugger_exception_handler && 
(*debugger_exception_handler)(pt_regs))
+               return;
+#endif
+*/
        printf ("data abort\n");
        show_regs (pt_regs);
        bad_mode ();
@@ -154,6 +182,12 @@
 
 void do_fiq (struct pt_regs *pt_regs)
 {
+/*
+#if defined(CONFIG_CMD_KGDB)
+       if (debugger_exception_handler && 
(*debugger_exception_handler)(pt_regs))
+               return;
+#endif
+*/
        printf ("fast interrupt request\n");
        show_regs (pt_regs);
        bad_mode ();
@@ -161,19 +195,27 @@
 
 void do_irq (struct pt_regs *pt_regs)
 {
-#if defined (CONFIG_USE_IRQ)
-#if defined (ARM920_IRQ_CALLBACK)
-       ARM920_IRQ_CALLBACK();
-       return;
-#elif defined (CONFIG_ARCH_INTEGRATOR)
+//#if defined (CONFIG_USE_IRQ)
+//#if defined (ARM920_IRQ_CALLBACK)
+//     ARM920_IRQ_CALLBACK();
+//     return;
+//#elif defined (CONFIG_ARCH_INTEGRATOR)
        /* ASSUMED to be a timer interrupt  */
        /* Just clear it - count handled in */
        /* integratorap.c                   */
-       *(volatile ulong *)(CFG_TIMERBASE + 0x0C) = 0;
-#endif /* ARCH_INTEGRATOR */
-#else
+//     *(volatile ulong *)(CFG_TIMERBASE + 0x0C) = 0;
+//#endif /* ARCH_INTEGRATOR */
+//#else
+
+/*
+#if defined(CONFIG_CMD_KGDB)
+       if (debugger_exception_handler && 
(*debugger_exception_handler)(pt_regs))
+               return;
+#endif
+*/
        printf ("interrupt request\n");
        show_regs (pt_regs);
        bad_mode ();
-#endif
+
+//#endif
 }
diff -r -u u-boot/cpu/arm920t/s3c24x0/serial.c 
u-boot-UniPd/cpu/arm920t/s3c24x0/serial.c
--- u-boot/cpu/arm920t/s3c24x0/serial.c 2007-11-06 18:13:13.000000000 +0100
+++ u-boot-UniPd/cpu/arm920t/s3c24x0/serial.c   2009-01-15 17:29:24.000000000 
+0100
@@ -306,6 +306,114 @@
 
 #endif /* CONFIG_SERIAL_MULTI */
 
+#if defined(CONFIG_CMD_KGDB)
+/*
+  AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port
+  number 0 or number 1
+  - if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 :
+  configuration has been already done
+  - if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 :
+  configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE
+*/
+#if (CONFIG_KGDB_SER_INDEX & 2)
+void kgdb_serial_init (void)
+{
+       volatile char val;
+       unsigned short br_reg;
+
+       get_clocks ();
+       br_reg = (((((gd->cpu_clk / 16) / 18) * 10) / CONFIG_KGDB_BAUDRATE) +
+                 5) / 10;
+       /*
+        * Init onboard 16550 UART
+        */
+       out8 (ACTING_UART1_BASE + UART_LCR, 0x80);      /* set DLAB bit */
+       out8 (ACTING_UART1_BASE + UART_DLL, (br_reg & 0x00ff)); /* set divisor 
for 9600 baud */
+       out8 (ACTING_UART1_BASE + UART_DLM, ((br_reg & 0xff00) >> 8));  /* set 
divisor for 9600 baud */
+       out8 (ACTING_UART1_BASE + UART_LCR, 0x03);      /* line control 8 bits 
no parity */
+       out8 (ACTING_UART1_BASE + UART_FCR, 0x00);      /* disable FIFO */
+       out8 (ACTING_UART1_BASE + UART_MCR, 0x00);      /* no modem control DTR 
RTS */
+       val = in8 (ACTING_UART1_BASE + UART_LSR);       /* clear line status */
+       val = in8 (ACTING_UART1_BASE + UART_RBR);       /* read receive buffer 
*/
+       out8 (ACTING_UART1_BASE + UART_SCR, 0x00);      /* set scratchpad */
+       out8 (ACTING_UART1_BASE + UART_IER, 0x00);      /* set interrupt enable 
reg */
+}
+
+void putDebugChar (const char c)
+{
+       if (c == '\n')
+               serial_putc ('\r');
+
+       out8 (ACTING_UART1_BASE + UART_THR, c); /* put character out */
+
+       /* check THRE bit, wait for transfer done */
+       while ((in8 (ACTING_UART1_BASE + UART_LSR) & 0x20) != 0x20);
+}
+
+void putDebugStr (const char *s)
+{
+       while (*s) {
+               serial_putc (*s++);
+       }
+}
+
+int getDebugChar (void)
+{
+       unsigned char status = 0;
+
+       while (1) {
+               status = in8 (ACTING_UART1_BASE + UART_LSR);
+               if ((status & asyncLSRDataReady1) != 0x0) {
+                       break;
+               }
+               if ((status & ( asyncLSRFramingError1 |
+                               asyncLSROverrunError1 |
+                               asyncLSRParityError1  |
+                               asyncLSRBreakInterrupt1 )) != 0) {
+                       out8 (ACTING_UART1_BASE + UART_LSR,
+                             asyncLSRFramingError1 |
+                             asyncLSROverrunError1 |
+                             asyncLSRParityError1  |
+                             asyncLSRBreakInterrupt1);
+               }
+       }
+       return (0x000000ff & (int) in8 (ACTING_UART1_BASE));
+}
+
+void kgdb_interruptible (int yes)
+{
+       return;
+}
+
+#else  /* ! (CONFIG_KGDB_SER_INDEX & 2) */
+
+void kgdb_serial_init (void)
+{
+       serial_printf ("[on serial] ");
+}
+
+void putDebugChar (int c)
+{
+       serial_putc (c);
+}
+
+void putDebugStr (const char *str)
+{
+       serial_puts (str);
+}
+
+int getDebugChar (void)
+{
+       return serial_getc ();
+}
+
+void kgdb_interruptible (int yes)
+{
+       return;
+}
+#endif /* (CONFIG_KGDB_SER_INDEX & 2) */
+#endif
+
 #endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) ||
          defined(CONFIG_S3C2440) || defined (CONFIG_S3C2442) ||
          defined (CONFIG_TRAB) */
diff -r -u u-boot/cpu/arm920t/start.S u-boot-UniPd/cpu/arm920t/start.S
--- u-boot/cpu/arm920t/start.S  2008-01-21 11:27:32.000000000 +0100
+++ u-boot-UniPd/cpu/arm920t/start.S    2009-01-21 16:21:13.000000000 +0100
@@ -160,6 +160,8 @@
  */
 
 start_code:
+#define START_SVC32 1
+#if defined (START_SVC32)
        /*
         * set the cpu to SVC32 mode
         */
@@ -167,6 +169,8 @@
        bic     r0,r0,#0x1f
        orr     r0,r0,#0xd3
        msr     cpsr,r0
+#else
+#endif
 
 #if defined (CONFIG_S3C2440) && defined (CFG_UART0_EARLY_INIT)
        # setup GPIOs
@@ -757,8 +761,8 @@
 #define I_BIT   0x80
 
 /*
- * use bad_save_user_regs for abort/prefetch/undef/swi ...
- * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
+ * use bad_save_user_regs for abort/prefetch/undef/swi
+ * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling 
  */
 
        .macro  bad_save_user_regs
@@ -780,7 +784,7 @@
        sub     sp, sp, #S_FRAME_SIZE
        stmia   sp, {r0 - r12}                  @ Calling r0-r12
        add     r7, sp, #S_PC
-       stmdb   r7, {sp, lr}^                   @ Calling SP, LR
+       stmdb   r7, {sp, lr}^                   @ NOTE: Save USER SP and LR
        str     lr, [r7, #0]                    @ Save calling PC
        mrs     r6, spsr
        str     r6, [r7, #4]                    @ Save CPSR
@@ -788,6 +792,57 @@
        mov     r0, sp
        .endm
 
+#if defined (CONFIG_CMD_KGDB)
+#if defined (START_SVC32)
+       /*
+        * if u-boot run in SVC32 mode is not so simple to access SVC sp and lr
+        * registers and kgdb need the exact content of this registers. ^ 
guarantee
+        * access to user registers but there is no simple way like sp_svc to 
access
+        * those registers. This solution work well with SVC <-> UND. doesn't 
work
+        * with USR <-> UND because writing mode bits is a privileged action.
+        * Probably more appropriate und_save_svc_regs/und_save_svc_regs will 
be written...
+        */
+       .macro  und_save_regs
+       sub     sp, sp, #S_FRAME_SIZE
+       stmia   sp, {r0 - r12}                  @ Calling r0-r12
+       add     r7, sp, #S_PC
+       str     lr, [r7, #0]                    @ Save calling PC
+       mrs     r6, spsr
+       str     r6, [r7, #4]                    @ Save CPSR
+       str     r0, [r7, #8]                    @ Save OLD_R0
+
+       mrs     r0, cpsr                        @ move cpsr in r0
+       msr     cpsr_c, r6                      @ move in the previous mode and 
save sp and lr in 
+       mov     r1, sp                          @ r1 and
+       mov     r2, lr                          @ r2 then
+        msr     cpsr_c, r0                     @ return in the correct mode and
+
+       stmdb   r7, {r1, r2}                    @ save registers on the stack
+       mov     r0, sp
+       .endm
+
+       .macro  und_restore_regs
+       add     r7, sp, #S_PC                   @ set r7 to point program 
counter
+       ldr     r6, [r7, #4]                    @ load spsr in r6
+       ldmdb   r7, {r1, r2}                    @ load sp in r1 and lr in r2
+
+       mrs     r0, cpsr                        @ move cpsr in r0
+       msr     cpsr_c, r6                      @ move in the previous mode and 
restore r1 and r2 in 
+       mov     sp, r1                          @ sp and
+       mov     lr, r2                          @ lr then
+        msr     cpsr_c, r0                     @ return in the correct mode and
+
+       ldmia   sp, {r0 - r12}                  @ Calling r0 - lr
+       mov     r0, r0
+       ldr     lr, [sp, #S_PC]                 @ Get PC
+       add     sp, sp, #S_FRAME_SIZE
+       movs    pc, lr                          @ return & move spsr_svc into 
cpsr
+       .endm
+#else
+#endif /* START_SVC32 */
+
+#endif /* CONFIG_CMD_KGDB */
+
        .macro  irq_restore_user_regs
        ldmia   sp, {r0 - lr}^                  @ Calling r0 - lr
        mov     r0, r0
@@ -823,12 +878,24 @@
 /*
  * exception handlers
  */
+
+#if defined(CONFIG_CMD_KGDB)
+       .align  5
+undefined_instruction:
+       get_irq_stack
+       und_save_regs
+       bl      do_undefined_instruction
+       und_restore_regs
+
+#else /* CONFIG_CMD_KGDB */
        .align  5
 undefined_instruction:
        get_bad_stack
        bad_save_user_regs
        bl      do_undefined_instruction
 
+#endif /* CONFIG_CMD_KGDB */
+
        .align  5
 software_interrupt:
        get_bad_stack
@@ -854,7 +921,6 @@
        bl      do_not_used
 
 #ifdef CONFIG_USE_IRQ
-
        .align  5
 irq:
        get_irq_stack
@@ -871,7 +937,6 @@
        irq_restore_user_regs
 
 #else
-
        .align  5
 irq:
        get_bad_stack
diff -r -u u-boot/examples/Makefile u-boot-UniPd/examples/Makefile
--- u-boot/examples/Makefile    2007-11-06 18:07:07.000000000 +0100
+++ u-boot-UniPd/examples/Makefile      2009-01-15 19:54:59.000000000 +0100
@@ -30,7 +30,7 @@
 endif
 
 ifeq ($(ARCH),arm)
-LOAD_ADDR = 0xc100000
+LOAD_ADDR = 0x30000000
 endif
 
 ifeq ($(ARCH),mips)
diff -r -u u-boot/examples/hello_world.c u-boot-UniPd/examples/hello_world.c
--- u-boot/examples/hello_world.c       2007-11-06 18:07:07.000000000 +0100
+++ u-boot-UniPd/examples/hello_world.c 2009-01-19 15:14:08.000000000 +0100
@@ -49,6 +49,14 @@
        /* consume input */
        (void) getc();
 
-       printf ("\n\n");
+//     asm volatile ("\t.long 0xe7f001f0\n");
+       kgdb_breakpoint(argc, argv);
+
+       printf ("break0 test\n\n");
+       printf ("break1 test\n\n");
+       printf ("break2 test\n\n");
+
+//     asm volatile ("\t.long 0xef9f0001\n");
+
        return (0);
 }
diff -r -u u-boot/include/_exports.h u-boot-UniPd/include/_exports.h
--- u-boot/include/_exports.h   2007-11-06 18:07:07.000000000 +0100
+++ u-boot-UniPd/include/_exports.h     2009-01-19 15:16:07.000000000 +0100
@@ -24,3 +24,6 @@
 EXPORT_FUNC(i2c_write)
 EXPORT_FUNC(i2c_read)
 #endif
+#ifdef CONFIG_CMD_KGDB
+EXPORT_FUNC(kgdb_breakpoint)
+#endif
\ No newline at end of file
diff -r -u u-boot/include/configs/serp.h u-boot-UniPd/include/configs/serp.h
--- u-boot/include/configs/serp.h       2007-12-05 15:12:22.000000000 +0100
+++ u-boot-UniPd/include/configs/serp.h 2009-01-15 12:59:37.000000000 +0100
@@ -111,6 +111,7 @@
 #define CONFIG_CMD_EXT2
 #define CONFIG_CMD_LICENSE
 #define CONFIG_CMD_TERMINAL
+#define CONFIG_CMD_KGDB
 
 #define CONFIG_BOOTDELAY       10
 #define CONFIG_BOOTARGS        ""
@@ -119,7 +120,6 @@
 #define CONFIG_DOS_PARTITION   1
 #if defined(CONFIG_CMD_KGDB)
 #define CONFIG_KGDB_BAUDRATE   115200          /* speed to run kgdb serial 
port */
-/* what's this ? it's not used anywhere */
 #define CONFIG_KGDB_SER_INDEX  1               /* which serial port to use */
 #endif
 
diff -r -u u-boot/include/exports.h u-boot-UniPd/include/exports.h
--- u-boot/include/exports.h    2007-11-06 18:07:07.000000000 +0100
+++ u-boot-UniPd/include/exports.h      2009-01-19 15:14:12.000000000 +0100
@@ -25,6 +25,9 @@
 void setenv (char *varname, char *varvalue);
 long simple_strtol(const char *cp,char **endp,unsigned int base);
 int strcmp(const char * cs,const char * ct);
+#ifdef CONFIG_CMD_KGDB
+void kgdb_breakpoint(int argc, char *argv[]);
+#endif
 #ifdef CONFIG_HAS_UID
 void forceenv (char *varname, char *varvalue);
 #endif
diff -r -u u-boot/lib_arm/Makefile u-boot-UniPd/lib_arm/Makefile
--- u-boot/lib_arm/Makefile     2007-11-06 18:07:08.000000000 +0100
+++ u-boot-UniPd/lib_arm/Makefile       2009-01-15 13:03:04.000000000 +0100
@@ -28,7 +28,7 @@
 SOBJS  = _ashldi3.o _ashrdi3.o _divsi3.o _modsi3.o _udivsi3.o _umodsi3.o
 
 COBJS  = armlinux.o board.o \
-         cache.o div0.o
+         cache.o div0.o kgdb.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
diff -r -u u-boot/lib_arm/board.c u-boot-UniPd/lib_arm/board.c
--- u-boot/lib_arm/board.c      2007-11-06 18:07:08.000000000 +0100
+++ u-boot-UniPd/lib_arm/board.c        2009-01-15 20:48:37.000000000 +0100
@@ -284,6 +284,8 @@
                }
        }
 
+
+
 #ifndef CFG_NO_FLASH
        /* configure available FLASH banks */
        size = flash_init ();
@@ -345,6 +347,11 @@
        serial_initialize();
 #endif
 
+#if defined(CONFIG_CMD_KGDB)
+       puts ("KGDB:  ");
+       kgdb_init ();
+#endif
+
        /* IP Address */
        gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
 
_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to