📄 gdb-6.1-bdm-m68k.patch
字号:
+ if (bdmWriteSystemRegister (BDM_REG_TDR, tdr) < 0)+ bdm_report_error ();+ if (bdm_debug_level)+ printf_filtered ("Remove %s Watchpoint @0x%08lx-0x%08lx\n",+ (type == hw_read) ? "read" :+ ((type == hw_write) ? "write" : "access"),+ addr, addr+len-1);+ }+ else {+ return(-1);+ }+ return(0);+}++int+cf_stopped_data_address(void)+{+ unsigned long tdr;+ unsigned long ablr;++ if (cpu_type != BDM_COLDFIRE) {+ return(-1);+ }++ if (bdmReadSystemRegister (BDM_REG_TDR, &tdr) < 0)+ bdm_report_error ();+ if (bdmReadSystemRegister (BDM_REG_ABLR, &ablr) < 0)+ bdm_report_error ();++ if (tdr & TDR_L1_EAR) {+ return(ablr);+ }+ return(0);+}++#ifdef SYSCALL_TRAP+/* Immediately after a function call, return the saved pc before the frame+ is setup. For uCLinux which uses a TRAP #0 for a system call we need to+ read the first long word of the stack to see if the stack frame format is+ type 4 and the vector is 32 (0x4080), and the opcode at the PC is+ "move.w #0x2700,sr". If it is then get the second long from the stack. */++CORE_ADDR+m68k_bdm_saved_pc_after_call (struct frame_info *frame)+{+ unsigned int op;+ unsigned int eframe;+ int sp;+ + sp = read_register (SP_REGNUM);+ eframe = read_memory_integer (sp, 2);+ op = read_memory_integer (frame->pc, 4);++ /*+ * This test could break if some changes the syste call.+ */+ + if (eframe == 0x4080 && op == 0x46fc2700)+ return read_memory_integer (sp + 4, 4);+ else+ return read_memory_integer (sp, 4);+}+#endif /* SYSCALL_TRAP */+ +unsigned char *m68k_bdm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)+{+ *lenptr = breakpointSize;+ return breakpointCode;+}++/*+ * Short pause+ */+static void+nap (int microseconds)+{+#if defined (__MINGW32__)+ Sleep (microseconds / 1000);+#else+ struct timeval tv;++ tv.tv_sec = microseconds / 1000000;+ tv.tv_usec = microseconds % 1000000;+ select (0, NULL, NULL, NULL, &tv);+#endif+}++/*+ * Return interface status+ */+static int+bdm_get_status (void)+{+ int status;++ if ((status = bdmStatus ()) < 0)+ bdm_report_error ();+ return status;+}++static void+bdm_get_status_interactive (int pid, char *arg)+{+ printf_filtered ("BDM status: 0x%x\n", bdm_get_status ());+}++/*+ * release chip: reset and disable bdm mode+ */+static void+bdm_release_chip (void)+{+ have_atemp = 0;+ registers_changed ();+ inferior_ptid = bdm_ptid = null_ptid;+ if (bdmRelease () < 0)+ bdm_report_error ();+}++/*+ * stop chip+ */+static void+bdm_stop_chip (void)+{+ if (bdm_debug_level)+ printf_filtered ("bdm stop chip called\n");+ if (bdmStop () < 0)+ bdm_report_error ();+}++/*+ * Allow chip to resume execution+ */+static void+bdm_go (void)+{+ have_atemp = 0;+ if (bdmGo () < 0)+ bdm_report_error ();+}++/*+ * Reset chip, enter BDM mode+ */+static void+bdm_reset (void)+{+ have_atemp = 0;+ registers_changed ();+ inferior_ptid = bdm_ptid = null_ptid;+ if (bdmReset () < 0)+ bdm_report_error ();+ nap (TIME_TO_COME_UP);+}++/*+ * step cpu32 chip: execute a single instruction+ * This is complicated by the presence of interrupts.+ * Consider the following sequence of events:+ * - User attempts to `continue' from a breakpoint.+ * - Gdb calls bdm_step_chip to single-step the instruction that+ * had been replaced by the BGND instruction.+ * - The target processor executes the instruction and stops.+ * - GDB replaces the instruction with a BGND instruction to+ * force a breakpoint the next time the instruction is hit.+ * - GDB calls bdm_go and the target resumes execution.+ * This all seems fine, but now consider what happens when a interrupt+ * is pending:+ * - User attempts to `continue' from a breakpoint.+ * - Gdb calls bdm_step_chip to single-step the instruction that+ * had been replaced by the BGND instruction.+ * - The target processor does not execute the replaced instruction,+ * but rather executes the first instruction of the interrupt+ * service routine, then stops.+ * - GDB replaces the instruction with a BGND instruction to+ * force a breakpoint the next time the instruction is hit.+ * - GDB calls bdm_go and the target resumes execution.+ * - The target finishes off the interrupt, and upon returing from+ * the interrupt generates another breakpoint!+ * The solution is simple -- disable interrupts when single stepping.+ * The problem then becomes the handling of instructions which involve+ * the program status word!+ */+static void+bdm_step_cpu32_chip (void)+{+ unsigned long pc;+ unsigned short instruction;+ unsigned short immediate;+ unsigned long d7;+ unsigned long sr;+ unsigned long nsr;+ enum {+ op_other,+ op_ANDIsr,+ op_EORIsr,+ op_ORIsr,+ op_TOsr,+ op_FROMsr,+ op_FROMsrTOd7+ } op;++ /*+ * Get the existing status register+ */+ if (bdmReadSystemRegister (BDM_REG_SR, &sr) < 0)+ bdm_report_error ();++ /*+ * Read the instuction about to be executed+ */+ if ((bdmReadSystemRegister (BDM_REG_RPC, &pc) < 0)+ || (bdmReadWord (pc, &instruction) < 0))+ bdm_report_error ();++ /*+ * See what operation is to be performed+ */+ if (instruction == 0x027C)+ op = op_ANDIsr;+ else if (instruction == 0x0A7C)+ op = op_EORIsr;+ else if (instruction == 0x007C)+ op = op_ORIsr;+ else if (instruction == 0x40C7)+ op = op_FROMsrTOd7;+ else if ((instruction & 0xFFC0) == 0x40C0)+ op = op_FROMsr;+ else if ((instruction & 0xFFC0) == 0x46C0)+ op = op_TOsr;+ else+ op = op_other;++ /*+ * Set things up for the single-step operation+ */+ switch (op) {+ case op_FROMsr:+ /*+ * It's storing the SR somewhere.+ * Store the SR in D7 and change the instruction+ * to save D7. This fails if the addressing mode+ * is one of the esoteric modes that uses D7 as+ * and index register, but we'll just have to hope+ * that doesn't happen too often.+ */+ if ((bdmReadRegister (7, &d7) < 0)+ || (bdmWriteRegister (7, sr) < 0)+ || (bdmWriteWord (pc, 0x3007 |+ ((instruction & 0x38) << 3) |+ ((instruction & 0x07) << 9)) < 0))+ bdm_report_error ();+ break;++ case op_ANDIsr:+ case op_EORIsr:+ case op_ORIsr:+ /*+ * It's an immediate operation to the SR -- pick up the value+ */+ if (bdmReadWord (pc+2, &immediate) < 0)+ bdm_report_error ();+ break;++ case op_TOsr:+ case op_other:+ break;+ }++ /*+ * Ensure the step is done with interrupts disabled+ */+ if (bdmWriteSystemRegister (BDM_REG_SR, sr | 0x0700) < 0)+ bdm_report_error ();++ /*+ * Do the single-step+ */+ if (bdmStep () < 0)+ bdm_report_error ();++ /*+ * Get the ATEMP register since the following operations may+ * modify it.+ */+ if (bdmReadSystemRegister (BDM_REG_ATEMP, &atemp) < 0)+ bdm_report_error ();+ have_atemp = 1;++ /*+ * Clean things up+ */+ switch (op) {+ case op_FROMsr:+ if ((bdmWriteRegister (7, d7) < 0)+ || (bdmWriteWord (pc, instruction) < 0)+ || (bdmWriteSystemRegister (BDM_REG_SR, sr) < 0))+ bdm_report_error ();+ break;++ case op_FROMsrTOd7:+ if ((bdmReadRegister (7, &d7) < 0)+ || (bdmWriteRegister (7, (d7 & ~0xFFFF) | (sr & 0xFFFF)) < 0)+ || (bdmWriteSystemRegister (BDM_REG_SR, sr) < 0))+ bdm_report_error ();+ break;++ case op_ANDIsr:+ if (bdmWriteSystemRegister (BDM_REG_SR, sr & immediate) < 0)+ bdm_report_error ();+ break;+ + case op_EORIsr:+ if (bdmWriteSystemRegister (BDM_REG_SR, sr ^ immediate) < 0)+ bdm_report_error ();+ break;++ case op_ORIsr:+ if (bdmWriteSystemRegister (BDM_REG_SR, sr | immediate) < 0)+ bdm_report_error ();+ break;++ case op_TOsr:+ break;++ case op_other:+ if ((bdmReadSystemRegister (BDM_REG_SR, &nsr) < 0)+ || (bdmWriteSystemRegister (BDM_REG_SR, (nsr & ~0x0700) | (sr & 0x0700)) < 0))+ bdm_report_error ();+ break;+ }+}++static void+bdm_step_chip (void)+{+ /*+ * The cpu32 is harder to step than the Coldfire.+ */+ if (cpu_type == BDM_CPU32) {+ bdm_step_cpu32_chip();+ return;+ }++ /*+ * Do the single-step+ */+ if (bdmStep () < 0)+ bdm_report_error ();+}++/*+ * true if runnable+ */+static int+bdm_can_run (void)+{+ if (bdm_debug_level)+ printf_filtered ("bdm can run called\n");+ return 1;+}++static void+bdm_setdelay(int delay)+{+ if (bdmSetDelay (delay) < 0)+ bdm_report_error ();+}++static void +bdm_setdelay_interactive (char *arg, int from_tty)+{+ char *dummy;++ if (!arg) {+ if (bdm_delay >= 0)+ 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) {+ bdm_debug_level = strtoul(arg, &dummy, 0);+ bdmSetDebugFlag (bdm_debug_level);+ }+ 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -