📄 gdb-5.3-bdm-m68k.patch
字号:
+ printf_filtered("bdm_delay is %d", bdm_delay);+ else + printf_filtered("using default delay %d", BDM_DEFAULT_DELAY);+ }+ else {+ bdm_delay = strtoul(arg, &dummy, 0);+ bdm_setdelay (bdm_delay);+ }+}++static void +bdm_setdebug_interactive (char *arg, int from_tty)+{+ char *dummy;++ if (arg) {+ bdmDebugLevel = strtoul(arg, &dummy, 0);+ bdmSetDebugFlag (bdmDebugLevel);+ }+ else+ error ("Argument missing");+}++static void +bdm_setdriverdebug_interactive (char *arg, int from_tty)+{+ char *dummy;++ if (arg)+ bdmSetDriverDebugFlag (strtoul(arg, &dummy, 0));+ else+ error ("Argument missing");+}++static void +bdm_set_no_wait (char *arg, int from_tty)+{+ bdm_gdb_no_wait = 1;+}++static void +bdm_set_wait (char *arg, int from_tty)+{+ if (cpu_type == BDM_CPU32) {+ error ("No wait mode is not supported on a CPU32");+ return;+ }+ if (bdm_get_status ())+ bdm_gdb_no_wait = 0;+ else+ error ("The target is running, please stop first");+}++static void +bdm_issue_stop (char *arg, int from_tty)+{+ bdm_stop_chip ();+}++/*+ * Open a connection the target via bdm+ * name is the devicename of bdm and the filename to be used+ * used for communication.+ */+static void+bdm_open (char *name, int from_tty)+{+ char *p;+ int version;+ unsigned long csr;++ if (bdmIsOpen ())+ error ("Bdm is already open, must close it first");+ if (name == NULL)+ error ("Use `target bdm <DEVICE-NAME>' to use the bdm target");++ /*+ * Find the first whitespace character after device and chop it off+ */+ for (p = name; (*p != '\0') && (!isspace (*p)); p++) ;+ if ((*p == '\0') && (p == name))+ error ("Please include the name the bdm port device.");+ dev_name = savestring (name, p - name);++ target_preopen (from_tty);+ unpush_target (&bdm_ops);++ if (bdmOpen (dev_name) < 0)+ bdm_report_error ();+ if (bdmStatus () & (BDM_TARGETPOWER | BDM_TARGETNC)) {+ bdmClose ();+ error ("Target or cable problem");+ }++ /*+ * Ask the driver for it's version.+ * We are only interested in the major number when checking the + * driver version number.+ */+ if (bdmGetDrvVersion (&version) < 0)+ bdm_report_error ();+ if ((version & 0xff00) != (BDM_DRV_VERSION & 0xff00)) {+ printf_filtered ("Incorrect driver version, looking for %i.%i"\+ " and found %i.%i\n", + BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff, + version >> 8, version & 0xff);+ bdmClose ();+ error ("Can't run with wrong BDM driver");+ }++ /*+ * Get the processor type.+ */+ if (bdmGetProcessor (&cpu_type) < 0)+ bdm_report_error ();+ switch (cpu_type) {+ case BDM_CPU32:+ bdm_reg_names = cpu32_reg_names;+ breakpointCode = cpu32_breakpoint;+ breakpointSize = sizeof cpu32_breakpoint;+ break;++ case BDM_COLDFIRE:+ bdm_reg_names = cf_reg_names;+ breakpointCode = cf_breakpoint;+ breakpointSize = sizeof cf_breakpoint;+ cf_init_watchpoints();++ /*+ * Read the CSR register to determine the debug module+ * version.+ */+ if (bdmReadSystemRegister (BDM_REG_CSR, &csr) < 0)+ bdm_report_error ();+ cf_debug_ver = (csr >> 20) & 0x0f;+ break;++ default:+ bdmClose ();+ error ("Unknown processor type returned from the driver.");+ }++ push_target (&bdm_ops);++ if (bdm_delay >= 0)+ bdm_setdelay (bdm_delay);+ else+ bdm_setdelay (BDM_DEFAULT_DELAY);+ if (from_tty)+ printf_filtered ("Remote %s connected to %s\n",+ target_shortname, dev_name);+ if (cpu_type == BDM_COLDFIRE)+ printf_filtered (" Coldfire debug module version is %ld (%s)\n",+ cf_debug_ver,+ cf_debug_ver == 0 ? "5206(e)" : "5307/5407(e)");+}++/*+ * Terminate current application and return to system prompt.+ * On a target, just let the program keep on running+ */+static void+bdm_kill (void)+{+#ifdef BDM_GDB_RELEASE_CPU_ON_EXIT+ if (bdm_get_status () & BDM_TARGETSTOPPED)+ bdm_go ();+#else + bdm_stop_chip ();+ bdm_reset ();+#endif+ bdm_prog_loaded = 0;+}++static void+bdm_close (quitting)+int quitting;+{+ if (quitting)+ bdm_kill ();+ bdmClose ();+}++/*+ * _detach -- Terminate the open connection to the remote debugger.+ * takes a program previously attached to and detaches it.+ * We better not have left any breakpoints+ * in the program or it'll die when it hits one.+ * Close the open connection to the remote debugger.+ * Use this when you want to detach and do something else+ * with your gdb.+ */+static void+bdm_detach (char *args, int from_tty)+{+ pop_target (); /* calls bdm_close to do the real work */+}++/*+ * _resume -- Tell the remote machine to resume.+ */+static void+bdm_resume (ptid_t pid, int step, enum target_signal sig)+{+ if (step)+ bdm_step_chip ();+ else+ bdm_go ();+}++/*+ * We have fallen into an exception supported by the runtime system.+ * by executing a `breakpoint' instruction.+ */+static void +analyze_exception (struct target_waitstatus *status)+{+ unsigned long pc, sp;+ unsigned short vec;+ char opcode[20]; /* `big enough' */++ if (cpu_type == BDM_CPU32) {+ if (bdmReadSystemRegister (BDM_REG_PCC, &pc) < 0)+ bdm_report_error ();+ }+ else {+ if (bdmReadSystemRegister (BDM_REG_RPC, &pc) < 0)+ bdm_report_error ();+ if (pc)+ pc -= 2;+ }+ status->kind = TARGET_WAITKIND_STOPPED;++ /*+ * See if it was a `breakpoint' instruction+ */+ if (bdmReadMemory (pc, opcode, breakpointSize) < 0)+ bdm_report_error ();+ if (memcmp (breakpointCode, opcode, breakpointSize) == 0) {+ if (bdmWriteSystemRegister (BDM_REG_RPC, pc) < 0)+ bdm_report_error ();+ status->value.sig = TARGET_SIGNAL_TRAP;+ return;+ }+ /*+ * FIXME: Why an illegal instruction signal ?+ */+ status->value.sig = TARGET_SIGNAL_ILL;+}++static int sigintFlag;+static void +bdm_signal_handler (int s)+{+ sigintFlag++;+}++/*+ * Wait until the remote machine stops, then return,+ * storing status in status just as `wait' would.+ */+static ptid_t+bdm_wait (ptid_t pid, struct target_waitstatus *status)+{+ unsigned long csr;+ int bdm_stat;+ int detach = 0;+ int ui_count = 0;+ void (*ofunc) ();++ hit_watchpoint = 0;+ if (bdm_gdb_no_wait) {+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_GRANT;+ return null_ptid;+ }++ status->kind = TARGET_WAITKIND_EXITED;+ status->value.integer = 0;++ /*+ * Catch SIGINT signals+ */+ sigintFlag = 0;+ ofunc = signal (SIGINT, bdm_signal_handler);++ /*+ * A work around a problem with the 5206e processor. Not sure+ * what the issue is. It could be the processor.+ */+ if (cpu_type == BDM_COLDFIRE && cf_debug_ver == 0)+ nap (10000);++ /*+ * Wait here till the target requires service+ */+ while ((bdm_stat = bdm_get_status ()) == 0) {+ ui_count = 0;+ while (ui_count++ < 6) {+ nap (50000);++ /* N.B. The UI may destroy our world (for instance by calling+ remote_stop,) in which case we want to get out of here as+ quickly as possible. It is not safe to touch scb, since+ someone else might have freed it. The ui_loop_hook signals that + we should exit by returning 1. */++ if (ui_loop_hook)+ detach = ui_loop_hook (0);++ if (detach || sigintFlag)+ bdm_stop_chip ();+ }+ }+ + signal (SIGINT, ofunc);++ /*+ * Determine why the target stopped+ */+ switch (bdm_stat) {+ case BDM_TARGETNC:+ status->kind = TARGET_WAITKIND_EXITED;+ status->value.integer = 9999;+ break;+ case BDM_TARGETPOWER:+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_PWR;+ break;+ case BDM_TARGETRESET:+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_ABRT;+ break;+ case BDM_TARGETSTOPPED:+ case BDM_TARGETHALT:+ case BDM_TARGETSTOPPED | BDM_TARGETHALT:+ if (sigintFlag) {+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_TSTP;+ }+ else {+ if (cpu_type == BDM_CPU32) {+ if (!haveAtemp+ && (bdmReadSystemRegister (BDM_REG_ATEMP, &atemp) < 0))+ bdm_report_error ();+ switch (atemp & 0xffff) {+ case 0xffff: /* double bus fault */+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_BUS;+ break;+ case 0x0: /* HW bkpt */+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_TRAP;+ break;+ case 0x1: /* background mode */+ analyze_exception (status);+ break;+ default:+ printf_filtered ("bdm_wait: Unknown atemp:%#lx\n", atemp);+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_GRANT;+ }+ }+ else {+ if (bdmReadSystemRegister (BDM_REG_CSR, &csr) < 0)+ bdm_report_error ();+ if (csr & 0x08000000) { /* double bus fault */+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_BUS;+ }+ else {+ if (csr & 0x04000000) { /* hardware trigger */+ hit_watchpoint = 1;+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_TRAP;+ }+ else {+ if (csr & 0x01000000) { /* -BKPT signal */+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_TRAP;+ }+ else {+ if (csr & 0x02000000) { /* HALT/software bkpt */+ analyze_exception (status);+ }+ else {+ printf_filtered ("bdm_wait: Unknown csr:%#lx",+ csr);+ status->kind = TARGET_WAITKIND_STOPPED;+ status->value.sig = TARGET_SIGNAL_GRANT;+ }+ }+ }+ }+ }+ }+ break;+ default:+ printf_filtered ("bdm_wait: Unknown BDM status: %#x", bdm_stat);+ break;+ }+ haveAtemp = 0;+ return null_ptid;+}++/*+ * The following routines handle the Coldfire hardware breakpoints. Only one+ * breakpoint supported so far, and it can be either a PC breakpoint or an+ * address watchpoint. Unfortunately, the TARGET_CAN_USE_HARDWARE_WATCHPOINT+ * macro only allows for bounds checking within one of the two types and not+ * limits that cover the sum of both, so extra work is needed.+ *+ * (Actually, very few processors seem to have much support for that routine+ * at all.)+ *+ * As a result, the way this is handled is that the can_use routine will allow+ * the first breakpoint of either type to be added. Any further checking so+ * that only one of the two can be used is done later when GDB actually tries+ * to create the breakpoints, usually when the processor is restarted.+ *+ * We keep a local copy of the breakpoints list becasue the chain that GDB+ * keeps isn't exported globally.+ *+ * While things could be simplified with only one breakpoint present, setting+ * up more general routines allows for later expansion if newer versions of+ * the ColdFire chip support more breakpoints at once.+ *+ * Also, the ColdFire supports things like multi-level triggers and triggers+ * based on the data bus instead of just the address bus. The GDB commands+ * don't allow for access to this, but much of it isn't necessary anyway,+ * as GDB has its own method of handling 'breakpoint conditions' that is+ * sufficient for most tasks.+ */++#define TDR_TRC_DDATA 0x00000000+#define TDR_TRC_HALT 0x40000000+#define TDR_TRC_DINT 0x80000000+#define TDR_L2_EBL 0x20000000+#define TDR_L2_ALL 0x1FFF0000+#define TDR_L2_EDLW 0x10000000+#define TDR_L2_EDWL 0x08000000+#define TDR_L2_EDWU 0x04000000+#define TDR_L2_EDLL 0x02000000+#define TDR_L2_EDLM 0x01000000+#define TDR_L2_EDUM 0x00800000+#define TDR_L2_EDUU 0x00400000+#define TDR_L2_DI 0x00200000+#define TDR_L2_EAI 0x00100000+#define TDR_L2_EAR 0x00080000+#define TDR_L2_EAL 0x00040000+#define TDR_L2_EPC 0x00020000+#define TDR_L2_PCI 0x00010000+#define TDR_L1_EBL 0x00002000+#define TDR_L1_ALL 0x00001FFF+#define TDR_L1_EDLW 0x00001000+#define TDR_L1_EDWL 0x00000800+#define TDR_L1_EDWU 0x00000400+#define TDR_L1_EDLL 0x00000200+#define TDR_L1_EDLM 0x00000100+#define TDR_L1_EDUM 0x00000080+#define TDR_L1_EDUU 0x00000040+#define TDR_L1_DI 0x00000020+#define TDR_L1_EAI 0x00000010+#define TDR_L1_EAR 0x00000008+#define TDR_L1_EAL 0x00000004+#define TDR_L1_EPC 0x00000002+#define TDR_L1_PCI 0x00000001++struct cf_break {+ enum target_hw_bp_type type;+ CORE_ADDR addr;+ int len;+};++#define CF_BREAKPOINT_MAX 1++static struct cf_break cf_breakpoints[CF_BREAKPOINT_MAX];+static int cf_breakpoint_count;++static int+cf_init_watchpoints(void)+{+ if (cpu_type != BDM_COLDFIRE) {+ return(-1);+ }+ cf_breakpoint_count = 0;+ if (bdmWriteSystemRegister (BDM_REG_TDR, TDR_TRC_HALT) < 0)+ bdm_report_error ();+ return(0);+}++int+cf_stopped_by_watchpoint(void)+{+ return hit_watchpoint;+}++int+cf_can_use_watchpoint(type, cnt, ot)+ enum target_hw_bp_type type;+ int cnt;+ int ot;+{+ unsigned long tdr;++ if (cpu_type != BDM_COLDFIRE) {+ return(0);+ }++ if (type == bp_hardware_breakpoint || type == bp_read_watchpoint ||+ type == bp_hardware_watchpoint || type == bp_access_watchpoint) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -