Imported Upstream version 7.9
[platform/upstream/gdb.git] / gdb / microblaze-rom.c
1 /* Remote debugging interface to Xilinx MicroBlaze.
2
3    Copyright (C) 2009-2015 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "gdbcore.h"
22 #include "target.h"
23 #include "monitor.h"
24 #include "serial.h"
25 #include "regcache.h"
26
27 void _initialize_picobug_rom (void);
28
29 static char *picobug_inits[] =
30 {"\r", NULL};
31
32 static struct target_ops picobug_ops;
33 static struct monitor_ops picobug_cmds;
34
35 /* Picobug only supports a subset of registers from MCore.  In reality,
36    it doesn't support ss1, either.  */
37 static char *picobug_regnames[] = {
38   "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
39   "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",
40   0,      0,      0,      0,      0,      0,      0,      0,
41   0,      0,      0,      0,      0,      0,      0,      0,
42   "psr",  "vbr",  "epsr", "fpsr", "epc",  "fpc",  0,      "ss1",
43   "ss2",  "ss3",  "ss4",  0,      0,      0,      0,      0,
44   0,      0,      0,      0,      0,      0,      0,      0,
45   0,      0,      0,      0,      0,      0,      0,      0,
46   "pc" };
47
48
49
50 static void
51 picobug_open (const char *args, int from_tty)
52 {
53   monitor_open (args, &picobug_cmds, from_tty);
54 }
55 /* We choose to write our own dumpregs routine, since the output of
56    the register dumping is rather difficult to encapsulate in a
57    regexp:
58
59 picobug> rd
60      pc 2f00031e      epc 2f00031e      fpc 00000000
61     psr 80000101     epsr 80000101     fpsr 00000000
62 ss0-ss4 bad0beef 00000000 00000000 00000000 00000000      vbr 30005c00
63   r0-r7 2f0fff4c 00000090 00000001 00000002 00000003 00000004 00000005 00000006
64  r8-r15 2f0fff64 00000000 00000000 00000000 00000000 00000000 00000000 2f00031e
65 */
66
67 static int
68 picobug_dumpregs (struct regcache *regcache)
69 {
70   struct gdbarch *gdbarch = get_regcache_arch (regcache);
71   char buf[1024];
72   int resp_len;
73   char *p;
74
75   /* Send the dump register command to the monitor and
76      get the reply.  */
77   monitor_printf (picobug_cmds.dump_registers);
78   resp_len = monitor_expect_prompt (buf, sizeof (buf));
79
80   p = strtok (buf, " \t\r\n");
81   while (p)
82     {
83       if (strchr (p, '-'))
84         {
85           /* Got a range.  Either r0-r7, r8-r15 or ss0-ss4.  */
86           if (strncmp (p, "r0", 2) == 0 || strncmp (p, "r8", 2) == 0)
87             {
88               int rn = (p[1] == '0' ? 0 : 8);
89               int i = 0;
90
91               /* Get the next 8 values and record them.  */
92               while (i < 8)
93                 {
94                   p = strtok (NULL, " \t\r\n");
95                   if (p)
96                     monitor_supply_register (regcache, rn + i, p);
97                   i++;
98                 }
99             }
100           else if (strncmp (p, "ss", 2) == 0)
101             {
102               /* Get the next five values, ignoring the first.  */
103               int rn;
104               p = strtok (NULL, " \t\r\n");
105               for (rn = 39; rn < 43; rn++)
106                 {
107                   p = strtok (NULL, " \t\r\n");
108                   if (p)
109                     monitor_supply_register (regcache, rn, p);
110                 }
111             }
112           else
113             {
114               break;
115             }
116         }
117       else
118         {
119           /* Simple register type, paired.  */
120           char *name = p;
121           int i;
122
123           /* Get and record value.  */
124           p = strtok (NULL, " \t\r\n");
125           if (p)
126             {
127               for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
128                 {
129                   if (picobug_regnames[i]
130                       && strcmp (picobug_regnames[i], name) == 0)
131                     break;
132                 }
133
134               if (i <= gdbarch_num_regs (gdbarch))
135                 monitor_supply_register (regcache, i, p);
136             }
137         }
138       p = strtok (NULL, " \t\r\n");
139     }
140
141   return 0;
142 }
143
144 static void
145 init_picobug_cmds (void)
146 {
147   picobug_cmds.flags = MO_GETMEM_NEEDS_RANGE | MO_CLR_BREAK_USES_ADDR
148                        | MO_PRINT_PROGRAM_OUTPUT;
149
150   picobug_cmds.init = picobug_inits;            /* Init strings         */
151   picobug_cmds.cont = "g\n";                    /* continue command     */
152   picobug_cmds.step = "s\n";                    /* single step          */
153   picobug_cmds.set_break = "br %x\n";           /* set a breakpoint     */
154   picobug_cmds.clr_break = "nobr %x\n";         /* clear a breakpoint   */
155   picobug_cmds.clr_all_break = "nobr\n";        /* clear all breakpoints */
156   picobug_cmds.setmem.cmdb = "mm %x %x ;b\n";   /* setmem.cmdb (addr, value) */
157   picobug_cmds.setmem.cmdw = "mm %x %x ;h\n";   /* setmem.cmdw (addr, value) */
158   picobug_cmds.setmem.cmdl = "mm %x %x ;w\n";   /* setmem.cmdl (addr, value) */
159   picobug_cmds.getmem.cmdb = "md %x %x\n";      /* getmem.cmdb (start addr,
160                                                    end addr)            */
161   picobug_cmds.getmem.resp_delim = ":";         /* getmem.resp_delim    */
162   picobug_cmds.setreg.cmd = "rm %s %x\n";       /* setreg.cmd (name, value) */
163   picobug_cmds.getreg.cmd = "rd %s\n";          /* getreg.cmd (name)    */
164   picobug_cmds.getreg.resp_delim = ":";         /* getreg.resp_delim    */
165   picobug_cmds.dump_registers = "rd\n";         /* dump_registers       */
166   picobug_cmds.dumpregs = picobug_dumpregs;     /* dump registers parser */
167   picobug_cmds.load = "lo\n";                   /* download command     */
168   picobug_cmds.prompt = "picobug> ";            /* monitor command prompt */
169   picobug_cmds.line_term = "\n";                /* end-of-line terminator */
170   picobug_cmds.target = &picobug_ops;           /* target operations    */
171   picobug_cmds.stopbits = SERIAL_1_STOPBITS;    /* number of stop bits  */
172   picobug_cmds.regnames = picobug_regnames;     /* registers names      */
173   picobug_cmds.num_breakpoints = 20;            /* number of breakpoints */
174   picobug_cmds.magic = MONITOR_OPS_MAGIC;       /* magic                */
175 }
176
177 void
178 _initialize_picobug_rom (void)
179 {
180   int i;
181
182   /* Initialize m32r RevC monitor target.  */
183   init_picobug_cmds ();
184   init_monitor_ops (&picobug_ops);
185   picobug_ops.to_shortname = "picobug";
186   picobug_ops.to_longname = "picobug monitor";
187   picobug_ops.to_doc = "Debug via the picobug monitor.\n\
188 Specify the serial device it is connected to (e.g. /dev/ttya).";
189   picobug_ops.to_open = picobug_open;
190
191   add_target (&picobug_ops);
192 }