GDB (API)
|
00001 /* Remote debugging interface to Xilinx MicroBlaze. 00002 00003 Copyright (C) 2009-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "gdbcore.h" 00022 #include "target.h" 00023 #include "monitor.h" 00024 #include "gdb_string.h" 00025 #include "serial.h" 00026 #include "regcache.h" 00027 00028 void _initialize_picobug_rom (void); 00029 00030 static char *picobug_inits[] = 00031 {"\r", NULL}; 00032 00033 static struct target_ops picobug_ops; 00034 static struct monitor_ops picobug_cmds; 00035 00036 /* Picobug only supports a subset of registers from MCore. In reality, 00037 it doesn't support ss1, either. */ 00038 static char *picobug_regnames[] = { 00039 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 00040 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 00041 0, 0, 0, 0, 0, 0, 0, 0, 00042 0, 0, 0, 0, 0, 0, 0, 0, 00043 "psr", "vbr", "epsr", "fpsr", "epc", "fpc", 0, "ss1", 00044 "ss2", "ss3", "ss4", 0, 0, 0, 0, 0, 00045 0, 0, 0, 0, 0, 0, 0, 0, 00046 0, 0, 0, 0, 0, 0, 0, 0, 00047 "pc" }; 00048 00049 00050 00051 static void 00052 picobug_open (char *args, int from_tty) 00053 { 00054 monitor_open (args, &picobug_cmds, from_tty); 00055 } 00056 /* We choose to write our own dumpregs routine, since the output of 00057 the register dumping is rather difficult to encapsulate in a 00058 regexp: 00059 00060 picobug> rd 00061 pc 2f00031e epc 2f00031e fpc 00000000 00062 psr 80000101 epsr 80000101 fpsr 00000000 00063 ss0-ss4 bad0beef 00000000 00000000 00000000 00000000 vbr 30005c00 00064 r0-r7 2f0fff4c 00000090 00000001 00000002 00000003 00000004 00000005 00000006 00065 r8-r15 2f0fff64 00000000 00000000 00000000 00000000 00000000 00000000 2f00031e 00066 */ 00067 00068 static int 00069 picobug_dumpregs (struct regcache *regcache) 00070 { 00071 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00072 char buf[1024]; 00073 int resp_len; 00074 char *p; 00075 00076 /* Send the dump register command to the monitor and 00077 get the reply. */ 00078 monitor_printf (picobug_cmds.dump_registers); 00079 resp_len = monitor_expect_prompt (buf, sizeof (buf)); 00080 00081 p = strtok (buf, " \t\r\n"); 00082 while (p) 00083 { 00084 if (strchr (p, '-')) 00085 { 00086 /* Got a range. Either r0-r7, r8-r15 or ss0-ss4. */ 00087 if (strncmp (p, "r0", 2) == 0 || strncmp (p, "r8", 2) == 0) 00088 { 00089 int rn = (p[1] == '0' ? 0 : 8); 00090 int i = 0; 00091 00092 /* Get the next 8 values and record them. */ 00093 while (i < 8) 00094 { 00095 p = strtok (NULL, " \t\r\n"); 00096 if (p) 00097 monitor_supply_register (regcache, rn + i, p); 00098 i++; 00099 } 00100 } 00101 else if (strncmp (p, "ss", 2) == 0) 00102 { 00103 /* Get the next five values, ignoring the first. */ 00104 int rn; 00105 p = strtok (NULL, " \t\r\n"); 00106 for (rn = 39; rn < 43; rn++) 00107 { 00108 p = strtok (NULL, " \t\r\n"); 00109 if (p) 00110 monitor_supply_register (regcache, rn, p); 00111 } 00112 } 00113 else 00114 { 00115 break; 00116 } 00117 } 00118 else 00119 { 00120 /* Simple register type, paired. */ 00121 char *name = p; 00122 int i; 00123 00124 /* Get and record value. */ 00125 p = strtok (NULL, " \t\r\n"); 00126 if (p) 00127 { 00128 for (i = 0; i < gdbarch_num_regs (gdbarch); i++) 00129 { 00130 if (picobug_regnames[i] 00131 && strcmp (picobug_regnames[i], name) == 0) 00132 break; 00133 } 00134 00135 if (i <= gdbarch_num_regs (gdbarch)) 00136 monitor_supply_register (regcache, i, p); 00137 } 00138 } 00139 p = strtok (NULL, " \t\r\n"); 00140 } 00141 00142 return 0; 00143 } 00144 00145 static void 00146 init_picobug_cmds (void) 00147 { 00148 picobug_cmds.flags = MO_GETMEM_NEEDS_RANGE | MO_CLR_BREAK_USES_ADDR 00149 | MO_PRINT_PROGRAM_OUTPUT; 00150 00151 picobug_cmds.init = picobug_inits; /* Init strings */ 00152 picobug_cmds.cont = "g\n"; /* continue command */ 00153 picobug_cmds.step = "s\n"; /* single step */ 00154 picobug_cmds.set_break = "br %x\n"; /* set a breakpoint */ 00155 picobug_cmds.clr_break = "nobr %x\n"; /* clear a breakpoint */ 00156 picobug_cmds.clr_all_break = "nobr\n"; /* clear all breakpoints */ 00157 picobug_cmds.setmem.cmdb = "mm %x %x ;b\n"; /* setmem.cmdb (addr, value) */ 00158 picobug_cmds.setmem.cmdw = "mm %x %x ;h\n"; /* setmem.cmdw (addr, value) */ 00159 picobug_cmds.setmem.cmdl = "mm %x %x ;w\n"; /* setmem.cmdl (addr, value) */ 00160 picobug_cmds.getmem.cmdb = "md %x %x\n"; /* getmem.cmdb (start addr, 00161 end addr) */ 00162 picobug_cmds.getmem.resp_delim = ":"; /* getmem.resp_delim */ 00163 picobug_cmds.setreg.cmd = "rm %s %x\n"; /* setreg.cmd (name, value) */ 00164 picobug_cmds.getreg.cmd = "rd %s\n"; /* getreg.cmd (name) */ 00165 picobug_cmds.getreg.resp_delim = ":"; /* getreg.resp_delim */ 00166 picobug_cmds.dump_registers = "rd\n"; /* dump_registers */ 00167 picobug_cmds.dumpregs = picobug_dumpregs; /* dump registers parser */ 00168 picobug_cmds.load = "lo\n"; /* download command */ 00169 picobug_cmds.prompt = "picobug> "; /* monitor command prompt */ 00170 picobug_cmds.line_term = "\n"; /* end-of-line terminator */ 00171 picobug_cmds.target = &picobug_ops; /* target operations */ 00172 picobug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ 00173 picobug_cmds.regnames = picobug_regnames; /* registers names */ 00174 picobug_cmds.num_breakpoints = 20; /* number of breakpoints */ 00175 picobug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */ 00176 } 00177 00178 void 00179 _initialize_picobug_rom (void) 00180 { 00181 int i; 00182 00183 /* Initialize m32r RevC monitor target. */ 00184 init_picobug_cmds (); 00185 init_monitor_ops (&picobug_ops); 00186 picobug_ops.to_shortname = "picobug"; 00187 picobug_ops.to_longname = "picobug monitor"; 00188 picobug_ops.to_doc = "Debug via the picobug monitor.\n\ 00189 Specify the serial device it is connected to (e.g. /dev/ttya)."; 00190 picobug_ops.to_open = picobug_open; 00191 00192 add_target (&picobug_ops); 00193 }