2003-02-06 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / gdb / sparclet-rom.c
CommitLineData
c906108c 1/* Remote target glue for the SPARC Sparclet ROM monitor.
b5a2688f
AC
2
3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
4 Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23
24#include "defs.h"
25#include "gdbcore.h"
26#include "target.h"
27#include "monitor.h"
28#include "serial.h"
29#include "srec.h"
30#include "symtab.h"
c5aa993b 31#include "symfile.h" /* for generic_load */
4e052eda 32#include "regcache.h"
c906108c
SS
33#include <time.h>
34
a14ed312 35extern void report_transfer_performance (unsigned long, time_t, time_t);
c906108c
SS
36
37static struct target_ops sparclet_ops;
38
a14ed312 39static void sparclet_open (char *args, int from_tty);
c906108c
SS
40
41/* This array of registers need to match the indexes used by GDB.
42 This exists because the various ROM monitors use different strings
43 than does GDB, and don't necessarily support all the registers
44 either. So, typing "info reg sp" becomes a "r30". */
45
46/*PSR 0x00000080 impl ver icc AW LE EE EC EF PIL S PS ET CWP WIM
c5aa993b
JM
47 0x0 0x0 0x0 0 0 0 0 0 0x0 1 0 0 0x00 0x2
48 0000010
49 INS LOCALS OUTS GLOBALS
50 0 0x00000000 0x00000000 0x00000000 0x00000000
51 1 0x00000000 0x00000000 0x00000000 0x00000000
52 2 0x00000000 0x00000000 0x00000000 0x00000000
53 3 0x00000000 0x00000000 0x00000000 0x00000000
54 4 0x00000000 0x00000000 0x00000000 0x00000000
55 5 0x00000000 0x00001000 0x00000000 0x00000000
56 6 0x00000000 0x00000000 0x123f0000 0x00000000
57 7 0x00000000 0x00000000 0x00000000 0x00000000
58 pc: 0x12010000 0x00000000 unimp
59 npc: 0x12010004 0x00001000 unimp 0x1000
60 tbr: 0x00000000
61 y: 0x00000000
62 */
c906108c
SS
63/* these correspond to the offsets from tm-* files from config directories */
64
65/* is wim part of psr?? */
66/* monitor wants lower case */
5af923b0
MS
67static char *sparclet_regnames[] = {
68 "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
69 "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
70 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
71 "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
72
73 "", "", "", "", "", "", "", "", /* no FPU regs */
74 "", "", "", "", "", "", "", "",
75 "", "", "", "", "", "", "", "",
76 "", "", "", "", "", "", "", "",
77 /* no CPSR, FPSR */
78 "y", "psr", "wim", "tbr", "pc", "npc", "", "",
79
80 "ccsr", "ccpr", "cccrcr", "ccor", "ccobr", "ccibr", "ccir", "",
81
82 /* ASR15 ASR19 (don't display them) */
83 "asr1", "", "asr17", "asr18", "", "asr20", "asr21", "asr22",
84/*
85 "awr0", "awr1", "awr2", "awr3", "awr4", "awr5", "awr6", "awr7",
86 "awr8", "awr9", "awr10", "awr11", "awr12", "awr13", "awr14", "awr15",
87 "awr16", "awr17", "awr18", "awr19", "awr20", "awr21", "awr22", "awr23",
88 "awr24", "awr25", "awr26", "awr27", "awr28", "awr29", "awr30", "awr31",
89 "apsr",
90 */
91};
92
c906108c
SS
93
94
95/* Function: sparclet_supply_register
96 Just returns with no action.
97 This function is required, because parse_register_dump (monitor.c)
98 expects to be able to call it. If we don't supply something, it will
99 call a null pointer and core-dump. Since this function does not
100 actually do anything, GDB will request the registers individually. */
101
102static void
fba45db2 103sparclet_supply_register (char *regname, int regnamelen, char *val, int vallen)
c906108c
SS
104{
105 return;
106}
107
108static void
819cc324 109sparclet_load (struct serial *desc, char *file, int hashmark)
c906108c
SS
110{
111 bfd *abfd;
112 asection *s;
113 int i;
114 CORE_ADDR load_offset;
115 time_t start_time, end_time;
116 unsigned long data_count = 0;
117
118 /* enable user to specify address for downloading as 2nd arg to load */
119
c5aa993b
JM
120 i = sscanf (file, "%*s 0x%lx", &load_offset);
121 if (i >= 1)
c906108c
SS
122 {
123 char *p;
124
125 for (p = file; *p != '\000' && !isspace (*p); p++);
126
127 *p = '\000';
128 }
129 else
130 load_offset = 0;
131
132 abfd = bfd_openr (file, 0);
133 if (!abfd)
134 {
135 printf_filtered ("Unable to open file %s\n", file);
136 return;
137 }
138
139 if (bfd_check_format (abfd, bfd_object) == 0)
140 {
141 printf_filtered ("File is not an object file\n");
142 return;
143 }
c5aa993b 144
c906108c
SS
145 start_time = time (NULL);
146
147 for (s = abfd->sections; s; s = s->next)
148 if (s->flags & SEC_LOAD)
149 {
150 bfd_size_type section_size;
151 bfd_vma vma;
152
153 vma = bfd_get_section_vma (abfd, s) + load_offset;
154 section_size = bfd_section_size (abfd, s);
155
156 data_count += section_size;
157
158 printf_filtered ("%s\t: 0x%4x .. 0x%4x ",
159 bfd_get_section_name (abfd, s), vma,
160 vma + section_size);
161 gdb_flush (gdb_stdout);
162
163 monitor_printf ("load c r %x %x\r", vma, section_size);
164
165 monitor_expect ("load: loading ", NULL, 0);
166 monitor_expect ("\r", NULL, 0);
167
168 for (i = 0; i < section_size; i += 2048)
169 {
170 int numbytes;
171 char buf[2048];
172
173 numbytes = min (sizeof buf, section_size - i);
174
175 bfd_get_section_contents (abfd, s, buf, i, numbytes);
176
2cd58942 177 serial_write (desc, buf, numbytes);
c906108c
SS
178
179 if (hashmark)
180 {
181 putchar_unfiltered ('#');
182 gdb_flush (gdb_stdout);
183 }
184 } /* Per-packet (or S-record) loop */
185
186 monitor_expect_prompt (NULL, 0);
187
188 putchar_unfiltered ('\n');
189 } /* Loadable sections */
190
191 monitor_printf ("reg pc %x\r", bfd_get_start_address (abfd));
192 monitor_expect_prompt (NULL, 0);
193 monitor_printf ("reg npc %x\r", bfd_get_start_address (abfd) + 4);
194 monitor_expect_prompt (NULL, 0);
195
196 monitor_printf ("run\r");
197
198 end_time = time (NULL);
199
c5aa993b 200 if (hashmark)
c906108c
SS
201 putchar_unfiltered ('\n');
202
203 report_transfer_performance (data_count, start_time, end_time);
204
205 pop_target ();
206 push_remote_target (monitor_get_dev_name (), 1);
207
b5a2688f 208 throw_exception (RETURN_QUIT);
c906108c
SS
209}
210
211/* Define the monitor command strings. Since these are passed directly
212 through to a printf style function, we may include formatting
213 strings. We also need a CR or LF on the end. */
214
215/* need to pause the monitor for timing reasons, so slow it down */
216
c5aa993b
JM
217static char *sparclet_inits[] =
218{"\n\r\r\n", NULL};
c906108c 219
c5aa993b 220static struct monitor_ops sparclet_cmds;
c906108c 221
c5aa993b
JM
222static void
223init_sparclet_cmds (void)
c906108c 224{
c5aa993b
JM
225 sparclet_cmds.flags = MO_CLR_BREAK_USES_ADDR |
226 MO_HEX_PREFIX |
227 MO_NO_ECHO_ON_OPEN |
228 MO_NO_ECHO_ON_SETMEM |
229 MO_RUN_FIRST_TIME |
230 MO_GETMEM_READ_SINGLE; /* flags */
231 sparclet_cmds.init = sparclet_inits; /* Init strings */
232 sparclet_cmds.cont = "cont\r"; /* continue command */
233 sparclet_cmds.step = "step\r"; /* single step */
234 sparclet_cmds.stop = "\r"; /* break interrupts the program */
235 sparclet_cmds.set_break = "+bp %x\r"; /* set a breakpoint */
236 sparclet_cmds.clr_break = "-bp %x\r"; /* can't use "br" because only 2 hw bps are supported */
237 sparclet_cmds.clr_all_break = "-bp %x\r"; /* clear a breakpoint */
238 "-bp\r"; /* clear all breakpoints */
239 sparclet_cmds.fill = "fill %x -n %x -v %x -b\r"; /* fill (start length val) */
c906108c
SS
240 /* can't use "fi" because it takes words, not bytes */
241 /* ex [addr] [-n count] [-b|-s|-l] default: ex cur -n 1 -b */
c5aa993b
JM
242 sparclet_cmds.setmem.cmdb = "ex %x -b\r%x\rq\r"; /* setmem.cmdb (addr, value) */
243 sparclet_cmds.setmem.cmdw = "ex %x -s\r%x\rq\r"; /* setmem.cmdw (addr, value) */
244 sparclet_cmds.setmem.cmdl = "ex %x -l\r%x\rq\r"; /* setmem.cmdl (addr, value) */
245 sparclet_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
246 sparclet_cmds.setmem.resp_delim = NULL; /*": " *//* setmem.resp_delim */
247 sparclet_cmds.setmem.term = NULL; /*"? " *//* setmem.term */
248 sparclet_cmds.setmem.term_cmd = NULL; /*"q\r" *//* setmem.term_cmd */
c906108c
SS
249 /* since the parsing of multiple bytes is difficult due to
250 interspersed addresses, we'll only read 1 value at a time,
251 even tho these can handle a count */
252 /* we can use -n to set count to read, but may have to parse? */
c5aa993b
JM
253 sparclet_cmds.getmem.cmdb = "ex %x -n 1 -b\r"; /* getmem.cmdb (addr, #bytes) */
254 sparclet_cmds.getmem.cmdw = "ex %x -n 1 -s\r"; /* getmem.cmdw (addr, #swords) */
255 sparclet_cmds.getmem.cmdl = "ex %x -n 1 -l\r"; /* getmem.cmdl (addr, #words) */
256 sparclet_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, #dwords) */
257 sparclet_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
258 sparclet_cmds.getmem.term = NULL; /* getmem.term */
259 sparclet_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
260 sparclet_cmds.setreg.cmd = "reg %s 0x%x\r"; /* setreg.cmd (name, value) */
261 sparclet_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
262 sparclet_cmds.setreg.term = NULL; /* setreg.term */
263 sparclet_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
264 sparclet_cmds.getreg.cmd = "reg %s\r"; /* getreg.cmd (name) */
265 sparclet_cmds.getreg.resp_delim = " "; /* getreg.resp_delim */
266 sparclet_cmds.getreg.term = NULL; /* getreg.term */
267 sparclet_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
268 sparclet_cmds.dump_registers = "reg\r"; /* dump_registers */
269 sparclet_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
270 sparclet_cmds.supply_register = sparclet_supply_register; /* supply_register */
271 sparclet_cmds.load_routine = sparclet_load; /* load_routine */
272 sparclet_cmds.load = NULL; /* download command (srecs on console) */
273 sparclet_cmds.loadresp = NULL; /* load response */
274 sparclet_cmds.prompt = "monitor>"; /* monitor command prompt */
c906108c 275 /* yikes! gdb core dumps without this delimitor!! */
c5aa993b
JM
276 sparclet_cmds.line_term = "\r"; /* end-of-command delimitor */
277 sparclet_cmds.cmd_end = NULL; /* optional command terminator */
278 sparclet_cmds.target = &sparclet_ops; /* target operations */
279 sparclet_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
280 sparclet_cmds.regnames = sparclet_regnames; /* registers names */
281 sparclet_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
c906108c
SS
282};
283
284static void
fba45db2 285sparclet_open (char *args, int from_tty)
c906108c
SS
286{
287 monitor_open (args, &sparclet_cmds, from_tty);
288}
289
290void
fba45db2 291_initialize_sparclet (void)
c906108c
SS
292{
293 int i;
c5aa993b 294 init_sparclet_cmds ();
c906108c
SS
295
296 for (i = 0; i < NUM_REGS; i++)
297 if (sparclet_regnames[i][0] == 'c' ||
298 sparclet_regnames[i][0] == 'a')
c5aa993b 299 sparclet_regnames[i] = 0; /* mon can't report c* or a* regs */
c906108c 300
c5aa993b 301 sparclet_regnames[0] = 0; /* mon won't report %G0 */
c906108c
SS
302
303 init_monitor_ops (&sparclet_ops);
c5aa993b 304 sparclet_ops.to_shortname = "sparclet"; /* for the target command */
c906108c
SS
305 sparclet_ops.to_longname = "SPARC Sparclet monitor";
306 /* use SW breaks; target only supports 2 HW breakpoints */
c5aa993b
JM
307 sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint;
308 sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint;
c906108c 309
c5aa993b 310 sparclet_ops.to_doc =
c906108c
SS
311 "Use a board running the Sparclet debug monitor.\n\
312Specify the serial device it is connected to (e.g. /dev/ttya).";
313
314 sparclet_ops.to_open = sparclet_open;
315 add_target (&sparclet_ops);
316}
This page took 0.318607 seconds and 4 git commands to generate.