📄 gdb-4.18-bdm-m68k.patch
字号:
+ downLoadStartAddress = bfd_get_start_address (abfd);+ downLoadBaseAddress = address;+ downLoaderFirst = 0;+ if (bdmDebugLevel)+ printf_filtered ("Start address:%#x Base address:%#x", downLoadStartAddress, downLoadBaseAddress);+ }++ /*+ * Set the appropriate destination address space+ */+ if (bfd_get_section_flags (abfd, sec) & SEC_CODE)+ dfc = 0x6; /* Supervisor program space */+ else+ dfc = 0x5; /* Supervisor data space */+ if (bdmWriteSystemRegister (BDM_REG_DFC, dfc) < 0) {+ downLoaderReturn = -1;+ return;+ }++ /*+ * Load the section in `sizeof cbuf` chunks+ */+ nleft = bfd_get_section_size_before_reloc (sec);+ if (nleft == 0)+ return;+ offset = 0;+ while (nleft) {+ if (nleft > sizeof cbuf)+ count = sizeof cbuf;+ else+ count = nleft;+ if (!bfd_get_section_contents (abfd, sec, cbuf, offset, count)) {+ downloadErrorString = "Error reading section contents";+ downLoaderReturn = -1;+ return;+ }+ if (bdmWriteMemory (address, cbuf, count) < 0) {+ downLoaderReturn = -1;+ return;+ }+ address += count;+ offset += count;+ nleft -= count;+ }+}++/*+ * Load an executable image into the target+ */+static int+loadExecutable (const char *name)+{+ bfd *abfd;+ unsigned long dfc;+ unsigned long l;++ /*+ * Make sure target is there+ */+ if (!bdmCheck ())+ return -1;++ /*+ * Open and verify the file+ */+ bfd_init ();+ abfd = bfd_openr (name, "default");+ if (abfd == NULL) {+ downloadErrorString = bfd_errmsg (bfd_get_error());+ return -1;+ }+ if (!bfd_check_format (abfd, bfd_object)) {+ downloadErrorString = "Not an object file";+ return -1;+ }++ /*+ * Save the destination function code register+ */+ if (bdmReadSystemRegister (BDM_REG_DFC, &dfc) < 0)+ return -1;++ /*+ * Load each section of the executable file+ */+ downLoaderFirst = 1;+ downLoaderReturn = 0;+ bfd_map_over_sections (abfd, downloadSection, NULL);+ if (downLoaderReturn < 0)+ return -1;++ /*+ * Set up stack pointer and program counter+ */+ if ((bdmReadLongWord (downLoadBaseAddress, &l) < 0)+ || (bdmWriteSystemRegister (BDM_REG_SSP, l) < 0)+ || (bdmReadLongWord (downLoadBaseAddress+4, &l) < 0)+ || (bdmWriteSystemRegister (BDM_REG_RPC, l) < 0)+ || (bdmWriteSystemRegister (BDM_REG_VBR, downLoadBaseAddress) < 0)+ || (bdmWriteSystemRegister (BDM_REG_DFC, dfc) < 0))+ return -1;+ return 0;+}++/*+ * The breakpoint codes for the different processors+ */+static char cpu32_breakpoint[] = {0x4a, 0xfa};+static char cf_breakpoint[] = {0x4a, 0xc8};+static char *breakpointCode;+static int breakpointSize;++unsigned char *m68k_bdm_breakpoint_from_pc (pcptr, lenptr)+ CORE_ADDR *pcptr;+ int *lenptr;+{+ *lenptr = breakpointSize;+ return breakpointCode;+}++/*+ * Short pause+ */+static void+nap (int microseconds)+{+ struct timeval tv;++ tv.tv_sec = microseconds / 1000000;+ tv.tv_usec = microseconds % 1000000;+ select (0, NULL, NULL, NULL, &tv);+}++/*+ * Display error message and jump back to main input loop+ */+static void+bdm_report_error (void)+{+ error ("BDM error: %s", bdmErrorString ());+}++/*+ * Initialize bdm interface port+ */+static void+bdm_init (int tty, char *arg)+{+}++/*+ * 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 ("BDM status: 0x%x\n", bdm_get_status ());+}++/*+ * release chip: reset and disable bdm mode+ */+static void+bdm_release_chip (void)+{+ haveAtemp = 0;+ registers_changed ();+ if (bdmRelease () < 0)+ bdm_report_error ();+}++/*+ * stop chip+ */+static void+bdm_stop_chip (void)+{+ if (bdmStop () < 0)+ bdm_report_error ();+}++/*+ * Allow chip to resume execution+ */+static void+bdm_go (void)+{+ haveAtemp = 0;+ if (bdmGo () < 0)+ bdm_report_error ();+}++/*+ * Reset chip, enter BDM mode+ */+static void+bdm_reset (void)+{+ registers_changed ();+ 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 ();+ haveAtemp = 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)+{+ 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) {+ 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;++ 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -