Blackfin arch: add supporting for kgdb
authorSonic Zhang <sonic.zhang@analog.com>
Mon, 13 Oct 2008 06:07:19 +0000 (14:07 +0800)
committerBryan Wu <cooloney@kernel.org>
Mon, 13 Oct 2008 06:07:19 +0000 (14:07 +0800)
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
Documentation/blackfin/kgdb.txt [deleted file]
arch/blackfin/Kconfig.debug
arch/blackfin/include/asm/kgdb.h
arch/blackfin/kernel/kgdb.c
arch/blackfin/kernel/traps.c
arch/blackfin/mach-bf561/include/mach/mem_map.h
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/ints-priority.c

diff --git a/Documentation/blackfin/kgdb.txt b/Documentation/blackfin/kgdb.txt
deleted file mode 100644 (file)
index 84f6a48..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-                       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.
index 0afa898..2cb0a30 100644 (file)
@@ -2,6 +2,9 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
+config HAVE_ARCH_KGDB
+       def_bool y
+
 config DEBUG_MMRS
        bool "Generate Blackfin MMR tree"
        select DEBUG_FS
index 0f73847..26ebac6 100644 (file)
@@ -124,9 +124,16 @@ enum regnames {
 /* Number of bytes of registers.  */
 #define NUMREGBYTES BFIN_NUM_REGS*4
 
-#define BREAKPOINT() asm("   EXCPT 2;");
-#define BREAK_INSTR_SIZE       2
-#define HW_BREAKPOINT_NUM              6
+static inline void arch_kgdb_breakpoint(void)
+{
+       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 */
 #define WPPWR          0x1
@@ -163,10 +170,11 @@ enum regnames {
 #define WPDAEN1                0x8
 #define WPDCNTEN0      0x10
 #define WPDCNTEN1      0x20
+
 #define WPDSRC0                0xc0
-#define WPDACC0                0x300
+#define WPDACC0_OFFSET 8
 #define WPDSRC1                0xc00
-#define WPDACC1                0x3000
+#define WPDACC1_OFFSET 12
 
 /* Watchpoint status register bits mask */
 #define STATIA0                0x1
@@ -178,7 +186,4 @@ enum regnames {
 #define STATDA0                0x40
 #define STATDA1                0x80
 
-extern void kgdb_print(const char *fmt, ...);
-extern void init_kgdb_uart(void);
-
 #endif
index a1f9641..b795a20 100644 (file)
@@ -1,32 +1,9 @@
 /*
- * File:         arch/blackfin/kernel/kgdb.c
- * Based on:
- * Author:       Sonic Zhang
+ * arch/blackfin/kernel/kgdb.c - Blackfin kgdb pieces
  *
- * Created:
- * Description:
+ * Copyright 2005-2008 Analog Devices Inc.
  *
- * Rev:          $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
- *
- * Modified:
- *               Copyright 2005-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Licensed under the GPL-2 or later.
  */
 
 #include <linux/string.h>
 #include <linux/kgdb.h>
 #include <linux/console.h>
 #include <linux/init.h>
-#include <linux/debugger.h>
 #include <linux/errno.h>
 #include <linux/irq.h>
+#include <linux/uaccess.h>
 #include <asm/system.h>
 #include <asm/traps.h>
 #include <asm/blackfin.h>
+#include <asm/dma.h>
 
 /* Put the error code here just in case the user cares.  */
-int gdb_bf533errcode;
+int gdb_bfin_errcode;
 /* Likewise, the vector number here (since GDB only gets the signal
    number through the usual means, and that's not very specific).  */
-int gdb_bf533vector = -1;
+int gdb_bfin_vector = -1;
 
 #if KGDB_MAX_NO_CPUS != 8
 #error change the definition of slavecpulocks
 #endif
 
-void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+#ifdef CONFIG_BFIN_WDT
+# error "Please unselect blackfin watchdog driver before build KGDB."
+#endif
+
+void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
        gdb_regs[BFIN_R0] = regs->r0;
        gdb_regs[BFIN_R1] = regs->r1;
@@ -133,7 +115,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
        gdb_regs[BFIN_SEQSTAT] = p->thread.seqstat;
 }
 
-void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
        regs->r0 = gdb_regs[BFIN_R0];
        regs->r1 = gdb_regs[BFIN_R1];
@@ -199,171 +181,208 @@ struct hw_breakpoint {
        unsigned int dataacc:2;
        unsigned short count;
        unsigned int addr;
-} breakinfo[HW_BREAKPOINT_NUM];
+} breakinfo[HW_WATCHPOINT_NUM];
 
-int kgdb_arch_init(void)
-{
-       debugger_step = 0;
-
-       kgdb_remove_all_hw_break();
-       return 0;
-}
-
-int kgdb_set_hw_break(unsigned long addr)
+int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 {
        int breakno;
-       for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
-               if (!breakinfo[breakno].occupied) {
+       int bfin_type;
+       int dataacc = 0;
+
+       switch (type) {
+       case BP_HARDWARE_BREAKPOINT:
+               bfin_type = TYPE_INST_WATCHPOINT;
+               break;
+       case BP_WRITE_WATCHPOINT:
+               dataacc = 1;
+               bfin_type = TYPE_DATA_WATCHPOINT;
+               break;
+       case BP_READ_WATCHPOINT:
+               dataacc = 2;
+               bfin_type = TYPE_DATA_WATCHPOINT;
+               break;
+       case BP_ACCESS_WATCHPOINT:
+               dataacc = 3;
+               bfin_type = TYPE_DATA_WATCHPOINT;
+               break;
+       default:
+               return -ENOSPC;
+       }
+
+       /* Becasue hardware data watchpoint impelemented in current
+        * Blackfin can not trigger an exception event as the hardware
+        * instrction watchpoint does, we ignaore all data watch point here.
+        * They can be turned on easily after future blackfin design
+        * supports this feature.
+        */
+       for (breakno = 0; breakno < HW_INST_WATCHPOINT_NUM; breakno++)
+               if (bfin_type == breakinfo[breakno].type
+                       && !breakinfo[breakno].occupied) {
                        breakinfo[breakno].occupied = 1;
                        breakinfo[breakno].enabled = 1;
-                       breakinfo[breakno].type = 1;
                        breakinfo[breakno].addr = addr;
+                       breakinfo[breakno].dataacc = dataacc;
+                       breakinfo[breakno].count = 0;
                        return 0;
                }
 
        return -ENOSPC;
 }
 
-int kgdb_remove_hw_break(unsigned long addr)
+int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 {
        int breakno;
-       for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
-               if (breakinfo[breakno].addr == addr)
-                       memset(&(breakinfo[breakno]), 0, sizeof(struct hw_breakpoint));
+       int bfin_type;
+
+       switch (type) {
+       case BP_HARDWARE_BREAKPOINT:
+               bfin_type = TYPE_INST_WATCHPOINT;
+               break;
+       case BP_WRITE_WATCHPOINT:
+       case BP_READ_WATCHPOINT:
+       case BP_ACCESS_WATCHPOINT:
+               bfin_type = TYPE_DATA_WATCHPOINT;
+               break;
+       default:
+               return 0;
+       }
+       for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++)
+               if (bfin_type == breakinfo[breakno].type
+                       && breakinfo[breakno].occupied
+                       && breakinfo[breakno].addr == addr) {
+                       breakinfo[breakno].occupied = 0;
+                       breakinfo[breakno].enabled = 0;
+               }
 
        return 0;
 }
 
-void kgdb_remove_all_hw_break(void)
+void bfin_remove_all_hw_break(void)
 {
-       memset(breakinfo, 0, sizeof(struct hw_breakpoint)*8);
-}
+       int breakno;
 
-/*
-void kgdb_show_info(void)
-{
-       printk(KERN_DEBUG "hwd: wpia0=0x%x, wpiacnt0=%d, wpiactl=0x%x, wpstat=0x%x\n",
-               bfin_read_WPIA0(), bfin_read_WPIACNT0(),
-               bfin_read_WPIACTL(), bfin_read_WPSTAT());
+       memset(breakinfo, 0, sizeof(struct hw_breakpoint)*HW_WATCHPOINT_NUM);
+
+       for (breakno = 0; breakno < HW_INST_WATCHPOINT_NUM; breakno++)
+               breakinfo[breakno].type = TYPE_INST_WATCHPOINT;
+       for (; breakno < HW_WATCHPOINT_NUM; breakno++)
+               breakinfo[breakno].type = TYPE_DATA_WATCHPOINT;
 }
-*/
 
-void kgdb_correct_hw_break(void)
+void bfin_correct_hw_break(void)
 {
        int breakno;
-       int correctit;
-       uint32_t wpdactl = bfin_read_WPDACTL();
+       unsigned int wpiactl = 0;
+       unsigned int wpdactl = 0;
+       int enable_wp = 0;
+
+       for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++)
+               if (breakinfo[breakno].enabled) {
+                       enable_wp = 1;
 
-       correctit = 0;
-       for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) {
-               if (breakinfo[breakno].type == 1) {
                        switch (breakno) {
                        case 0:
-                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN0)) {
-                                       correctit = 1;
-                                       wpdactl &= ~(WPIREN01|EMUSW0);
-                                       wpdactl |= WPIAEN0|WPICNTEN0;
-                                       bfin_write_WPIA0(breakinfo[breakno].addr);
-                                       bfin_write_WPIACNT0(breakinfo[breakno].skip);
-                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN0)) {
-                                       correctit = 1;
-                                       wpdactl &= ~WPIAEN0;
-                               }
+                               wpiactl |= WPIAEN0|WPICNTEN0;
+                               bfin_write_WPIA0(breakinfo[breakno].addr);
+                               bfin_write_WPIACNT0(breakinfo[breakno].count
+                                       + breakinfo->skip);
                                break;
-
                        case 1:
-                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN1)) {
-                                       correctit = 1;
-                                       wpdactl &= ~(WPIREN01|EMUSW1);
-                                       wpdactl |= WPIAEN1|WPICNTEN1;
-                                       bfin_write_WPIA1(breakinfo[breakno].addr);
-                                       bfin_write_WPIACNT1(breakinfo[breakno].skip);
-                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN1)) {
-                                       correctit = 1;
-                                       wpdactl &= ~WPIAEN1;
-                               }
+                               wpiactl |= WPIAEN1|WPICNTEN1;
+                               bfin_write_WPIA1(breakinfo[breakno].addr);
+                               bfin_write_WPIACNT1(breakinfo[breakno].count
+                                       + breakinfo->skip);
                                break;
-
                        case 2:
-                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN2)) {
-                                       correctit = 1;
-                                       wpdactl &= ~(WPIREN23|EMUSW2);
-                                       wpdactl |= WPIAEN2|WPICNTEN2;
-                                       bfin_write_WPIA2(breakinfo[breakno].addr);
-                                       bfin_write_WPIACNT2(breakinfo[breakno].skip);
-                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN2)) {
-                                       correctit = 1;
-                                       wpdactl &= ~WPIAEN2;
-                               }
+                               wpiactl |= WPIAEN2|WPICNTEN2;
+                               bfin_write_WPIA2(breakinfo[breakno].addr);
+                               bfin_write_WPIACNT2(breakinfo[breakno].count
+                                       + breakinfo->skip);
                                break;
-
                        case 3:
-                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN3)) {
-                                       correctit = 1;
-                                       wpdactl &= ~(WPIREN23|EMUSW3);
-                                       wpdactl |= WPIAEN3|WPICNTEN3;
-                                       bfin_write_WPIA3(breakinfo[breakno].addr);
-                                       bfin_write_WPIACNT3(breakinfo[breakno].skip);
-                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN3)) {
-                                       correctit = 1;
-                                       wpdactl &= ~WPIAEN3;
-                               }
+                               wpiactl |= WPIAEN3|WPICNTEN3;
+                               bfin_write_WPIA3(breakinfo[breakno].addr);
+                               bfin_write_WPIACNT3(breakinfo[breakno].count
+                                       + breakinfo->skip);
                                break;
                        case 4:
-                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN4)) {
-                                       correctit = 1;
-                                       wpdactl &= ~(WPIREN45|EMUSW4);
-                                       wpdactl |= WPIAEN4|WPICNTEN4;
-                                       bfin_write_WPIA4(breakinfo[breakno].addr);
-                                       bfin_write_WPIACNT4(breakinfo[breakno].skip);
-                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN4)) {
-                                       correctit = 1;
-                                       wpdactl &= ~WPIAEN4;
-                               }
+                               wpiactl |= WPIAEN4|WPICNTEN4;
+                               bfin_write_WPIA4(breakinfo[breakno].addr);
+                               bfin_write_WPIACNT4(breakinfo[breakno].count
+                                       + breakinfo->skip);
                                break;
                        case 5:
-                               if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN5)) {
-                                       correctit = 1;
-                                       wpdactl &= ~(WPIREN45|EMUSW5);
-                                       wpdactl |= WPIAEN5|WPICNTEN5;
-                                       bfin_write_WPIA5(breakinfo[breakno].addr);
-                                       bfin_write_WPIACNT5(breakinfo[breakno].skip);
-                               } else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN5)) {
-                                       correctit = 1;
-                                       wpdactl &= ~WPIAEN5;
-                               }
+                               wpiactl |= WPIAEN5|WPICNTEN5;
+                               bfin_write_WPIA5(breakinfo[breakno].addr);
+                               bfin_write_WPIACNT5(breakinfo[breakno].count
+                                       + breakinfo->skip);
+                               break;
+                       case 6:
+                               wpdactl |= WPDAEN0|WPDCNTEN0|WPDSRC0;
+                               wpdactl |= breakinfo[breakno].dataacc
+                                       << WPDACC0_OFFSET;
+                               bfin_write_WPDA0(breakinfo[breakno].addr);
+                               bfin_write_WPDACNT0(breakinfo[breakno].count
+                                       + breakinfo->skip);
+                               break;
+                       case 7:
+                               wpdactl |= WPDAEN1|WPDCNTEN1|WPDSRC1;
+                               wpdactl |= breakinfo[breakno].dataacc
+                                       << WPDACC1_OFFSET;
+                               bfin_write_WPDA1(breakinfo[breakno].addr);
+                               bfin_write_WPDACNT1(breakinfo[breakno].count
+                                       + breakinfo->skip);
                                break;
                        }
                }
-       }
-       if (correctit) {
-               wpdactl &= ~WPAND;
-               wpdactl |= WPPWR;
-               /*printk("correct_hw_break: wpdactl=0x%x\n", wpdactl);*/
+
+       /* Should enable WPPWR bit first before set any other
+        * WPIACTL and WPDACTL bits */
+       if (enable_wp) {
+               bfin_write_WPIACTL(WPPWR);
+               CSYNC();
+               bfin_write_WPIACTL(wpiactl|WPPWR);
                bfin_write_WPDACTL(wpdactl);
                CSYNC();
-               /*kgdb_show_info();*/
        }
 }
 
 void kgdb_disable_hw_debug(struct pt_regs *regs)
 {
        /* Disable hardware debugging while we are in kgdb */
-       bfin_write_WPIACTL(bfin_read_WPIACTL() & ~0x1);
+       bfin_write_WPIACTL(0);
+       bfin_write_WPDACTL(0);
        CSYNC();
 }
 
-void kgdb_post_master_code(struct pt_regs *regs, int eVector, int err_code)
+#ifdef CONFIG_SMP
+void kgdb_passive_cpu_callback(void *info)
+{
+       kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+       smp_call_function(kgdb_passive_cpu_callback, NULL, 0, 0);
+}
+
+void kgdb_roundup_cpu(int cpu, unsigned long flags)
+{
+       smp_call_function_single(cpu, kgdb_passive_cpu_callback, NULL, 0, 0);
+}
+#endif
+
+void kgdb_post_primary_code(struct pt_regs *regs, int eVector, int err_code)
 {
        /* Master processor is completely in the debugger */
-       gdb_bf533vector = eVector;
-       gdb_bf533errcode = err_code;
+       gdb_bfin_vector = eVector;
+       gdb_bfin_errcode = err_code;
 }
 
-int kgdb_arch_handle_exception(int exceptionVector, int signo,
+int kgdb_arch_handle_exception(int vector, int signo,
                               int err_code, char *remcom_in_buffer,
                               char *remcom_out_buffer,
-                              struct pt_regs *linux_regs)
+                              struct pt_regs *regs)
 {
        long addr;
        long breakno;
@@ -385,44 +404,40 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo,
                /* try to read optional parameter, pc unchanged if no parm */
                ptr = &remcom_in_buffer[1];
                if (kgdb_hex2long(&ptr, &addr)) {
-                       linux_regs->retx = addr;
+                       regs->retx = addr;
                }
-               newPC = linux_regs->retx;
+               newPC = regs->retx;
 
                /* clear the trace bit */
-               linux_regs->syscfg &= 0xfffffffe;
+               regs->syscfg &= 0xfffffffe;
 
                /* set the trace bit if we're stepping */
                if (remcom_in_buffer[0] == 's') {
-                       linux_regs->syscfg |= 0x1;
-                       debugger_step = linux_regs->ipend;
-                       debugger_step >>= 6;
-                       for (i = 10; i > 0; i--, debugger_step >>= 1)
-                               if (debugger_step & 1)
+                       regs->syscfg |= 0x1;
+                       kgdb_single_step = regs->ipend;
+                       kgdb_single_step >>= 6;
+                       for (i = 10; i > 0; i--, kgdb_single_step >>= 1)
+                               if (kgdb_single_step & 1)
                                        break;
                        /* i indicate event priority of current stopped instruction
                         * user space instruction is 0, IVG15 is 1, IVTMR is 10.
-                        * debugger_step > 0 means in single step mode
+                        * kgdb_single_step > 0 means in single step mode
                         */
-                       debugger_step = i + 1;
-               } else {
-                       debugger_step = 0;
+                       kgdb_single_step = i + 1;
                }
 
-               wp_status = bfin_read_WPSTAT();
-               CSYNC();
-
-               if (exceptionVector == VEC_WATCH) {
-                       for (breakno = 0; breakno < 6; ++breakno) {
+               if (vector == VEC_WATCH) {
+                       wp_status = bfin_read_WPSTAT();
+                       for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++) {
                                if (wp_status & (1 << breakno)) {
                                        breakinfo->skip = 1;
                                        break;
                                }
                        }
+                       bfin_write_WPSTAT(0);
                }
-               kgdb_correct_hw_break();
 
-               bfin_write_WPSTAT(0);
+               bfin_correct_hw_break();
 
                return 0;
        }                       /* switch */
@@ -431,5 +446,385 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo,
 
 struct kgdb_arch arch_kgdb_ops = {
        .gdb_bpt_instr = {0xa1},
+#ifdef CONFIG_SMP
+       .flags = KGDB_HW_BREAKPOINT|KGDB_THR_PROC_SWAP,
+#else
        .flags = KGDB_HW_BREAKPOINT,
+#endif
+       .set_hw_breakpoint = bfin_set_hw_break,
+       .remove_hw_breakpoint = bfin_remove_hw_break,
+       .remove_all_hw_break = bfin_remove_all_hw_break,
+       .correct_hw_break = bfin_correct_hw_break,
 };
+
+static int hex(char ch)
+{
+       if ((ch >= 'a') && (ch <= 'f'))
+               return ch - 'a' + 10;
+       if ((ch >= '0') && (ch <= '9'))
+               return ch - '0';
+       if ((ch >= 'A') && (ch <= 'F'))
+               return ch - 'A' + 10;
+       return -1;
+}
+
+static int validate_memory_access_address(unsigned long addr, int size)
+{
+       int cpu = raw_smp_processor_id();
+
+       if (size < 0)
+               return EFAULT;
+       if (addr >= 0x1000 && (addr + size) <= physical_mem_end)
+               return 0;
+       if (addr >= SYSMMR_BASE)
+               return 0;
+       if (addr >= ASYNC_BANK0_BASE
+          && addr + size <= ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE)
+               return 0;
+       if (cpu == 0) {
+               if (addr >= L1_SCRATCH_START
+                  && (addr + size <= L1_SCRATCH_START + L1_SCRATCH_LENGTH))
+                       return 0;
+#if L1_CODE_LENGTH != 0
+               if (addr >= L1_CODE_START
+                  && (addr + size <= L1_CODE_START + L1_CODE_LENGTH))
+                       return 0;
+#endif
+#if L1_DATA_A_LENGTH != 0
+               if (addr >= L1_DATA_A_START
+                  && (addr + size <= L1_DATA_A_START + L1_DATA_A_LENGTH))
+                       return 0;
+#endif
+#if L1_DATA_B_LENGTH != 0
+               if (addr >= L1_DATA_B_START
+                  && (addr + size <= L1_DATA_B_START + L1_DATA_B_LENGTH))
+                       return 0;
+#endif
+#ifdef CONFIG_SMP
+       } else if (cpu == 1) {
+               if (addr >= COREB_L1_SCRATCH_START
+                  && (addr + size <= COREB_L1_SCRATCH_START
+                  + L1_SCRATCH_LENGTH))
+                       return 0;
+# if L1_CODE_LENGTH != 0
+               if (addr >= COREB_L1_CODE_START
+                  && (addr + size <= COREB_L1_CODE_START + L1_CODE_LENGTH))
+                       return 0;
+# endif
+# if L1_DATA_A_LENGTH != 0
+               if (addr >= COREB_L1_DATA_A_START
+                  && (addr + size <= COREB_L1_DATA_A_START + L1_DATA_A_LENGTH))
+                       return 0;
+# endif
+# if L1_DATA_B_LENGTH != 0
+               if (addr >= COREB_L1_DATA_B_START
+                  && (addr + size <= COREB_L1_DATA_B_START + L1_DATA_B_LENGTH))
+                       return 0;
+# endif
+#endif
+       }
+
+#if L2_LENGTH != 0
+       if (addr >= L2_START
+          && addr + size <= L2_START + L2_LENGTH)
+               return 0;
+#endif
+
+       return EFAULT;
+}
+
+/*
+ * Convert the memory pointed to by mem into hex, placing result in buf.
+ * Return a pointer to the last char put in buf (null). May return an error.
+ */
+int kgdb_mem2hex(char *mem, char *buf, int count)
+{
+       char *tmp;
+       int err = 0;
+       unsigned char *pch;
+       unsigned short mmr16;
+       unsigned long mmr32;
+       int cpu = raw_smp_processor_id();
+
+       if (validate_memory_access_address((unsigned long)mem, count))
+               return EFAULT;
+
+       /*
+        * We use the upper half of buf as an intermediate buffer for the
+        * raw memory copy.  Hex conversion will work against this one.
+        */
+       tmp = buf + count;
+
+       if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
+               switch (count) {
+               case 2:
+                       if ((unsigned int)mem % 2 == 0) {
+                               mmr16 = *(unsigned short *)mem;
+                               pch = (unsigned char *)&mmr16;
+                               *tmp++ = *pch++;
+                               *tmp++ = *pch++;
+                               tmp -= 2;
+                       } else
+                               err = EFAULT;
+                       break;
+               case 4:
+                       if ((unsigned int)mem % 4 == 0) {
+                               mmr32 = *(unsigned long *)mem;
+                               pch = (unsigned char *)&mmr32;
+                               *tmp++ = *pch++;
+                               *tmp++ = *pch++;
+                               *tmp++ = *pch++;
+                               *tmp++ = *pch++;
+                               tmp -= 4;
+                       } else
+                               err = EFAULT;
+                       break;
+               default:
+                       err = EFAULT;
+               }
+       } else if (cpu == 0 && (unsigned int)mem >= L1_CODE_START &&
+               (unsigned int)(mem + count) <= L1_CODE_START + L1_CODE_LENGTH
+#ifdef CONFIG_SMP
+               || cpu == 1 && (unsigned int)mem >= COREB_L1_CODE_START &&
+               (unsigned int)(mem + count) <=
+               COREB_L1_CODE_START + L1_CODE_LENGTH
+#endif
+               ) {
+               /* access L1 instruction SRAM*/
+               if (dma_memcpy(tmp, mem, count) == NULL)
+                       err = EFAULT;
+       } else
+               err = probe_kernel_read(tmp, mem, count);
+
+       if (!err) {
+               while (count > 0) {
+                       buf = pack_hex_byte(buf, *tmp);
+                       tmp++;
+                       count--;
+               }
+
+               *buf = 0;
+       }
+
+       return err;
+}
+
+/*
+ * Copy the binary array pointed to by buf into mem.  Fix $, #, and
+ * 0x7d escaped with 0x7d.  Return a pointer to the character after
+ * the last byte written.
+ */
+int kgdb_ebin2mem(char *buf, char *mem, int count)
+{
+       char *tmp_old;
+       char *tmp_new;
+       unsigned short *mmr16;
+       unsigned long *mmr32;
+       int err = 0;
+       int size = 0;
+       int cpu = raw_smp_processor_id();
+
+       tmp_old = tmp_new = buf;
+
+       while (count-- > 0) {
+               if (*tmp_old == 0x7d)
+                       *tmp_new = *(++tmp_old) ^ 0x20;
+               else
+                       *tmp_new = *tmp_old;
+               tmp_new++;
+               tmp_old++;
+               size++;
+       }
+
+       if (validate_memory_access_address((unsigned long)mem, size))
+               return EFAULT;
+
+       if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
+               switch (size) {
+               case 2:
+                       if ((unsigned int)mem % 2 == 0) {
+                               mmr16 = (unsigned short *)buf;
+                               *(unsigned short *)mem = *mmr16;
+                       } else
+                               return EFAULT;
+                       break;
+               case 4:
+                       if ((unsigned int)mem % 4 == 0) {
+                               mmr32 = (unsigned long *)buf;
+                               *(unsigned long *)mem = *mmr32;
+                       } else
+                               return EFAULT;
+                       break;
+               default:
+                       return EFAULT;
+               }
+       } else if (cpu == 0 && (unsigned int)mem >= L1_CODE_START &&
+               (unsigned int)(mem + count) < L1_CODE_START + L1_CODE_LENGTH
+#ifdef CONFIG_SMP
+               || cpu == 1 && (unsigned int)mem >= COREB_L1_CODE_START &&
+               (unsigned int)(mem + count) <=
+               COREB_L1_CODE_START + L1_CODE_LENGTH
+#endif
+               ) {
+               /* access L1 instruction SRAM */
+               if (dma_memcpy(mem, buf, size) == NULL)
+                       err = EFAULT;
+       } else
+               err = probe_kernel_write(mem, buf, size);
+
+       return err;
+}
+
+/*
+ * Convert the hex array pointed to by buf into binary to be placed in mem.
+ * Return a pointer to the character AFTER the last byte written.
+ * May return an error.
+ */
+int kgdb_hex2mem(char *buf, char *mem, int count)
+{
+       char *tmp_raw;
+       char *tmp_hex;
+       unsigned short *mmr16;
+       unsigned long *mmr32;
+       int cpu = raw_smp_processor_id();
+
+       if (validate_memory_access_address((unsigned long)mem, count))
+               return EFAULT;
+
+       /*
+        * We use the upper half of buf as an intermediate buffer for the
+        * raw memory that is converted from hex.
+        */
+       tmp_raw = buf + count * 2;
+
+       tmp_hex = tmp_raw - 1;
+       while (tmp_hex >= buf) {
+               tmp_raw--;
+               *tmp_raw = hex(*tmp_hex--);
+               *tmp_raw |= hex(*tmp_hex--) << 4;
+       }
+
+       if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
+               switch (count) {
+               case 2:
+                       if ((unsigned int)mem % 2 == 0) {
+                               mmr16 = (unsigned short *)tmp_raw;
+                               *(unsigned short *)mem = *mmr16;
+                       } else
+                               return EFAULT;
+                       break;
+               case 4:
+                       if ((unsigned int)mem % 4 == 0) {
+                               mmr32 = (unsigned long *)tmp_raw;
+                               *(unsigned long *)mem = *mmr32;
+                       } else
+                               return EFAULT;
+                       break;
+               default:
+                       return EFAULT;
+               }
+       } else if (cpu == 0 && (unsigned int)mem >= L1_CODE_START &&
+               (unsigned int)(mem + count) <= L1_CODE_START + L1_CODE_LENGTH
+#ifdef CONFIG_SMP
+               || cpu == 1 && (unsigned int)mem >= COREB_L1_CODE_START &&
+               (unsigned int)(mem + count) <=
+               COREB_L1_CODE_START + L1_CODE_LENGTH
+#endif
+               ) {
+               /* access L1 instruction SRAM */
+               if (dma_memcpy(mem, tmp_raw, count) == NULL)
+                       return EFAULT;
+       } else
+               return probe_kernel_write(mem, tmp_raw, count);
+       return 0;
+}
+
+int kgdb_validate_break_address(unsigned long addr)
+{
+       int cpu = raw_smp_processor_id();
+
+       if (addr >= 0x1000 && (addr + BREAK_INSTR_SIZE) <= physical_mem_end)
+               return 0;
+       if (addr >= ASYNC_BANK0_BASE
+          && addr + BREAK_INSTR_SIZE <= ASYNC_BANK3_BASE + ASYNC_BANK3_BASE)
+               return 0;
+#if L1_CODE_LENGTH != 0
+       if (cpu == 0 && addr >= L1_CODE_START
+          && addr + BREAK_INSTR_SIZE <= L1_CODE_START + L1_CODE_LENGTH)
+               return 0;
+# ifdef CONFIG_SMP
+       else if (cpu == 1 && addr >= COREB_L1_CODE_START
+          && addr + BREAK_INSTR_SIZE <= COREB_L1_CODE_START + L1_CODE_LENGTH)
+               return 0;
+# endif
+#endif
+#if L2_LENGTH != 0
+       if (addr >= L2_START
+          && addr + BREAK_INSTR_SIZE <= L2_START + L2_LENGTH)
+               return 0;
+#endif
+
+       return EFAULT;
+}
+
+int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
+{
+       int err;
+       int cpu = raw_smp_processor_id();
+
+       if ((cpu == 0 && (unsigned int)addr >= L1_CODE_START
+               && (unsigned int)(addr + BREAK_INSTR_SIZE)
+               < L1_CODE_START + L1_CODE_LENGTH)
+#ifdef CONFIG_SMP
+               || (cpu == 1 && (unsigned int)addr >= COREB_L1_CODE_START
+               && (unsigned int)(addr + BREAK_INSTR_SIZE)
+               < COREB_L1_CODE_START + L1_CODE_LENGTH)
+#endif
+               ) {
+               /* access L1 instruction SRAM */
+               if (dma_memcpy(saved_instr, (void *)addr, BREAK_INSTR_SIZE)
+                       == NULL)
+                       return -EFAULT;
+
+               if (dma_memcpy((void *)addr, arch_kgdb_ops.gdb_bpt_instr,
+                       BREAK_INSTR_SIZE) == NULL)
+                       return -EFAULT;
+
+               return 0;
+       } else {
+               err = probe_kernel_read(saved_instr, (char *)addr,
+                       BREAK_INSTR_SIZE);
+               if (err)
+                       return err;
+
+               return probe_kernel_write((char *)addr,
+                       arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
+       }
+}
+
+int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
+{
+       if ((unsigned int)addr >= L1_CODE_START &&
+               (unsigned int)(addr + BREAK_INSTR_SIZE) <
+                       L1_CODE_START + L1_CODE_LENGTH) {
+               /* access L1 instruction SRAM */
+               if (dma_memcpy((void *)addr, bundle, BREAK_INSTR_SIZE) == NULL)
+                       return -EFAULT;
+
+               return 0;
+       } else
+               return probe_kernel_write((char *)addr,
+                               (char *)bundle, BREAK_INSTR_SIZE);
+}
+
+int kgdb_arch_init(void)
+{
+       kgdb_single_step = 0;
+
+       bfin_remove_all_hw_break();
+       return 0;
+}
+
+void kgdb_arch_exit(void)
+{
+}
index bd41fca..8d561ba 100644 (file)
 #include <asm/dma.h>
 
 #ifdef CONFIG_KGDB
-# include <linux/debugger.h>
 # include <linux/kgdb.h>
 
 # define CHK_DEBUGGER_TRAP() \
        do { \
-               CHK_DEBUGGER(trapnr, sig, info.si_code, fp, ); \
+               kgdb_handle_exception(trapnr, sig, info.si_code, fp); \
        } while (0)
 # define CHK_DEBUGGER_TRAP_MAYBE() \
        do { \
@@ -300,7 +299,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
                info.si_code = SEGV_STACKFLOW;
                sig = SIGSEGV;
                printk(KERN_NOTICE EXC_0x03(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x04 - User Defined, Caught by default */
        /* 0x05 - User Defined, Caught by default */
@@ -329,7 +328,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
                info.si_code = TRAP_TRACEFLOW;
                sig = SIGTRAP;
                printk(KERN_NOTICE EXC_0x11(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x12 - Reserved, Caught by default */
        /* 0x13 - Reserved, Caught by default */
@@ -351,35 +350,35 @@ asmlinkage void trap_c(struct pt_regs *fp)
                info.si_code = ILL_ILLOPC;
                sig = SIGILL;
                printk(KERN_NOTICE EXC_0x21(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x22 - Illegal Instruction Combination, handled here */
        case VEC_ILGAL_I:
                info.si_code = ILL_ILLPARAOP;
                sig = SIGILL;
                printk(KERN_NOTICE EXC_0x22(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x23 - Data CPLB protection violation, handled here */
        case VEC_CPLB_VL:
                info.si_code = ILL_CPLB_VI;
                sig = SIGBUS;
                printk(KERN_NOTICE EXC_0x23(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x24 - Data access misaligned, handled here */
        case VEC_MISALI_D:
                info.si_code = BUS_ADRALN;
                sig = SIGBUS;
                printk(KERN_NOTICE EXC_0x24(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x25 - Unrecoverable Event, handled here */
        case VEC_UNCOV:
                info.si_code = ILL_ILLEXCPT;
                sig = SIGILL;
                printk(KERN_NOTICE EXC_0x25(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr,
                error case is handled here */
@@ -387,7 +386,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
                info.si_code = BUS_ADRALN;
                sig = SIGBUS;
                printk(KERN_NOTICE EXC_0x26(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
                break;
        /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */
        case VEC_CPLB_MHIT:
@@ -399,7 +397,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
                else
 #endif
                        printk(KERN_NOTICE EXC_0x27(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x28 - Emulation Watchpoint, handled here */
        case VEC_WATCH:
@@ -418,7 +416,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
                info.si_code = BUS_OPFETCH;
                sig = SIGBUS;
                printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n");
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
 #else
        /* 0x29 - Reserved, Caught by default */
@@ -428,21 +426,20 @@ asmlinkage void trap_c(struct pt_regs *fp)
                info.si_code = BUS_ADRALN;
                sig = SIGBUS;
                printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x2B - Instruction CPLB protection violation, handled here */
        case VEC_CPLB_I_VL:
                info.si_code = ILL_CPLB_VI;
                sig = SIGBUS;
                printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */
        case VEC_CPLB_I_M:
                info.si_code = ILL_CPLB_MISS;
                sig = SIGBUS;
                printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
                break;
        /* 0x2D - Instruction CPLB Multiple Hits, handled here */
        case VEC_CPLB_I_MHIT:
@@ -454,14 +451,14 @@ asmlinkage void trap_c(struct pt_regs *fp)
                else
 #endif
                        printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x2E - Illegal use of Supervisor Resource, handled here */
        case VEC_ILL_RES:
                info.si_code = ILL_PRVOPC;
                sig = SIGILL;
                printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        /* 0x2F - Reserved, Caught by default */
        /* 0x30 - Reserved, Caught by default */
@@ -508,14 +505,14 @@ asmlinkage void trap_c(struct pt_regs *fp)
                        printk(KERN_NOTICE HWC_default(KERN_NOTICE));
                        break;
                }
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        default:
                info.si_code = TRAP_ILLTRAP;
                sig = SIGTRAP;
                printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
                        (fp->seqstat & SEQSTAT_EXCAUSE));
-               CHK_DEBUGGER_TRAP();
+               CHK_DEBUGGER_TRAP_MAYBE();
                break;
        }
 
index c26d848..9d6674a 100644 (file)
 /* Memory Map for ADSP-BF561 processors */
 
 #ifdef CONFIG_BF561
-#define L1_CODE_START     0xFFA00000
-#define L1_DATA_A_START     0xFF800000
-#define L1_DATA_B_START     0xFF900000
+#define COREA_L1_CODE_START     0xFFA00000
+#define COREA_L1_DATA_A_START     0xFF800000
+#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
 
 
 /* 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
 
 #endif                         /* _MEM_MAP_533_H_ */
index 90c7397..5a219b2 100644 (file)
@@ -190,8 +190,8 @@ ENTRY(_ex_single_step)
        if cc jump .Lfind_priority_done;
        jump.s .Lfind_priority_start;
 .Lfind_priority_done:
-       p4.l = _debugger_step;
-       p4.h = _debugger_step;
+       p4.l = _kgdb_single_step;
+       p4.h = _kgdb_single_step;
        r6 = [p4];
        cc = r6 == 0;
        if cc jump .Ldo_single_step;
@@ -1071,7 +1071,12 @@ ENTRY(_ex_table)
         */
        .long _ex_syscall       /* 0x00 - User Defined - Linux Syscall */
        .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 */
+#endif
        .long _ex_trap_c        /* 0x03 - User Defined - userspace stack overflow */
        .long _ex_trap_c        /* 0x04 - User Defined - dump trace buffer */
        .long _ex_replaceable   /* 0x05 - User Defined */
index 5fa5367..ff4d5c2 100644 (file)
@@ -1136,8 +1136,4 @@ void do_irq(int vec, struct pt_regs *fp)
                vec = ivg->irqno;
        }
        asm_do_IRQ(vec, fp);
-
-#ifdef CONFIG_KGDB
-       kgdb_process_breakpoint();
-#endif
 }